user_agent_parser 2.1.0 → 2.1.5

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZDY2ZWUzN2RkZmIzYWU2NDcwZmM2Zjk0OTUxMGE3ZDVmNTZjN2ZkNQ==
5
- data.tar.gz: !binary |-
6
- NWE4ODE2OTY3NjIwOGY2MWYxY2E3YmEzMjgxYWIxYzU3YTJiZGYxZQ==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- MGJhMmVmNjMxMDk0ZWUzNDM1MDlmM2NmY2JlNDk4MTVjYzEyNjIxZGFjMDli
10
- MWYyMzg1ZTIwZTdkNzIxNmRjZTI3NTMyNWU1YzFhNDE1ZGMxZjM5MTZjMTYw
11
- ZGM3NWFmODMyY2NkZWRiMjkwNTcyODUwY2ZhZWM4Njg4YTk4ZDc=
12
- data.tar.gz: !binary |-
13
- ZWU1ZjE4YTQ1MmFiNjZlZGE0NGQzOTQ2ODQ2OGEwZmE0MTBhYWZkOGIzZjE5
14
- ZWQwYjJjZDI1MGJmMWMyMDVlYTE4YzkxNmRhZjJlMDYyNGQ2YWEzY2IyYTE0
15
- ZmQ4MjM4ZjlhOTA2MDQ1MGZiZGVjMmEwNjAwMjE4OTIxN2Q1Zjk=
2
+ SHA1:
3
+ metadata.gz: 80f68759d3f70ad50acdc09e5d68214172cac287
4
+ data.tar.gz: 3d55b8c54039e2931b0d36dca2ba82333cec730b
5
+ SHA512:
6
+ metadata.gz: fb24b29ea2f06c2a48e3593e26e00ed5d7805b8c485081742b902a260500bbd5b18b015a5faa8851d6b184c005735700bc5ba46d6a7394d4f0d29ed2a87aa5ae
7
+ data.tar.gz: e5fbf51ff61e036548f607d33050ff2862a31f1066c9fe8cdfe995db32fe77971e2543f06a71a610699260f0e1d566b09a4d9953ea7cff2be161cdd0913b7c65
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
@@ -70,9 +96,16 @@ All accepted pull requests will earn you commit and release rights.
70
96
 
71
97
  ## Releasing a new version
72
98
 
73
- 1. Update the version in user_agent_parser.gemspec
74
- 2. `git commit user_agent_parser.gemspec -m 'Version bump'`
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
75
107
  3. `rake release`
108
+ 4. Create a [new Github release](https://github.com/toolmantim/user_agent_parser/releases/new)
76
109
 
77
110
  ## License
78
111
 
@@ -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
@@ -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
 
@@ -55,16 +60,23 @@ user_agent_parsers:
55
60
  - regex: '(Opera Tablet).*Version/(\d+)\.(\d+)(?:\.(\d+))?'
56
61
  - regex: '(Opera)/.+Opera Mobi.+Version/(\d+)\.(\d+)'
57
62
  family_replacement: 'Opera Mobile'
63
+ - regex: '(Opera)/(\d+)\.(\d+).+Opera Mobi'
64
+ family_replacement: 'Opera Mobile'
65
+ - regex: 'Opera Mobi.+(Opera)/(\d+)\.(\d+)'
66
+ family_replacement: 'Opera Mobile'
58
67
  - regex: 'Opera Mobi'
59
68
  family_replacement: 'Opera Mobile'
60
- - regex: '(Opera Mini)/(\d+)\.(\d+)'
61
- - regex: '(Opera Mini)/att/(\d+)\.(\d+)'
69
+ - regex: '(Opera Mini)(?:/att)?/(\d+)\.(\d+)'
62
70
  - regex: '(Opera)/9.80.*Version/(\d+)\.(\d+)(?:\.(\d+))?'
63
71
 
64
72
  # Opera 14 for Android uses a WebKit render engine.
65
73
  - regex: '(?:Mobile Safari).*(OPR)/(\d+)\.(\d+)\.(\d+)'
66
74
  family_replacement: 'Opera Mobile'
67
75
 
76
+ # Opera 15 for Desktop is similar to Chrome but includes an "OPR" Version string.
77
+ - regex: '(?:Chrome).*(OPR)/(\d+)\.(\d+)\.(\d+)'
78
+ family_replacement: 'Opera'
79
+
68
80
  # Palm WebOS looks a lot like Safari.
69
81
  - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?'
70
82
  family_replacement: 'webOS Browser'
@@ -73,13 +85,13 @@ user_agent_parsers:
73
85
  # http://luakit.org/projects/luakit/
74
86
  - regex: '(luakit)'
75
87
  family_replacement: 'LuaKit'
76
-
88
+
77
89
  # Snowshoe
78
90
  - regex: '(Snowshoe)/(\d+)\.(\d+).(\d+)'
79
91
 
80
92
  # Lightning (for Thunderbird)
81
93
  # http://www.mozilla.org/projects/calendar/lightning/
82
- - regex: '(Lightning)/(\d+)\.(\d+)([ab]?\d+[a-z]*)'
94
+ - regex: '(Lightning)/(\d+)\.(\d+)\.?((?:[ab]?\d+[a-z]*)|(?:\d*))'
83
95
 
84
96
  # Swiftfox
85
97
  - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+(?:pre)?) \(Swiftfox\)'
@@ -88,7 +100,7 @@ user_agent_parsers:
88
100
  family_replacement: 'Swiftfox'
89
101
 
90
102
  # Rekonq
91
- - regex: '(rekonq)/(\d+)\.(\d+) Safari'
103
+ - regex: '(rekonq)/(\d+)\.(\d+)\.?(\d+)? Safari'
92
104
  family_replacement: 'Rekonq'
93
105
  - regex: 'rekonq'
94
106
  family_replacement: 'Rekonq'
@@ -137,9 +149,6 @@ user_agent_parsers:
137
149
  - regex: '(SLP Browser)/(\d+)\.(\d+)'
138
150
  family_replacement: 'Tizen Browser'
139
151
 
140
- # Epiphany browser (identifies as Chromium)
141
- - regex: '(Epiphany)/(\d+)\.(\d+).(\d+)'
142
-
143
152
  # Sogou Explorer 2.X
144
153
  - regex: '(SE 2\.X) MetaSr (\d+)\.(\d+)'
145
154
  family_replacement: 'Sogou Explorer'
@@ -150,6 +159,14 @@ user_agent_parsers:
150
159
  - regex: '(FlyFlow)/(\d+)\.(\d+)'
151
160
  family_replacement: 'Baidu Explorer'
152
161
 
162
+ # QQ Browsers
163
+ - regex: '(MQQBrowser/Mini)(?:(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
164
+ family_replacement: 'QQ Browser Mini'
165
+ - regex: '(MQQBrowser)(?:/(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?'
166
+ family_replacement: 'QQ Browser Mobile'
167
+ - regex: '(QQBrowser)(?:/(\d+)(?:\.(\d+)\.(\d+)(?:\.(\d+))?)?)?'
168
+ family_replacement: 'QQ Browser'
169
+
153
170
  # Pingdom
154
171
  - regex: '(Pingdom.com_bot_version_)(\d+)\.(\d+)'
155
172
  family_replacement: 'PingdomBot'
@@ -158,10 +175,18 @@ user_agent_parsers:
158
175
  - regex: '(facebookexternalhit)/(\d+)\.(\d+)'
159
176
  family_replacement: 'FacebookBot'
160
177
 
178
+ # LinkedIn
179
+ - regex: '(LinkedInBot)/(\d+)\.(\d+)'
180
+ family_replacement: 'LinkedInBot'
181
+
161
182
  # Twitterbot
162
183
  - regex: '(Twitterbot)/(\d+)\.(\d+)'
163
184
  family_replacement: 'TwitterBot'
164
185
 
186
+ # Google Plus
187
+ - regex: 'Google.*/\+/web/snippet'
188
+ family_replacement: 'GooglePlusBot'
189
+
165
190
  # Rackspace Monitoring
166
191
  - regex: '(Rackspace Monitoring)/(\d+)\.(\d+)'
167
192
  family_replacement: 'RackspaceBot'
@@ -177,24 +202,59 @@ user_agent_parsers:
177
202
  - regex: '(Chrome)/(\d+)\.(\d+)\.(\d+).* MRCHROME'
178
203
  family_replacement: 'Mail.ru Chromium Browser'
179
204
 
205
+ # AOL Browser (IE-based)
206
+ - regex: '(AOL) (\d+)\.(\d+); AOLBuild (\d+)'
207
+
180
208
  #### END SPECIAL CASES TOP ####
181
209
 
182
210
  #### MAIN CASES - this catches > 50% of all browsers ####
183
211
 
184
212
  # Browser/major_version.minor_version.beta_version
185
- - 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+)'
213
+ - regex: '(AdobeAIR|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Flock|Netscape|Lunascape|WebPilot|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+)'
214
+
215
+ # Outlook 2007
216
+ - regex: 'MSOffice 12'
217
+ family_replacement: 'Outlook'
218
+ v1_replacement: '2007'
219
+
220
+ # Outlook 2010
221
+ - regex: 'MSOffice 14'
222
+ family_replacement: 'Outlook'
223
+ v1_replacement: '2010'
224
+
225
+ # Outlook 2013
226
+ - regex: 'Microsoft Outlook 15\.\d+\.\d+'
227
+ family_replacement: 'Outlook'
228
+ v1_replacement: '2013'
229
+
230
+ # Apple Air Mail
231
+ - regex: '(Airmail) (\d+)\.(\d+)(?:\.(\d+))?'
232
+
233
+ # Thunderbird
234
+ - regex: '(Thunderbird)/(\d+)\.(\d+)\.(\d+(?:pre)?)'
235
+ family_replacement: 'Thunderbird'
236
+
237
+ # Chrome/Chromium/major_version.minor_version.beta_version
238
+ - regex: '(Chromium|Chrome)/(\d+)\.(\d+)\.(\d+)'
239
+
240
+ # Dolphin Browser
241
+ # @ref: http://www.dolphin.com
242
+ - regex: '\b(Dolphin)(?: |HDCN/|/INT\-)(\d+)\.(\d+)\.?(\d+)?'
186
243
 
187
244
  # Browser/major_version.minor_version
188
- - 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+)'
245
+ - 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|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|mDolphin)/(\d+)\.(\d+)\.?(\d+)?'
246
+
247
+ # Chrome/Chromium/major_version.minor_version
248
+ - regex: '(Chromium|Chrome)/(\d+)\.(\d+)'
189
249
 
190
250
  # Browser major_version.minor_version.beta_version (space instead of slash)
191
251
  - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)'
192
252
  # Browser major_version.minor_version (space instead of slash)
193
253
  - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris) (\d+)\.(\d+)\.?(\d+)?'
194
-
254
+
195
255
  # Kindle WebKit
196
256
  - regex: '(Kindle)/(\d+)\.(\d+)'
197
-
257
+
198
258
  # weird android UAs
199
259
  - regex: '(Android) Donut'
200
260
  v1_replacement: '1'
@@ -223,10 +283,6 @@ user_agent_parsers:
223
283
  - regex: '(MSIE) (\d+)\.(\d+).*XBLWP7'
224
284
  family_replacement: 'IE Large Screen'
225
285
 
226
- # AFTER THE EDGE CASES ABOVE!
227
- - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
228
- - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
229
-
230
286
  #### END MAIN CASES ####
231
287
 
232
288
  #### SPECIAL CASES ####
@@ -268,8 +324,9 @@ user_agent_parsers:
268
324
  - regex: '(BonEcho)/(\d+)\.(\d+)\.(\d+)'
269
325
  family_replacement: 'Bon Echo'
270
326
 
271
- - regex: 'M?QQBrowser'
272
- family_replacement: 'QQ Browser'
327
+ # @note: iOS / OSX Applications
328
+ - regex: '(CFNetwork)(?:/(\d+)\.(\d+)\.?(\d+)?)?'
329
+ family_replacement: 'CFNetwork'
273
330
 
274
331
  - regex: '(iPod).+Version/(\d+)\.(\d+)\.(\d+)'
275
332
  family_replacement: 'Mobile Safari'
@@ -300,8 +357,10 @@ user_agent_parsers:
300
357
  - regex: '(QtCarBrowser)'
301
358
  v1_replacement: '1'
302
359
 
303
- - regex: '(iBrowser/Mini)(\d+).(\d+)'
360
+ - regex: '^(iBrowser/Mini)(\d+).(\d+)'
304
361
  family_replacement: 'iBrowser Mini'
362
+ - regex: '^(iBrowser|iRAPP)/(\d+).(\d+)'
363
+
305
364
  # nokia browsers
306
365
  # based on: http://www.developer.nokia.com/Community/Wiki/User-Agent_headers_for_Nokia_devices
307
366
  - regex: '^(Nokia)'
@@ -342,6 +401,9 @@ user_agent_parsers:
342
401
  - regex: '(Pre)/(\d+)\.(\d+)'
343
402
  family_replacement: 'Palm Pre'
344
403
 
404
+ # fork of Links
405
+ - regex: '(ELinks)/(\d+)\.(\d+)'
406
+ - regex: '(ELinks) \((\d+)\.(\d+)'
345
407
  - regex: '(Links) \((\d+)\.(\d+)'
346
408
 
347
409
  - regex: '(QtWeb) Internet Browser/(\d+)\.(\d+)'
@@ -379,6 +441,21 @@ user_agent_parsers:
379
441
  - regex: '(Phantom)/V(\d+)\.(\d+)'
380
442
  family_replacement: 'Phantom Browser'
381
443
 
444
+ - regex: 'Trident(.*)rv.(\d+)\.(\d+)'
445
+ family_replacement: 'IE'
446
+
447
+ # Apple Mail
448
+
449
+ # apple mail - not directly detectable, have it after Safari stuff
450
+ - regex: '(AppleWebKit)/(\d+)\.(\d+)\.(\d+)'
451
+ family_replacement: 'AppleMail'
452
+
453
+ # AFTER THE EDGE CASES ABOVE!
454
+ # AFTER IE11
455
+ # BEFORE all other IE
456
+ - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
457
+ - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
458
+
382
459
  - regex: '([MS]?IE) (\d+)\.(\d+)'
383
460
  family_replacement: 'IE'
384
461
 
@@ -386,13 +463,69 @@ user_agent_parsers:
386
463
  family_replacement: 'Python Requests'
387
464
 
388
465
  os_parsers:
466
+ ##########
467
+ # HbbTV vendors
468
+ ##########
469
+
470
+ # starts with the easy one : Panasonic seems consistent across years, hope it will continue
471
+ #HbbTV/1.1.1 (;Panasonic;VIERA 2011;f.532;0071-0802 2000-0000;)
472
+ #HbbTV/1.1.1 (;Panasonic;VIERA 2012;1.261;0071-3103 2000-0000;)
473
+ #HbbTV/1.2.1 (;Panasonic;VIERA 2013;3.672;4101-0003 0002-0000;)
474
+ #- regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Panasonic);VIERA ([0-9]{4});'
475
+
476
+ # Sony is consistent too but do not place year like the other
477
+ # Opera/9.80 (Linux armv7l; HbbTV/1.1.1 (; Sony; KDL32W650A; PKG3.211EUA; 2013;); ) Presto/2.12.362 Version/12.11
478
+ # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Sony; KDL40HX751; PKG1.902EUA; 2012;);; en) Presto/2.10.250 Version/11.60
479
+ # Opera/9.80 (Linux mips; U; HbbTV/1.1.1 (; Sony; KDL22EX320; PKG4.017EUA; 2011;);; en) Presto/2.7.61 Version/11.00
480
+ #- regex: 'HbbTV/\d+\.\d+\.\d+ \(; (Sony);.*;.*; ([0-9]{4});\)'
481
+
482
+
483
+ # LG is consistent too, but we need to add manually the year model
484
+ #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 ;)
485
+ #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 ;)
486
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \( ;(LG)E ;NetCast 4.0'
487
+ os_v1_replacement: '2013'
488
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \( ;(LG)E ;NetCast 3.0'
489
+ os_v1_replacement: '2012'
490
+
491
+ # Samsung is on its way of normalizing their user-agent
492
+ # HbbTV/1.1.1 (;Samsung;SmartTV2013;T-FXPDEUC-1102.2;;) WebKit
493
+ # HbbTV/1.1.1 (;Samsung;SmartTV2013;T-MST12DEUC-1102.1;;) WebKit
494
+ # HbbTV/1.1.1 (;Samsung;SmartTV2012;;;) WebKit
495
+ # HbbTV/1.1.1 (;;;;;) Maple_2011
496
+ - regex: 'HbbTV/1.1.1 \(;;;;;\) Maple_2011'
497
+ os_replacement: 'Samsung'
498
+ os_v1_replacement: '2011'
499
+ # manage the two models of 2013
500
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});.*FXPDEUC'
501
+ os_v2_replacement: 'UE40F7000'
502
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});.*MST12DEUC'
503
+ os_v2_replacement: 'UE32F4500'
504
+ # generic Samsung (works starting in 2012)
505
+ #- regex: 'HbbTV/\d+\.\d+\.\d+ \(;(Samsung);SmartTV([0-9]{4});'
506
+
507
+ # Philips : not found any other way than a manual mapping
508
+ # 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
509
+ # 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
510
+ - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/4'
511
+ os_v1_replacement: '2013'
512
+ - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/3'
513
+ os_v1_replacement: '2012'
514
+ - regex: 'HbbTV/1.1.1 \(; (Philips);.*NETTV/2'
515
+ os_v1_replacement: '2011'
516
+
517
+ # the HbbTV emulator developers use HbbTV/1.1.1 (;;;;;) firetv-firefox-plugin 1.1.20
518
+ - regex: 'HbbTV/\d+\.\d+\.\d+.*(firetv)-firefox-plugin (\d+).(\d+).(\d+)'
519
+ os_replacement: 'FireHbbTV'
520
+
521
+ # generic HbbTV, hoping to catch manufacturer name (always after 2nd comma) and the first string that looks like a 2011-2019 year
522
+ - regex: 'HbbTV/\d+\.\d+\.\d+ \(.*; ?([a-zA-Z]+) ?;.*(201[1-9]).*\)'
389
523
 
390
524
  ##########
391
525
  # Android
392
526
  # can actually detect rooted android os. do we care?
393
527
  ##########
394
- - regex: '(Android) (\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?'
395
- - regex: '(Android)\-(\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?'
528
+ - regex: '(Android)[ \-/](\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?'
396
529
 
397
530
  - regex: '(Android) Donut'
398
531
  os_v1_replacement: '1'
@@ -413,6 +546,17 @@ os_parsers:
413
546
  - regex: '(Android) Honeycomb'
414
547
  os_v1_replacement: '3'
415
548
 
549
+ # UCWEB
550
+ - regex: '^UCWEB.*; (Adr) (\d+)\.(\d+)(?:[.\-]([a-z0-9]+))?;'
551
+ os_replacement: 'Android'
552
+ - regex: '^UCWEB.*; (iPad OS|iPh OS) (\d+)_(\d+)(?:_(\d+))?;'
553
+ os_replacement: 'iOS'
554
+ - regex: '^UCWEB.*; (wds) (\d+)\.(\d+)(?:\.(\d+))?;'
555
+ os_replacement: 'Windows Phone'
556
+ # JUC
557
+ - regex: '^(JUC).*; ?U; ?(?:Android)?(\d+)\.(\d+)(?:[\.\-]([a-z0-9]+))?'
558
+ os_replacement: 'Android'
559
+
416
560
  ##########
417
561
  # Kindle Android
418
562
  ##########
@@ -427,43 +571,58 @@ os_parsers:
427
571
  # lots of ua strings have Windows NT 4.1 !?!?!?!? !?!? !? !????!?! !!! ??? !?!?! ?
428
572
  # (very) roughly ordered in terms of frequency of occurence of regex (win xp currently most frequent, etc)
429
573
  ##########
430
-
431
- - regex: '(Windows (?:NT 5\.2|NT 5\.1))'
432
- os_replacement: 'Windows XP'
433
574
 
434
- # ie mobile des ktop mode
575
+ # ie mobile desktop mode
435
576
  # spoofs nt 6.1. must come before windows 7
436
577
  - regex: '(XBLWP7)'
437
578
  os_replacement: 'Windows Phone'
438
579
 
580
+ # @note: These need to come before Windows NT 6.1
581
+ - regex: '(Windows Phone) (?:OS[ /])?(\d+)\.(\d+)'
582
+ - regex: '(Windows ?Mobile)'
583
+ os_replacement: 'Windows Mobile'
584
+
585
+ - regex: '(Windows (?:NT 5\.2|NT 5\.1))'
586
+ os_replacement: 'Windows XP'
587
+
439
588
  - regex: '(Windows NT 6\.1)'
440
589
  os_replacement: 'Windows 7'
441
590
 
442
591
  - regex: '(Windows NT 6\.0)'
443
592
  os_replacement: 'Windows Vista'
444
593
 
594
+ - regex: '(Win 9x 4\.90)'
595
+ os_replacement: 'Windows ME'
596
+
445
597
  - regex: '(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\.0|Windows Vista|Windows 2000|Windows 3.1)'
446
598
 
447
599
  - regex: '(Windows NT 6\.2; ARM;)'
448
600
  os_replacement: 'Windows RT'
449
-
450
- # is this a spoof or is nt 6.2 out and about in some capacity?
451
601
  - regex: '(Windows NT 6\.2)'
452
602
  os_replacement: 'Windows 8'
453
603
 
604
+ - regex: '(Windows NT 6\.3; ARM;)'
605
+ os_replacement: 'Windows RT 8.1'
606
+ - regex: '(Windows NT 6\.3)'
607
+ os_replacement: 'Windows 8.1'
608
+
454
609
  - regex: '(Windows NT 5\.0)'
455
610
  os_replacement: 'Windows 2000'
456
611
 
457
- - regex: '(Windows Phone) (\d+)\.(\d+)'
458
- - regex: '(Windows Phone) OS (\d+)\.(\d+)'
459
- - regex: '(Windows ?Mobile)'
460
- os_replacement: 'Windows Mobile'
461
-
462
612
  - regex: '(WinNT4.0)'
463
613
  os_replacement: 'Windows NT 4.0'
464
614
 
465
- - regex: '(Win98)'
466
- os_replacement: 'Windows 98'
615
+ - regex: '(Windows ?CE)'
616
+ os_replacement: 'Windows CE'
617
+
618
+ - regex: 'Win ?(95|98|3.1|NT|ME|2000)'
619
+ os_replacement: 'Windows $1'
620
+
621
+ - regex: 'Win16'
622
+ os_replacement: 'Windows 3.1'
623
+
624
+ - regex: 'Win32'
625
+ os_replacement: 'Windows 95'
467
626
 
468
627
  ##########
469
628
  # Tizen OS from Samsung
@@ -473,10 +632,36 @@ os_parsers:
473
632
 
474
633
  ##########
475
634
  # Mac OS
476
- # http://en.wikipedia.org/wiki/Mac_OS_X#Versions
635
+ # @ref: http://en.wikipedia.org/wiki/Mac_OS_X#Versions
636
+ # @ref: http://www.puredarwin.org/curious/versions
477
637
  ##########
478
638
  - regex: '(Mac OS X) (\d+)[_.](\d+)(?:[_.](\d+))?'
479
-
639
+ # Leopard
640
+ - regex: ' (Dar)(win)/(9).(\d+).*\((?:i386|x86_64|Power Macintosh)\)'
641
+ os_replacement: 'Mac OS X'
642
+ os_v1_replacement: '10'
643
+ os_v2_replacement: '5'
644
+ # Snow Leopard
645
+ - regex: ' (Dar)(win)/(10).(\d+).*\((?:i386|x86_64)\)'
646
+ os_replacement: 'Mac OS X'
647
+ os_v1_replacement: '10'
648
+ os_v2_replacement: '6'
649
+ # Lion
650
+ - regex: ' (Dar)(win)/(11).(\d+).*\((?:i386|x86_64)\)'
651
+ os_replacement: 'Mac OS X'
652
+ os_v1_replacement: '10'
653
+ os_v2_replacement: '7'
654
+ # Mountain Lion
655
+ - regex: ' (Dar)(win)/(12).(\d+).*\((?:i386|x86_64)\)'
656
+ os_replacement: 'Mac OS X'
657
+ os_v1_replacement: '10'
658
+ os_v2_replacement: '8'
659
+ # Mavericks
660
+ - regex: ' (Dar)(win)/(13).(\d+).*\((?:i386|x86_64)\)'
661
+ os_replacement: 'Mac OS X'
662
+ os_v1_replacement: '10'
663
+ os_v2_replacement: '9'
664
+
480
665
  # IE on Mac doesn't specify version number
481
666
  - regex: 'Mac_PowerPC'
482
667
  os_replacement: 'Mac OS'
@@ -490,7 +675,7 @@ os_parsers:
490
675
  # iOS
491
676
  # http://en.wikipedia.org/wiki/IOS_version_history
492
677
  ##########
493
- - regex: '(CPU OS|iPhone OS) (\d+)_(\d+)(?:_(\d+))?'
678
+ - regex: '(CPU OS|iPhone OS|CPU iPhone) +(\d+)[_\.](\d+)(?:[_\.](\d+))?'
494
679
  os_replacement: 'iOS'
495
680
 
496
681
  # remaining cases are mostly only opera uas, so catch opera as to not catch iphone spoofs
@@ -503,8 +688,29 @@ os_parsers:
503
688
 
504
689
  - regex: '(AppleTV)/(\d+)\.(\d+)'
505
690
  os_replacement: 'ATV OS X'
506
- os_v1_replacement: '$1'
507
- os_v2_replacement: '$2'
691
+
692
+ ##########
693
+ # CFNetwork iOS Apps
694
+ # @ref: https://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history
695
+ ##########
696
+ - regex: 'CFNetwork/.* Darwin/(9)\.\d+'
697
+ os_replacement: 'iOS'
698
+ os_v1_replacement: '1'
699
+ - regex: 'CFNetwork/.* Darwin/(10)\.\d+'
700
+ os_replacement: 'iOS'
701
+ os_v1_replacement: '4'
702
+ - regex: 'CFNetwork/.* Darwin/(11)\.\d+'
703
+ os_replacement: 'iOS'
704
+ os_v1_replacement: '5'
705
+ - regex: 'CFNetwork/.* Darwin/(13)\.\d+'
706
+ os_replacement: 'iOS'
707
+ os_v1_replacement: '6'
708
+ - regex: 'CFNetwork/.* Darwin/(14)\.\d+'
709
+ os_replacement: 'iOS'
710
+ os_v1_replacement: '7'
711
+ # iOS Apps
712
+ - regex: '\b(iOS[ /]|iPhone(?:/| v|[ _]OS[/,]|; | OS : |\d,\d/|\d,\d; )|iPad/)(\d{1,2})[_\.](\d{1,2})(?:[_\.](\d+))?'
713
+ os_replacement: 'iOS'
508
714
 
509
715
  ##########
510
716
  # Chrome OS
@@ -518,15 +724,16 @@ os_parsers:
518
724
  ##########
519
725
  # Linux distros
520
726
  ##########
521
- - regex: '(Debian)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
727
+ - regex: '([Dd]ebian)'
728
+ os_replacement: 'Debian'
522
729
  - regex: '(Linux Mint)(?:/(\d+))?'
523
- - regex: '(Mandriva)(?: Linux)?/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
730
+ - regex: '(Mandriva)(?: Linux)?/(?:[\d.-]+m[a-z]{2}(\d+).(\d))?'
524
731
 
525
732
  ##########
526
733
  # Symbian + Symbian OS
527
734
  # http://en.wikipedia.org/wiki/History_of_Symbian
528
735
  ##########
529
- - regex: '(Symbian[Oo][Ss])/(\d+)\.(\d+)'
736
+ - regex: '(Symbian[Oo][Ss])[/ ](\d+)\.(\d+)'
530
737
  os_replacement: 'Symbian OS'
531
738
  - regex: '(Symbian/3).+NokiaBrowser/7\.3'
532
739
  os_replacement: 'Symbian^3 Anna'
@@ -534,13 +741,15 @@ os_parsers:
534
741
  os_replacement: 'Symbian^3 Belle'
535
742
  - regex: '(Symbian/3)'
536
743
  os_replacement: 'Symbian^3'
537
- - regex: '(Series 60|SymbOS|S60)'
744
+ - regex: '\b(Series 60|SymbOS|S60Version|S60V\d|S60\b)'
538
745
  os_replacement: 'Symbian OS'
539
746
  - regex: '(MeeGo)'
540
747
  - regex: 'Symbian [Oo][Ss]'
541
748
  os_replacement: 'Symbian OS'
542
749
  - regex: 'Series40;'
543
750
  os_replacement: 'Nokia Series 40'
751
+ - regex: 'Series30Plus;'
752
+ os_replacement: 'Nokia Series 30 Plus'
544
753
 
545
754
  ##########
546
755
  # BlackBerry devices
@@ -561,7 +770,7 @@ os_parsers:
561
770
  ##########
562
771
  # Firefox OS
563
772
  ##########
564
- - regex: '\(Mobile;.+Firefox/\d+\.\d+'
773
+ - regex: '\((?:Mobile|Tablet);.+Firefox/\d+\.\d+'
565
774
  os_replacement: 'Firefox OS'
566
775
 
567
776
  ##########
@@ -578,12 +787,10 @@ os_parsers:
578
787
  ##########
579
788
  # Google TV
580
789
  ##########
581
- - regex: '(GoogleTV) (\d+)\.(\d+)\.(\d+)'
582
- # Old style
583
- - regex: '(GoogleTV)\/\d+'
790
+ - regex: '(GoogleTV)(?: (\d+)\.(\d+)(?:\.(\d+))?|/[\da-z]+)'
584
791
 
585
792
  - regex: '(WebTV)/(\d+).(\d+)'
586
-
793
+
587
794
  ##########
588
795
  # Misc mobile
589
796
  ##########
@@ -595,19 +802,20 @@ os_parsers:
595
802
  # Generic patterns
596
803
  # since the majority of os cases are very specific, these go last
597
804
  ##########
598
- # first.second.third.fourth bits
599
- - regex: '(SUSE|Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
805
+ - regex: '(Fedora|Red Hat|PCLinuxOS|Puppy|Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Slackware|(?:Free|Open|Net|\b)BSD)[/ ](\d+)\.(\d+)(?:\.(\d+)(?:\.(\d+))?)?'
600
806
 
601
- # first.second.third bits
602
- - regex: '(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\d+)\.(\d+)\.(\d+)'
807
+ # Gentoo Linux + Kernel Version
808
+ - regex: '(Linux)[ /](\d+)\.(\d+)(?:\.(\d+))?.*gentoo'
809
+ os_replacement: 'Gentoo'
603
810
 
604
- # first.second bits
605
- - regex: '(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\d+)\.(\d+)'
811
+ # Opera Mini Bada
812
+ - regex: '\((Bada);'
606
813
 
607
814
  # just os
608
- - regex: '(Windows|OpenBSD|FreeBSD|NetBSD|Ubuntu|Kubuntu|Android|Arch Linux|CentOS|WeTab|Slackware)'
609
- - regex: '(Linux)/(\d+)\.(\d+)'
610
- - regex: '(Linux|BSD)'
815
+ - regex: '(Windows|Android|WeTab|Maemo)'
816
+ - regex: '(Ubuntu|Kubuntu|Arch Linux|CentOS|Slackware|Gentoo|openSUSE|SUSE|Red Hat|Fedora|PCLinuxOS|Gentoo|Mageia|(?:Free|Open|Net|\b)BSD)'
817
+ # Linux + Kernel Version
818
+ - regex: '(Linux)(?:[ /](\d+)\.(\d+)(?:\.(\d+))?)?'
611
819
  - regex: 'SunOS'
612
820
  os_replacement: 'Solaris'
613
821
 
@@ -682,6 +890,16 @@ device_parsers:
682
890
  device_replacement: 'Kindle Fire HD 8.9" WiFi'
683
891
  - regex: '(KFJWA Build)'
684
892
  device_replacement: 'Kindle Fire HD 8.9" 4G'
893
+ - regex: '(KFSOWI Build)'
894
+ device_replacement: 'Kindle Fire HD 7" WiFi'
895
+ - regex: '(KFTHWI Build)'
896
+ device_replacement: 'Kindle Fire HDX 7" WiFi'
897
+ - regex: '(KFTHWA Build)'
898
+ device_replacement: 'Kindle Fire HDX 7" 4G'
899
+ - regex: '(KFAPWI Build)'
900
+ device_replacement: 'Kindle Fire HDX 8.9" WiFi'
901
+ - regex: '(KFAPWA Build)'
902
+ device_replacement: 'Kindle Fire HDX 8.9" 4G'
685
903
  - regex: '(Kindle Fire)'
686
904
  - regex: '(Kindle)'
687
905
  - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
@@ -690,11 +908,11 @@ device_parsers:
690
908
  #########
691
909
  # Android General Device Matching (far from perfect)
692
910
  #########
693
- - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{2}; WOWMobile (.+) Build'
694
- - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{2}; (.+) Build'
695
- - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{2}; (.+) Build'
696
- - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+;[A-Za-z]{2}\-[A-Za-z]{2};(.+) Build'
697
- - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{2}; (.+) Build'
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'
698
916
  - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; (.+) Build'
699
917
  - regex: 'Android[\- ][\d]+\.[\d]+; (.+) Build'
700
918
 
@@ -768,7 +986,10 @@ device_parsers:
768
986
 
769
987
  - regex: 'Googlebot-Mobile/(\d+).(\d+)'
770
988
  device_replacement: 'Spider'
771
-
989
+
990
+ - regex: 'Googlebot/\d+.\d+'
991
+ device_replacement: 'Spider'
992
+
772
993
  ##########
773
994
  # complete but probably catches spoofs
774
995
  # iSTUFF
@@ -777,6 +998,7 @@ device_parsers:
777
998
  # cannot determine specific device type from ua string. (3g, 3gs, 4, etc)
778
999
  - regex: '(iPad) Simulator;'
779
1000
  - regex: '(iPad);'
1001
+ - regex: '(iPod) touch;'
780
1002
  - regex: '(iPod);'
781
1003
  - regex: '(iPhone) Simulator;'
782
1004
  - regex: '(iPhone);'
@@ -871,6 +1093,12 @@ device_parsers:
871
1093
  - regex: 'Lenovo_([A-Za-z0-9]+)'
872
1094
  device_replacement: 'Lenovo $1'
873
1095
 
1096
+ ##########
1097
+ # HbbTV (European and Australian standard)
1098
+ # written before the LG regexes, as LG is making HbbTV too
1099
+ ##########
1100
+ - regex: '(HbbTV)/[0-9]+\.[0-9]+\.[0-9]+'
1101
+
874
1102
  ##########
875
1103
  # lg
876
1104
  ##########
@@ -980,6 +1208,6 @@ device_parsers:
980
1208
  ##########
981
1209
  # Spiders (this is hack...)
982
1210
  ##########
983
- - 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|crawler)'
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)'
984
1212
  device_replacement: 'Spider'
985
1213
 
metadata CHANGED
@@ -1,25 +1,28 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: user_agent_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Lucas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-09 00:00:00.000000000 Z
11
+ date: 2014-05-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
15
15
  email: t@toolmantim.com
16
- executables: []
16
+ executables:
17
+ - user_agent_parser
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
20
21
  - MIT-LICENSE
21
22
  - Readme.md
23
+ - bin/user_agent_parser
22
24
  - lib/user_agent_parser.rb
25
+ - lib/user_agent_parser/cli.rb
23
26
  - lib/user_agent_parser/device.rb
24
27
  - lib/user_agent_parser/operating_system.rb
25
28
  - lib/user_agent_parser/parser.rb
@@ -36,17 +39,17 @@ require_paths:
36
39
  - lib
37
40
  required_ruby_version: !ruby/object:Gem::Requirement
38
41
  requirements:
39
- - - ! '>='
42
+ - - ">="
40
43
  - !ruby/object:Gem::Version
41
44
  version: 1.8.7
42
45
  required_rubygems_version: !ruby/object:Gem::Requirement
43
46
  requirements:
44
- - - ! '>='
47
+ - - ">="
45
48
  - !ruby/object:Gem::Version
46
49
  version: '0'
47
50
  requirements: []
48
51
  rubyforge_project:
49
- rubygems_version: 2.0.3
52
+ rubygems_version: 2.2.2
50
53
  signing_key:
51
54
  specification_version: 4
52
55
  summary: A simple, comprehensive Ruby gem for parsing user agent strings with the