user_agent_parser 1.0.1 → 2.1.2

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