user_agent_parser 2.0.0 → 2.1.4

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.

@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 63fba72411cd6f5a6abb1a1fc066479f60b50d14
4
+ data.tar.gz: a169357b37a9dbe604c73cd1e10414324c139b4a
5
+ SHA512:
6
+ metadata.gz: c4de6f103556c10c73080d12f6fda1db551a7a0b487a5ba0812fd11bac9db7b6c9773e57458843d2ce151c1717377eea1567bde79143f6f146b673eda29ef8da
7
+ data.tar.gz: dac63ba14206459b3ed336586c9b1a7a330b54b6be76297704f0313c240a699c591ed1f6ba854c2cd0db613b6479d8435f7c0c2d22b54fc5d6138cde2e6d3a8e
data/Readme.md CHANGED
@@ -43,6 +43,21 @@ parser.parse 'Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.5.24 Version/10.53'
43
43
  => #<UserAgentParser::UserAgent Opera 10.53 (Windows XP)>
44
44
  ```
45
45
 
46
+ In a larger application, you could store a parser in a global to avoid repeat pattern loading:
47
+
48
+ ```ruby
49
+ module MyApplication
50
+
51
+ # Instantiate the parser on load as it's quite expensive
52
+ USER_AGENT_PARSER = UserAgentParser::Parser.new
53
+
54
+ def self.user_agent_parser
55
+ USER_AGENT_PARSER
56
+ end
57
+
58
+ end
59
+ ```
60
+
46
61
  ## The pattern database
47
62
 
48
63
  The [ua-parser database](https://github.com/tobie/ua-parser/blob/master/regexes.yaml) is included via a [git submodule](http://help.github.com/submodules/). To update the database the submodule needs to be updated and the gem re-released (pull requests for this are very welcome!).
@@ -59,6 +74,17 @@ or when instantiating a `UserAgentParser::Parser`:
59
74
  UserAgentParser::Parser.new(patterns_path: '/some/path/to/regexes.yaml').parse(ua_string)
60
75
  ```
61
76
 
77
+ ## Binary: user_agent_parser
78
+
79
+ There is a binary called `user_agent_parser` that will read from
80
+ standard input, parse each line and print the result, for example:
81
+
82
+ ```ruby
83
+ $ cat SOME-FILE.json | user_agent_parser --format '%n %M' | distribution
84
+ ```
85
+
86
+ See `user_agent_parser -h` for more information.
87
+
62
88
  ## Contributing
63
89
 
64
90
  1. Fork
@@ -68,6 +94,19 @@ UserAgentParser::Parser.new(patterns_path: '/some/path/to/regexes.yaml').parse(u
68
94
 
69
95
  All accepted pull requests will earn you commit and release rights.
70
96
 
97
+ ## Releasing a new version
98
+
99
+ 1. Update the version in `user_agent_parser.gemspec`
100
+ 2. `git commit user_agent_parser.gemspec` with the following message format:
101
+
102
+ Version x.x.x
103
+
104
+ Changelog:
105
+ * Some new feature
106
+ * Some new bug fix
107
+ 3. `rake release`
108
+ 4. Create a [new Github release](https://github.com/toolmantim/user_agent_parser/releases/new)
109
+
71
110
  ## License
72
111
 
73
112
  MIT
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+
5
+ require 'user_agent_parser'
6
+ require 'user_agent_parser/cli'
7
+
8
+ options = {}
9
+
10
+ optparse = OptionParser.new do|opts|
11
+ opts.on('--name', 'Print name only') do
12
+ options[:name] = true
13
+ end
14
+
15
+ opts.on('--version', 'Print version only') do
16
+ options[:version] = true
17
+ end
18
+
19
+ opts.on('--major', 'Print major version only') do
20
+ options[:major] = true
21
+ end
22
+
23
+ opts.on('--minor', 'Print minor version only') do
24
+ options[:minor] = true
25
+ end
26
+
27
+ opts.on('--os', 'Print operating system only') do
28
+ options[:os] = true
29
+ end
30
+
31
+ opts.on('--format format',
32
+ 'Print output in specified format. The available formatters are:',
33
+ ' - %n: name',
34
+ ' - %v: version',
35
+ ' - %M: major version',
36
+ ' - %m: minor version',
37
+ ' - %o: operating system'
38
+ ) do |format|
39
+ options[:format] = format
40
+ end
41
+
42
+ opts.on('-h', '--help', 'Display this screen') do
43
+ puts opts
44
+ exit
45
+ end
46
+ end
47
+
48
+ optparse.parse!
49
+
50
+ parser = UserAgentParser::Parser.new
51
+
52
+ ARGF.each do |line|
53
+ puts UserAgentParser::Cli.new(parser.parse(line), options).run!
54
+ end
@@ -0,0 +1,54 @@
1
+ module UserAgentParser
2
+ class Cli
3
+ def initialize(user_agent, options = {})
4
+ @user_agent = user_agent
5
+ @options = options
6
+ end
7
+
8
+ def run!
9
+ if @options[:name]
10
+ @user_agent.name
11
+ elsif @options[:version]
12
+ with_version do |version|
13
+ version.to_s
14
+ end
15
+ elsif @options[:major]
16
+ major
17
+ elsif @options[:minor]
18
+ minor
19
+ elsif @options[:os]
20
+ @user_agent.os.to_s
21
+ elsif format = @options[:format]
22
+ format.gsub('%n', @user_agent.name).
23
+ gsub('%v', version.to_s).
24
+ gsub('%M', major.to_s).
25
+ gsub('%m', minor.to_s).
26
+ gsub('%o', @user_agent.os.to_s)
27
+ else
28
+ @user_agent.to_s
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def major
35
+ with_version do |version|
36
+ version.major
37
+ end
38
+ end
39
+
40
+ def minor
41
+ with_version do |version|
42
+ version.minor
43
+ end
44
+ end
45
+
46
+ def version
47
+ @version ||= @user_agent.version
48
+ end
49
+
50
+ def with_version(&block)
51
+ block.call(version) if version
52
+ end
53
+ end
54
+ end
@@ -71,7 +71,7 @@ module UserAgentParser
71
71
  end
72
72
 
73
73
  def user_agent_from_pattern_match(pattern, match, os = nil, device = nil)
74
- name, v1, v2, v3 = match[1], match[2], match[3], match[4]
74
+ name, v1, v2, v3, v4 = match[1], match[2], match[3], match[4], match[5]
75
75
 
76
76
  if pattern["family_replacement"]
77
77
  name = pattern["family_replacement"].sub('$1', name || '')
@@ -89,7 +89,11 @@ module UserAgentParser
89
89
  v3 = pattern["v3_replacement"].sub('$1', v3 || '')
90
90
  end
91
91
 
92
- version = version_from_segments(v1, v2, v3)
92
+ if pattern["v4_replacement"]
93
+ v4 = pattern["v4_replacement"].sub('$1', v4 || '')
94
+ end
95
+
96
+ version = version_from_segments(v1, v2, v3, v4)
93
97
 
94
98
  UserAgent.new(name, version, os, device)
95
99
  end
@@ -1,6 +1,11 @@
1
1
  user_agent_parsers:
2
2
  #### SPECIAL CASES TOP ####
3
3
 
4
+ # HbbTV standard defines what features the browser should understand.
5
+ # but it's like targeting "HTML5 browsers", effective browser support depends on the model
6
+ # See os_parsers if you want to target a specific TV
7
+ - regex: '(HbbTV)/(\d+)\.(\d+)\.(\d+) \('
8
+
4
9
  # must go before Firefox to catch SeaMonkey/Camino
5
10
  - regex: '(SeaMonkey|Camino)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)'
6
11
 
@@ -61,6 +66,14 @@ user_agent_parsers:
61
66
  - regex: '(Opera Mini)/att/(\d+)\.(\d+)'
62
67
  - regex: '(Opera)/9.80.*Version/(\d+)\.(\d+)(?:\.(\d+))?'
63
68
 
69
+ # Opera 14 for Android uses a WebKit render engine.
70
+ - regex: '(?:Mobile Safari).*(OPR)/(\d+)\.(\d+)\.(\d+)'
71
+ family_replacement: 'Opera Mobile'
72
+
73
+ # Opera 15 for Desktop is similar to Chrome but includes an "OPR" Version string.
74
+ - regex: '(?:Chrome).*(OPR)/(\d+)\.(\d+)\.(\d+)'
75
+ family_replacement: 'Opera'
76
+
64
77
  # Palm WebOS looks a lot like Safari.
65
78
  - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?'
66
79
  family_replacement: 'webOS Browser'
@@ -75,7 +88,7 @@ user_agent_parsers:
75
88
 
76
89
  # Lightning (for Thunderbird)
77
90
  # http://www.mozilla.org/projects/calendar/lightning/
78
- - regex: '(Lightning)/(\d+)\.(\d+)([ab]?\d+[a-z]*)'
91
+ - regex: '(Lightning)/(\d+)\.(\d+)\.?((?:[ab]?\d+[a-z]*)|(?:\d*))'
79
92
 
80
93
  # Swiftfox
81
94
  - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+(?:pre)?) \(Swiftfox\)'
@@ -84,7 +97,7 @@ user_agent_parsers:
84
97
  family_replacement: 'Swiftfox'
85
98
 
86
99
  # Rekonq
87
- - regex: '(rekonq)/(\d+)\.(\d+) Safari'
100
+ - regex: '(rekonq)/(\d+)\.(\d+)\.?(\d+)? Safari'
88
101
  family_replacement: 'Rekonq'
89
102
  - regex: 'rekonq'
90
103
  family_replacement: 'Rekonq'
@@ -133,9 +146,6 @@ user_agent_parsers:
133
146
  - regex: '(SLP Browser)/(\d+)\.(\d+)'
134
147
  family_replacement: 'Tizen Browser'
135
148
 
136
- # Epiphany browser (identifies as Chromium)
137
- - regex: '(Epiphany)/(\d+)\.(\d+).(\d+)'
138
-
139
149
  # Sogou Explorer 2.X
140
150
  - regex: '(SE 2\.X) MetaSr (\d+)\.(\d+)'
141
151
  family_replacement: 'Sogou Explorer'
@@ -154,6 +164,10 @@ user_agent_parsers:
154
164
  - regex: '(facebookexternalhit)/(\d+)\.(\d+)'
155
165
  family_replacement: 'FacebookBot'
156
166
 
167
+ # LinkedIn
168
+ - regex: '(LinkedInBot)/(\d+)\.(\d+)'
169
+ family_replacement: 'LinkedInBot'
170
+
157
171
  # Twitterbot
158
172
  - regex: '(Twitterbot)/(\d+)\.(\d+)'
159
173
  family_replacement: 'TwitterBot'
@@ -173,15 +187,49 @@ user_agent_parsers:
173
187
  - regex: '(Chrome)/(\d+)\.(\d+)\.(\d+).* MRCHROME'
174
188
  family_replacement: 'Mail.ru Chromium Browser'
175
189
 
190
+ # AOL Browser (IE-based)
191
+ - regex: '(AOL) (\d+)\.(\d+); AOLBuild (\d+)'
192
+
193
+
194
+
195
+
176
196
  #### END SPECIAL CASES TOP ####
177
197
 
178
198
  #### MAIN CASES - this catches > 50% of all browsers ####
179
199
 
180
200
  # Browser/major_version.minor_version.beta_version
181
- - regex: '(AdobeAIR|Chromium|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Shiira|Sunrise|Chrome|Flock|Netscape|Lunascape|WebPilot|Vodafone|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iris|UP\.Browser|Bunjalloo|Google Earth|Raven for Mac|Openwave)/(\d+)\.(\d+)\.(\d+)'
201
+ - regex: '(AdobeAIR|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Flock|Netscape|Lunascape|WebPilot|Vodafone|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iris|UP\.Browser|Bunjalloo|Google Earth|Raven for Mac|Openwave)/(\d+)\.(\d+)\.(\d+)'
202
+
203
+ # Outlook 2007
204
+ - regex: 'MSOffice 12'
205
+ family_replacement: 'Outlook'
206
+ v1_replacement: '2007'
207
+
208
+ # Outlook 2010
209
+ - regex: 'MSOffice 14'
210
+ family_replacement: 'Outlook'
211
+ v1_replacement: '2010'
212
+
213
+ # Outlook 2013
214
+ - regex: 'Microsoft Outlook 15\.\d+\.\d+'
215
+ family_replacement: 'Outlook'
216
+ v1_replacement: '2013'
217
+
218
+ # Apple Air Mail
219
+ - regex: '(Airmail) (\d+)\.(\d+)(?:\.(\d+))?'
220
+
221
+ # Thunderbird
222
+ - regex: '(Thunderbird)/(\d+)\.(\d+)\.(\d+(?:pre)?)'
223
+ family_replacement: 'Thunderbird'
224
+
225
+ # Chrome/Chromium/major_version.minor_version.beta_version
226
+ - regex: '(Chromium|Chrome)/(\d+)\.(\d+)\.(\d+)'
182
227
 
183
228
  # Browser/major_version.minor_version
184
- - regex: '(Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|Vodafone|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser)/(\d+)\.(\d+)'
229
+ - regex: '(bingbot|Bolt|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Chrome|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|Vodafone|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser)/(\d+)\.(\d+)'
230
+
231
+ # Chrome/Chromium/major_version.minor_version
232
+ - regex: '(Chromium|Chrome)/(\d+)\.(\d+)'
185
233
 
186
234
  # Browser major_version.minor_version.beta_version (space instead of slash)
187
235
  - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)'
@@ -219,10 +267,6 @@ user_agent_parsers:
219
267
  - regex: '(MSIE) (\d+)\.(\d+).*XBLWP7'
220
268
  family_replacement: 'IE Large Screen'
221
269
 
222
- # AFTER THE EDGE CASES ABOVE!
223
- - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
224
- - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
225
-
226
270
  #### END MAIN CASES ####
227
271
 
228
272
  #### SPECIAL CASES ####
@@ -338,6 +382,9 @@ user_agent_parsers:
338
382
  - regex: '(Pre)/(\d+)\.(\d+)'
339
383
  family_replacement: 'Palm Pre'
340
384
 
385
+ # fork of Links
386
+ - regex: '(ELinks)/(\d+)\.(\d+)'
387
+ - regex: '(ELinks) \((\d+)\.(\d+)'
341
388
  - regex: '(Links) \((\d+)\.(\d+)'
342
389
 
343
390
  - regex: '(QtWeb) Internet Browser/(\d+)\.(\d+)'
@@ -349,6 +396,9 @@ user_agent_parsers:
349
396
  - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
350
397
  family_replacement: 'Amazon Silk'
351
398
 
399
+ # Phantomjs, should go before Safari
400
+ - regex: '(PhantomJS)/(\d+)\.(\d+)\.(\d+)'
401
+
352
402
  # WebKit Nightly
353
403
  - regex: '(AppleWebKit)/(\d+)\.?(\d+)?\+ .* Safari'
354
404
  family_replacement: 'WebKit Nightly'
@@ -372,13 +422,85 @@ user_agent_parsers:
372
422
  - regex: '(Phantom)/V(\d+)\.(\d+)'
373
423
  family_replacement: 'Phantom Browser'
374
424
 
375
- - regex: '(MSIE) (\d+)\.(\d+)'
425
+ - regex: 'Trident(.*)rv.(\d+)\.(\d+)'
426
+ family_replacement: 'IE'
427
+
428
+ # Apple Mail
429
+
430
+ # apple mail - not directly detectable, have it after Safari stuff
431
+ - regex: '(AppleWebKit)/(\d+)\.(\d+)\.(\d+)'
432
+ family_replacement: 'AppleMail'
433
+
434
+ # AFTER THE EDGE CASES ABOVE!
435
+ # AFTER IE11
436
+ # BEFORE all other IE
437
+ - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
438
+ - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
439
+
440
+ - regex: '([MS]?IE) (\d+)\.(\d+)'
376
441
  family_replacement: 'IE'
377
442
 
378
443
  - regex: '(python-requests)/(\d+)\.(\d+)'
379
444
  family_replacement: 'Python Requests'
380
445
 
381
446
  os_parsers:
447
+ ##########
448
+ # HbbTV vendors
449
+ ##########
450
+
451
+ # starts with the easy one : Panasonic seems consistent across years, hope it will continue
452
+ #HbbTV/1.1.1 (;Panasonic;VIERA 2011;f.532;0071-0802 2000-0000;)
453
+ #HbbTV/1.1.1 (;Panasonic;VIERA 2012;1.261;0071-3103 2000-0000;)
454
+ #HbbTV/1.2.1 (;Panasonic;VIERA 2013;3.672;4101-0003 0002-0000;)
455
+ #- regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Panasonic);VIERA ([0-9]{4});'
456
+
457
+ # Sony is consistent too but do not place year like the other
458
+ # Opera/9.80 (Linux armv7l; HbbTV/1.1.1 (; Sony; KDL32W650A; PKG3.211EUA; 2013;); ) Presto/2.12.362 Version/12.11
459
+ # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Sony; KDL40HX751; PKG1.902EUA; 2012;);; en) Presto/2.10.250 Version/11.60
460
+ # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Sony; KDL22EX320; PKG4.017EUA; 2011;);; en) Presto/2.7.61 Version/11.00
461
+ #- regex: 'HbbTV/\d+\.\d+\.\d+ \(; (Sony);.*;.*; ([0-9]{4});\)'
462
+
463
+
464
+ # LG is consistent too, but we need to add manually the year model
465
+ #Mozilla/5.0 (Unknown; Linux armv7l) AppleWebKit/537.1+ (KHTML, like Gecko) Safari/537.1+ HbbTV/1.1.1 ( ;LGE ;NetCast 4.0 ;03.20.30 ;1.0M ;)
466
+ #Mozilla/5.0 (DirectFB; Linux armv7l) AppleWebKit/534.26+ (KHTML, like Gecko) Version/5.0 Safari/534.26+ HbbTV/1.1.1 ( ;LGE ;NetCast 3.0 ;1.0 ;1.0M ;)
467
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \( ;(LG)E ;NetCast 4.0'
468
+ os_v1_replacement: '2013'
469
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \( ;(LG)E ;NetCast 3.0'
470
+ os_v1_replacement: '2012'
471
+
472
+ # Samsung is on its way of normalizing their user-agent
473
+ # HbbTV/1.1.1 (;Samsung;SmartTV2013;T-FXPDEUC-1102.2;;) WebKit
474
+ # HbbTV/1.1.1 (;Samsung;SmartTV2013;T-MST12DEUC-1102.1;;) WebKit
475
+ # HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit
476
+ # HbbTV/1.1.1 (;;;;;) Maple_2011
477
+ - regex: 'HbbTV/1.1.1 \(;;;;;\) Maple_2011'
478
+ os_replacement: 'Samsung'
479
+ os_v1_replacement: '2011'
480
+ # manage the two models of 2013
481
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});.*FXPDEUC'
482
+ os_v2_replacement: 'UE40F7000'
483
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});.*MST12DEUC'
484
+ os_v2_replacement: 'UE32F4500'
485
+ # generic Samsung (works starting in 2012)
486
+ #- regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});'
487
+
488
+ # Philips : not found any other way than a manual mapping
489
+ # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/4.1.3 PHILIPSTV/1.1.1; en) Presto/2.10.250 Version/11.60
490
+ # Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.2.1; en) Presto/2.6.33 Version/10.70
491
+ - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/4'
492
+ os_v1_replacement: '2013'
493
+ - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/3'
494
+ os_v1_replacement: '2012'
495
+ - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/2'
496
+ os_v1_replacement: '2011'
497
+
498
+ # the HbbTV emulator developers use HbbTV/1.1.1 (;;;;;) firetv-firefox-plugin 1.1.20
499
+ - regex: 'HbbTV/\d+\.\d+\.\d+.*(firetv)-firefox-plugin (\d+).(\d+).(\d+)'
500
+ os_replacement: 'FireHbbTV'
501
+
502
+ # generic HbbTV, hoping to catch manufacturer name (always after 2nd comma) and the first string that looks like a 2011-2019 year
503
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \(.*; ?([a-zA-Z]+) ?;.*(201[1-9]).*\)'
382
504
 
383
505
  ##########
384
506
  # Android
@@ -420,7 +542,7 @@ os_parsers:
420
542
  # lots of ua strings have Windows NT 4.1 !?!?!?!? !?!? !? !????!?! !!! ??? !?!?! ?
421
543
  # (very) roughly ordered in terms of frequency of occurence of regex (win xp currently most frequent, etc)
422
544
  ##########
423
-
545
+
424
546
  - regex: '(Windows (?:NT 5\.2|NT 5\.1))'
425
547
  os_replacement: 'Windows XP'
426
548
 
@@ -435,6 +557,9 @@ os_parsers:
435
557
  - regex: '(Windows NT 6\.0)'
436
558
  os_replacement: 'Windows Vista'
437
559
 
560
+ - regex: '(Win 9x 4\.90)'
561
+ os_replacement: 'Windows Me'
562
+
438
563
  - regex: '(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\.0|Windows Vista|Windows 2000|Windows 3.1)'
439
564
 
440
565
  - regex: '(Windows NT 6\.2; ARM;)'
@@ -496,8 +621,6 @@ os_parsers:
496
621
 
497
622
  - regex: '(AppleTV)/(\d+)\.(\d+)'
498
623
  os_replacement: 'ATV OS X'
499
- os_v1_replacement: '$1'
500
- os_v2_replacement: '$2'
501
624
 
502
625
  ##########
503
626
  # Chrome OS
@@ -511,9 +634,10 @@ os_parsers:
511
634
  ##########
512
635
  # Linux distros
513
636
  ##########
514
- - regex: '(Debian)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
637
+ - regex: '([Dd]ebian)'
638
+ os_replacement: 'Debian'
515
639
  - regex: '(Linux Mint)(?:/(\d+))?'
516
- - regex: '(Mandriva)(?: Linux)?/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
640
+ - regex: '(Mandriva)(?: Linux)?/(?:[\d.-]+m[a-z]{2}(\d+).(\d))?'
517
641
 
518
642
  ##########
519
643
  # Symbian + Symbian OS
@@ -554,7 +678,7 @@ os_parsers:
554
678
  ##########
555
679
  # Firefox OS
556
680
  ##########
557
- - regex: '\(Mobile;.+Firefox/\d+\.\d+'
681
+ - regex: '\((?:Mobile|Tablet);.+Firefox/\d+\.\d+'
558
682
  os_replacement: 'Firefox OS'
559
683
 
560
684
  ##########
@@ -573,7 +697,7 @@ os_parsers:
573
697
  ##########
574
698
  - regex: '(GoogleTV) (\d+)\.(\d+)\.(\d+)'
575
699
  # Old style
576
- - regex: '(GoogleTV)\/\d+'
700
+ - regex: '(GoogleTV)/[\da-z]+'
577
701
 
578
702
  - regex: '(WebTV)/(\d+).(\d+)'
579
703
 
@@ -589,16 +713,17 @@ os_parsers:
589
713
  # since the majority of os cases are very specific, these go last
590
714
  ##########
591
715
  # first.second.third.fourth bits
592
- - regex: '(SUSE|Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
716
+ - regex: '(Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
593
717
 
594
718
  # first.second.third bits
595
- - regex: '(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\d+)\.(\d+)\.(\d+)'
719
+ - regex: '(Red Hat|Puppy|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)'
596
720
 
597
721
  # first.second bits
598
722
  - regex: '(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\d+)\.(\d+)'
599
723
 
600
724
  # just os
601
- - regex: '(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)'
725
+ - regex: '(Windows|OpenBSD|FreeBSD|NetBSD|Android|WeTab)'
726
+ - regex: '(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Gentoo|Mageia)'
602
727
  - regex: '(Linux)/(\d+)\.(\d+)'
603
728
  - regex: '(Linux|BSD)'
604
729
  - regex: 'SunOS'
@@ -675,6 +800,16 @@ device_parsers:
675
800
  device_replacement: 'Kindle Fire HD 8.9" WiFi'
676
801
  - regex: '(KFJWA Build)'
677
802
  device_replacement: 'Kindle Fire HD 8.9" 4G'
803
+ - regex: '(KFSOWI Build)'
804
+ device_replacement: 'Kindle Fire HD 7" WiFi'
805
+ - regex: '(KFTHWI Build)'
806
+ device_replacement: 'Kindle Fire HDX 7" WiFi'
807
+ - regex: '(KFTHWA Build)'
808
+ device_replacement: 'Kindle Fire HDX 7" 4G'
809
+ - regex: '(KFAPWI Build)'
810
+ device_replacement: 'Kindle Fire HDX 8.9" WiFi'
811
+ - regex: '(KFAPWA Build)'
812
+ device_replacement: 'Kindle Fire HDX 8.9" 4G'
678
813
  - regex: '(Kindle Fire)'
679
814
  - regex: '(Kindle)'
680
815
  - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
@@ -683,11 +818,11 @@ device_parsers:
683
818
  #########
684
819
  # Android General Device Matching (far from perfect)
685
820
  #########
686
- - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{2}; WOWMobile (.+) Build'
687
- - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{2}; (.+) Build'
688
- - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{2}; (.+) Build'
689
- - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+;[A-Za-z]{2}\-[A-Za-z]{2};(.+) Build'
690
- - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{2}; (.+) Build'
821
+ - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; WOWMobile (.+) Build'
822
+ - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{0,2}; (.+) Build'
823
+ - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; (.+) Build'
824
+ - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+;[A-Za-z]{2}\-[A-Za-z]{0,2};(.+) Build'
825
+ - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; (.+) Build'
691
826
  - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; (.+) Build'
692
827
  - regex: 'Android[\- ][\d]+\.[\d]+; (.+) Build'
693
828
 
@@ -752,6 +887,16 @@ device_parsers:
752
887
  - regex: '(AppleTV)'
753
888
  device_replacement: 'AppleTV'
754
889
 
890
+ ##########
891
+ # Catch the google mobile crawler before checking for iPhones.
892
+ ##########
893
+
894
+ - regex: 'AdsBot-Google-Mobile'
895
+ device_replacement: 'Spider'
896
+
897
+ - regex: 'Googlebot-Mobile/(\d+).(\d+)'
898
+ device_replacement: 'Spider'
899
+
755
900
  ##########
756
901
  # complete but probably catches spoofs
757
902
  # iSTUFF
@@ -760,6 +905,7 @@ device_parsers:
760
905
  # cannot determine specific device type from ua string. (3g, 3gs, 4, etc)
761
906
  - regex: '(iPad) Simulator;'
762
907
  - regex: '(iPad);'
908
+ - regex: '(iPod) touch;'
763
909
  - regex: '(iPod);'
764
910
  - regex: '(iPhone) Simulator;'
765
911
  - regex: '(iPhone);'
@@ -854,6 +1000,12 @@ device_parsers:
854
1000
  - regex: 'Lenovo_([A-Za-z0-9]+)'
855
1001
  device_replacement: 'Lenovo $1'
856
1002
 
1003
+ ##########
1004
+ # HbbTV (European and Australian standard)
1005
+ # written before the LG regexes, as LG is making HbbTV too
1006
+ ##########
1007
+ - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+'
1008
+
857
1009
  ##########
858
1010
  # lg
859
1011
  ##########
@@ -963,6 +1115,6 @@ device_parsers:
963
1115
  ##########
964
1116
  # Spiders (this is hack...)
965
1117
  ##########
966
- - regex: '(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)'
1118
+ - 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)'
967
1119
  device_replacement: 'Spider'
968
1120
 
metadata CHANGED
@@ -1,26 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: user_agent_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
5
- prerelease:
4
+ version: 2.1.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tim Lucas
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-18 00:00:00.000000000 Z
11
+ date: 2014-03-13 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: A simple, comprehensive Ruby gem for parsing user agent strings with
15
14
  the help of BrowserScope's UA database
16
15
  email: t@toolmantim.com
17
- executables: []
16
+ executables:
17
+ - user_agent_parser
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - MIT-LICENSE
22
22
  - Readme.md
23
+ - bin/user_agent_parser
23
24
  - lib/user_agent_parser.rb
25
+ - lib/user_agent_parser/cli.rb
24
26
  - lib/user_agent_parser/device.rb
25
27
  - lib/user_agent_parser/operating_system.rb
26
28
  - lib/user_agent_parser/parser.rb
@@ -30,27 +32,26 @@ files:
30
32
  homepage: http://github.com/toolmantim/user_agent_parser
31
33
  licenses:
32
34
  - MIT
35
+ metadata: {}
33
36
  post_install_message:
34
37
  rdoc_options: []
35
38
  require_paths:
36
39
  - lib
37
40
  required_ruby_version: !ruby/object:Gem::Requirement
38
- none: false
39
41
  requirements:
40
- - - ! '>='
42
+ - - ">="
41
43
  - !ruby/object:Gem::Version
42
44
  version: 1.8.7
43
45
  required_rubygems_version: !ruby/object:Gem::Requirement
44
- none: false
45
46
  requirements:
46
- - - ! '>='
47
+ - - ">="
47
48
  - !ruby/object:Gem::Version
48
49
  version: '0'
49
50
  requirements: []
50
51
  rubyforge_project:
51
- rubygems_version: 1.8.23
52
+ rubygems_version: 2.2.1
52
53
  signing_key:
53
- specification_version: 3
54
+ specification_version: 4
54
55
  summary: A simple, comprehensive Ruby gem for parsing user agent strings with the
55
56
  help of BrowserScope's UA database
56
57
  test_files: []