user_agent_parser 1.0.2 → 2.1.3

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.
@@ -1,33 +1,37 @@
1
1
  module UserAgentParser
2
-
3
2
  class UserAgent
3
+ attr_reader :name, :version, :os, :device
4
4
 
5
- attr_accessor :family, :version, :os
5
+ # For backwards compatibility with older versions of this gem.
6
+ alias_method :family, :name
6
7
 
7
- def initialize(family="Other", version=nil, os=nil)
8
- self.family = family
9
- self.version = version
10
- self.os = os
8
+ def initialize(name = nil, version = nil, os = nil, device = nil)
9
+ @name = name || 'Other'
10
+ @version = version
11
+ @os = os
12
+ @device = device
11
13
  end
12
14
 
13
15
  def to_s
14
- s = family
15
- s += " #{version}" if version
16
- s
16
+ string = name
17
+ string += " #{version}" if version
18
+ string
17
19
  end
18
20
 
19
21
  def inspect
20
- s = to_s
21
- s += " (#{os})" if os
22
- "#<#{self.class} #{s}>"
22
+ string = to_s
23
+ string += " (#{os})" if os
24
+ string += " (#{device})" if device
25
+ "#<#{self.class} #{string}>"
23
26
  end
24
-
25
- def ==(other)
26
- family == other.family &&
27
+
28
+ def eql?(other)
29
+ self.class.eql?(other.class) &&
30
+ name == other.name &&
27
31
  version == other.version &&
28
32
  os == other.os
29
33
  end
30
34
 
35
+ alias_method :==, :eql?
31
36
  end
32
-
33
37
  end
@@ -1,37 +1,47 @@
1
1
  module UserAgentParser
2
-
3
2
  class Version
4
3
 
5
- attr_accessor :version
4
+ # Private: Regex used to split version string into major, minor, patch,
5
+ # and patch_minor.
6
+ SEGMENTS_REGEX = /\d+\-\d+|\d+[a-zA-Z]+$|\d+|[A-Za-z][0-9A-Za-z-]*$/
7
+
8
+ attr_reader :version
6
9
  alias :to_s :version
7
10
 
8
11
  def initialize(version)
9
- self.version = version.to_s.strip
12
+ @version = version.to_s.strip
10
13
  end
11
14
 
12
- def segments
13
- version.scan(/\d+\-\d+|\d+[a-zA-Z]+$|\d+|[A-Za-z][0-9A-Za-z-]*$/).map do |s|
14
- /^\d+$/ =~ s ? s.to_i : s
15
- end
15
+ def major
16
+ segments[0]
17
+ end
18
+
19
+ def minor
20
+ segments[1]
21
+ end
22
+
23
+ def patch
24
+ segments[2]
16
25
  end
17
26
 
18
- def [](segment)
19
- segments[segment]
27
+ def patch_minor
28
+ segments[3]
20
29
  end
21
-
22
- def major; self[0] end
23
- def minor; self[1] end
24
- def patch; self[2] end
25
- def patch_minor; self[3] end
26
-
30
+
27
31
  def inspect
28
32
  "#<#{self.class} #{to_s}>"
29
33
  end
30
-
31
- def ==(other)
32
- version == other.version
34
+
35
+ def eql?(other)
36
+ self.class.eql?(other.class) &&
37
+ version == other.version
33
38
  end
34
39
 
35
- end
40
+ alias_method :==, :eql?
36
41
 
37
- end
42
+ # Private
43
+ def segments
44
+ @segments ||= version.scan(SEGMENTS_REGEX)
45
+ end
46
+ end
47
+ end
@@ -1,9 +1,10 @@
1
1
  user_agent_parsers:
2
2
  #### SPECIAL CASES TOP ####
3
3
 
4
- # must go before Opera
5
- - regex: '^(Opera)/(\d+)\.(\d+) \(Nintendo Wii'
6
- family_replacement: 'Wii'
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+) \('
7
8
 
8
9
  # must go before Firefox to catch SeaMonkey/Camino
9
10
  - regex: '(SeaMonkey|Camino)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)'
@@ -65,21 +66,29 @@ user_agent_parsers:
65
66
  - regex: '(Opera Mini)/att/(\d+)\.(\d+)'
66
67
  - regex: '(Opera)/9.80.*Version/(\d+)\.(\d+)(?:\.(\d+))?'
67
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
+
68
77
  # Palm WebOS looks a lot like Safari.
69
- - regex: '(webOSBrowser)/(\d+)\.(\d+)'
70
- - regex: '(webOS)/(\d+)\.(\d+)'
71
- family_replacement: 'webOSBrowser'
72
- - regex: '(wOSBrowser).+TouchPad/(\d+)\.(\d+)'
73
- family_replacement: 'webOS TouchPad'
78
+ - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?'
79
+ family_replacement: 'webOS Browser'
74
80
 
75
81
  # LuaKit has no version info.
76
82
  # http://luakit.org/projects/luakit/
77
83
  - regex: '(luakit)'
78
84
  family_replacement: 'LuaKit'
85
+
86
+ # Snowshoe
87
+ - regex: '(Snowshoe)/(\d+)\.(\d+).(\d+)'
79
88
 
80
89
  # Lightning (for Thunderbird)
81
90
  # http://www.mozilla.org/projects/calendar/lightning/
82
- - regex: '(Lightning)/(\d+)\.(\d+)([ab]?\d+[a-z]*)'
91
+ - regex: '(Lightning)/(\d+)\.(\d+)\.?((?:[ab]?\d+[a-z]*)|(?:\d*))'
83
92
 
84
93
  # Swiftfox
85
94
  - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+(?:pre)?) \(Swiftfox\)'
@@ -88,7 +97,7 @@ user_agent_parsers:
88
97
  family_replacement: 'Swiftfox'
89
98
 
90
99
  # Rekonq
91
- - regex: '(rekonq)/(\d+)\.(\d+) Safari'
100
+ - regex: '(rekonq)/(\d+)\.(\d+)\.?(\d+)? Safari'
92
101
  family_replacement: 'Rekonq'
93
102
  - regex: 'rekonq'
94
103
  family_replacement: 'Rekonq'
@@ -110,9 +119,6 @@ user_agent_parsers:
110
119
  # Bots
111
120
  - regex: '(YottaaMonitor|BrowserMob|HttpMonitor|YandexBot|Slurp|BingPreview|PagePeeker|ThumbShotsBot|WebThumb|URL2PNG|ZooShot|GomezA|Catchpoint bot|Willow Internet Crawler|Google SketchUp|Read%20Later)'
112
121
 
113
- # must go before NetFront below
114
- - regex: '(Kindle)/(\d+)\.(\d+)'
115
-
116
122
  - regex: '(Symphony) (\d+).(\d+)'
117
123
 
118
124
  - regex: '(Minimo)'
@@ -130,20 +136,23 @@ user_agent_parsers:
130
136
  family_replacement: 'Chrome Frame'
131
137
 
132
138
  # UC Browser
133
- - regex: '(UC Browser)(\d+)\.(\d+)\.(\d+)'
139
+ - regex: '(UCBrowser)[ /](\d+)\.(\d+)\.(\d+)'
140
+ family_replacement: 'UC Browser'
141
+ - regex: '(UC Browser)[ /](\d+)\.(\d+)\.(\d+)'
142
+ - regex: '(UC Browser|UCBrowser|UCWEB)(\d+)\.(\d+)\.(\d+)'
143
+ family_replacement: 'UC Browser'
134
144
 
135
145
  # Tizen Browser (second case included in browser/major.minor regex)
136
146
  - regex: '(SLP Browser)/(\d+)\.(\d+)'
137
147
  family_replacement: 'Tizen Browser'
138
148
 
139
- # Epiphany browser (identifies as Chromium)
140
- - regex: '(Epiphany)/(\d+)\.(\d+).(\d+)'
141
-
142
149
  # Sogou Explorer 2.X
143
150
  - regex: '(SE 2\.X) MetaSr (\d+)\.(\d+)'
144
151
  family_replacement: 'Sogou Explorer'
145
-
146
- # Baidu Browser
152
+
153
+ # Baidu Browsers (desktop spoofs chrome & IE, explorer is mobile)
154
+ - regex: '(baidubrowser)[/\s](\d+)'
155
+ family_replacement: 'Baidu Browser'
147
156
  - regex: '(FlyFlow)/(\d+)\.(\d+)'
148
157
  family_replacement: 'Baidu Explorer'
149
158
 
@@ -155,28 +164,81 @@ user_agent_parsers:
155
164
  - regex: '(facebookexternalhit)/(\d+)\.(\d+)'
156
165
  family_replacement: 'FacebookBot'
157
166
 
167
+ # LinkedIn
168
+ - regex: '(LinkedInBot)/(\d+)\.(\d+)'
169
+ family_replacement: 'LinkedInBot'
170
+
158
171
  # Twitterbot
159
172
  - regex: '(Twitterbot)/(\d+)\.(\d+)'
160
173
  family_replacement: 'TwitterBot'
161
174
 
175
+ # Rackspace Monitoring
176
+ - regex: '(Rackspace Monitoring)/(\d+)\.(\d+)'
177
+ family_replacement: 'RackspaceBot'
178
+
162
179
  # PyAMF
163
180
  - regex: '(PyAMF)/(\d+)\.(\d+)\.(\d+)'
164
181
 
182
+ # Yandex Browser
183
+ - regex: '(YaBrowser)/(\d+)\.(\d+)\.(\d+)'
184
+ family_replacement: 'Yandex Browser'
185
+
186
+ # Mail.ru Amigo/Internet Browser (Chromium-based)
187
+ - regex: '(Chrome)/(\d+)\.(\d+)\.(\d+).* MRCHROME'
188
+ family_replacement: 'Mail.ru Chromium Browser'
189
+
190
+ # AOL Browser (IE-based)
191
+ - regex: '(AOL) (\d+)\.(\d+); AOLBuild (\d+)'
192
+
193
+
194
+
195
+
165
196
  #### END SPECIAL CASES TOP ####
166
197
 
167
198
  #### MAIN CASES - this catches > 50% of all browsers ####
168
199
 
169
200
  # Browser/major_version.minor_version.beta_version
170
- - 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|Bunjaloo|Google Earth|Raven for Mac)/(\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+)'
171
227
 
172
228
  # Browser/major_version.minor_version
173
- - 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)/(\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+)'
174
233
 
175
234
  # Browser major_version.minor_version.beta_version (space instead of slash)
176
235
  - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)'
177
236
  # Browser major_version.minor_version (space instead of slash)
178
- - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris|BREW) (\d+)\.(\d+)\.?(\d+)?'
179
-
237
+ - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris) (\d+)\.(\d+)\.?(\d+)?'
238
+
239
+ # Kindle WebKit
240
+ - regex: '(Kindle)/(\d+)\.(\d+)'
241
+
180
242
  # weird android UAs
181
243
  - regex: '(Android) Donut'
182
244
  v1_replacement: '1'
@@ -205,28 +267,38 @@ user_agent_parsers:
205
267
  - regex: '(MSIE) (\d+)\.(\d+).*XBLWP7'
206
268
  family_replacement: 'IE Large Screen'
207
269
 
208
- # AFTER THE EDGE CASES ABOVE!
209
- - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
210
- - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
211
-
212
270
  #### END MAIN CASES ####
213
271
 
214
272
  #### SPECIAL CASES ####
215
273
  - regex: '(Obigo)InternetBrowser'
216
274
  - regex: '(Obigo)\-Browser'
217
275
  - regex: '(Obigo|OBIGO)[^\d]*(\d+)(?:.(\d+))?'
276
+ family_replacement: 'Obigo'
218
277
 
219
278
  - regex: '(MAXTHON|Maxthon) (\d+)\.(\d+)'
220
279
  family_replacement: 'Maxthon'
221
280
  - regex: '(Maxthon|MyIE2|Uzbl|Shiira)'
222
281
  v1_replacement: '0'
223
282
 
224
- - regex: '(PLAYSTATION) (\d+)'
225
- family_replacement: 'PlayStation'
226
- - regex: '(PlayStation Portable)[^\d]+(\d+).(\d+)'
283
+ - regex: 'PLAYSTATION 3.+WebKit'
284
+ family_replacement: 'NetFront NX'
285
+ - regex: 'PLAYSTATION 3'
286
+ family_replacement: 'NetFront'
287
+ - regex: '(PlayStation Portable)'
288
+ family_replacement: 'NetFront'
289
+ - regex: '(PlayStation Vita)'
290
+ family_replacement: 'NetFront NX'
291
+
292
+ - regex: 'AppleWebKit.+ (NX)/(\d+)\.(\d+)\.(\d+)'
293
+ family_replacement: 'NetFront NX'
294
+ - regex: '(Nintendo 3DS)'
295
+ family_replacement: 'NetFront NX'
227
296
 
228
297
  - regex: '(BrowseX) \((\d+)\.(\d+)\.(\d+)'
229
298
 
299
+ - regex: '(NCSA_Mosaic)/(\d+)\.(\d+)'
300
+ family_replacement: 'NCSA Mosaic'
301
+
230
302
  # Polaris/d.d is above
231
303
  - regex: '(POLARIS)/(\d+)\.(\d+)'
232
304
  family_replacement: 'Polaris'
@@ -236,6 +308,9 @@ user_agent_parsers:
236
308
  - regex: '(BonEcho)/(\d+)\.(\d+)\.(\d+)'
237
309
  family_replacement: 'Bon Echo'
238
310
 
311
+ - regex: 'M?QQBrowser'
312
+ family_replacement: 'QQ Browser'
313
+
239
314
  - regex: '(iPod).+Version/(\d+)\.(\d+)\.(\d+)'
240
315
  family_replacement: 'Mobile Safari'
241
316
  - regex: '(iPod).*Version/(\d+)\.(\d+)'
@@ -254,36 +329,50 @@ user_agent_parsers:
254
329
  family_replacement: 'Mobile Safari'
255
330
 
256
331
  - regex: '(AvantGo) (\d+).(\d+)'
332
+
333
+ - regex: '(OneBrowser)/(\d+).(\d+)'
334
+ family_replacement: 'ONE Browser'
257
335
 
258
336
  - regex: '(Avant)'
259
337
  v1_replacement: '1'
260
338
 
339
+ # This is the Tesla Model S (see similar entry in device parsers)
340
+ - regex: '(QtCarBrowser)'
341
+ v1_replacement: '1'
342
+
343
+ - regex: '(iBrowser/Mini)(\d+).(\d+)'
344
+ family_replacement: 'iBrowser Mini'
261
345
  # nokia browsers
262
346
  # based on: http://www.developer.nokia.com/Community/Wiki/User-Agent_headers_for_Nokia_devices
263
347
  - regex: '^(Nokia)'
264
348
  family_replacement: 'Nokia Services (WAP) Browser'
265
349
  - regex: '(NokiaBrowser)/(\d+)\.(\d+).(\d+)\.(\d+)'
350
+ family_replacement: 'Nokia Browser'
266
351
  - regex: '(NokiaBrowser)/(\d+)\.(\d+).(\d+)'
352
+ family_replacement: 'Nokia Browser'
267
353
  - regex: '(NokiaBrowser)/(\d+)\.(\d+)'
354
+ family_replacement: 'Nokia Browser'
268
355
  - regex: '(BrowserNG)/(\d+)\.(\d+).(\d+)'
269
- family_replacement: 'NokiaBrowser'
356
+ family_replacement: 'Nokia Browser'
270
357
  - regex: '(Series60)/5\.0'
271
- family_replacement: 'NokiaBrowser'
358
+ family_replacement: 'Nokia Browser'
272
359
  v1_replacement: '7'
273
360
  v2_replacement: '0'
274
361
  - regex: '(Series60)/(\d+)\.(\d+)'
275
362
  family_replacement: 'Nokia OSS Browser'
276
363
  - regex: '(S40OviBrowser)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
277
- family_replacement: 'Nokia Series 40 Ovi Browser'
364
+ family_replacement: 'Ovi Browser'
278
365
  - regex: '(Nokia)[EN]?(\d+)'
279
366
 
280
367
  # BlackBerry devices
368
+ - regex: '(BB10);'
369
+ family_replacement: 'BlackBerry WebKit'
281
370
  - regex: '(PlayBook).+RIM Tablet OS (\d+)\.(\d+)\.(\d+)'
282
- family_replacement: 'Blackberry WebKit'
371
+ family_replacement: 'BlackBerry WebKit'
283
372
  - regex: '(Black[bB]erry).+Version/(\d+)\.(\d+)\.(\d+)'
284
- family_replacement: 'Blackberry WebKit'
373
+ family_replacement: 'BlackBerry WebKit'
285
374
  - regex: '(Black[bB]erry)\s?(\d+)'
286
- family_replacement: 'Blackberry'
375
+ family_replacement: 'BlackBerry'
287
376
 
288
377
  - regex: '(OmniWeb)/v(\d+)\.(\d+)'
289
378
 
@@ -293,6 +382,9 @@ user_agent_parsers:
293
382
  - regex: '(Pre)/(\d+)\.(\d+)'
294
383
  family_replacement: 'Palm Pre'
295
384
 
385
+ # fork of Links
386
+ - regex: '(ELinks)/(\d+)\.(\d+)'
387
+ - regex: '(ELinks) \((\d+)\.(\d+)'
296
388
  - regex: '(Links) \((\d+)\.(\d+)'
297
389
 
298
390
  - regex: '(QtWeb) Internet Browser/(\d+)\.(\d+)'
@@ -302,6 +394,10 @@ user_agent_parsers:
302
394
 
303
395
  # Amazon Silk, should go before Safari
304
396
  - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
397
+ family_replacement: 'Amazon Silk'
398
+
399
+ # Phantomjs, should go before Safari
400
+ - regex: '(PhantomJS)/(\d+)\.(\d+)\.(\d+)'
305
401
 
306
402
  # WebKit Nightly
307
403
  - regex: '(AppleWebKit)/(\d+)\.?(\d+)?\+ .* Safari'
@@ -322,13 +418,89 @@ user_agent_parsers:
322
418
 
323
419
  - regex: '(Teleca)'
324
420
  family_replacement: 'Teleca Browser'
421
+
422
+ - regex: '(Phantom)/V(\d+)\.(\d+)'
423
+ family_replacement: 'Phantom Browser'
325
424
 
326
- - regex: '(MSIE) (\d+)\.(\d+)'
425
+ - regex: 'Trident(.*)rv.(\d+)\.(\d+)'
327
426
  family_replacement: 'IE'
328
427
 
329
- - regex: '(Nintendo 3DS).* Version/(\d+)\.(\d+)(?:\.(\w+))'
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+)'
441
+ family_replacement: 'IE'
442
+
443
+ - regex: '(python-requests)/(\d+)\.(\d+)'
444
+ family_replacement: 'Python Requests'
330
445
 
331
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]).*\)'
332
504
 
333
505
  ##########
334
506
  # Android
@@ -356,6 +528,12 @@ os_parsers:
356
528
  - regex: '(Android) Honeycomb'
357
529
  os_v1_replacement: '3'
358
530
 
531
+ ##########
532
+ # Kindle Android
533
+ ##########
534
+ - regex: '(Silk-Accelerated=[a-z]{4,5})'
535
+ os_replacement: 'Android'
536
+
359
537
  ##########
360
538
  # Windows
361
539
  # http://en.wikipedia.org/wiki/Windows_NT#Releases
@@ -364,7 +542,6 @@ os_parsers:
364
542
  # lots of ua strings have Windows NT 4.1 !?!?!?!? !?!? !? !????!?! !!! ??? !?!?! ?
365
543
  # (very) roughly ordered in terms of frequency of occurence of regex (win xp currently most frequent, etc)
366
544
  ##########
367
- - regex: '(Windows Phone 6\.5)'
368
545
 
369
546
  - regex: '(Windows (?:NT 5\.2|NT 5\.1))'
370
547
  os_replacement: 'Windows XP'
@@ -372,7 +549,7 @@ os_parsers:
372
549
  # ie mobile des ktop mode
373
550
  # spoofs nt 6.1. must come before windows 7
374
551
  - regex: '(XBLWP7)'
375
- os_replacement: 'Windows Phone OS'
552
+ os_replacement: 'Windows Phone'
376
553
 
377
554
  - regex: '(Windows NT 6\.1)'
378
555
  os_replacement: 'Windows 7'
@@ -380,7 +557,13 @@ os_parsers:
380
557
  - regex: '(Windows NT 6\.0)'
381
558
  os_replacement: 'Windows Vista'
382
559
 
383
- - regex: '(Windows 98|Windows XP|Windows ME|Windows 95|Windows CE|Windows 7|Windows NT 4\.0|Windows Vista|Windows 2000)'
560
+ - regex: '(Win 9x 4\.90)'
561
+ os_replacement: 'Windows Me'
562
+
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)'
564
+
565
+ - regex: '(Windows NT 6\.2; ARM;)'
566
+ os_replacement: 'Windows RT'
384
567
 
385
568
  # is this a spoof or is nt 6.2 out and about in some capacity?
386
569
  - regex: '(Windows NT 6\.2)'
@@ -389,8 +572,8 @@ os_parsers:
389
572
  - regex: '(Windows NT 5\.0)'
390
573
  os_replacement: 'Windows 2000'
391
574
 
392
- - regex: '(Windows Phone OS) (\d+)\.(\d+)'
393
-
575
+ - regex: '(Windows Phone) (\d+)\.(\d+)'
576
+ - regex: '(Windows Phone) OS (\d+)\.(\d+)'
394
577
  - regex: '(Windows ?Mobile)'
395
578
  os_replacement: 'Windows Mobile'
396
579
 
@@ -406,13 +589,15 @@ os_parsers:
406
589
  ##########
407
590
  - regex: '(Tizen)/(\d+)\.(\d+)'
408
591
 
409
-
410
-
411
592
  ##########
412
593
  # Mac OS
413
594
  # http://en.wikipedia.org/wiki/Mac_OS_X#Versions
414
595
  ##########
415
596
  - regex: '(Mac OS X) (\d+)[_.](\d+)(?:[_.](\d+))?'
597
+
598
+ # IE on Mac doesn't specify version number
599
+ - regex: 'Mac_PowerPC'
600
+ os_replacement: 'Mac OS'
416
601
 
417
602
  # builds before tiger don't seem to specify version?
418
603
 
@@ -436,8 +621,6 @@ os_parsers:
436
621
 
437
622
  - regex: '(AppleTV)/(\d+)\.(\d+)'
438
623
  os_replacement: 'ATV OS X'
439
- os_v1_replacement: '$1'
440
- os_v2_replacement: '$2'
441
624
 
442
625
  ##########
443
626
  # Chrome OS
@@ -451,9 +634,10 @@ os_parsers:
451
634
  ##########
452
635
  # Linux distros
453
636
  ##########
454
- - regex: '(Debian)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
637
+ - regex: '([Dd]ebian)'
638
+ os_replacement: 'Debian'
455
639
  - regex: '(Linux Mint)(?:/(\d+))?'
456
- - regex: '(Mandriva)(?: Linux)?/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
640
+ - regex: '(Mandriva)(?: Linux)?/(?:[\d.-]+m[a-z]{2}(\d+).(\d))?'
457
641
 
458
642
  ##########
459
643
  # Symbian + Symbian OS
@@ -472,10 +656,14 @@ os_parsers:
472
656
  - regex: '(MeeGo)'
473
657
  - regex: 'Symbian [Oo][Ss]'
474
658
  os_replacement: 'Symbian OS'
659
+ - regex: 'Series40;'
660
+ os_replacement: 'Nokia Series 40'
475
661
 
476
662
  ##########
477
663
  # BlackBerry devices
478
664
  ##########
665
+ - regex: '(BB10);.+Version/(\d+)\.(\d+)\.(\d+)'
666
+ os_replacement: 'BlackBerry OS'
479
667
  - regex: '(Black[Bb]erry)[0-9a-z]+/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
480
668
  os_replacement: 'BlackBerry OS'
481
669
  - regex: '(Black[Bb]erry).+Version/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
@@ -485,38 +673,61 @@ os_parsers:
485
673
  - regex: '(Play[Bb]ook)'
486
674
  os_replacement: 'BlackBerry Tablet OS'
487
675
  - regex: '(Black[Bb]erry)'
488
- os_replacement: 'Blackberry OS'
676
+ os_replacement: 'BlackBerry OS'
677
+
678
+ ##########
679
+ # Firefox OS
680
+ ##########
681
+ - regex: '\((?:Mobile|Tablet);.+Firefox/\d+\.\d+'
682
+ os_replacement: 'Firefox OS'
683
+
684
+ ##########
685
+ # BREW
686
+ # yes, Brew is lower-cased for Brew MP
687
+ ##########
688
+ - regex: '(BREW)[ /](\d+)\.(\d+)\.(\d+)'
689
+ - regex: '(BREW);'
690
+ - regex: '(Brew MP|BMP)[ /](\d+)\.(\d+)\.(\d+)'
691
+ os_replacement: 'Brew MP'
692
+ - regex: 'BMP;'
693
+ os_replacement: 'Brew MP'
489
694
 
490
695
  ##########
491
696
  # Google TV
492
697
  ##########
493
698
  - regex: '(GoogleTV) (\d+)\.(\d+)\.(\d+)'
494
699
  # Old style
495
- - regex: '(GoogleTV)\/\d+'
700
+ - regex: '(GoogleTV)/[\da-z]+'
496
701
 
702
+ - regex: '(WebTV)/(\d+).(\d+)'
703
+
497
704
  ##########
498
705
  # Misc mobile
499
706
  ##########
500
- - regex: '(webOS|hpwOS)/(\d+)\.(\d+)(?:\.(\d+))?'
707
+ - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?'
501
708
  os_replacement: 'webOS'
709
+ - regex: '(VRE);'
502
710
 
503
711
  ##########
504
712
  # Generic patterns
505
713
  # since the majority of os cases are very specific, these go last
506
714
  ##########
507
715
  # first.second.third.fourth bits
508
- - regex: '(SUSE|Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
716
+ - regex: '(Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
509
717
 
510
718
  # first.second.third bits
511
- - regex: '(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\d+)\.(\d+)\.(\d+)'
719
+ - regex: '(Red Hat|Puppy|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)'
512
720
 
513
721
  # first.second bits
514
722
  - regex: '(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\d+)\.(\d+)'
515
- - regex: '(PlayStation Vita) (\d+)\.(\d+)'
516
723
 
517
724
  # just os
518
- - 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)'
727
+ - regex: '(Linux)/(\d+)\.(\d+)'
519
728
  - regex: '(Linux|BSD)'
729
+ - regex: 'SunOS'
730
+ os_replacement: 'Solaris'
520
731
 
521
732
  device_parsers:
522
733
  ##########
@@ -547,16 +758,16 @@ device_parsers:
547
758
  device_replacement: 'HTC $1 (Sprint)'
548
759
  - regex: 'HTC ([A-Za-z0-9]+ [A-Z])'
549
760
  device_replacement: 'HTC $1'
550
- - regex: 'HTC-([A-Za-z0-9]+)'
551
- device_replacement: 'HTC $1'
552
- - regex: 'HTC_([A-Za-z0-9]+)'
553
- device_replacement: 'HTC $1'
554
- - regex: 'HTC ([A-Za-z0-9]+)'
761
+ - regex: 'HTC[-_/\s]([A-Za-z0-9]+)'
555
762
  device_replacement: 'HTC $1'
556
763
  - regex: '(ADR[A-Za-z0-9]+)'
557
764
  device_replacement: 'HTC $1'
558
765
  - regex: '(HTC)'
559
766
 
767
+ # Tesla Model S
768
+ - regex: '(QtCarBrowser)'
769
+ device_replacement: 'Tesla Model S'
770
+
560
771
  # Samsung
561
772
  - regex: '(SamsungSGHi560)'
562
773
  device_replacement: 'Samsung SGHi560'
@@ -567,14 +778,53 @@ device_parsers:
567
778
  - regex: 'SonyEricsson([A-Za-z0-9]+)/'
568
779
  device_replacement: 'Ericsson $1'
569
780
 
781
+ ##########
782
+ # PlayStation
783
+ # The Vita spoofs the Kindle
784
+ ##########
785
+ - regex: 'PLAYSTATION 3'
786
+ device_replacement: 'PlayStation 3'
787
+ - regex: '(PlayStation Portable)'
788
+ - regex: '(PlayStation Vita)'
789
+
790
+ ##########
791
+ # incomplete!
792
+ # Kindle
793
+ # http://amazonsilk.wordpress.com/useful-bits/silk-user-agent/
794
+ ##########
795
+ - regex: '(KFOT Build)'
796
+ device_replacement: 'Kindle Fire'
797
+ - regex: '(KFTT Build)'
798
+ device_replacement: 'Kindle Fire HD'
799
+ - regex: '(KFJWI Build)'
800
+ device_replacement: 'Kindle Fire HD 8.9" WiFi'
801
+ - regex: '(KFJWA Build)'
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'
813
+ - regex: '(Kindle Fire)'
814
+ - regex: '(Kindle)'
815
+ - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
816
+ device_replacement: 'Kindle Fire'
817
+
570
818
  #########
571
819
  # Android General Device Matching (far from perfect)
572
820
  #########
573
- - regex: 'Android[\- ][\d]+\.[\d]+\; [A-Za-z]{2}\-[A-Za-z]{2}\; WOWMobile (.+) Build'
574
- - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{2}\; (.+) Build'
575
- - regex: 'Android[\- ][\d]+\.[\d]+\-update1\; [A-Za-z]{2}\-[A-Za-z]{2}\; (.+) Build'
576
- - 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'
577
826
  - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; (.+) Build'
827
+ - regex: 'Android[\- ][\d]+\.[\d]+; (.+) Build'
578
828
 
579
829
  ##########
580
830
  # NOKIA
@@ -582,6 +832,8 @@ device_parsers:
582
832
  ##########
583
833
  - regex: 'NokiaN([0-9]+)'
584
834
  device_replacement: 'Nokia N$1'
835
+ - regex: 'NOKIA([A-Za-z0-9\v-]+)'
836
+ device_replacement: 'Nokia $1'
585
837
  - regex: 'Nokia([A-Za-z0-9\v-]+)'
586
838
  device_replacement: 'Nokia $1'
587
839
  - regex: 'NOKIA ([A-Za-z0-9\-]+)'
@@ -594,14 +846,19 @@ device_parsers:
594
846
  device_replacement: 'Nokia'
595
847
 
596
848
  ##########
597
- # Blackberry
849
+ # BlackBerry
598
850
  # http://www.useragentstring.com/pages/BlackBerry/
599
851
  ##########
852
+ - regex: 'BB10; ([A-Za-z0-9\- ]+)\)'
853
+ device_replacement: 'BlackBerry $1'
600
854
  - regex: '(PlayBook).+RIM Tablet OS'
601
- device_replacement: 'Blackberry Playbook'
602
- - regex: '(Black[Bb]erry [0-9]+);'
855
+ device_replacement: 'BlackBerry Playbook'
856
+ - regex: 'Black[Bb]erry ([0-9]+);'
857
+ device_replacement: 'BlackBerry $1'
603
858
  - regex: 'Black[Bb]erry([0-9]+)'
604
859
  device_replacement: 'BlackBerry $1'
860
+ - regex: 'Black[Bb]erry;'
861
+ device_replacement: 'BlackBerry'
605
862
 
606
863
  ##########
607
864
  # PALM / HP
@@ -611,8 +868,8 @@ device_parsers:
611
868
  device_replacement: 'Palm Pre'
612
869
  - regex: '(Pixi)/(\d+)\.(\d+)'
613
870
  device_replacement: 'Palm Pixi'
614
- - regex: '(Touchpad)/(\d+)\.(\d+)'
615
- device_replacement: 'HP Touchpad'
871
+ - regex: '(Touch[Pp]ad)/(\d+)\.(\d+)'
872
+ device_replacement: 'HP TouchPad'
616
873
  - regex: 'HPiPAQ([A-Za-z0-9]+)/(\d+).(\d+)'
617
874
  device_replacement: 'HP iPAQ $1'
618
875
  - regex: 'Palm([A-Za-z0-9]+)'
@@ -622,21 +879,6 @@ device_parsers:
622
879
  - regex: 'webOS.*(P160UNA)/(\d+).(\d+)'
623
880
  device_replacement: 'HP Veer'
624
881
 
625
- ##########
626
- # PlayStation
627
- ##########
628
- - regex: '(PlayStation Portable)'
629
- - regex: '(PlayStation Vita)'
630
-
631
- ##########
632
- # incomplete!
633
- # Kindle
634
- ##########
635
- - regex: '(Kindle Fire)'
636
- - regex: '(Kindle)'
637
- - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
638
- device_replacement: 'Kindle Fire'
639
-
640
882
  ##########
641
883
  # AppleTV
642
884
  # No built in browser that I can tell
@@ -645,6 +887,16 @@ device_parsers:
645
887
  - regex: '(AppleTV)'
646
888
  device_replacement: 'AppleTV'
647
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
+
648
900
  ##########
649
901
  # complete but probably catches spoofs
650
902
  # iSTUFF
@@ -653,6 +905,7 @@ device_parsers:
653
905
  # cannot determine specific device type from ua string. (3g, 3gs, 4, etc)
654
906
  - regex: '(iPad) Simulator;'
655
907
  - regex: '(iPad);'
908
+ - regex: '(iPod) touch;'
656
909
  - regex: '(iPod);'
657
910
  - regex: '(iPhone) Simulator;'
658
911
  - regex: '(iPhone);'
@@ -665,6 +918,14 @@ device_parsers:
665
918
  - regex: 'acer_([A-Za-z0-9]+)_'
666
919
  device_replacement: 'Acer $1'
667
920
 
921
+ ##########
922
+ # Alcatel
923
+ ##########
924
+ - regex: 'ALCATEL-([A-Za-z0-9]+)'
925
+ device_replacement: 'Alcatel $1'
926
+ - regex: 'Alcatel-([A-Za-z0-9]+)'
927
+ device_replacement: 'Alcatel $1'
928
+
668
929
  ##########
669
930
  # Amoi
670
931
  ##########
@@ -702,14 +963,18 @@ device_parsers:
702
963
  ##########
703
964
  - regex: 'DoCoMo/2\.0 ([A-Za-z0-9]+)'
704
965
  device_replacement: 'DoCoMo $1'
705
- - regex: '([A-Za-z0-9]+)\_W\;FOMA'
966
+ - regex: '([A-Za-z0-9]+)_W\;FOMA'
706
967
  device_replacement: 'DoCoMo $1'
707
968
  - regex: '([A-Za-z0-9]+)\;FOMA'
708
969
  device_replacement: 'DoCoMo $1'
709
970
 
710
971
  ##########
711
- # Huawei Vodafone
972
+ # Huawei
712
973
  ##########
974
+ - regex: 'Huawei([A-Za-z0-9]+)'
975
+ device_replacement: 'Huawei $1'
976
+ - regex: 'HUAWEI-([A-Za-z0-9]+)'
977
+ device_replacement: 'Huawei $1'
713
978
  - regex: 'vodafone([A-Za-z0-9]+)'
714
979
  device_replacement: 'Huawei Vodafone $1'
715
980
 
@@ -732,9 +997,15 @@ device_parsers:
732
997
  ##########
733
998
  - regex: 'Lenovo\-([A-Za-z0-9]+)'
734
999
  device_replacement: 'Lenovo $1'
735
- - regex: 'Lenovo\_([A-Za-z0-9]+)'
1000
+ - regex: 'Lenovo_([A-Za-z0-9]+)'
736
1001
  device_replacement: 'Lenovo $1'
737
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
+
738
1009
  ##########
739
1010
  # lg
740
1011
  ##########
@@ -773,7 +1044,21 @@ device_parsers:
773
1044
  device_replacement: 'Motorola $1'
774
1045
  - regex: 'MOT\-([A-Za-z0-9]+)'
775
1046
  device_replacement: 'Motorola $1'
1047
+
1048
+ ##########
1049
+ # nintendo
1050
+ ##########
1051
+ - regex: '(Nintendo WiiU)'
1052
+ device_replacement: 'Nintendo Wii U'
1053
+ - regex: 'Nintendo (DS|3DS|DSi|Wii);'
1054
+ device_replacement: 'Nintendo $1'
776
1055
 
1056
+ ##########
1057
+ # pantech
1058
+ ##########
1059
+ - regex: 'Pantech([A-Za-z0-9]+)'
1060
+ device_replacement: 'Pantech $1'
1061
+
777
1062
  ##########
778
1063
  # philips
779
1064
  ##########
@@ -790,6 +1075,12 @@ device_parsers:
790
1075
  - regex: 'SAMSUNG\; ([A-Za-z0-9\-]+)'
791
1076
  device_replacement: 'Samsung $1'
792
1077
 
1078
+ ##########
1079
+ # Sega
1080
+ ##########
1081
+ - regex: 'Dreamcast'
1082
+ device_replacement: 'Sega Dreamcast'
1083
+
793
1084
  ##########
794
1085
  # Softbank
795
1086
  ##########
@@ -799,10 +1090,9 @@ device_parsers:
799
1090
  device_replacement: 'Softbank $1'
800
1091
 
801
1092
  ##########
802
- # Sony
1093
+ # WebTV
803
1094
  ##########
804
- - regex: '(PlayStation3 PPC)'
805
- device_replacement: 'Playstation 3'
1095
+ - regex: '(WebTV)/(\d+).(\d+)'
806
1096
 
807
1097
  ##########
808
1098
  # Generic Smart Phone
@@ -813,58 +1103,18 @@ device_parsers:
813
1103
  ##########
814
1104
  # Generic Feature Phone
815
1105
  ##########
816
- - regex: '^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\-|airn|alav|asus|attw|au\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\-n|bw\-u|beck|benq|bilb|blac|c55/|cdm\-|chtm|capi|comp|cond|craw|dall|dbte|dc\-s|dica|ds\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\-|fly\_|g\-mo|g1 u|g560|gf\-5|grun|gene|go.w|good|grad|hcit|hd\-m|hd\-p|hd\-t|hei\-|hp i|hpip|hs\-c|htc |htc\-|htca|htcg)'
1106
+ - regex: '^(1207|3gso|4thp|501i|502i|503i|504i|505i|506i|6310|6590|770s|802s|a wa|acer|acs\-|airn|alav|asus|attw|au\-m|aur |aus |abac|acoo|aiko|alco|alca|amoi|anex|anny|anyw|aptu|arch|argo|bell|bird|bw\-n|bw\-u|beck|benq|bilb|blac|c55/|cdm\-|chtm|capi|comp|cond|craw|dall|dbte|dc\-s|dica|ds\-d|ds12|dait|devi|dmob|doco|dopo|el49|erk0|esl8|ez40|ez60|ez70|ezos|ezze|elai|emul|eric|ezwa|fake|fly\-|fly_|g\-mo|g1 u|g560|gf\-5|grun|gene|go.w|good|grad|hcit|hd\-m|hd\-p|hd\-t|hei\-|hp i|hpip|hs\-c|htc |htc\-|htca|htcg)'
817
1107
  device_replacement: 'Generic Feature Phone'
818
- - regex: '^(htcp|htcs|htct|htc\_|haie|hita|huaw|hutc|i\-20|i\-go|i\-ma|i230|iac|iac\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\-|klon|lexi|lg g|lg\-a|lg\-b|lg\-c|lg\-d|lg\-f|lg\-g|lg\-k|lg\-l|lg\-m|lg\-o|lg\-p|lg\-s|lg\-t|lg\-u|lg\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\-|lge/|lynx|leno|m1\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\-|nem\-|newg|neon)'
1108
+ - regex: '^(htcp|htcs|htct|htc_|haie|hita|huaw|hutc|i\-20|i\-go|i\-ma|i230|iac|iac\-|iac/|ig01|im1k|inno|iris|jata|java|kddi|kgt|kgt/|kpt |kwc\-|klon|lexi|lg g|lg\-a|lg\-b|lg\-c|lg\-d|lg\-f|lg\-g|lg\-k|lg\-l|lg\-m|lg\-o|lg\-p|lg\-s|lg\-t|lg\-u|lg\-w|lg/k|lg/l|lg/u|lg50|lg54|lge\-|lge/|lynx|leno|m1\-w|m3ga|m50/|maui|mc01|mc21|mcca|medi|meri|mio8|mioa|mo01|mo02|mode|modo|mot |mot\-|mt50|mtp1|mtv |mate|maxo|merc|mits|mobi|motv|mozz|n100|n101|n102|n202|n203|n300|n302|n500|n502|n505|n700|n701|n710|nec\-|nem\-|newg|neon)'
819
1109
  device_replacement: 'Generic Feature Phone'
820
1110
  - regex: '^(netf|noki|nzph|o2 x|o2\-x|opwv|owg1|opti|oran|ot\-s|p800|pand|pg\-1|pg\-2|pg\-3|pg\-6|pg\-8|pg\-c|pg13|phil|pn\-2|pt\-g|palm|pana|pire|pock|pose|psio|qa\-a|qc\-2|qc\-3|qc\-5|qc\-7|qc07|qc12|qc21|qc32|qc60|qci\-|qwap|qtek|r380|r600|raks|rim9|rove|s55/|sage|sams|sc01|sch\-|scp\-|sdk/|se47|sec\-|sec0|sec1|semc|sgh\-|shar|sie\-|sk\-0|sl45|slid|smb3|smt5|sp01|sph\-|spv |spv\-|sy01|samm|sany|sava|scoo|send|siem|smar|smit|soft|sony|t\-mo|t218|t250|t600|t610|t618|tcl\-|tdg\-|telm|tim\-|ts70|tsm\-|tsm3|tsm5|tx\-9|tagt)'
821
1111
  device_replacement: 'Generic Feature Phone'
822
- - regex: '^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\-|your|zte\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\-|webc|whit|wmlb|xda\-|xda\_)'
1112
+ - regex: '^(talk|teli|topl|tosh|up.b|upg1|utst|v400|v750|veri|vk\-v|vk40|vk50|vk52|vk53|vm40|vx98|virg|vite|voda|vulc|w3c |w3c\-|wapj|wapp|wapu|wapm|wig |wapi|wapr|wapv|wapy|wapa|waps|wapt|winc|winw|wonu|x700|xda2|xdag|yas\-|your|zte\-|zeto|aste|audi|avan|blaz|brew|brvw|bumb|ccwa|cell|cldc|cmd\-|dang|eml2|fetc|hipt|http|ibro|idea|ikom|ipaq|jbro|jemu|jigs|keji|kyoc|kyok|libw|m\-cr|midp|mmef|moto|mwbp|mywa|newt|nok6|o2im|pant|pdxg|play|pluc|port|prox|rozo|sama|seri|smal|symb|treo|upsi|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|wap\-|webc|whit|wmlb|xda\-|xda_)'
823
1113
  device_replacement: 'Generic Feature Phone'
824
1114
 
825
1115
  ##########
826
1116
  # Spiders (this is hack...)
827
1117
  ##########
828
- - 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)'
829
1119
  device_replacement: 'Spider'
830
1120
 
831
-
832
- mobile_user_agent_families:
833
- - 'Firefox Mobile'
834
- - 'Opera Mobile'
835
- - 'Opera Mini'
836
- - 'Mobile Safari'
837
- - 'webOS'
838
- - 'IE Mobile'
839
- - 'Playstation Portable'
840
- - 'Nokia'
841
- - 'Blackberry'
842
- - 'Palm'
843
- - 'Silk'
844
- - 'Android'
845
- - 'Maemo'
846
- - 'Obigo'
847
- - 'Netfront'
848
- - 'AvantGo'
849
- - 'Teleca'
850
- - 'SEMC-Browser'
851
- - 'Bolt'
852
- - 'Iris'
853
- - 'UP.Browser'
854
- - 'Symphony'
855
- - 'Minimo'
856
- - 'Bunjaloo'
857
- - 'Jasmine'
858
- - 'Dolfin'
859
- - 'Polaris'
860
- - 'BREW'
861
- - 'Chrome Mobile'
862
- - 'UC Browser'
863
- - 'Tizen Browser'
864
-
865
- # Some select mobile OSs report a desktop browser.
866
- # make sure we note they're mobile
867
- mobile_os_families:
868
- - 'Windows Phone 6.5'
869
- - 'Windows CE'
870
- - 'Symbian OS'