diff --git a/Readme.md b/Readme.md index de2c0af..e58f68d 100644 --- a/Readme.md +++ b/Readme.md @@ -39,6 +39,25 @@ operating_system = user_agent.os operating_system.to_s => "Windows Vista" +# Device information can also be determined from some devices +user_agent = UserAgentParser.parse "Mozilla/5.0 (Linux; Android 7.0; SAMSUNG SM-G930T Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/5.0 Chrome/51.0.2704.106 Mobile Safari/537.36" +=> # +user_agent.device.family +=> "Samsung SM-G930T" +user_agent.device.brand +=> "Samsung" +user_agent.device.model "SM-G930T" + +user_agent = UserAgentParser.parse "Mozilla/5.0 (iPad; CPU OS 10_2_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) GSA/23.1.148956103 Mobile/14D27 Safari/600.1.4" +=> # +irb(main):026:0> user_agent.device.family +=> "iPad" +irb(main):027:0> user_agent.device.brand +=> "Apple" +irb(main):028:0> user_agent.device.model +=> "iPad" + + # The parser database will be loaded and parsed on every call to # UserAgentParser.parse. To avoid this, instantiate your own Parser instance. parser = UserAgentParser::Parser.new diff --git a/lib/user_agent_parser/device.rb b/lib/user_agent_parser/device.rb index d278238..5df7d25 100644 --- a/lib/user_agent_parser/device.rb +++ b/lib/user_agent_parser/device.rb @@ -1,11 +1,13 @@ module UserAgentParser class Device - attr_reader :family + attr_reader :family, :model, :brand alias_method :name, :family - def initialize(family = nil) + def initialize(family = nil, model = nil, brand = nil) @family = family || 'Other' + @model = model || @family + @brand = brand end def to_s diff --git a/lib/user_agent_parser/parser.rb b/lib/user_agent_parser/parser.rb index dfed166..c2b7de9 100644 --- a/lib/user_agent_parser/parser.rb +++ b/lib/user_agent_parser/parser.rb @@ -128,14 +128,26 @@ def os_from_pattern_match(pattern, match) def device_from_pattern_match(pattern, match) match = match.to_a.map(&:to_s) - family = match[1] + family = model = match[1] + brand = nil if pattern["device_replacement"] family = pattern["device_replacement"] match.each_with_index { |m,i| family = family.sub("$#{i}", m) } end + if pattern["model_replacement"] + model = pattern["model_replacement"] + match.each_with_index { |m,i| model = model.sub("$#{i}", m) } + end + if pattern["brand_replacement"] + brand = pattern["brand_replacement"] + match.each_with_index { |m,i| brand = brand.sub("$#{i}", m) } + brand.strip! + end + + model.strip! unless model.nil? - Device.new(family.strip) + Device.new(family.strip, model, brand) end def version_from_segments(*segments) diff --git a/spec/parser_spec.rb b/spec/parser_spec.rb index 11fbe00..f1239f1 100644 --- a/spec/parser_spec.rb +++ b/spec/parser_spec.rb @@ -21,6 +21,8 @@ def self.file_to_test_cases(file) 'minor' => test_case['minor'], 'patch' => test_case['patch'], 'patch_minor' => test_case['patch_minor'], + 'brand' => test_case['brand'], + 'model' => test_case['model'], } end.reject do |test_case| # We don't do the hacky javascript user agent overrides @@ -37,7 +39,7 @@ def self.file_to_yaml(resource) end def self.user_agent_test_cases - file_to_test_cases("test_resources/firefox_user_agent_strings.yaml") + file_to_test_cases("test_resources/firefox_user_agent_strings.yaml") file_to_test_cases("tests/test_ua.yaml") end @@ -83,7 +85,7 @@ def custom_patterns_path ua.device.family.must_equal("Custom device") end end - + describe "#parse" do user_agent_test_cases.each do |test_case| it "parses UA for #{test_case_to_test_name(test_case)}" do @@ -133,15 +135,20 @@ def custom_patterns_path end end end - + device_test_cases.each do |test_case| it "parses device for #{test_case_to_test_name(test_case)}" do user_agent = PARSER.parse(test_case['user_agent_string']) device = user_agent.device - if test_case['family'] device.family.must_equal_test_case_property(test_case, 'family') end + if test_case['model'] + device.model.must_equal_test_case_property(test_case, 'model') + end + if test_case['brand'] + device.brand.must_equal_test_case_property(test_case, 'brand') + end end end end