user_agent_parser 2.11.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/user_agent_parser/parser.rb +42 -29
- data/lib/user_agent_parser.rb +2 -2
- data/vendor/uap-core/regexes.yaml +77 -8
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f014ae2d784eb25f63242a361c9c9186ad108c7199fd1655944da1dcfeaff28
|
4
|
+
data.tar.gz: 36357407d451f17dada0fa4115f5f19e8a69af6932a1c3fc999ecd55abc958a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 :
|
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
|
-
|
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(
|
41
|
-
|
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
|
-
|
44
|
-
yml
|
45
|
-
|
46
|
-
|
47
|
-
|
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
|
-
|
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
|
-
|
84
|
-
|
85
|
-
|
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)
|
data/lib/user_agent_parser.rb
CHANGED
@@ -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,
|
14
|
-
Parser.new(
|
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+)
|
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
|
2675
|
-
device_replacement: '$
|
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: '$
|
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.
|
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-
|
11
|
+
date: 2022-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
|
-
description:
|
14
|
-
|
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.
|
51
|
+
rubygems_version: 3.3.24
|
51
52
|
signing_key:
|
52
53
|
specification_version: 4
|
53
|
-
summary:
|
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: []
|