user_agent_parser 1.0.1 → 2.1.2

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.

@@ -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]*)'
@@ -14,7 +15,7 @@ user_agent_parsers:
14
15
  - regex: '(Fennec)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)'
15
16
  family_replacement: 'Firefox Mobile'
16
17
  - regex: '(Fennec)/(\d+)\.(\d+)(pre)'
17
- family_replacment: 'Firefox Mobile'
18
+ family_replacement: 'Firefox Mobile'
18
19
  - regex: '(Fennec)/(\d+)\.(\d+)'
19
20
  family_replacement: 'Firefox Mobile'
20
21
  - regex: 'Mobile.*(Firefox)/(\d+)\.(\d+)'
@@ -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,6 +97,8 @@ user_agent_parsers:
88
97
  family_replacement: 'Swiftfox'
89
98
 
90
99
  # Rekonq
100
+ - regex: '(rekonq)/(\d+)\.(\d+)\.?(\d+)? Safari'
101
+ family_replacement: 'Rekonq'
91
102
  - regex: 'rekonq'
92
103
  family_replacement: 'Rekonq'
93
104
 
@@ -105,19 +116,18 @@ user_agent_parsers:
105
116
  - regex: '(Comodo_Dragon)/(\d+)\.(\d+)\.(\d+)'
106
117
  family_replacement: 'Comodo Dragon'
107
118
 
108
- # YottaaMonitor bot
109
- - regex: '(YottaaMonitor)'
110
-
111
- # must go before NetFront below
112
- - regex: '(Kindle)/(\d+)\.(\d+)'
119
+ # Bots
120
+ - regex: '(YottaaMonitor|BrowserMob|HttpMonitor|YandexBot|Slurp|BingPreview|PagePeeker|ThumbShotsBot|WebThumb|URL2PNG|ZooShot|GomezA|Catchpoint bot|Willow Internet Crawler|Google SketchUp|Read%20Later)'
113
121
 
114
122
  - regex: '(Symphony) (\d+).(\d+)'
115
123
 
116
- - regex: 'Minimo'
124
+ - regex: '(Minimo)'
117
125
 
118
126
  # Chrome Mobile
119
127
  - regex: '(CrMo)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
120
128
  family_replacement: 'Chrome Mobile'
129
+ - regex: '(CriOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
130
+ family_replacement: 'Chrome Mobile iOS'
121
131
  - regex: '(Chrome)/(\d+)\.(\d+)\.(\d+)\.(\d+) Mobile'
122
132
  family_replacement: 'Chrome Mobile'
123
133
 
@@ -126,34 +136,109 @@ user_agent_parsers:
126
136
  family_replacement: 'Chrome Frame'
127
137
 
128
138
  # UC Browser
129
- - 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'
130
144
 
131
145
  # Tizen Browser (second case included in browser/major.minor regex)
132
146
  - regex: '(SLP Browser)/(\d+)\.(\d+)'
133
147
  family_replacement: 'Tizen Browser'
134
148
 
135
- # Epiphany browser (identifies as Chromium)
136
- - regex: '(Epiphany)/(\d+)\.(\d+).(\d+)'
137
-
138
149
  # Sogou Explorer 2.X
139
150
  - regex: '(SE 2\.X) MetaSr (\d+)\.(\d+)'
140
151
  family_replacement: 'Sogou Explorer'
141
152
 
153
+ # Baidu Browsers (desktop spoofs chrome & IE, explorer is mobile)
154
+ - regex: '(baidubrowser)[/\s](\d+)'
155
+ family_replacement: 'Baidu Browser'
156
+ - regex: '(FlyFlow)/(\d+)\.(\d+)'
157
+ family_replacement: 'Baidu Explorer'
158
+
159
+ # Pingdom
160
+ - regex: '(Pingdom.com_bot_version_)(\d+)\.(\d+)'
161
+ family_replacement: 'PingdomBot'
162
+
163
+ # Facebook
164
+ - regex: '(facebookexternalhit)/(\d+)\.(\d+)'
165
+ family_replacement: 'FacebookBot'
166
+
167
+ # LinkedIn
168
+ - regex: '(LinkedInBot)/(\d+)\.(\d+)'
169
+ family_replacement: 'LinkedInBot'
170
+
171
+ # Twitterbot
172
+ - regex: '(Twitterbot)/(\d+)\.(\d+)'
173
+ family_replacement: 'TwitterBot'
174
+
175
+ # Rackspace Monitoring
176
+ - regex: '(Rackspace Monitoring)/(\d+)\.(\d+)'
177
+ family_replacement: 'RackspaceBot'
178
+
179
+ # PyAMF
180
+ - regex: '(PyAMF)/(\d+)\.(\d+)\.(\d+)'
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
+
142
196
  #### END SPECIAL CASES TOP ####
143
197
 
144
198
  #### MAIN CASES - this catches > 50% of all browsers ####
145
199
 
146
200
  # Browser/major_version.minor_version.beta_version
147
- - 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|NetFront|Netfront|Konqueror|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|Opera Mini|iCab|NetNewsWire|ThunderBrowse|Iron|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+)'
148
227
 
149
228
  # Browser/major_version.minor_version
150
- - regex: '(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|Iron|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris)/(\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+)'
151
233
 
152
234
  # Browser major_version.minor_version.beta_version (space instead of slash)
153
235
  - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)'
154
236
  # Browser major_version.minor_version (space instead of slash)
155
- - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris|BREW) (\d+)\.(\d+)\.?(\d+)?'
156
-
237
+ - regex: '(iCab|Lunascape|Opera|Android|Jasmine|Polaris) (\d+)\.(\d+)\.?(\d+)?'
238
+
239
+ # Kindle WebKit
240
+ - regex: '(Kindle)/(\d+)\.(\d+)'
241
+
157
242
  # weird android UAs
158
243
  - regex: '(Android) Donut'
159
244
  v1_replacement: '1'
@@ -182,28 +267,38 @@ user_agent_parsers:
182
267
  - regex: '(MSIE) (\d+)\.(\d+).*XBLWP7'
183
268
  family_replacement: 'IE Large Screen'
184
269
 
185
- # AFTER THE EDGE CASES ABOVE!
186
- - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
187
- - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
188
-
189
270
  #### END MAIN CASES ####
190
271
 
191
272
  #### SPECIAL CASES ####
192
273
  - regex: '(Obigo)InternetBrowser'
193
274
  - regex: '(Obigo)\-Browser'
194
275
  - regex: '(Obigo|OBIGO)[^\d]*(\d+)(?:.(\d+))?'
276
+ family_replacement: 'Obigo'
195
277
 
196
278
  - regex: '(MAXTHON|Maxthon) (\d+)\.(\d+)'
197
279
  family_replacement: 'Maxthon'
198
280
  - regex: '(Maxthon|MyIE2|Uzbl|Shiira)'
199
281
  v1_replacement: '0'
200
282
 
201
- - regex: '(PLAYSTATION) (\d+)'
202
- family_replacement: 'PlayStation'
203
- - 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'
204
296
 
205
297
  - regex: '(BrowseX) \((\d+)\.(\d+)\.(\d+)'
206
298
 
299
+ - regex: '(NCSA_Mosaic)/(\d+)\.(\d+)'
300
+ family_replacement: 'NCSA Mosaic'
301
+
207
302
  # Polaris/d.d is above
208
303
  - regex: '(POLARIS)/(\d+)\.(\d+)'
209
304
  family_replacement: 'Polaris'
@@ -213,56 +308,71 @@ user_agent_parsers:
213
308
  - regex: '(BonEcho)/(\d+)\.(\d+)\.(\d+)'
214
309
  family_replacement: 'Bon Echo'
215
310
 
311
+ - regex: 'M?QQBrowser'
312
+ family_replacement: 'QQ Browser'
313
+
216
314
  - regex: '(iPod).+Version/(\d+)\.(\d+)\.(\d+)'
217
315
  family_replacement: 'Mobile Safari'
218
316
  - regex: '(iPod).*Version/(\d+)\.(\d+)'
219
317
  family_replacement: 'Mobile Safari'
220
- - regex: '(iPod)'
221
- family_replacement: 'Mobile Safari'
222
318
  - regex: '(iPhone).*Version/(\d+)\.(\d+)\.(\d+)'
223
319
  family_replacement: 'Mobile Safari'
224
320
  - regex: '(iPhone).*Version/(\d+)\.(\d+)'
225
321
  family_replacement: 'Mobile Safari'
226
- - regex: '(iPhone)'
227
- family_replacement: 'Mobile Safari'
228
322
  - regex: '(iPad).*Version/(\d+)\.(\d+)\.(\d+)'
229
323
  family_replacement: 'Mobile Safari'
230
324
  - regex: '(iPad).*Version/(\d+)\.(\d+)'
231
325
  family_replacement: 'Mobile Safari'
232
- - regex: '(iPad)'
326
+ - regex: '(iPod|iPhone|iPad);.*CPU.*OS (\d+)(?:_\d+)?_(\d+).*Mobile'
327
+ family_replacement: 'Mobile Safari'
328
+ - regex: '(iPod|iPhone|iPad)'
233
329
  family_replacement: 'Mobile Safari'
234
330
 
235
331
  - regex: '(AvantGo) (\d+).(\d+)'
332
+
333
+ - regex: '(OneBrowser)/(\d+).(\d+)'
334
+ family_replacement: 'ONE Browser'
236
335
 
237
336
  - regex: '(Avant)'
238
337
  v1_replacement: '1'
239
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'
240
345
  # nokia browsers
241
346
  # based on: http://www.developer.nokia.com/Community/Wiki/User-Agent_headers_for_Nokia_devices
242
347
  - regex: '^(Nokia)'
243
348
  family_replacement: 'Nokia Services (WAP) Browser'
244
349
  - regex: '(NokiaBrowser)/(\d+)\.(\d+).(\d+)\.(\d+)'
350
+ family_replacement: 'Nokia Browser'
245
351
  - regex: '(NokiaBrowser)/(\d+)\.(\d+).(\d+)'
352
+ family_replacement: 'Nokia Browser'
246
353
  - regex: '(NokiaBrowser)/(\d+)\.(\d+)'
354
+ family_replacement: 'Nokia Browser'
247
355
  - regex: '(BrowserNG)/(\d+)\.(\d+).(\d+)'
248
- family_replacement: 'NokiaBrowser'
356
+ family_replacement: 'Nokia Browser'
249
357
  - regex: '(Series60)/5\.0'
250
- family_replacement: 'NokiaBrowser'
358
+ family_replacement: 'Nokia Browser'
251
359
  v1_replacement: '7'
252
360
  v2_replacement: '0'
253
361
  - regex: '(Series60)/(\d+)\.(\d+)'
254
362
  family_replacement: 'Nokia OSS Browser'
255
363
  - regex: '(S40OviBrowser)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
256
- family_replacement: 'Nokia Series 40 Ovi Browser'
364
+ family_replacement: 'Ovi Browser'
257
365
  - regex: '(Nokia)[EN]?(\d+)'
258
366
 
259
367
  # BlackBerry devices
368
+ - regex: '(BB10);'
369
+ family_replacement: 'BlackBerry WebKit'
260
370
  - regex: '(PlayBook).+RIM Tablet OS (\d+)\.(\d+)\.(\d+)'
261
- family_replacement: 'Blackberry WebKit'
371
+ family_replacement: 'BlackBerry WebKit'
262
372
  - regex: '(Black[bB]erry).+Version/(\d+)\.(\d+)\.(\d+)'
263
- family_replacement: 'Blackberry WebKit'
373
+ family_replacement: 'BlackBerry WebKit'
264
374
  - regex: '(Black[bB]erry)\s?(\d+)'
265
- family_replacement: 'Blackberry'
375
+ family_replacement: 'BlackBerry'
266
376
 
267
377
  - regex: '(OmniWeb)/v(\d+)\.(\d+)'
268
378
 
@@ -272,6 +382,9 @@ user_agent_parsers:
272
382
  - regex: '(Pre)/(\d+)\.(\d+)'
273
383
  family_replacement: 'Palm Pre'
274
384
 
385
+ # fork of Links
386
+ - regex: '(ELinks)/(\d+)\.(\d+)'
387
+ - regex: '(ELinks) \((\d+)\.(\d+)'
275
388
  - regex: '(Links) \((\d+)\.(\d+)'
276
389
 
277
390
  - regex: '(QtWeb) Internet Browser/(\d+)\.(\d+)'
@@ -281,9 +394,13 @@ user_agent_parsers:
281
394
 
282
395
  # Amazon Silk, should go before Safari
283
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+)'
284
401
 
285
402
  # WebKit Nightly
286
- - regex: '(AppleWebKit)/(\d+)\.?(\d+)?\+ .* Version/\d+\.\d+.\d+ Safari/'
403
+ - regex: '(AppleWebKit)/(\d+)\.?(\d+)?\+ .* Safari'
287
404
  family_replacement: 'WebKit Nightly'
288
405
 
289
406
  # Safari
@@ -301,11 +418,89 @@ user_agent_parsers:
301
418
 
302
419
  - regex: '(Teleca)'
303
420
  family_replacement: 'Teleca Browser'
421
+
422
+ - regex: '(Phantom)/V(\d+)\.(\d+)'
423
+ family_replacement: 'Phantom Browser'
304
424
 
305
- - regex: '(MSIE) (\d+)\.(\d+)'
425
+ - regex: 'Trident(.*)rv.(\d+)\.(\d+)'
306
426
  family_replacement: 'IE'
307
427
 
428
+ # Apple Mail
429
+
430
+ # apple mail - not directly detectable, have it after Safari stuff
431
+ - regex: '(AppleWebKit)/(\d+)\.(\d+)\.(\d+)'
432
+ family_replacement: 'AppleMail'
433
+
434
+ # AFTER THE EDGE CASES ABOVE!
435
+ # AFTER IE11
436
+ # BEFORE all other IE
437
+ - regex: '(Firefox)/(\d+)\.(\d+)\.(\d+)'
438
+ - regex: '(Firefox)/(\d+)\.(\d+)(pre|[ab]\d+[a-z]*)?'
439
+
440
+ - regex: '([MS]?IE) (\d+)\.(\d+)'
441
+ family_replacement: 'IE'
442
+
443
+ - regex: '(python-requests)/(\d+)\.(\d+)'
444
+ family_replacement: 'Python Requests'
445
+
308
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]).*\)'
309
504
 
310
505
  ##########
311
506
  # Android
@@ -333,6 +528,12 @@ os_parsers:
333
528
  - regex: '(Android) Honeycomb'
334
529
  os_v1_replacement: '3'
335
530
 
531
+ ##########
532
+ # Kindle Android
533
+ ##########
534
+ - regex: '(Silk-Accelerated=[a-z]{4,5})'
535
+ os_replacement: 'Android'
536
+
336
537
  ##########
337
538
  # Windows
338
539
  # http://en.wikipedia.org/wiki/Windows_NT#Releases
@@ -341,7 +542,6 @@ os_parsers:
341
542
  # lots of ua strings have Windows NT 4.1 !?!?!?!? !?!? !? !????!?! !!! ??? !?!?! ?
342
543
  # (very) roughly ordered in terms of frequency of occurence of regex (win xp currently most frequent, etc)
343
544
  ##########
344
- - regex: '(Windows Phone 6\.5)'
345
545
 
346
546
  - regex: '(Windows (?:NT 5\.2|NT 5\.1))'
347
547
  os_replacement: 'Windows XP'
@@ -349,7 +549,7 @@ os_parsers:
349
549
  # ie mobile des ktop mode
350
550
  # spoofs nt 6.1. must come before windows 7
351
551
  - regex: '(XBLWP7)'
352
- os_replacement: 'Windows Phone OS'
552
+ os_replacement: 'Windows Phone'
353
553
 
354
554
  - regex: '(Windows NT 6\.1)'
355
555
  os_replacement: 'Windows 7'
@@ -357,7 +557,13 @@ os_parsers:
357
557
  - regex: '(Windows NT 6\.0)'
358
558
  os_replacement: 'Windows Vista'
359
559
 
360
- - 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'
361
567
 
362
568
  # is this a spoof or is nt 6.2 out and about in some capacity?
363
569
  - regex: '(Windows NT 6\.2)'
@@ -366,8 +572,8 @@ os_parsers:
366
572
  - regex: '(Windows NT 5\.0)'
367
573
  os_replacement: 'Windows 2000'
368
574
 
369
- - regex: '(Windows Phone OS) (\d+)\.(\d+)'
370
-
575
+ - regex: '(Windows Phone) (\d+)\.(\d+)'
576
+ - regex: '(Windows Phone) OS (\d+)\.(\d+)'
371
577
  - regex: '(Windows ?Mobile)'
372
578
  os_replacement: 'Windows Mobile'
373
579
 
@@ -383,13 +589,15 @@ os_parsers:
383
589
  ##########
384
590
  - regex: '(Tizen)/(\d+)\.(\d+)'
385
591
 
386
-
387
-
388
592
  ##########
389
593
  # Mac OS
390
594
  # http://en.wikipedia.org/wiki/Mac_OS_X#Versions
391
595
  ##########
392
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'
393
601
 
394
602
  # builds before tiger don't seem to specify version?
395
603
 
@@ -411,6 +619,9 @@ os_parsers:
411
619
  - regex: '(iPhone|iPad|iPod).*Mac OS X.*Version/(\d+)\.(\d+)'
412
620
  os_replacement: 'iOS'
413
621
 
622
+ - regex: '(AppleTV)/(\d+)\.(\d+)'
623
+ os_replacement: 'ATV OS X'
624
+
414
625
  ##########
415
626
  # Chrome OS
416
627
  # if version 0.0.0, probably this stuff:
@@ -423,9 +634,10 @@ os_parsers:
423
634
  ##########
424
635
  # Linux distros
425
636
  ##########
426
- - regex: '(Debian)-(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
637
+ - regex: '([Dd]ebian)'
638
+ os_replacement: 'Debian'
427
639
  - regex: '(Linux Mint)(?:/(\d+))?'
428
- - regex: '(Mandriva)(?: Linux)?/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
640
+ - regex: '(Mandriva)(?: Linux)?/(?:[\d.-]+m[a-z]{2}(\d+).(\d))?'
429
641
 
430
642
  ##########
431
643
  # Symbian + Symbian OS
@@ -444,10 +656,14 @@ os_parsers:
444
656
  - regex: '(MeeGo)'
445
657
  - regex: 'Symbian [Oo][Ss]'
446
658
  os_replacement: 'Symbian OS'
659
+ - regex: 'Series40;'
660
+ os_replacement: 'Nokia Series 40'
447
661
 
448
662
  ##########
449
663
  # BlackBerry devices
450
664
  ##########
665
+ - regex: '(BB10);.+Version/(\d+)\.(\d+)\.(\d+)'
666
+ os_replacement: 'BlackBerry OS'
451
667
  - regex: '(Black[Bb]erry)[0-9a-z]+/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
452
668
  os_replacement: 'BlackBerry OS'
453
669
  - regex: '(Black[Bb]erry).+Version/(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?'
@@ -457,30 +673,61 @@ os_parsers:
457
673
  - regex: '(Play[Bb]ook)'
458
674
  os_replacement: 'BlackBerry Tablet OS'
459
675
  - regex: '(Black[Bb]erry)'
460
- os_replacement: 'Blackberry OS'
676
+ os_replacement: 'BlackBerry OS'
461
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'
694
+
695
+ ##########
696
+ # Google TV
697
+ ##########
698
+ - regex: '(GoogleTV) (\d+)\.(\d+)\.(\d+)'
699
+ # Old style
700
+ - regex: '(GoogleTV)/[\da-z]+'
701
+
702
+ - regex: '(WebTV)/(\d+).(\d+)'
703
+
462
704
  ##########
463
705
  # Misc mobile
464
706
  ##########
465
- - regex: '(webOS|hpwOS)/(\d+)\.(\d+)(?:\.(\d+))?'
707
+ - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?'
466
708
  os_replacement: 'webOS'
709
+ - regex: '(VRE);'
467
710
 
468
711
  ##########
469
712
  # Generic patterns
470
713
  # since the majority of os cases are very specific, these go last
471
714
  ##########
472
715
  # first.second.third.fourth bits
473
- - regex: '(SUSE|Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
716
+ - regex: '(Fedora|Red Hat|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)'
474
717
 
475
718
  # first.second.third bits
476
- - regex: '(SUSE|Fedora|Red Hat|Puppy|PCLinuxOS|CentOS)/(\d+)\.(\d+)\.(\d+)'
719
+ - regex: '(Red Hat|Puppy|PCLinuxOS)/(\d+)\.(\d+)\.(\d+)'
477
720
 
478
721
  # first.second bits
479
722
  - regex: '(Ubuntu|Kindle|Bada|Lubuntu|BackTrack|Red Hat|Slackware)/(\d+)\.(\d+)'
480
723
 
481
724
  # just os
482
- - 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+)'
483
728
  - regex: '(Linux|BSD)'
729
+ - regex: 'SunOS'
730
+ os_replacement: 'Solaris'
484
731
 
485
732
  device_parsers:
486
733
  ##########
@@ -510,31 +757,74 @@ device_parsers:
510
757
  - regex: 'Sprint APA(9292)'
511
758
  device_replacement: 'HTC $1 (Sprint)'
512
759
  - regex: 'HTC ([A-Za-z0-9]+ [A-Z])'
513
- device_replacement: HTC $1
514
- - regex: 'HTC-([A-Za-z0-9]+)'
515
- device_replacement: 'HTC $1'
516
- - regex: 'HTC_([A-Za-z0-9]+)'
517
760
  device_replacement: 'HTC $1'
518
- - regex: 'HTC ([A-Za-z0-9]+)'
761
+ - regex: 'HTC[-_/\s]([A-Za-z0-9]+)'
519
762
  device_replacement: 'HTC $1'
520
- - regex: '(ADR[A-z0-9]+)'
763
+ - regex: '(ADR[A-Za-z0-9]+)'
521
764
  device_replacement: 'HTC $1'
522
765
  - regex: '(HTC)'
523
766
 
767
+ # Tesla Model S
768
+ - regex: '(QtCarBrowser)'
769
+ device_replacement: 'Tesla Model S'
770
+
771
+ # Samsung
772
+ - regex: '(SamsungSGHi560)'
773
+ device_replacement: 'Samsung SGHi560'
774
+
524
775
  #########
525
776
  # Ericsson - must come before nokia since they also use symbian
526
777
  #########
527
- - regex: 'SonyEricsson([A-z0-9]+)/'
778
+ - regex: 'SonyEricsson([A-Za-z0-9]+)/'
528
779
  device_replacement: 'Ericsson $1'
529
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
+
530
818
  #########
531
819
  # Android General Device Matching (far from perfect)
532
820
  #########
533
- - regex: 'Android[\- ][\d]+\.[\d]+\; [A-z]{2}\-[A-z]{2}\; WOWMobile (.+) Build'
534
- - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; [A-z]{2}\-[A-z]{2}\; (.+) Build'
535
- - regex: 'Android[\- ][\d]+\.[\d]+\-update1\; [A-z]{2}\-[A-z]{2}\; (.+) Build'
536
- - regex: 'Android[\- ][\d]+\.[\d]+\; [A-z]{2}\-[A-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'
537
826
  - regex: 'Android[\- ][\d]+\.[\d]+\.[\d]+; (.+) Build'
827
+ - regex: 'Android[\- ][\d]+\.[\d]+; (.+) Build'
538
828
 
539
829
  ##########
540
830
  # NOKIA
@@ -542,6 +832,8 @@ device_parsers:
542
832
  ##########
543
833
  - regex: 'NokiaN([0-9]+)'
544
834
  device_replacement: 'Nokia N$1'
835
+ - regex: 'NOKIA([A-Za-z0-9\v-]+)'
836
+ device_replacement: 'Nokia $1'
545
837
  - regex: 'Nokia([A-Za-z0-9\v-]+)'
546
838
  device_replacement: 'Nokia $1'
547
839
  - regex: 'NOKIA ([A-Za-z0-9\-]+)'
@@ -554,14 +846,19 @@ device_parsers:
554
846
  device_replacement: 'Nokia'
555
847
 
556
848
  ##########
557
- # Blackberry
849
+ # BlackBerry
558
850
  # http://www.useragentstring.com/pages/BlackBerry/
559
851
  ##########
852
+ - regex: 'BB10; ([A-Za-z0-9\- ]+)\)'
853
+ device_replacement: 'BlackBerry $1'
560
854
  - regex: '(PlayBook).+RIM Tablet OS'
561
- device_replacement: 'Blackberry Playbook'
562
- - regex: '(Black[Bb]erry [0-9]+);'
855
+ device_replacement: 'BlackBerry Playbook'
856
+ - regex: 'Black[Bb]erry ([0-9]+);'
857
+ device_replacement: 'BlackBerry $1'
563
858
  - regex: 'Black[Bb]erry([0-9]+)'
564
859
  device_replacement: 'BlackBerry $1'
860
+ - regex: 'Black[Bb]erry;'
861
+ device_replacement: 'BlackBerry'
565
862
 
566
863
  ##########
567
864
  # PALM / HP
@@ -571,26 +868,35 @@ device_parsers:
571
868
  device_replacement: 'Palm Pre'
572
869
  - regex: '(Pixi)/(\d+)\.(\d+)'
573
870
  device_replacement: 'Palm Pixi'
574
- - regex: '(Touchpad)/(\d+)\.(\d+)'
575
- device_replacement: 'HP Touchpad'
576
- - regex: 'HPiPAQ([A-z0-9]+)/(\d+).(\d+)'
871
+ - regex: '(Touch[Pp]ad)/(\d+)\.(\d+)'
872
+ device_replacement: 'HP TouchPad'
873
+ - regex: 'HPiPAQ([A-Za-z0-9]+)/(\d+).(\d+)'
577
874
  device_replacement: 'HP iPAQ $1'
578
- - regex: 'Palm([A-z0-9]+)'
875
+ - regex: 'Palm([A-Za-z0-9]+)'
579
876
  device_replacement: 'Palm $1'
580
- - regex: 'Treo([A-z0-9]+)'
877
+ - regex: 'Treo([A-Za-z0-9]+)'
581
878
  device_replacement: 'Palm Treo $1'
582
879
  - regex: 'webOS.*(P160UNA)/(\d+).(\d+)'
583
880
  device_replacement: 'HP Veer'
584
881
 
585
882
  ##########
586
- # incomplete!
587
- # Kindle
883
+ # AppleTV
884
+ # No built in browser that I can tell
885
+ # Stack Overflow indicated iTunes-AppleTV/4.1 as a known UA for app available and I'm seeing it in live traffic
588
886
  ##########
589
- - regex: '(Kindle Fire)'
590
- - regex: '(Kindle)'
591
- - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?'
592
- device_replacement: 'Kindle Fire'
887
+ - regex: '(AppleTV)'
888
+ device_replacement: 'AppleTV'
593
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
+
594
900
  ##########
595
901
  # complete but probably catches spoofs
596
902
  # iSTUFF
@@ -599,6 +905,7 @@ device_parsers:
599
905
  # cannot determine specific device type from ua string. (3g, 3gs, 4, etc)
600
906
  - regex: '(iPad) Simulator;'
601
907
  - regex: '(iPad);'
908
+ - regex: '(iPod) touch;'
602
909
  - regex: '(iPod);'
603
910
  - regex: '(iPhone) Simulator;'
604
911
  - regex: '(iPhone);'
@@ -606,101 +913,119 @@ device_parsers:
606
913
  ##########
607
914
  # Acer
608
915
  ##########
609
- - regex: 'acer_([A-z0-9]+)_'
916
+ - regex: 'acer_([A-Za-z0-9]+)_'
610
917
  device_replacement: 'Acer $1'
611
- - regex: 'acer_([A-z0-9]+)_'
918
+ - regex: 'acer_([A-Za-z0-9]+)_'
612
919
  device_replacement: 'Acer $1'
613
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
+
614
929
  ##########
615
930
  # Amoi
616
931
  ##########
617
- - regex: 'Amoi\-([A-z0-9]+)'
932
+ - regex: 'Amoi\-([A-Za-z0-9]+)'
618
933
  device_replacement: 'Amoi $1'
619
- - regex: 'AMOI\-([A-z0-9]+)'
934
+ - regex: 'AMOI\-([A-Za-z0-9]+)'
620
935
  device_replacement: 'Amoi $1'
621
936
 
622
937
  ##########
623
938
  # Amoi
624
939
  ##########
625
- - regex: 'Asus\-([A-z0-9]+)'
940
+ - regex: 'Asus\-([A-Za-z0-9]+)'
626
941
  device_replacement: 'Asus $1'
627
- - regex: 'ASUS\-([A-z0-9]+)'
942
+ - regex: 'ASUS\-([A-Za-z0-9]+)'
628
943
  device_replacement: 'Asus $1'
629
944
 
630
945
  ##########
631
946
  # Bird
632
947
  ##########
633
- - regex: 'BIRD\-([A-z0-9]+)'
948
+ - regex: 'BIRD\-([A-Za-z0-9]+)'
634
949
  device_replacement: 'Bird $1'
635
- - regex: 'BIRD\.([A-z0-9]+)'
950
+ - regex: 'BIRD\.([A-Za-z0-9]+)'
636
951
  device_replacement: 'Bird $1'
637
- - regex: 'BIRD ([A-z0-9]+)'
952
+ - regex: 'BIRD ([A-Za-z0-9]+)'
638
953
  device_replacement: 'Bird $1'
639
954
 
640
955
  ##########
641
956
  # Dell
642
957
  ##########
643
- - regex: 'Dell ([A-z0-9]+)'
958
+ - regex: 'Dell ([A-Za-z0-9]+)'
644
959
  device_replacement: 'Dell $1'
645
960
 
646
961
  ##########
647
962
  # DoCoMo
648
963
  ##########
649
- - regex: 'DoCoMo/2\.0 ([A-z0-9]+)'
964
+ - regex: 'DoCoMo/2\.0 ([A-Za-z0-9]+)'
650
965
  device_replacement: 'DoCoMo $1'
651
- - regex: '([A-z0-9]+)\_W\;FOMA'
966
+ - regex: '([A-Za-z0-9]+)_W\;FOMA'
652
967
  device_replacement: 'DoCoMo $1'
653
- - regex: '([A-z0-9]+)\;FOMA'
968
+ - regex: '([A-Za-z0-9]+)\;FOMA'
654
969
  device_replacement: 'DoCoMo $1'
655
970
 
656
971
  ##########
657
- # Huawei Vodafone
972
+ # Huawei
658
973
  ##########
659
- - regex: 'vodafone([A-z0-9]+)'
974
+ - regex: 'Huawei([A-Za-z0-9]+)'
975
+ device_replacement: 'Huawei $1'
976
+ - regex: 'HUAWEI-([A-Za-z0-9]+)'
977
+ device_replacement: 'Huawei $1'
978
+ - regex: 'vodafone([A-Za-z0-9]+)'
660
979
  device_replacement: 'Huawei Vodafone $1'
661
980
 
662
981
  ##########
663
982
  # i-mate
664
983
  ##########
665
- - regex: 'i\-mate ([A-z0-9]+)'
984
+ - regex: 'i\-mate ([A-Za-z0-9]+)'
666
985
  device_replacement: 'i-mate $1'
667
986
 
668
987
  ##########
669
988
  # kyocera
670
989
  ##########
671
- - regex: 'Kyocera\-([A-z0-9]+)'
990
+ - regex: 'Kyocera\-([A-Za-z0-9]+)'
672
991
  device_replacement: 'Kyocera $1'
673
- - regex: 'KWC\-([A-z0-9]+)'
992
+ - regex: 'KWC\-([A-Za-z0-9]+)'
674
993
  device_replacement: 'Kyocera $1'
675
994
 
676
995
  ##########
677
996
  # lenovo
678
997
  ##########
679
- - regex: 'Lenovo\-([A-z0-9]+)'
998
+ - regex: 'Lenovo\-([A-Za-z0-9]+)'
680
999
  device_replacement: 'Lenovo $1'
681
- - regex: 'Lenovo\_([A-z0-9]+)'
1000
+ - regex: 'Lenovo_([A-Za-z0-9]+)'
682
1001
  device_replacement: 'Lenovo $1'
683
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
+
684
1009
  ##########
685
1010
  # lg
686
1011
  ##########
687
- - regex: 'LG/([A-z0-9]+)'
1012
+ - regex: 'LG/([A-Za-z0-9]+)'
688
1013
  device_replacement: 'LG $1'
689
- - regex: 'LG-LG([A-z0-9]+)'
1014
+ - regex: 'LG-LG([A-Za-z0-9]+)'
690
1015
  device_replacement: 'LG $1'
691
- - regex: 'LGE-LG([A-z0-9]+)'
1016
+ - regex: 'LGE-LG([A-Za-z0-9]+)'
692
1017
  device_replacement: 'LG $1'
693
- - regex: 'LGE VX([A-z0-9]+)'
1018
+ - regex: 'LGE VX([A-Za-z0-9]+)'
694
1019
  device_replacement: 'LG $1'
695
- - regex: 'LG ([A-z0-9]+)'
1020
+ - regex: 'LG ([A-Za-z0-9]+)'
696
1021
  device_replacement: 'LG $1'
697
- - regex: 'LGE LG\-AX([A-z0-9]+)'
1022
+ - regex: 'LGE LG\-AX([A-Za-z0-9]+)'
698
1023
  device_replacement: 'LG $1'
699
- - regex: 'LG\-([A-z0-9]+)'
1024
+ - regex: 'LG\-([A-Za-z0-9]+)'
700
1025
  device_replacement: 'LG $1'
701
- - regex: 'LGE\-([A-z0-9]+)'
1026
+ - regex: 'LGE\-([A-Za-z0-9]+)'
702
1027
  device_replacement: 'LG $1'
703
- - regex: 'LG([A-z0-9]+)'
1028
+ - regex: 'LG([A-Za-z0-9]+)'
704
1029
  device_replacement: 'LG $1'
705
1030
 
706
1031
  ##########
@@ -714,36 +1039,61 @@ device_parsers:
714
1039
  ##########
715
1040
  # motorola
716
1041
  ##########
717
- - regex: '(Motorola)\-([A-z0-9]+)'
718
- - regex: 'MOTO\-([A-z0-9]+)'
1042
+ - regex: '(Motorola)\-([A-Za-z0-9]+)'
1043
+ - regex: 'MOTO\-([A-Za-z0-9]+)'
719
1044
  device_replacement: 'Motorola $1'
720
- - regex: 'MOT\-([A-z0-9]+)'
1045
+ - regex: 'MOT\-([A-Za-z0-9]+)'
721
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'
722
1055
 
1056
+ ##########
1057
+ # pantech
1058
+ ##########
1059
+ - regex: 'Pantech([A-Za-z0-9]+)'
1060
+ device_replacement: 'Pantech $1'
1061
+
723
1062
  ##########
724
1063
  # philips
725
1064
  ##########
726
- - regex: 'Philips([A-z0-9]+)'
1065
+ - regex: 'Philips([A-Za-z0-9]+)'
727
1066
  device_replacement: 'Philips $1'
728
- - regex: 'Philips ([A-z0-9]+)'
1067
+ - regex: 'Philips ([A-Za-z0-9]+)'
729
1068
  device_replacement: 'Philips $1'
730
1069
 
731
1070
  ##########
732
1071
  # Samsung
733
1072
  ##########
734
- - regex: 'SAMSUNG-([A-z0-9\-]+)'
1073
+ - regex: 'SAMSUNG-([A-Za-z0-9\-]+)'
735
1074
  device_replacement: 'Samsung $1'
736
- - regex: 'SAMSUNG\; ([A-z0-9\-]+)'
1075
+ - regex: 'SAMSUNG\; ([A-Za-z0-9\-]+)'
737
1076
  device_replacement: 'Samsung $1'
738
1077
 
1078
+ ##########
1079
+ # Sega
1080
+ ##########
1081
+ - regex: 'Dreamcast'
1082
+ device_replacement: 'Sega Dreamcast'
1083
+
739
1084
  ##########
740
1085
  # Softbank
741
1086
  ##########
742
- - regex: 'Softbank/1\.0/([A-z0-9]+)'
1087
+ - regex: 'Softbank/1\.0/([A-Za-z0-9]+)'
743
1088
  device_replacement: 'Softbank $1'
744
- - regex: 'Softbank/2\.0/([A-z0-9]+)'
1089
+ - regex: 'Softbank/2\.0/([A-Za-z0-9]+)'
745
1090
  device_replacement: 'Softbank $1'
746
1091
 
1092
+ ##########
1093
+ # WebTV
1094
+ ##########
1095
+ - regex: '(WebTV)/(\d+).(\d+)'
1096
+
747
1097
  ##########
748
1098
  # Generic Smart Phone
749
1099
  ##########
@@ -753,58 +1103,18 @@ device_parsers:
753
1103
  ##########
754
1104
  # Generic Feature Phone
755
1105
  ##########
756
- - 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)'
757
1107
  device_replacement: 'Generic Feature Phone'
758
- - 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)'
759
1109
  device_replacement: 'Generic Feature Phone'
760
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)'
761
1111
  device_replacement: 'Generic Feature Phone'
762
- - 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_)'
763
1113
  device_replacement: 'Generic Feature Phone'
764
1114
 
765
1115
  ##########
766
1116
  # Spiders (this is hack...)
767
1117
  ##########
768
- - 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)'
769
1119
  device_replacement: 'Spider'
770
1120
 
771
-
772
- mobile_user_agent_families:
773
- - 'Firefox Mobile'
774
- - 'Opera Mobile'
775
- - 'Opera Mini'
776
- - 'Mobile Safari'
777
- - 'webOS'
778
- - 'IE Mobile'
779
- - 'Playstation Portable'
780
- - 'Nokia'
781
- - 'Blackberry'
782
- - 'Palm'
783
- - 'Silk'
784
- - 'Android'
785
- - 'Maemo'
786
- - 'Obigo'
787
- - 'Netfront'
788
- - 'AvantGo'
789
- - 'Teleca'
790
- - 'SEMC-Browser'
791
- - 'Bolt'
792
- - 'Iris'
793
- - 'UP.Browser'
794
- - 'Symphony'
795
- - 'Minimo'
796
- - 'Bunjaloo'
797
- - 'Jasmine'
798
- - 'Dolfin'
799
- - 'Polaris'
800
- - 'BREW'
801
- - 'Chrome Mobile'
802
- - 'UC Browser'
803
- - 'Tizen Browser'
804
-
805
- # Some select mobile OSs report a desktop browser.
806
- # make sure we note they're mobile
807
- mobile_os_families:
808
- - 'Windows Phone 6.5'
809
- - 'Windows CE'
810
- - 'Symbian OS'