user_agent_parser 2.1.5 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of user_agent_parser might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Readme.md +7 -3
- data/bin/user_agent_parser +8 -3
- data/lib/user_agent_parser/cli.rb +6 -2
- data/lib/user_agent_parser/device.rb +7 -5
- data/lib/user_agent_parser/operating_system.rb +7 -5
- data/lib/user_agent_parser/parser.rb +6 -6
- data/lib/user_agent_parser/user_agent.rb +6 -7
- data/lib/user_agent_parser/version.rb +9 -4
- data/vendor/ua-parser/regexes.yaml +167 -45
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e6c42fb7a24030be52fa5c096b8af27e362bb02
|
4
|
+
data.tar.gz: 60cfeb6d90444739f7f81f0e035704e23b5597df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fe9aa53552e5fb33d04bdc412a4cfb684ef5e04cb75f0d3747a8036ae804891072f1114dba9729d243d7bb138e610f954ee108dc4d1dda025ac1155bf4e2445
|
7
|
+
data.tar.gz: 06ba11a996ca450f7db3a5fc5175c76d703e3cd2496013c0d09bc34a1f63cf8a145ee2a1fa1ee48b37152074ab6c12b98c0e4f62c9e305af59432f69d7fd10b3
|
data/Readme.md
CHANGED
@@ -2,9 +2,13 @@
|
|
2
2
|
|
3
3
|
UserAgentParser is a simple, comprehensive Ruby gem for parsing user agent strings. It uses [BrowserScope](http://www.browserscope.org/)'s [parsing patterns](https://github.com/tobie/ua-parser).
|
4
4
|
|
5
|
-
##
|
5
|
+
## Supported Rubies
|
6
6
|
|
7
|
-
* Ruby
|
7
|
+
* Ruby 2.1
|
8
|
+
* Ruby 2.0
|
9
|
+
* Ruby 1.9.3
|
10
|
+
* Ruby 1.9.2
|
11
|
+
* JRuby
|
8
12
|
|
9
13
|
## Installation
|
10
14
|
|
@@ -21,7 +25,7 @@ user_agent = UserAgentParser.parse 'Mozilla/5.0 (compatible; MSIE 9.0; Windows N
|
|
21
25
|
=> #<UserAgentParser::UserAgent IE 9.0 (Windows Vista)>
|
22
26
|
user_agent.to_s
|
23
27
|
=> "IE 9.0"
|
24
|
-
user_agent.
|
28
|
+
user_agent.family
|
25
29
|
=> "IE"
|
26
30
|
user_agent.version.to_s
|
27
31
|
=> "9.0"
|
data/bin/user_agent_parser
CHANGED
@@ -8,8 +8,12 @@ require 'user_agent_parser/cli'
|
|
8
8
|
options = {}
|
9
9
|
|
10
10
|
optparse = OptionParser.new do|opts|
|
11
|
-
opts.on('--
|
12
|
-
options[:
|
11
|
+
opts.on('--family', 'Print family only') do
|
12
|
+
options[:family] = true
|
13
|
+
end
|
14
|
+
|
15
|
+
opts.on('--name', 'Print name (alias for family) only') do
|
16
|
+
options[:family] = true
|
13
17
|
end
|
14
18
|
|
15
19
|
opts.on('--version', 'Print version only') do
|
@@ -30,7 +34,8 @@ optparse = OptionParser.new do|opts|
|
|
30
34
|
|
31
35
|
opts.on('--format format',
|
32
36
|
'Print output in specified format. The available formatters are:',
|
33
|
-
' - %
|
37
|
+
' - %f: family',
|
38
|
+
' - %n: name (alias for family)',
|
34
39
|
' - %v: version',
|
35
40
|
' - %M: major version',
|
36
41
|
' - %m: minor version',
|
@@ -6,7 +6,9 @@ module UserAgentParser
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def run!
|
9
|
-
if @options[:
|
9
|
+
if @options[:family]
|
10
|
+
@user_agent.family
|
11
|
+
elsif @options[:name]
|
10
12
|
@user_agent.name
|
11
13
|
elsif @options[:version]
|
12
14
|
with_version do |version|
|
@@ -19,7 +21,9 @@ module UserAgentParser
|
|
19
21
|
elsif @options[:os]
|
20
22
|
@user_agent.os.to_s
|
21
23
|
elsif format = @options[:format]
|
22
|
-
format.
|
24
|
+
format.
|
25
|
+
gsub('%f', @user_agent.family).
|
26
|
+
gsub('%n', @user_agent.name).
|
23
27
|
gsub('%v', version.to_s).
|
24
28
|
gsub('%M', major.to_s).
|
25
29
|
gsub('%m', minor.to_s).
|
@@ -1,13 +1,15 @@
|
|
1
1
|
module UserAgentParser
|
2
2
|
class Device
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :family
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
alias_method :name, :family
|
6
|
+
|
7
|
+
def initialize(family = nil)
|
8
|
+
@family = family || 'Other'
|
7
9
|
end
|
8
10
|
|
9
11
|
def to_s
|
10
|
-
|
12
|
+
family
|
11
13
|
end
|
12
14
|
|
13
15
|
def inspect
|
@@ -15,7 +17,7 @@ module UserAgentParser
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def eql?(other)
|
18
|
-
self.class.eql?(other.class) &&
|
20
|
+
self.class.eql?(other.class) && family == other.family
|
19
21
|
end
|
20
22
|
|
21
23
|
alias_method :==, :eql?
|
@@ -1,14 +1,16 @@
|
|
1
1
|
module UserAgentParser
|
2
2
|
class OperatingSystem
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :family, :version
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
alias_method :name, :family
|
6
|
+
|
7
|
+
def initialize(family = 'Other', version = nil)
|
8
|
+
@family = family
|
7
9
|
@version = version
|
8
10
|
end
|
9
11
|
|
10
12
|
def to_s
|
11
|
-
string =
|
13
|
+
string = family
|
12
14
|
unless version.nil?
|
13
15
|
string += " #{version}"
|
14
16
|
end
|
@@ -21,7 +23,7 @@ module UserAgentParser
|
|
21
23
|
|
22
24
|
def eql?(other)
|
23
25
|
self.class.eql?(other.class) &&
|
24
|
-
|
26
|
+
family == other.family &&
|
25
27
|
version == other.version
|
26
28
|
end
|
27
29
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
|
3
3
|
module UserAgentParser
|
4
|
-
|
4
|
+
|
5
5
|
class Parser
|
6
6
|
attr_reader :patterns_path
|
7
7
|
|
@@ -71,10 +71,10 @@ module UserAgentParser
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def user_agent_from_pattern_match(pattern, match, os = nil, device = nil)
|
74
|
-
|
74
|
+
family, v1, v2, v3, v4 = match[1], match[2], match[3], match[4], match[5]
|
75
75
|
|
76
76
|
if pattern["family_replacement"]
|
77
|
-
|
77
|
+
family = pattern["family_replacement"].sub('$1', family || '')
|
78
78
|
end
|
79
79
|
|
80
80
|
if pattern["v1_replacement"]
|
@@ -95,7 +95,7 @@ module UserAgentParser
|
|
95
95
|
|
96
96
|
version = version_from_segments(v1, v2, v3, v4)
|
97
97
|
|
98
|
-
UserAgent.new(
|
98
|
+
UserAgent.new(family, version, os, device)
|
99
99
|
end
|
100
100
|
|
101
101
|
def os_from_pattern_match(pattern, match)
|
@@ -137,8 +137,8 @@ module UserAgentParser
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def version_from_segments(*segments)
|
140
|
-
|
141
|
-
|
140
|
+
segments = segments.compact
|
141
|
+
segments.empty? ? nil : Version.new(*segments)
|
142
142
|
end
|
143
143
|
end
|
144
144
|
end
|
@@ -1,19 +1,18 @@
|
|
1
1
|
module UserAgentParser
|
2
2
|
class UserAgent
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :family, :version, :os, :device
|
4
4
|
|
5
|
-
|
6
|
-
alias_method :family, :name
|
5
|
+
alias_method :name, :family
|
7
6
|
|
8
|
-
def initialize(
|
9
|
-
@
|
7
|
+
def initialize(family = nil, version = nil, os = nil, device = nil)
|
8
|
+
@family = family || 'Other'
|
10
9
|
@version = version
|
11
10
|
@os = os
|
12
11
|
@device = device
|
13
12
|
end
|
14
13
|
|
15
14
|
def to_s
|
16
|
-
string =
|
15
|
+
string = family
|
17
16
|
string += " #{version}" if version
|
18
17
|
string
|
19
18
|
end
|
@@ -27,7 +26,7 @@ module UserAgentParser
|
|
27
26
|
|
28
27
|
def eql?(other)
|
29
28
|
self.class.eql?(other.class) &&
|
30
|
-
|
29
|
+
family == other.family &&
|
31
30
|
version == other.version &&
|
32
31
|
os == other.os
|
33
32
|
end
|
@@ -1,15 +1,20 @@
|
|
1
1
|
module UserAgentParser
|
2
2
|
class Version
|
3
3
|
|
4
|
-
# Private: Regex used to split version string into major, minor,
|
5
|
-
# and patch_minor.
|
4
|
+
# Private: Regex used to split string version string into major, minor,
|
5
|
+
# patch, and patch_minor.
|
6
6
|
SEGMENTS_REGEX = /\d+\-\d+|\d+[a-zA-Z]+$|\d+|[A-Za-z][0-9A-Za-z-]*$/
|
7
7
|
|
8
8
|
attr_reader :version
|
9
9
|
alias :to_s :version
|
10
10
|
|
11
|
-
def initialize(
|
12
|
-
|
11
|
+
def initialize(*args)
|
12
|
+
if args.length == 1 && args.first.is_a?(String)
|
13
|
+
@version = args.first.to_s.strip
|
14
|
+
else
|
15
|
+
@segments = args.map(&:to_s).map(&:strip)
|
16
|
+
@version = segments.join(".")
|
17
|
+
end
|
13
18
|
end
|
14
19
|
|
15
20
|
def major
|
@@ -6,8 +6,8 @@ user_agent_parsers:
|
|
6
6
|
# See os_parsers if you want to target a specific TV
|
7
7
|
- regex: '(HbbTV)/(\d+)\.(\d+)\.(\d+) \('
|
8
8
|
|
9
|
-
# must go before Firefox to catch SeaMonkey/Camino
|
10
|
-
- regex: '(SeaMonkey|Camino)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)'
|
9
|
+
# must go before Firefox to catch Chimera/SeaMonkey/Camino
|
10
|
+
- regex: '(Chimera|SeaMonkey|Camino)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)?'
|
11
11
|
|
12
12
|
# Firefox
|
13
13
|
- regex: '(Pale[Mm]oon)/(\d+)\.(\d+)\.?(\d+)?'
|
@@ -49,7 +49,7 @@ user_agent_parsers:
|
|
49
49
|
- regex: '(Navigator)/(\d+)\.(\d+)([ab]\d+)'
|
50
50
|
family_replacement: 'Netscape'
|
51
51
|
|
52
|
-
- regex: '(Netscape6)/(\d+)\.(\d+)
|
52
|
+
- regex: '(Netscape6)/(\d+)\.(\d+)\.?([ab]?\d+)?'
|
53
53
|
family_replacement: 'Netscape'
|
54
54
|
|
55
55
|
- regex: '(MyIBrow)/(\d+)\.(\d+)'
|
@@ -62,7 +62,7 @@ user_agent_parsers:
|
|
62
62
|
family_replacement: 'Opera Mobile'
|
63
63
|
- regex: '(Opera)/(\d+)\.(\d+).+Opera Mobi'
|
64
64
|
family_replacement: 'Opera Mobile'
|
65
|
-
- regex: 'Opera Mobi.+(Opera)
|
65
|
+
- regex: 'Opera Mobi.+(Opera)(?:/|\s+)(\d+)\.(\d+)'
|
66
66
|
family_replacement: 'Opera Mobile'
|
67
67
|
- regex: 'Opera Mobi'
|
68
68
|
family_replacement: 'Opera Mobile'
|
@@ -126,6 +126,28 @@ user_agent_parsers:
|
|
126
126
|
|
127
127
|
- regex: '(Minimo)'
|
128
128
|
|
129
|
+
- regex: 'PLAYSTATION 3.+WebKit'
|
130
|
+
family_replacement: 'NetFront NX'
|
131
|
+
- regex: 'PLAYSTATION 3'
|
132
|
+
family_replacement: 'NetFront'
|
133
|
+
- regex: '(PlayStation Portable)'
|
134
|
+
family_replacement: 'NetFront'
|
135
|
+
- regex: '(PlayStation Vita)'
|
136
|
+
family_replacement: 'NetFront NX'
|
137
|
+
|
138
|
+
- regex: 'AppleWebKit.+ (NX)/(\d+)\.(\d+)\.(\d+)'
|
139
|
+
family_replacement: 'NetFront NX'
|
140
|
+
- regex: '(Nintendo 3DS)'
|
141
|
+
family_replacement: 'NetFront NX'
|
142
|
+
|
143
|
+
# Amazon Silk, should go before Safari and Chrome Mobile
|
144
|
+
- regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
|
145
|
+
family_replacement: 'Amazon Silk'
|
146
|
+
|
147
|
+
|
148
|
+
# @ref: http://www.puffinbrowser.com
|
149
|
+
- regex: '(Puffin)/(\d+)\.(\d+)(?:\.(\d+))?'
|
150
|
+
|
129
151
|
# Chrome Mobile
|
130
152
|
- regex: '(CrMo)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
|
131
153
|
family_replacement: 'Chrome Mobile'
|
@@ -247,6 +269,18 @@ user_agent_parsers:
|
|
247
269
|
# Chrome/Chromium/major_version.minor_version
|
248
270
|
- regex: '(Chromium|Chrome)/(\d+)\.(\d+)'
|
249
271
|
|
272
|
+
##########
|
273
|
+
# IE Mobile needs to happen before Android to catch cases such as:
|
274
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920)...
|
275
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; ANZ821)...
|
276
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Orange)...
|
277
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Vodafone)...
|
278
|
+
##########
|
279
|
+
|
280
|
+
# IE Mobile
|
281
|
+
- regex: '(IEMobile)[ /](\d+)\.(\d+)'
|
282
|
+
family_replacement: 'IE Mobile'
|
283
|
+
|
250
284
|
# Browser major_version.minor_version.beta_version (space instead of slash)
|
251
285
|
- regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)'
|
252
286
|
# Browser major_version.minor_version (space instead of slash)
|
@@ -275,9 +309,6 @@ user_agent_parsers:
|
|
275
309
|
- regex: '(Android) Honeycomb'
|
276
310
|
v1_replacement: '3'
|
277
311
|
|
278
|
-
# IE Mobile
|
279
|
-
- regex: '(IEMobile)[ /](\d+)\.(\d+)'
|
280
|
-
family_replacement: 'IE Mobile'
|
281
312
|
# desktop mode
|
282
313
|
# http://www.anandtech.com/show/3982/windows-phone-7-review
|
283
314
|
- regex: '(MSIE) (\d+)\.(\d+).*XBLWP7'
|
@@ -296,20 +327,6 @@ user_agent_parsers:
|
|
296
327
|
- regex: '(Maxthon|MyIE2|Uzbl|Shiira)'
|
297
328
|
v1_replacement: '0'
|
298
329
|
|
299
|
-
- regex: 'PLAYSTATION 3.+WebKit'
|
300
|
-
family_replacement: 'NetFront NX'
|
301
|
-
- regex: 'PLAYSTATION 3'
|
302
|
-
family_replacement: 'NetFront'
|
303
|
-
- regex: '(PlayStation Portable)'
|
304
|
-
family_replacement: 'NetFront'
|
305
|
-
- regex: '(PlayStation Vita)'
|
306
|
-
family_replacement: 'NetFront NX'
|
307
|
-
|
308
|
-
- regex: 'AppleWebKit.+ (NX)/(\d+)\.(\d+)\.(\d+)'
|
309
|
-
family_replacement: 'NetFront NX'
|
310
|
-
- regex: '(Nintendo 3DS)'
|
311
|
-
family_replacement: 'NetFront NX'
|
312
|
-
|
313
330
|
- regex: '(BrowseX) \((\d+)\.(\d+)\.(\d+)'
|
314
331
|
|
315
332
|
- regex: '(NCSA_Mosaic)/(\d+)\.(\d+)'
|
@@ -321,7 +338,7 @@ user_agent_parsers:
|
|
321
338
|
- regex: '(Embider)/(\d+)\.(\d+)'
|
322
339
|
family_replacement: 'Polaris'
|
323
340
|
|
324
|
-
- regex: '(BonEcho)/(\d+)\.(\d+)
|
341
|
+
- regex: '(BonEcho)/(\d+)\.(\d+)\.?([ab]?\d+)?'
|
325
342
|
family_replacement: 'Bon Echo'
|
326
343
|
|
327
344
|
# @note: iOS / OSX Applications
|
@@ -340,7 +357,7 @@ user_agent_parsers:
|
|
340
357
|
family_replacement: 'Mobile Safari'
|
341
358
|
- regex: '(iPad).*Version/(\d+)\.(\d+)'
|
342
359
|
family_replacement: 'Mobile Safari'
|
343
|
-
- regex: '(iPod|iPhone|iPad);.*CPU.*OS (\d+)(
|
360
|
+
- regex: '(iPod|iPhone|iPad);.*CPU.*OS (\d+)_(\d+)(?:_(\d+))?.*Mobile'
|
344
361
|
family_replacement: 'Mobile Safari'
|
345
362
|
- regex: '(iPod|iPhone|iPad)'
|
346
363
|
family_replacement: 'Mobile Safari'
|
@@ -411,10 +428,6 @@ user_agent_parsers:
|
|
411
428
|
#- regex: '\(iPad;.+(Version)/(\d+)\.(\d+)(?:\.(\d+))?.*Safari/'
|
412
429
|
# family_replacement: 'iPad'
|
413
430
|
|
414
|
-
# Amazon Silk, should go before Safari
|
415
|
-
- regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
|
416
|
-
family_replacement: 'Amazon Silk'
|
417
|
-
|
418
431
|
# Phantomjs, should go before Safari
|
419
432
|
- regex: '(PhantomJS)/(\d+)\.(\d+)\.(\d+)'
|
420
433
|
|
@@ -444,6 +457,9 @@ user_agent_parsers:
|
|
444
457
|
- regex: 'Trident(.*)rv.(\d+)\.(\d+)'
|
445
458
|
family_replacement: 'IE'
|
446
459
|
|
460
|
+
# Espial
|
461
|
+
- regex: '(Espial)/(\d+)(?:\.(\d+))?(?:\.(\d+))?'
|
462
|
+
|
447
463
|
# Apple Mail
|
448
464
|
|
449
465
|
# apple mail - not directly detectable, have it after Safari stuff
|
@@ -521,12 +537,22 @@ os_parsers:
|
|
521
537
|
# generic HbbTV, hoping to catch manufacturer name (always after 2nd comma) and the first string that looks like a 2011-2019 year
|
522
538
|
- regex: 'HbbTV/\d+\.\d+\.\d+ \(.*; ?([a-zA-Z]+) ?;.*(201[1-9]).*\)'
|
523
539
|
|
540
|
+
##########
|
541
|
+
# @note: Windows Phone needs to come before Windows NT 6.1 *and* before Android to catch cases such as:
|
542
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920)...
|
543
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; ANZ821)...
|
544
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Orange)...
|
545
|
+
# Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 920; Vodafone)...
|
546
|
+
##########
|
547
|
+
|
548
|
+
- regex: '(Windows Phone) (?:OS[ /])?(\d+)\.(\d+)'
|
549
|
+
|
524
550
|
##########
|
525
551
|
# Android
|
526
552
|
# can actually detect rooted android os. do we care?
|
527
553
|
##########
|
528
554
|
- regex: '(Android)[ \-/](\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?'
|
529
|
-
|
555
|
+
|
530
556
|
- regex: '(Android) Donut'
|
531
557
|
os_v1_replacement: '1'
|
532
558
|
os_v2_replacement: '2'
|
@@ -577,8 +603,7 @@ os_parsers:
|
|
577
603
|
- regex: '(XBLWP7)'
|
578
604
|
os_replacement: 'Windows Phone'
|
579
605
|
|
580
|
-
# @note:
|
581
|
-
- regex: '(Windows Phone) (?:OS[ /])?(\d+)\.(\d+)'
|
606
|
+
# @note: This needs to come before Windows NT 6.1
|
582
607
|
- regex: '(Windows ?Mobile)'
|
583
608
|
os_replacement: 'Windows Mobile'
|
584
609
|
|
@@ -689,6 +714,36 @@ os_parsers:
|
|
689
714
|
- regex: '(AppleTV)/(\d+)\.(\d+)'
|
690
715
|
os_replacement: 'ATV OS X'
|
691
716
|
|
717
|
+
# CFNetwork/Darwin - The specific CFNetwork or Darwin version determines
|
718
|
+
# whether the os maps to Mac OS, or iOS, or just Darwin.
|
719
|
+
# See: http://user-agents.me/cfnetwork-version-list
|
720
|
+
- regex: '(CFNetwork)/(5)48\.0\.3.* Darwin/11\.0\.0'
|
721
|
+
os_replacement: 'iOS'
|
722
|
+
- regex: '(CFNetwork)/(5)48\.(0)\.4.* Darwin/(1)1\.0\.0'
|
723
|
+
os_replacement: 'iOS'
|
724
|
+
- regex: '(CFNetwork)/(5)48\.(1)\.4'
|
725
|
+
os_replacement: 'iOS'
|
726
|
+
- regex: '(CFNetwork)/(4)85\.1(3)\.9'
|
727
|
+
os_replacement: 'iOS'
|
728
|
+
- regex: '(CFNetwork)/(6)09\.(1)\.4'
|
729
|
+
os_replacement: 'iOS'
|
730
|
+
- regex: '(CFNetwork)/(6)(0)9'
|
731
|
+
os_replacement: 'iOS'
|
732
|
+
- regex: '(CFNetwork)/6(7)2\.(1)\.13'
|
733
|
+
os_replacement: 'iOS'
|
734
|
+
- regex: '(CFNetwork)/6(7)2\.(1)\.(1)4'
|
735
|
+
os_replacement: 'iOS'
|
736
|
+
- regex: '(CF)(Network)/6(7)(2)\.1\.15'
|
737
|
+
os_replacement: 'iOS'
|
738
|
+
os_v1_replacement: '7'
|
739
|
+
os_v2_replacement: '1'
|
740
|
+
- regex: '(CFNetwork)/6(7)2\.(0)\.(?:2|8)'
|
741
|
+
os_replacement: 'iOS'
|
742
|
+
- regex: '(CFNetwork)/709\.1'
|
743
|
+
os_replacement: 'iOS'
|
744
|
+
os_v1_replacement: '8'
|
745
|
+
os_v2_replacement: '0.b5'
|
746
|
+
|
692
747
|
##########
|
693
748
|
# CFNetwork iOS Apps
|
694
749
|
# @ref: https://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
|
@@ -705,9 +760,13 @@ os_parsers:
|
|
705
760
|
- regex: 'CFNetwork/.* Darwin/(13)\.\d+'
|
706
761
|
os_replacement: 'iOS'
|
707
762
|
os_v1_replacement: '6'
|
708
|
-
- regex: 'CFNetwork
|
763
|
+
- regex: 'CFNetwork/6.* Darwin/(14)\.\d+'
|
709
764
|
os_replacement: 'iOS'
|
710
765
|
os_v1_replacement: '7'
|
766
|
+
- regex: 'CFNetwork/7.* Darwin/(14)\.\d+'
|
767
|
+
os_replacement: 'iOS'
|
768
|
+
os_v1_replacement: '8'
|
769
|
+
os_v2_replacement: '0'
|
711
770
|
# iOS Apps
|
712
771
|
- regex: '\b(iOS[ /]|iPhone(?:/| v|[ _]OS[/,]|; | OS : |\d,\d/|\d,\d; )|iPad/)(\d{1,2})[_\.](\d{1,2})(?:[_\.](\d+))?'
|
713
772
|
os_replacement: 'iOS'
|
@@ -861,7 +920,29 @@ device_parsers:
|
|
861
920
|
# Samsung
|
862
921
|
- regex: '(SamsungSGHi560)'
|
863
922
|
device_replacement: 'Samsung SGHi560'
|
923
|
+
|
924
|
+
- regex: '(SCH-[A-Za-z0-9_-]+)'
|
925
|
+
device_replacement: 'Samsung $1'
|
926
|
+
|
927
|
+
- regex: '(SGH-[A-Za-z0-9_-]+)'
|
928
|
+
device_replacement: 'Samsung $1'
|
929
|
+
|
930
|
+
- regex: '(GT-[A-Za-z0-9_-]+)'
|
931
|
+
device_replacement: 'Samsung $1'
|
932
|
+
|
933
|
+
- regex: '(SM-[A-Za-z0-9_-]+)'
|
934
|
+
device_replacement: 'Samsung $1'
|
864
935
|
|
936
|
+
- regex: '(SPH-[A-Za-z0-9_-]+)'
|
937
|
+
device_replacement: 'Samsung $1'
|
938
|
+
|
939
|
+
- regex: 'SAMSUNG-([A-Za-z0-9_-]+)'
|
940
|
+
device_replacement: 'Samsung $1'
|
941
|
+
|
942
|
+
- regex: 'SAMSUNG ([A-Za-z0-9_-]+)'
|
943
|
+
device_replacement: 'Samsung $1'
|
944
|
+
|
945
|
+
|
865
946
|
#########
|
866
947
|
# Ericsson - must come before nokia since they also use symbian
|
867
948
|
#########
|
@@ -874,8 +955,8 @@ device_parsers:
|
|
874
955
|
##########
|
875
956
|
- regex: 'PLAYSTATION 3'
|
876
957
|
device_replacement: 'PlayStation 3'
|
877
|
-
- regex: '(PlayStation Portable)'
|
878
|
-
- regex: '(PlayStation
|
958
|
+
- regex: '(PlayStation (:?Portable|Vita))'
|
959
|
+
- regex: '(PlayStation (:?\d+))'
|
879
960
|
|
880
961
|
##########
|
881
962
|
# incomplete!
|
@@ -905,16 +986,7 @@ device_parsers:
|
|
905
986
|
- regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
|
906
987
|
device_replacement: 'Kindle Fire'
|
907
988
|
|
908
|
-
|
909
|
-
# Android General Device Matching (far from perfect)
|
910
|
-
#########
|
911
|
-
- regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; WOWMobile (.+) Build'
|
912
|
-
- regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{0,2}; (.+) Build'
|
913
|
-
- regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; (.+) Build'
|
914
|
-
- regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+;[A-Za-z]{2}\-[A-Za-z]{0,2};(.+) Build'
|
915
|
-
- regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; (.+) Build'
|
916
|
-
- regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; (.+) Build'
|
917
|
-
- regex: 'Android[\- ][\d]+\.[\d]+; (.+) Build'
|
989
|
+
|
918
990
|
|
919
991
|
##########
|
920
992
|
# NOKIA
|
@@ -990,6 +1062,12 @@ device_parsers:
|
|
990
1062
|
- regex: 'Googlebot/\d+.\d+'
|
991
1063
|
device_replacement: 'Spider'
|
992
1064
|
|
1065
|
+
- regex: 'NING/(\d+).(\d+)'
|
1066
|
+
device_replacement: 'Spider'
|
1067
|
+
|
1068
|
+
- regex: 'MsnBot-Media /(\d+).(\d+)'
|
1069
|
+
device_replacement: 'Spider'
|
1070
|
+
|
993
1071
|
##########
|
994
1072
|
# complete but probably catches spoofs
|
995
1073
|
# iSTUFF
|
@@ -1018,7 +1096,14 @@ device_parsers:
|
|
1018
1096
|
device_replacement: 'Alcatel $1'
|
1019
1097
|
- regex: 'Alcatel-([A-Za-z0-9]+)'
|
1020
1098
|
device_replacement: 'Alcatel $1'
|
1021
|
-
|
1099
|
+
- regex: 'ALCATEL_ONE_TOUCH_([A-Za-z0-9]+)'
|
1100
|
+
device_replacement: 'Alcatel ONE TOUCH $1'
|
1101
|
+
- regex: 'ALCATEL (ONE TOUCH [A-Za-z0-9]+)'
|
1102
|
+
device_replacement: 'Alcatel $1'
|
1103
|
+
- regex: 'ALCATEL (one touch [A-Za-z0-9]+)'
|
1104
|
+
device_replacement: 'Alcatel $1'
|
1105
|
+
- regex: 'ALCATEL ([A-Za-z0-9]+)'
|
1106
|
+
device_replacement: 'Alcatel $1'
|
1022
1107
|
##########
|
1023
1108
|
# Amoi
|
1024
1109
|
##########
|
@@ -1137,6 +1222,14 @@ device_parsers:
|
|
1137
1222
|
device_replacement: 'Motorola $1'
|
1138
1223
|
- regex: 'MOT\-([A-Za-z0-9]+)'
|
1139
1224
|
device_replacement: 'Motorola $1'
|
1225
|
+
- regex: ' (DROID RAZR [A-Za-z0-9 ]+) '
|
1226
|
+
device_replacement: 'Motorola $1'
|
1227
|
+
- regex: ' (DROID[2 ][A-Za-z0-9 ]+) '
|
1228
|
+
device_replacement: 'Motorola $1'
|
1229
|
+
- regex: ' (Droid2| )'
|
1230
|
+
device_replacement: 'Motorola $1'
|
1231
|
+
- regex: ' (DROID2| )'
|
1232
|
+
device_replacement: 'Motorola $1'
|
1140
1233
|
|
1141
1234
|
##########
|
1142
1235
|
# nintendo
|
@@ -1167,6 +1260,16 @@ device_parsers:
|
|
1167
1260
|
device_replacement: 'Samsung $1'
|
1168
1261
|
- regex: 'SAMSUNG\; ([A-Za-z0-9\-]+)'
|
1169
1262
|
device_replacement: 'Samsung $1'
|
1263
|
+
|
1264
|
+
##########
|
1265
|
+
# ZTE
|
1266
|
+
##########
|
1267
|
+
- regex: 'ZTE-([A-Za-z0-9\-]+)'
|
1268
|
+
device_replacement: 'ZTE $1'
|
1269
|
+
- regex: 'ZTE ([A-Za-z0-9\-]+)'
|
1270
|
+
device_replacement: 'ZTE $1'
|
1271
|
+
- regex: 'ZTE_([A-Za-z0-9\-]+)'
|
1272
|
+
device_replacement: 'ZTE $1'
|
1170
1273
|
|
1171
1274
|
##########
|
1172
1275
|
# Sega
|
@@ -1182,11 +1285,30 @@ device_parsers:
|
|
1182
1285
|
- regex: 'Softbank/2\.0/([A-Za-z0-9]+)'
|
1183
1286
|
device_replacement: 'Softbank $1'
|
1184
1287
|
|
1288
|
+
##########
|
1289
|
+
# SONY #
|
1290
|
+
##########
|
1291
|
+
- regex: 'Sony([^ ]+) '
|
1292
|
+
device_replacement: 'Sony $1'
|
1293
|
+
|
1185
1294
|
##########
|
1186
1295
|
# WebTV
|
1187
1296
|
##########
|
1188
1297
|
- regex: '(WebTV)/(\d+).(\d+)'
|
1189
1298
|
|
1299
|
+
#########
|
1300
|
+
# Android General Device Matching (far from perfect)
|
1301
|
+
#########
|
1302
|
+
- regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [^;]+; ([A-Za-z0-9 _-]+) '
|
1303
|
+
- regex: 'Android[\- ][\d]+\.[\d]+; [^;]+; ([A-Za-z0-9 _-]+) '
|
1304
|
+
- regex: 'Android[\- ][\d]+\.[\d]+; [^;]+; WOWMobile ([A-Za-z0-9 _-]+) '
|
1305
|
+
- regex: 'Android[\- ][\d]+\.[\d]+\-update1; [^;]+; ([A-Za-z0-9 _-]+) '
|
1306
|
+
- regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+;[^;]+;([A-Za-z0-9 _-]+) '
|
1307
|
+
- regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; ([A-Za-z0-9 _-]+) '
|
1308
|
+
- regex: 'Android[\- ][\d]+\.[\d]+; ([A-Za-z0-9 _-]+) '
|
1309
|
+
- regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [^;]+; ([A-Za-z0-9\.\/_-]+) '
|
1310
|
+
- regex: 'Android[\- ][\d]+\.[\d]+; [^;]+; ([A-Za-z0-9\.\/_-]+) '
|
1311
|
+
|
1190
1312
|
##########
|
1191
1313
|
# Generic Smart Phone
|
1192
1314
|
##########
|
@@ -1208,6 +1330,6 @@ device_parsers:
|
|
1208
1330
|
##########
|
1209
1331
|
# Spiders (this is hack...)
|
1210
1332
|
##########
|
1211
|
-
- regex: '(bingbot|bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\-webcrawler|converacrawler|dataparksearch|findlinks|crawler|Netvibes|Sogou Pic Spider|ICC\-Crawler|Innovazion Crawler)'
|
1333
|
+
- regex: '(bingbot|bot|borg|google(^tv)|yahoo|slurp|msnbot|msrbot|openbot|archiver|netresearch|lycos|scooter|altavista|teoma|gigabot|baiduspider|blitzbot|oegp|charlotte|furlbot|http%20client|polybot|htdig|ichiro|mogimogi|larbin|pompos|scrubby|searchsight|seekbot|semanticdiscovery|silk|snappy|speedy|spider|voila|vortex|voyager|zao|zeal|fast\-webcrawler|converacrawler|dataparksearch|findlinks|crawler|Netvibes|Sogou Pic Spider|ICC\-Crawler|Innovazion Crawler|Daumoa|EtaoSpider|A6\-Indexer|YisouSpider|Riddler|DBot|wsr\-agent|Xenu|SeznamBot|PaperLiBot|SputnikBot|CCBot|ProoXiBot|Scrapy|Genieo|Screaming Frog|YahooCacheSystem|CiBra|Nutch)'
|
1212
1334
|
device_replacement: 'Spider'
|
1213
1335
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.2.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: 2014-
|
11
|
+
date: 2014-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A simple, comprehensive Ruby gem for parsing user agent strings with
|
14
14
|
the help of BrowserScope's UA database
|