user_agent_parser 2.1.0 → 2.1.5

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 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