user_agent_parser 2.11.0 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b48c15771051ce967fbd02b30cebe742074d6cc363f202f8136d2da8fcb53eae
4
- data.tar.gz: cec1845c163e7d79d232b9216182f08e4a4ca25236c06328afd1aa7262c4b0f6
3
+ metadata.gz: 5f014ae2d784eb25f63242a361c9c9186ad108c7199fd1655944da1dcfeaff28
4
+ data.tar.gz: 36357407d451f17dada0fa4115f5f19e8a69af6932a1c3fc999ecd55abc958a0
5
5
  SHA512:
6
- metadata.gz: f1c6d56ffe6f50176dd812ca4e717a4c2e63079eae3d91dbadb17fbefe6efa825ae05394c02e3de909c8bd5c76587d41ec33bc5c5fa6b283d5f8d9bc08c081b5
7
- data.tar.gz: 8f50066203f91d2ac548db3326944c7bca38bb8fc355c7b34e012287e09c0199ce6da8aee707227e5944e482f11d53decd2afef63ba500d564045d6e01dc2158
6
+ metadata.gz: 1dfc2207de8b2345dcf21a0f271122f96259165fe115397ecb290f9fb07a9924e399554a5f23110c27f24976feae5b189a9a482386bb9f60d74ce542625eda61
7
+ data.tar.gz: 7abd96ee88bcca1d800323d3d9fd2f508b0b36dc20885a79e5bdfb58154a48a00ed60b0f7750e3eb0fd6570bbbebaac48355f5ba250c35f05ace615c41baa5d5
@@ -4,6 +4,8 @@ require 'yaml'
4
4
 
5
5
  module UserAgentParser
6
6
  class Parser
7
+ extend Gem::Deprecate
8
+
7
9
  FAMILY_REPLACEMENT_KEYS = %w[
8
10
  family_replacement
9
11
  v1_replacement
@@ -22,11 +24,13 @@ module UserAgentParser
22
24
 
23
25
  private_constant :FAMILY_REPLACEMENT_KEYS, :OS_REPLACEMENT_KEYS
24
26
 
25
- attr_reader :patterns_path
27
+ attr_reader :patterns_paths
28
+
29
+ def initialize(patterns_path: nil, patterns_paths: [])
30
+ @patterns_paths = [patterns_path, *patterns_paths].compact
31
+ @patterns_paths = [UserAgentParser::DefaultPatternsPath] if @patterns_paths.empty?
26
32
 
27
- def initialize(options = {})
28
- @patterns_path = options[:patterns_path] || UserAgentParser::DefaultPatternsPath
29
- @ua_patterns, @os_patterns, @device_patterns = load_patterns(patterns_path)
33
+ @ua_patterns, @os_patterns, @device_patterns = load_patterns(@patterns_paths)
30
34
  end
31
35
 
32
36
  def parse(user_agent)
@@ -35,19 +39,41 @@ module UserAgentParser
35
39
  parse_ua(user_agent, os, device)
36
40
  end
37
41
 
42
+ def patterns_path
43
+ patterns_paths.first
44
+ end
45
+ deprecate :patterns_path, :patterns_paths, 2022, 12
46
+
38
47
  private
39
48
 
40
- def load_patterns(path)
41
- yml = YAML.load_file(path)
49
+ def load_patterns(patterns_paths)
50
+ patterns_paths.each_with_object([[], [], []]) do |path, patterns|
51
+ ua_patterns, os_patterns, device_patterns = load_patterns_file(path)
52
+ patterns[0] += ua_patterns
53
+ patterns[1] += os_patterns
54
+ patterns[2] += device_patterns
55
+ end
56
+ end
42
57
 
43
- # Parse all the regexs
44
- yml.each_pair do |_type, patterns|
45
- patterns.each do |pattern|
46
- pattern[:regex] = Regexp.new(pattern['regex'], pattern['regex_flag'] == 'i')
47
- end
58
+ def load_patterns_file(path)
59
+ yml = begin
60
+ YAML.load_file(path, freeze: true)
61
+ rescue ArgumentError
62
+ YAML.load_file(path)
48
63
  end
64
+ [
65
+ parse_pattern(yml['user_agent_parsers']),
66
+ parse_pattern(yml['os_parsers']),
67
+ parse_pattern(yml['device_parsers']),
68
+ ]
69
+ end
49
70
 
50
- [yml['user_agent_parsers'], yml['os_parsers'], yml['device_parsers']]
71
+ def parse_pattern(patterns)
72
+ patterns.map do |pattern|
73
+ pattern = pattern.dup
74
+ pattern[:regex] = Regexp.new(pattern.delete('regex'), pattern.delete('regex_flag') == 'i')
75
+ pattern
76
+ end
51
77
  end
52
78
 
53
79
  def parse_ua(user_agent, os = nil, device = nil)
@@ -80,24 +106,11 @@ module UserAgentParser
80
106
  end
81
107
  end
82
108
 
83
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4.0')
84
- def first_pattern_match(patterns, value)
85
- patterns.each do |pattern|
86
- if pattern[:regex].match?(value)
87
- return [pattern, pattern[:regex].match(value)]
88
- end
89
- end
90
- nil
91
- end
92
- else
93
- def first_pattern_match(patterns, value)
94
- patterns.each do |pattern|
95
- if (match = pattern[:regex].match(value))
96
- return [pattern, match]
97
- end
98
- end
99
- nil
109
+ def first_pattern_match(patterns, value)
110
+ patterns.each do |pattern|
111
+ return [pattern, pattern[:regex].match(value)] if pattern[:regex].match?(value)
100
112
  end
113
+ nil
101
114
  end
102
115
 
103
116
  def user_agent_from_pattern_match(pattern, match, os = nil, device = nil)
@@ -10,7 +10,7 @@ module UserAgentParser
10
10
  DefaultPatternsPath = File.join(File.dirname(__FILE__), '../vendor/uap-core/regexes.yaml')
11
11
 
12
12
  # Parse the given +user_agent_string+, returning a +UserAgent+
13
- def self.parse(user_agent_string, options = {})
14
- Parser.new(options).parse(user_agent_string)
13
+ def self.parse(user_agent_string, **args)
14
+ Parser.new(**args).parse(user_agent_string)
15
15
  end
16
16
  end
@@ -213,6 +213,10 @@ user_agent_parsers:
213
213
  - regex: '(Twitter for (?:iPhone|iPad)|TwitterAndroid)(?:\/(\d+)\.(\d+)|)'
214
214
  family_replacement: 'Twitter'
215
215
 
216
+ # Phantom app
217
+ - regex: 'Mozilla.{1,200}Mobile.{1,100}(Phantom\/ios|android).(\d+)\.(\d+)\.(\d+)'
218
+ family_replacement: 'Phantom'
219
+
216
220
  # aspiegel.com spider (owned by Huawei)
217
221
  - regex: 'Mozilla.{1,100}Mobile.{1,100}AspiegelBot'
218
222
  family_replacement: 'Spider'
@@ -381,7 +385,7 @@ user_agent_parsers:
381
385
  # Edge Mobile
382
386
  - regex: 'Windows Phone .{0,200}(Edge)/(\d+)\.(\d+)'
383
387
  family_replacement: 'Edge Mobile'
384
- - regex: '(EdgiOS|EdgA)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
388
+ - regex: '(EdgiOS|EdgA)/(\d+)\.(\d+)\.(\d+)(?:\.(\d+)|)'
385
389
  family_replacement: 'Edge Mobile'
386
390
 
387
391
  # Samsung Internet (based on Chrome, but lacking some features)
@@ -517,6 +521,10 @@ user_agent_parsers:
517
521
  # Palo Alto GlobalProtect Linux
518
522
  - regex: 'PAN (GlobalProtect)/(\d+)\.(\d+)\.(\d+) .{1,100} \(X11; Linux x86_64\)'
519
523
 
524
+ # Surveyon https://www.surveyon.com/
525
+ - regex: '^(surveyon)/(\d+)\.(\d+)\.(\d+)'
526
+ family_replacement: 'Surveyon'
527
+
520
528
  #### END SPECIAL CASES TOP ####
521
529
 
522
530
  #### MAIN CASES - this catches > 50% of all browsers ####
@@ -1120,6 +1128,7 @@ os_parsers:
1120
1128
 
1121
1129
  # Android 9; Android 10;
1122
1130
  - regex: '(Android) (\d+);'
1131
+ - regex: '(Android): (\d+)(?:\.(\d+)(?:\.(\d+)|)|);'
1123
1132
 
1124
1133
  # UCWEB
1125
1134
  - regex: '^UCWEB.{0,200}; (Adr) (\d+)\.(\d+)(?:[.\-]([a-z0-9]{1,100})|);'
@@ -1544,9 +1553,48 @@ os_parsers:
1544
1553
  os_replacement: 'iOS'
1545
1554
  os_v1_replacement: '14'
1546
1555
  os_v2_replacement: '5'
1556
+ - regex: 'CFNetwork/12.{0,100} Darwin/20\.5\.\d+'
1557
+ os_replacement: 'iOS'
1558
+ os_v1_replacement: '14'
1559
+ os_v2_replacement: '6'
1560
+ - regex: 'CFNetwork/12.{0,100} Darwin/20\.6\.\d+'
1561
+ os_replacement: 'iOS'
1562
+ os_v1_replacement: '14'
1563
+ os_v2_replacement: '8'
1547
1564
  - regex: 'CFNetwork/.{0,100} Darwin/(20)\.\d+'
1548
1565
  os_replacement: 'iOS'
1549
1566
  os_v1_replacement: '14'
1567
+ - regex: 'CFNetwork/13.{0,100} Darwin/21\.0\.\d+'
1568
+ os_replacement: 'iOS'
1569
+ os_v1_replacement: '15'
1570
+ os_v2_replacement: '0'
1571
+ - regex: 'CFNetwork/13.{0,100} Darwin/21\.1\.\d+'
1572
+ os_replacement: 'iOS'
1573
+ os_v1_replacement: '15'
1574
+ os_v2_replacement: '1'
1575
+ - regex: 'CFNetwork/13.{0,100} Darwin/21\.2\.\d+'
1576
+ os_replacement: 'iOS'
1577
+ os_v1_replacement: '15'
1578
+ os_v2_replacement: '2'
1579
+ - regex: 'CFNetwork/13.{0,100} Darwin/21\.3\.\d+'
1580
+ os_replacement: 'iOS'
1581
+ os_v1_replacement: '15'
1582
+ os_v2_replacement: '3'
1583
+ - regex: 'CFNetwork/13.{0,100} Darwin/21\.4\.\d+'
1584
+ os_replacement: 'iOS'
1585
+ os_v1_replacement: '15'
1586
+ os_v2_replacement: '4'
1587
+ - regex: 'CFNetwork/13.{0,100} Darwin/21\.5\.\d+'
1588
+ os_replacement: 'iOS'
1589
+ os_v1_replacement: '15'
1590
+ os_v2_replacement: '5'
1591
+ - regex: 'CFNetwork/13.{0,100} Darwin/21\.6\.\d+'
1592
+ os_replacement: 'iOS'
1593
+ os_v1_replacement: '15'
1594
+ os_v2_replacement: '6'
1595
+ - regex: 'CFNetwork/.{0,100} Darwin/(21)\.\d+'
1596
+ os_replacement: 'iOS'
1597
+ os_v1_replacement: '15'
1550
1598
  - regex: 'CFNetwork/.{0,100} Darwin/'
1551
1599
  os_replacement: 'iOS'
1552
1600
 
@@ -2461,10 +2509,6 @@ device_parsers:
2461
2509
  device_replacement: 'Dell $1'
2462
2510
  brand_replacement: 'Dell'
2463
2511
  model_replacement: '$1'
2464
- - regex: '; {0,2}Dell ([^;/]{1,100}?)(?: Build|\) AppleWebKit)'
2465
- device_replacement: 'Dell $1'
2466
- brand_replacement: 'Dell'
2467
- model_replacement: '$1'
2468
2512
 
2469
2513
  #########
2470
2514
  # Denver
@@ -2671,10 +2715,14 @@ device_parsers:
2671
2715
  device_replacement: '$1'
2672
2716
  brand_replacement: 'Google'
2673
2717
  model_replacement: '$1'
2674
- - regex: '; {0,2}(Pixel.{0,200}?)(?: Build|\) AppleWebKit)'
2675
- device_replacement: '$1'
2718
+ - regex: '; {0,2}([g|G]oogle)? (Pixel[ a-zA-z0-9]{1,100});(?: Build|.{0,50}\) AppleWebKit)'
2719
+ device_replacement: '$2'
2676
2720
  brand_replacement: 'Google'
2677
- model_replacement: '$1'
2721
+ model_replacement: '$2'
2722
+ - regex: '; {0,2}([g|G]oogle)? (Pixel.{0,200}?)(?: Build|\) AppleWebKit)'
2723
+ device_replacement: '$2'
2724
+ brand_replacement: 'Google'
2725
+ model_replacement: '$2'
2678
2726
 
2679
2727
  #########
2680
2728
  # Gigabyte
@@ -3801,6 +3849,18 @@ device_parsers:
3801
3849
  device_replacement: 'OnePlus $1'
3802
3850
  brand_replacement: 'OnePlus'
3803
3851
  model_replacement: '$1'
3852
+ - regex: '; {0,2}(HD1903|GM1917|IN2025|LE2115|LE2127|HD1907|BE2012|BE2025|BE2026|BE2028|BE2029|DE2117|DE2118|EB2101|GM1900|GM1910|GM1915|HD1905|HD1925|IN2015|IN2017|IN2019|KB2005|KB2007|LE2117|LE2125|BE2015|GM1903|HD1900|HD1901|HD1910|HD1913|IN2010|IN2013|IN2020|LE2111|LE2120|LE2121|LE2123|BE2011|IN2023|KB2003|LE2113|NE2215|DN2101)(?: Build|\) AppleWebKit)'
3853
+ device_replacement: 'OnePlus $1'
3854
+ brand_replacement: 'OnePlus'
3855
+ model_replacement: 'OnePlus $1'
3856
+ - regex: '; (OnePlus[ a-zA-z0-9]{0,50});((?: Build|.{0,50}\) AppleWebKit))'
3857
+ device_replacement: '$1'
3858
+ brand_replacement: 'OnePlus'
3859
+ model_replacement: '$1'
3860
+ - regex: '; (OnePlus[ a-zA-z0-9]{0,50})((?: Build|\) AppleWebKit))'
3861
+ device_replacement: '$1'
3862
+ brand_replacement: 'OnePlus'
3863
+ model_replacement: '$1'
3804
3864
 
3805
3865
  #########
3806
3866
  # Orion
@@ -5481,6 +5541,15 @@ device_parsers:
5481
5541
  device_replacement: 'Motorola $1'
5482
5542
  brand_replacement: 'Motorola'
5483
5543
  model_replacement: '$1'
5544
+ - regex: '; (moto[ a-zA-z0-9()]{0,50});((?: Build|.{0,50}\) AppleWebKit))'
5545
+ device_replacement: '$1'
5546
+ brand_replacement: 'Motorola'
5547
+ model_replacement: '$1'
5548
+ - regex: '; {0,2}(moto)(.{0,50})(?: Build|\) AppleWebKit)'
5549
+ device_replacement: 'Motorola$2'
5550
+ brand_replacement: 'Motorola'
5551
+ model_replacement: '$2'
5552
+
5484
5553
 
5485
5554
  ##########
5486
5555
  # nintendo
metadata CHANGED
@@ -1,17 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: user_agent_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.11.0
4
+ version: 2.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Lucas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-18 00:00:00.000000000 Z
11
+ date: 2022-10-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: A simple, comprehensive Ruby gem for parsing user agent strings with
14
- the help of BrowserScope's UA database
13
+ description: |
14
+ A simple, comprehensive Ruby gem for parsing user agent strings
15
+ with the help of BrowserScope's UserAgent database
15
16
  email: t@toolmantim.com
16
17
  executables:
17
18
  - user_agent_parser
@@ -47,9 +48,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
48
  - !ruby/object:Gem::Version
48
49
  version: '0'
49
50
  requirements: []
50
- rubygems_version: 3.3.11
51
+ rubygems_version: 3.3.24
51
52
  signing_key:
52
53
  specification_version: 4
53
- summary: A simple, comprehensive Ruby gem for parsing user agent strings with the
54
- help of BrowserScope's UA database
54
+ summary: Parsing user agent strings with the help of BrowserScope's UA database
55
55
  test_files: []