device_detector 0.7.0 → 0.8.0

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -0
  3. data/Rakefile +12 -6
  4. data/device_detector.gemspec +1 -1
  5. data/lib/device_detector.rb +65 -4
  6. data/lib/device_detector/client.rb +6 -6
  7. data/lib/device_detector/device.rb +62 -31
  8. data/lib/device_detector/memory_cache.rb +1 -1
  9. data/lib/device_detector/metadata_extractor.rb +4 -13
  10. data/lib/device_detector/model_extractor.rb +10 -1
  11. data/lib/device_detector/name_extractor.rb +1 -1
  12. data/lib/device_detector/os.rb +141 -5
  13. data/lib/device_detector/parser.rb +23 -12
  14. data/lib/device_detector/version.rb +1 -1
  15. data/lib/device_detector/version_extractor.rb +1 -1
  16. data/regexes/bots.yml +36 -1
  17. data/regexes/{browser_engines.yml → client/browser_engine.yml} +4 -1
  18. data/regexes/{browsers.yml → client/browsers.yml} +31 -27
  19. data/regexes/{feed_readers.yml → client/feed_readers.yml} +0 -1
  20. data/regexes/{libraries.yml → client/libraries.yml} +1 -1
  21. data/regexes/{mediaplayers.yml → client/mediaplayers.yml} +1 -1
  22. data/regexes/{mobile_apps.yml → client/mobile_apps.yml} +0 -1
  23. data/regexes/{pim.yml → client/pim.yml} +1 -1
  24. data/regexes/{devices → device}/cameras.yml +1 -1
  25. data/regexes/{devices → device}/car_browsers.yml +0 -1
  26. data/regexes/{devices → device}/consoles.yml +0 -1
  27. data/regexes/{devices → device}/mobiles.yml +193 -49
  28. data/regexes/{devices/portable_media_players.yml → device/portable_media_player.yml} +0 -1
  29. data/regexes/{devices → device}/televisions.yml +0 -3
  30. data/regexes/oss.yml +105 -102
  31. data/regexes/vendorfragments.yml +70 -0
  32. data/spec/device_detector/bot_fixtures_spec.rb +30 -0
  33. data/spec/device_detector/client_fixtures_spec.rb +31 -0
  34. data/spec/device_detector/concrete_user_agent_spec.rb +41 -1
  35. data/spec/device_detector/detector_fixtures_spec.rb +56 -0
  36. data/spec/device_detector/device_fixtures_spec.rb +36 -0
  37. data/spec/device_detector/device_spec.rb +3 -3
  38. data/spec/device_detector/memory_cache_spec.rb +1 -1
  39. data/spec/device_detector/model_extractor_spec.rb +7 -7
  40. data/spec/device_detector/os_fixtures_spec.rb +26 -0
  41. data/spec/device_detector/version_extractor_spec.rb +10 -10
  42. data/spec/device_detector_spec.rb +1 -1
  43. data/spec/fixtures/client/browser.yml +986 -0
  44. data/spec/fixtures/client/feed_reader.yml +180 -0
  45. data/spec/fixtures/client/library.yml +78 -0
  46. data/spec/fixtures/client/mediaplayer.yml +144 -0
  47. data/spec/fixtures/client/mobile_app.yml +24 -0
  48. data/spec/fixtures/client/pim.yml +90 -0
  49. data/spec/fixtures/detector/bots.yml +716 -0
  50. data/spec/fixtures/detector/camera.yml +91 -0
  51. data/spec/fixtures/detector/car_browser.yml +19 -0
  52. data/spec/fixtures/detector/console.yml +253 -0
  53. data/spec/fixtures/detector/desktop.yml +4568 -0
  54. data/spec/fixtures/detector/feature_phone.yml +719 -0
  55. data/spec/fixtures/detector/feed_reader.yml +462 -0
  56. data/spec/fixtures/detector/mediaplayer.yml +141 -0
  57. data/spec/fixtures/detector/mobile_apps.yml +32 -0
  58. data/spec/fixtures/detector/phablet.yml +1095 -0
  59. data/spec/fixtures/detector/portable_media_player.yml +145 -0
  60. data/spec/fixtures/detector/smart_display.yml +19 -0
  61. data/spec/fixtures/detector/smartphone.yml +28673 -0
  62. data/spec/fixtures/detector/tablet.yml +13201 -0
  63. data/spec/fixtures/detector/tv.yml +1380 -0
  64. data/spec/fixtures/detector/unknown.yml +3536 -0
  65. data/spec/fixtures/device/camera.yml +18 -0
  66. data/spec/fixtures/device/car_browser.yml +6 -0
  67. data/spec/fixtures/device/console.yml +72 -0
  68. data/spec/fixtures/parser/bots.yml +2055 -0
  69. data/spec/fixtures/parser/oss.yml +607 -0
  70. data/spec/fixtures/parser/vendorfragments.yml +156 -0
  71. data/spec/spec_helper.rb +6 -2
  72. metadata +84 -17
@@ -23,7 +23,7 @@ class DeviceDetector
23
23
 
24
24
  def matching_regex
25
25
  from_cache([self.class.name, user_agent]) do
26
- regexes.find { |r| user_agent =~ r['regex'] }
26
+ regexes.find { |r| user_agent =~ r[:regex] }
27
27
  end
28
28
  end
29
29
 
@@ -37,32 +37,43 @@ class DeviceDetector
37
37
 
38
38
  def filepaths
39
39
  filenames.map do |filename|
40
- File.join(ROOT, 'regexes', filename)
40
+ [ filename.to_sym, File.join(ROOT, 'regexes', filename) ]
41
41
  end
42
42
  end
43
43
 
44
- def regexes_for(filepaths)
44
+ def regexes_for(file_paths)
45
45
  from_cache(['regexes', self.class]) do
46
- raw_regexes = load_regexes
47
- parsed_regexes = raw_regexes.map { |r| parse_regexes(r) }
48
-
49
- parsed_regexes.flatten
46
+ load_regexes(file_paths).flat_map { |path, regex| parse_regexes(path, regex) }
50
47
  end
51
48
  end
52
49
 
53
- def load_regexes
54
- raw_files = filepaths.map { |path| File.read(path) }
50
+ def load_regexes(file_paths)
51
+ file_paths.map { |path, full_path| [path, symbolize_keys!(YAML.load_file(full_path))] }
52
+ end
55
53
 
56
- raw_files.map { |f| YAML.load(f) }
54
+ def symbolize_keys!(object)
55
+ case object
56
+ when Array
57
+ object.map!{ |v| symbolize_keys!(v) }
58
+ when Hash
59
+ object.keys.each{ |k| object[k.to_sym] = symbolize_keys!(object.delete(k)) if k.is_a?(String) }
60
+ end
61
+ object
57
62
  end
58
63
 
59
- def parse_regexes(raw_regexes)
64
+ def parse_regexes(path, raw_regexes)
60
65
  raw_regexes.map do |meta|
61
- meta['regex'] = Regexp.new(meta['regex']) if meta['regex'].is_a? String
66
+ fail "invalid device spec: #{meta.inspect}" unless meta[:regex].is_a? String
67
+ meta[:regex] = build_regex(meta[:regex])
68
+ meta[:path] = path
62
69
  meta
63
70
  end
64
71
  end
65
72
 
73
+ def build_regex(src)
74
+ Regexp.new('(?:^|[^A-Z0-9\_\-])(?:' + src + ')', Regexp::IGNORECASE)
75
+ end
76
+
66
77
  def from_cache(key)
67
78
  DeviceDetector.cache.get_or_set(key) { yield }
68
79
  end
@@ -1,3 +1,3 @@
1
1
  class DeviceDetector
2
- VERSION = '0.7.0'
2
+ VERSION = '0.8.0'
3
3
  end
@@ -4,7 +4,7 @@ class DeviceDetector
4
4
  private
5
5
 
6
6
  def metadata_string
7
- String(regex_meta['version'])
7
+ String(regex_meta[:version])
8
8
  end
9
9
 
10
10
  end
@@ -933,7 +933,37 @@
933
933
  name: 'Yottaa'
934
934
  url: 'http://www.yottaa.com/'
935
935
 
936
+ - regex: 'Yahoo Ad monitoring.*yahoo-ad-monitoring-SLN24857.*'
937
+ name: 'Yahoo Gemini'
938
+ category: 'Crawler'
939
+ url: 'https://help.yahoo.com/kb/yahoo-ad-monitoring-SLN24857.html'
940
+ producer:
941
+ name: 'Yahoo! Inc.'
942
+ url: 'http://www.yahoo.com'
936
943
 
944
+ - regex: '.*Java.*outbrain'
945
+ name: 'Outbrain'
946
+ category: 'Crawler'
947
+ url: ''
948
+ producer:
949
+ name: 'Outbrain'
950
+ url: 'http://www.outbrain.com/'
951
+
952
+ - regex: 'HubPages.*crawlingpolicy'
953
+ name: 'HubPages'
954
+ category: 'Crawler'
955
+ url: 'http://hubpages.com/help/crawlingpolicy'
956
+ producer:
957
+ name: 'HubPages'
958
+ url: 'http://hubpages.com/'
959
+
960
+ - regex: 'Pinterest/\d\.\d.*www.pinterest.com.*'
961
+ name: 'Pinterest'
962
+ url: ''
963
+ category: 'Crawler'
964
+ producer:
965
+ name: 'Pinterest'
966
+ url: 'http://www.pinterest.com/'
937
967
 
938
968
  - regex: 'lycos'
939
969
  name: 'Lycos'
@@ -980,6 +1010,11 @@
980
1010
  - regex: 'NetLyzer FastProbe'
981
1011
  name: 'NetLyzer FastProbe'
982
1012
 
1013
+ - regex: 'AdMantX.*admantx.com'
1014
+ name: 'ADMantX'
1015
+
1016
+ - regex: 'Server Density Service Monitoring.*'
1017
+ name: 'Server Density'
983
1018
 
984
1019
  - regex: '(nuhk|TsolCrawler|Yammybot|Openbot|Gulper Web Bot|grub-client|Download Demon|SearchExpress|Microsoft URL Control|borg|altavista|teoma|blitzbot|oegp|furlbot|http%20client|polybot|htdig|mogimogi|larbin|scrubby|searchsight|seekbot|semanticdiscovery|snappy|vortex|zao|zeal|fast-webcrawler|converacrawler|dataparksearch|findlinks|BrowserMob|HttpMonitor|ThumbShotsBot|URL2PNG|ZooShot|GomezA|Catchpoint bot|Google SketchUp|Read%20Later|Minimo|RackspaceBot)'
985
1020
  name: 'Bot'
@@ -996,4 +1031,4 @@
996
1031
  url: 'http://www.apache.org/foundation/'
997
1032
 
998
1033
  - regex: '[a-z0-9\-_]*(bot|crawler|archiver|transcoder|spider)'
999
- name: 'Generic Bot'
1034
+ name: 'Generic Bot'
@@ -8,6 +8,9 @@
8
8
  - regex: 'NetFront'
9
9
  name: 'NetFront'
10
10
 
11
+ - regex: 'Edge'
12
+ name: 'Edge'
13
+
11
14
  - regex: 'Trident'
12
15
  name: 'Trident'
13
16
 
@@ -24,4 +27,4 @@
24
27
  name: 'Gecko'
25
28
 
26
29
  - regex: 'KHTML'
27
- name: 'KHTML'
30
+ name: 'KHTML'
@@ -5,9 +5,9 @@
5
5
  # @license http://www.gnu.org/licenses/lgpl.html LGPL v3 or later
6
6
  ###############
7
7
 
8
- #newer versions of IE
8
+ # Spartan (newer versions of IE)
9
9
  - regex: 'Edge[ /](\d+[\.\d]+)'
10
- name: 'Internet Explorer'
10
+ name: 'Project Spartan'
11
11
  version: '$1'
12
12
  engine:
13
13
  default: 'Edge'
@@ -422,7 +422,7 @@
422
422
  version: '$1'
423
423
  engine:
424
424
  default: 'Text-based'
425
-
425
+
426
426
  #NCSA Mosaic
427
427
  - regex: 'NCSA_Mosaic(?:/(\d+[\.\d]+))?'
428
428
  name: 'NCSA Mosaic'
@@ -432,7 +432,7 @@
432
432
  - regex: 'ABrowse(?: (\d+[\.\d]+))?'
433
433
  name: 'ABrowse'
434
434
  version: '$1'
435
-
435
+
436
436
  #Amaya
437
437
  - regex: 'amaya(?:/(\d+[\.\d]+))?'
438
438
  name: 'Amaya'
@@ -442,31 +442,31 @@
442
442
  - regex: 'AmigaVoyager(?:/(\d+[\.\d]+))?'
443
443
  name: 'Amiga Voyager'
444
444
  version: '$1'
445
-
445
+
446
446
  #Amiga Aweb
447
447
  - regex: 'Amiga-Aweb(?:/(\d+[\.\d]+))?'
448
448
  name: 'Amiga Aweb'
449
449
  version: '$1'
450
-
450
+
451
451
  #Arora
452
452
  - regex: 'Arora(?:/(\d+[\.\d]+))?'
453
453
  name: 'Arora'
454
454
  version: '$1'
455
455
  engine:
456
456
  default: 'WebKit'
457
-
457
+
458
458
  #Beonex
459
459
  - regex: 'Beonex(?:/(\d+[\.\d]+))?'
460
460
  name: 'Beonex'
461
461
  version: '$1'
462
462
  engine:
463
463
  default: 'Gecko'
464
-
464
+
465
465
  #BlackBerry Browser
466
466
  - regex: 'BlackBerry|PlayBook|BB10'
467
467
  name: 'BlackBerry Browser'
468
468
  version: ''
469
-
469
+
470
470
  #BrowseX
471
471
  - regex: 'BrowseX \((\d+[\.\d]+)'
472
472
  name: 'BrowseX'
@@ -481,7 +481,7 @@
481
481
  - regex: 'Cheshire(?:/(\d+[\.\d]+))?'
482
482
  name: 'Cheshire'
483
483
  version: '$1'
484
-
484
+
485
485
  #Dillo
486
486
  - regex: 'Dillo(?:/(\d+[\.\d]+))?'
487
487
  name: 'Dillo'
@@ -495,52 +495,52 @@
495
495
  version: '$1'
496
496
  engine:
497
497
  default: 'WebKit'
498
-
498
+
499
499
  #Elinks
500
500
  - regex: 'Elinks(?:/(\d+[\.\d]+))?'
501
501
  name: 'Elinks'
502
502
  version: '$1'
503
503
  engine:
504
504
  default: 'Text-based'
505
-
505
+
506
506
  #Firebird
507
507
  - regex: 'Firebird(?:/(\d+[\.\d]+))?'
508
508
  name: 'Firebird'
509
509
  version: '$1'
510
510
  engine:
511
511
  default: 'Gecko'
512
-
512
+
513
513
  #Fluid
514
514
  - regex: 'Fluid(?:/(\d+[\.\d]+))?'
515
515
  name: 'Fluid'
516
516
  version: '$1'
517
517
  engine:
518
518
  default: 'WebKit'
519
-
519
+
520
520
  #Galeon
521
521
  - regex: 'Galeon(?:/(\d+[\.\d]+))?'
522
522
  name: 'Galeon'
523
523
  version: '$1'
524
524
  engine:
525
525
  default: 'Gecko'
526
-
526
+
527
527
  #Google Earth
528
528
  - regex: 'Google Earth(?:/(\d+[\.\d]+))?'
529
529
  name: 'Google Earth'
530
530
  version: '$1'
531
531
  engine:
532
532
  default: 'WebKit'
533
-
533
+
534
534
  #HotJava
535
535
  - regex: 'HotJava(?:/(\d+[\.\d]+))?'
536
536
  name: 'HotJava'
537
537
  version: '$1'
538
-
538
+
539
539
  #IBrowse
540
540
  - regex: 'IBrowse(?:[ /](\d+[\.\d]+))?'
541
541
  name: 'IBrowse'
542
542
  version: '$1'
543
-
543
+
544
544
  #iCab
545
545
  - regex: 'iCab(?:[ /](\d+[\.\d]+))?'
546
546
  name: 'iCab'
@@ -612,19 +612,19 @@
612
612
  version: '$1'
613
613
  engine:
614
614
  default: '' # multi engine
615
-
615
+
616
616
  #Kindle Browser
617
617
  - regex: 'Kindle/(\d+[\.\d]+)'
618
618
  name: 'Kindle Browser'
619
619
  version: '$1'
620
-
620
+
621
621
  #K-meleon
622
622
  - regex: 'K-meleon(?:/(\d+[\.\d]+))?'
623
623
  name: 'K-meleon'
624
624
  version: '$1'
625
625
  engine:
626
626
  default: 'Gecko'
627
-
627
+
628
628
  #Links
629
629
  - regex: 'Links(?: \((\d+[\.\d]+))?'
630
630
  name: 'Links'
@@ -636,19 +636,19 @@
636
636
  - regex: 'UP.Browser(?:/(\d+[\.\d]+))?'
637
637
  name: 'Openwave Mobile Browser'
638
638
  version: '$1'
639
-
639
+
640
640
  #OmniWeb
641
641
  - regex: 'OmniWeb(?:/[v]?(\d+[\.\d]+))?'
642
642
  name: 'OmniWeb'
643
643
  version: '$1'
644
644
  engine:
645
645
  default: 'WebKit'
646
-
646
+
647
647
  #Phoenix
648
648
  - regex: 'Phoenix(?:/(\d+[\.\d]+))?'
649
649
  name: 'Phoenix'
650
650
  version: '$1'
651
-
651
+
652
652
  #Mobile Silk
653
653
  - regex: 'Silk(?:/(\d+[\.\d]+))?'
654
654
  name: 'Mobile Silk'
@@ -677,7 +677,7 @@
677
677
  - regex: '^Nokia|Nokia[EN]?\d+'
678
678
  name: 'Nokia Browser'
679
679
  version: ''
680
-
680
+
681
681
  #NetFront
682
682
  - regex: 'NetFrontLifeBrowser(?:/(\d+[\.\d]+))?'
683
683
  name: 'NetFront Life'
@@ -706,6 +706,11 @@
706
706
  name: 'Obigo'
707
707
  version: ''
708
708
 
709
+ #Odyssey Web Browser
710
+ - regex: 'Odyssey Web Browser(?:.*OWB/(\d+[\.\d]+))?'
711
+ name: 'Odyssey Web Browser'
712
+ version: '$1'
713
+
709
714
  #Off By One
710
715
  - regex: 'OffByOne'
711
716
  name: 'Off By One'
@@ -761,7 +766,7 @@
761
766
  version: ''
762
767
  engine:
763
768
  default: 'WebKit'
764
-
769
+
765
770
  #Safari
766
771
  - regex: '(?:iPod|iPad|iPhone).+Version/(\d+[\.\d]+)'
767
772
  name: 'Mobile Safari'
@@ -783,4 +788,3 @@
783
788
  version: '$1'
784
789
  engine:
785
790
  default: 'WebKit'
786
-
@@ -100,4 +100,3 @@
100
100
  version: '$1'
101
101
  url: 'http://www.rssowl.org/'
102
102
  type: 'Feed Reader'
103
-
@@ -27,4 +27,4 @@
27
27
 
28
28
  - regex: '(?:perlclient|libwww-perl)(?:/?(\d+[\.\d]+))?'
29
29
  name: 'Perl'
30
- version: '$1'
30
+ version: '$1'
@@ -67,4 +67,4 @@
67
67
 
68
68
  - regex: 'stagefright(?:/([\d\.]+))?'
69
69
  name: 'Stagefright'
70
- version: '$1'
70
+ version: '$1'
@@ -29,4 +29,3 @@
29
29
  - regex: '.*__weibo__([0-9\.]+)__'
30
30
  name: 'Sina Weibo'
31
31
  version: '$1'
32
-
@@ -35,4 +35,4 @@
35
35
 
36
36
  - regex: 'The Bat!(?: Voyager)?(?:[/ ](\d+[\.\d]+))?'
37
37
  name: 'The Bat!'
38
- version: '$1'
38
+ version: '$1'
@@ -23,4 +23,4 @@ Samsung:
23
23
  - regex: 'EK-GC200'
24
24
  model: 'GALAXY Camera 2'
25
25
  - regex: 'EK-GC([0-9]{3})'
26
- model: 'GALAXY Camera $1'
26
+ model: 'GALAXY Camera $1'
@@ -10,4 +10,3 @@ Tesla:
10
10
  regex: 'QtCarBrowser'
11
11
  device: 'car browser'
12
12
  model: 'Model S'
13
-
@@ -38,4 +38,3 @@ Sony:
38
38
  regex: 'PlayStation (3|4|Portable|Vita)'
39
39
  device: 'console'
40
40
  model: 'PlayStation $1'
41
-
@@ -74,6 +74,9 @@ HTC:
74
74
  - regex: 'HTC[ _\-]((?:Flyer|P715a).*) Build'
75
75
  device: 'tablet'
76
76
  model: '$1'
77
+ - regex: 'HTC[ _\-]One[ _\-]max Build'
78
+ device: 'phablet'
79
+ model: 'One max'
77
80
  - regex: 'HTC[ _]([^/;]+) [0-9]+(?:\.[0-9]+)+ Build'
78
81
  model: '$1'
79
82
  - regex: 'HTC[ _]([^/;]+) Build'
@@ -115,6 +118,9 @@ Nokia:
115
118
  model: '$1'
116
119
  - regex: 'NOKIA/([a-z0-9 ]+)'
117
120
  model: '$1'
121
+ - regex: '(Lumia [a-z0-9\-]+ XL)'
122
+ device: 'phablet'
123
+ model: '$1'
118
124
  - regex: '(Lumia [a-z0-9\-]+)'
119
125
  model: '$1'
120
126
  - regex: 'Maemo RX-51 ([a-z0-9]+)'
@@ -231,7 +237,7 @@ Apple:
231
237
  device: 'smartphone'
232
238
  - regex: '(?:Apple-)?iPhone7[C,]1'
233
239
  model: 'iPhone 6 Plus'
234
- device: 'smartphone'
240
+ device: 'phablet'
235
241
  - regex: '(?:Apple-)?iPhone7[C,]2'
236
242
  model: 'iPhone 6'
237
243
  device: 'smartphone'
@@ -411,7 +417,7 @@ Arnova:
411
417
 
412
418
  # Asus
413
419
  Asus:
414
- regex: 'Asus|Transformer|TF300T|Slider SL101|PadFone|ME302(?:C|KL)|ME301T|ME371MG|ME17(?:1|2V|3X)|K00[0-9a-z] Build'
420
+ regex: 'Asus|Transformer|TF300T|Slider SL101|PadFone|ME302(?:C|KL)|ME301T|ME371MG|ME17(?:1|2V|3X)|K0[01][0-9a-z] Build'
415
421
  device: 'smartphone'
416
422
  models:
417
423
  # explicit tablet models
@@ -430,33 +436,33 @@ Asus:
430
436
  - regex: 'ME301T Build'
431
437
  model: 'MeMO Pad Smart 10'
432
438
  device: 'tablet'
433
- - regex: 'ME371MG Build'
434
- model: 'Fonepad'
439
+ - regex: 'K01[3A] Build'
440
+ model: 'MeMO Pad 7'
435
441
  device: 'tablet'
436
442
  - regex: 'K00U|ME173X Build'
437
443
  model: 'MeMO Pad HD 7'
438
444
  device: 'tablet'
439
- - regex: 'K00L Build'
445
+ - regex: '(?:K011|K00L) Build'
440
446
  model: 'MeMO Pad 8'
441
447
  device: 'tablet'
448
+ - regex: 'K014 Build'
449
+ model: 'MeMO Pad 8.9'
450
+ device: 'tablet'
442
451
  - regex: 'K00S Build'
443
452
  model: 'MeMO Pad HD 7 Dual SIM'
444
453
  device: 'tablet'
445
- - regex: 'K00E Build'
446
- model: 'Fonepad 7'
447
- device: 'tablet'
448
- - regex: 'K00Z Build'
449
- model: 'Fonepad 7 Dual SIM'
450
- device: 'tablet'
451
454
  - regex: 'K00F Build'
452
455
  model: 'MeMO Pad 10'
453
456
  device: 'tablet'
454
- - regex: 'K00G Build'
455
- model: 'Fonepad Note 6'
456
- device: 'tablet'
457
457
  - regex: 'K00C Build'
458
458
  model: 'Transformer Pad TF701T'
459
459
  device: 'tablet'
460
+ - regex: 'K010 Build'
461
+ model: 'Transformer Pad TF103C'
462
+ device: 'tablet'
463
+ - regex: 'K018 Build'
464
+ model: 'Transformer Pad TF103CG'
465
+ device: 'tablet'
460
466
  - regex: 'TF300T Build'
461
467
  model: 'Transformer Pad TF300T'
462
468
  device: 'tablet'
@@ -464,6 +470,24 @@ Asus:
464
470
  model: 'Eee Pad Slider SL101'
465
471
  device: 'tablet'
466
472
 
473
+ # explicit phablet models
474
+ - regex: 'ME371MG Build'
475
+ model: 'Fonepad'
476
+ device: 'phablet'
477
+ - regex: 'K00G Build'
478
+ model: 'Fonepad Note 6'
479
+ device: 'phablet'
480
+ - regex: '(?:K012|K00E) Build'
481
+ model: 'Fonepad 7'
482
+ device: 'phablet'
483
+ - regex: 'K00Z Build'
484
+ model: 'Fonepad 7 Dual SIM'
485
+ device: 'phablet'
486
+ - regex: 'K016 Build'
487
+ model: 'Fonepad 8'
488
+ device: 'phablet'
489
+
490
+
467
491
  # explicit smartphone models
468
492
  - regex: '(?:ASUS_)?T00[IQ]'
469
493
  model: 'ZenFone 4'
@@ -576,10 +600,10 @@ Bmobile:
576
600
 
577
601
  # bq
578
602
  bq:
579
- regex: 'bq [^/;]+ Build'
603
+ regex: 'Aquaris|bq [^/;]+ Build'
580
604
  device: 'tablet'
581
605
  models:
582
- - regex: 'bq (Aquaris[^/;]*) Build'
606
+ - regex: '(?:bq )?(Aquaris[^/;]*) Build'
583
607
  model: '$1'
584
608
  device: 'smartphone'
585
609
  - regex: 'bq ([^/;]+) Build'
@@ -591,6 +615,18 @@ Capitel:
591
615
  device: 'feature phone'
592
616
  model: '$1'
593
617
 
618
+ # Casio
619
+ Casio:
620
+ regex: '(C811|C7[57]1)(?: 4G)? Build'
621
+ device: 'smartphone'
622
+ models:
623
+ - regex: 'C751 Build'
624
+ model: "G'zOne Ravine"
625
+ - regex: 'C771 Build'
626
+ model: "G'zOne Commando"
627
+ - regex: 'C811 4G Build'
628
+ model: "G'zOne Commando 4G LTE"
629
+
594
630
  # Cat
595
631
  Cat:
596
632
  regex: 'Cat ?(tablet|stargate|nova)'
@@ -696,11 +732,11 @@ Denver:
696
732
 
697
733
  # Dell
698
734
  Dell:
699
- regex: 'Dell'
735
+ regex: 'Dell|Venue'
700
736
  device: 'smartphone'
701
737
  models:
702
- - regex: 'Dell ((?:Streak|Venue)[^/;]*) Build'
703
- model: '$1'
738
+ - regex: '(?:Dell )?(Streak|Venue) ?([^/;]*) Build'
739
+ model: '$1 $2'
704
740
  device: 'tablet'
705
741
  - regex: 'Dell; ((?:Streak|Venue)[^;/\)]*)'
706
742
  model: '$1'
@@ -768,6 +804,20 @@ Easypix:
768
804
  model: '$1'
769
805
  device: 'tablet'
770
806
 
807
+ # ECS
808
+ ECS:
809
+ regex: '(?:TA10CA3|TM105A?|TR10CS1) Build'
810
+ device: 'tablet'
811
+ models:
812
+ - regex: 'TA10CA3 Build'
813
+ model: 'TA10CA3'
814
+ - regex: 'TR10CS1 Build'
815
+ model: 'TR10CS1'
816
+ - regex: 'TM105A Build'
817
+ model: 'TM105A'
818
+ - regex: 'TM105 Build'
819
+ model: 'TM105'
820
+
771
821
  # Ericy
772
822
  Ericy:
773
823
  regex: 'Ericy-([a-z0-9]+)'
@@ -782,7 +832,7 @@ Rikomagic:
782
832
 
783
833
  # Sony & Sony Ericsson (combined as they are mixed up)
784
834
  Sony:
785
- regex: 'Sony(?: ?Ericsson)?|SGP|Xperia|C1[569]0[45]|C2[01]0[45]|C2305|C530[236]|C5502|C6[56]0[236]|C6616|C68(?:0[26]|[34]3)|C69(?:0[236]|16|43)|D200[45]|D21(?:0[45]|14)|D22(?:0[236]|12|43)|D230[2356]|D240[36]|D25(?:02|33)|D510[236]|D530[36]|D5322|D5503|D58[03]3|D65(?:0[23]|43)|D66[05]3|(?:WT|LT|SO|ST|SK|MK)[0-9]+[a-z]*[0-9]*(?: Build|\))|X?L39H|portalmmm/2\.0 K|X10[ia]v?|E1[05][ai]v?|MT[0-9]{2}[a-z]? Build|SO-0(?:[35]D|4E|[12]C)|R800[aix]'
835
+ regex: 'Sony(?: ?Ericsson)?|SGP|Xperia|C1[569]0[45]|C2[01]0[45]|C2305|C530[236]|C5502|C6[56]0[236]|C6616|C68(?:0[26]|[34]3)|C69(?:0[236]|16|43)|D200[45]|D21(?:0[45]|14)|D22(?:0[236]|12|43)|D230[2356]|D240[36]|D25(?:02|33)|D510[236]|D530[36]|D5322|D5503|D58[03]3|D65(?:0[23]|43)|D66[05]3|(?:WT|LT|SO|ST|SK|MK)[0-9]+[a-z]*[0-9]*(?: Build|\))|X?L39H|portalmmm/2\.0 K|X10[ia]v?|E1[05][ai]v?|MT[0-9]{2}[a-z]? Build|SO-0(?:[345]D|[234]E|[12]C|[1235]F|[12]G)|R800[aix]'
786
836
  device: 'smartphone'
787
837
  models:
788
838
  # SONY ERICSSON: explicit smartphone models
@@ -957,11 +1007,12 @@ Sony:
957
1007
  model: 'Xperia ZR'
958
1008
  - regex: '(?:Sony(?:Ericsson)?)?C650[236]'
959
1009
  model: 'Xperia ZL'
960
- - regex: '(?:Sony(?:Ericsson)?)?C66(?:0[236]|16)'
1010
+ - regex: '(?:Sony(?:Ericsson)?)?(?:C66(?:0[236]|16)|SO-02E)'
961
1011
  model: 'Xperia Z'
962
1012
  - regex: '(?:Sony(?:Ericsson)?)?(?:C68(?:0[26]|[34]3)|XL39H)'
1013
+ device: 'phablet'
963
1014
  model: 'Xperia Z Ultra'
964
- - regex: '(?:Sony(?:Ericsson)?)?C69(?:0[236]|16|43)|L39H'
1015
+ - regex: '(?:Sony(?:Ericsson)?)?(?:C69(?:0[236]|16|43)|L39H|SO-0[12]F)'
965
1016
  model: 'Xperia Z1'
966
1017
  - regex: '(?:Sony(?:Ericsson)?)?D200[45]'
967
1018
  model: 'Xperia E1'
@@ -989,22 +1040,24 @@ Sony:
989
1040
  model: 'Xperia T2 Ultra Dual'
990
1041
  - regex: '(?:Sony(?:Ericsson)?)?D5503'
991
1042
  model: 'Xperia Z1 Compact'
992
- - regex: '(?:Sony(?:Ericsson)?)?D58[03]3'
1043
+ - regex: '(?:Sony(?:Ericsson)?)?(?:D58[03]3|SO-02G)'
993
1044
  model: 'Xperia Z3 Compact'
994
- - regex: '(?:Sony(?:Ericsson)?)?D65(?:0[23]|43)'
1045
+ - regex: '(?:Sony(?:Ericsson)?)?(?:D65(?:0[23]|43)|SO-03F)'
995
1046
  model: 'Xperia Z2'
996
- - regex: '(?:Sony(?:Ericsson)?)?D66[05]3'
1047
+ - regex: '(?:Sony(?:Ericsson)?)?(?:D66[05]3|SO-01G)'
997
1048
  model: 'Xperia Z3'
998
1049
  - regex: '(?:Sony(?:Ericsson)?)?SO-04E'
999
1050
  model: 'Xperia A'
1051
+ - regex: '(?:Sony(?:Ericsson)?)?SO-04D'
1052
+ model: 'Xperia GX'
1000
1053
  - regex: '(?:Sony(?:Ericsson)?)?SO-05D'
1001
1054
  model: 'Xperia SX'
1002
1055
 
1003
1056
  # SONY: explicit tablet models
1004
- - regex: 'SGP(?:311|312|321) Build'
1057
+ - regex: 'SGP(?:311|312|321) Build|SO-03E'
1005
1058
  model: 'Xperia Tablet Z'
1006
1059
  device: 'tablet'
1007
- - regex: 'SGP(?:511|512|521) Build'
1060
+ - regex: 'SGP(?:511|512|521) Build|SO-05F'
1008
1061
  model: 'Xperia Tablet Z2'
1009
1062
  device: 'tablet'
1010
1063
  - regex: 'SGP(?:6[24]1) Build'
@@ -1095,6 +1148,33 @@ Ezio:
1095
1148
  device: 'feature phone'
1096
1149
  model: '$1'
1097
1150
 
1151
+ # Fujitsu
1152
+ Fujitsu:
1153
+ regex: 'F-01F|F-02[EF]|F-05[DE]|F-06E|F-08D|F-09E'
1154
+ device: 'smartphone'
1155
+ models:
1156
+ - regex: 'F-01F'
1157
+ model: 'Arrows NX F-01F'
1158
+ - regex: 'F-02E'
1159
+ model: 'Arrows X F-02E'
1160
+ - regex: 'F-05D'
1161
+ model: 'Arrows X LTE F-05D'
1162
+ - regex: 'F-06E'
1163
+ model: 'Arrows NX F-06E'
1164
+ - regex: 'F-08D'
1165
+ model: 'F-08D Disney Mobile'
1166
+ - regex: 'F-09E'
1167
+ model: 'Raku-Raku Smartphone Premium F-09E'
1168
+ - regex: 'F-12C'
1169
+ model: 'F-12C'
1170
+
1171
+ - regex: 'F-02F'
1172
+ model: 'Arrows Tab F-02F'
1173
+ device: 'tablet'
1174
+ - regex: 'F-05E'
1175
+ model: 'Arrows Tab F-05E'
1176
+ device: 'tablet'
1177
+
1098
1178
  # Gemini
1099
1179
  Gemini:
1100
1180
  regex: '(GEM[0-9]+[a-z]*)'
@@ -1139,7 +1219,10 @@ Google:
1139
1219
  model: 'Glass'
1140
1220
  - regex: 'Galaxy Nexus'
1141
1221
  model: 'Galaxy Nexus'
1142
- - regex: '(Nexus (?:S|4|5|6|One))'
1222
+ - regex: '(Nexus (?:S|4|5|One))'
1223
+ model: '$1'
1224
+ - regex: '(Nexus (?:6))'
1225
+ device: 'phablet'
1143
1226
  model: '$1'
1144
1227
  - regex: '(Nexus (?:7|9|10))'
1145
1228
  device: 'tablet'
@@ -1215,6 +1298,9 @@ Huawei:
1215
1298
  model: '$1'
1216
1299
  - regex: 'Ideos([^;/]*) Build'
1217
1300
  model: 'Ideos$1'
1301
+ - regex: 'HUAWEI MT([0-9]+)'
1302
+ device: 'phablet'
1303
+ model: 'Ascend Mate $1'
1218
1304
  - regex: 'Huawei[ _\-]?([^/;]*) Build'
1219
1305
  model: '$1'
1220
1306
  - regex: '(?:HW-)?Huawei(?:/1\.0/0?(?:Huawei))?[_\- /]?([a-z0-9\-_]+)'
@@ -1224,6 +1310,14 @@ Huawei:
1224
1310
  - regex: 'vodafone([a-z0-9]+)'
1225
1311
  model: 'Vodafone $1'
1226
1312
 
1313
+ # Hyundai
1314
+ Hyundai:
1315
+ regex: 'Hyundai'
1316
+ device: 'tablet'
1317
+ models:
1318
+ - regex: 'Hyundai ([^;/]+) Build'
1319
+ model: '$1'
1320
+
1227
1321
  # iBall
1228
1322
  iBall:
1229
1323
  regex: 'iBall[ _]([^/;]*)[ _]Build'
@@ -1423,6 +1517,20 @@ LCT:
1423
1517
  device: 'feature phone'
1424
1518
  model: '$1'
1425
1519
 
1520
+ # Le Pan
1521
+ 'Le Pan':
1522
+ regex: 'Le ?Pan|TC970 ([^;/]+)Build'
1523
+ device: 'tablet'
1524
+ models:
1525
+ - regex: 'TC802A'
1526
+ model: 'Le Pan Mini'
1527
+ - regex: 'TC970 ([^;/]+)Build'
1528
+ model: 'TC970 $1'
1529
+ - regex: 'Le ?Pan ?(II|S) Build'
1530
+ model: 'Le Pan $1'
1531
+ - regex: 'Le ?Pan ?([^;/]+) Build'
1532
+ model: '$1'
1533
+
1426
1534
  # lenco
1427
1535
  Lenco:
1428
1536
  regex: 'Lenco ([^/;]*) Build'
@@ -1501,9 +1609,17 @@ Lexibook:
1501
1609
 
1502
1610
  # lg
1503
1611
  LG:
1504
- regex: 'LG|portalmmm/2\.0 (?:KE|KG|KP|L3)|VX[0-9]+'
1612
+ regex: 'LG|portalmmm/2\.0 (?:KE|KG|KP|L3)|VX[0-9]+|L-01D|L-07C'
1505
1613
  device: 'smartphone'
1506
1614
  models:
1615
+ - regex: 'L-01D'
1616
+ model: 'Optimus LTE L-01D'
1617
+ - regex: 'L-07C'
1618
+ model: 'Optimus Bright L-07C'
1619
+
1620
+ - regex: 'LGE_DLNA_SDK|NetCast'
1621
+ device: 'tv'
1622
+ model: 'NetCast'
1507
1623
  - regex: 'LGE(?: |-LG| LG-AX|-)([a-z0-9]+)'
1508
1624
  model: '$1'
1509
1625
  - regex: 'LGE;([a-z0-9\-]+)'
@@ -2082,8 +2198,6 @@ Samsung:
2082
2198
  model: 'GALAXY S II Plus'
2083
2199
  - regex: '(?:SAMSUNG-)?(?:GT-I9195|SCH-I435)'
2084
2200
  model: 'GALAXY S4 mini'
2085
- - regex: '(?:SAMSUNG-)?GT-I9205'
2086
- model: 'GALAXY MEGA'
2087
2201
  - regex: '(?:SAMSUNG-)?GT-I9295'
2088
2202
  model: 'GALAXY S4 ACTIVE'
2089
2203
  - regex: '(?:SAMSUNG-)?(?:GT-I9300|SCH-I535|SCH-L710)'
@@ -2094,10 +2208,6 @@ Samsung:
2094
2208
  model: 'GALAXY S4'
2095
2209
  - regex: '(?:SAMSUNG-)?GT-I9506'
2096
2210
  model: 'GALAXY S4 with LTE+'
2097
- - regex: '(?:SAMSUNG-)?(?:(?:GT-)?N7100|SCH-I605|SCH-N719|SCH-R950|SPH-L900)'
2098
- model: 'GALAXY Note II'
2099
- - regex: '(?:SAMSUNG-)?GT-N7105'
2100
- model: 'GALAXY Note II LTE'
2101
2211
  - regex: '(?:SAMSUNG-)?GT-S5280'
2102
2212
  model: 'GALAXY STAR'
2103
2213
  - regex: '(?:SAMSUNG-)?GT-S5301'
@@ -2148,14 +2258,6 @@ Samsung:
2148
2258
  model: 'GALAXY S5 Dual-SIM'
2149
2259
  - regex: '(?:SAMSUNG-)?SM-G900'
2150
2260
  model: 'GALAXY S5'
2151
- - regex: '(?:SAMSUNG-)?SM-N7502'
2152
- model: 'GALAXY Note 3 Neo Duos'
2153
- - regex: '(?:SAMSUNG-)?SM-N750[L50]?'
2154
- model: 'GALAXY Note 3 Neo'
2155
- - regex: '(?:SAMSUNG-)?SM-N9002'
2156
- model: 'GALAXY Note 3 Duos'
2157
- - regex: '(?:SAMSUNG-)?SM-N900(?:[05689][VQ]?|[AKLPSTV]|W8)?'
2158
- model: 'GALAXY Note 3'
2159
2261
  - regex: '(?:SAMSUNG-)?SCH-I200'
2160
2262
  model: 'GALAXY Stellar'
2161
2263
  - regex: '(?:SAMSUNG-)?SCH-I829'
@@ -2166,12 +2268,41 @@ Samsung:
2166
2268
  model: 'GALAXY Centura'
2167
2269
 
2168
2270
  # explicit phablet models
2271
+ - regex: '(?:SAMSUNG-)?(?:(?:GT-)?N7100|SCH-I605|SCH-N719|SCH-R950|SPH-L900)'
2272
+ model: 'GALAXY Note II'
2273
+ device: 'phablet'
2274
+ - regex: '(?:SAMSUNG-)?GT-N7105'
2275
+ model: 'GALAXY Note II LTE'
2276
+ device: 'phablet'
2277
+ - regex: '(?:SAMSUNG-)?SM-N7502'
2278
+ model: 'GALAXY Note 3 Neo Duos'
2279
+ device: 'phablet'
2280
+ - regex: '(?:SAMSUNG-)?SM-N750[L50]?'
2281
+ model: 'GALAXY Note 3 Neo'
2282
+ device: 'phablet'
2283
+ - regex: '(?:SAMSUNG-)?SM-N9002'
2284
+ model: 'GALAXY Note 3 Duos'
2285
+ device: 'phablet'
2286
+ - regex: '(?:SAMSUNG-)?SM-N900(?:[05689][VQ]?|[AKLPSTV]|W8)?'
2287
+ model: 'GALAXY Note 3'
2288
+ device: 'phablet'
2169
2289
  - regex: '(?:SAMSUNG-)?SM-N910'
2170
2290
  model: 'GALAXY Note 4'
2171
2291
  device: 'phablet'
2172
2292
  - regex: '(?:SAMSUNG-)?SM-N915'
2173
2293
  model: 'GALAXY Note 4 Edge'
2174
2294
  device: 'phablet'
2295
+ - regex: '(?:SAMSUNG-)?GT-I915[028]'
2296
+ model: 'GALAXY Mega 5.8'
2297
+ device: 'phablet'
2298
+ - regex: '(?:SAMSUNG-)?GT-I920[05]'
2299
+ model: 'GALAXY Mega 6.3'
2300
+ device: 'phablet'
2301
+
2302
+ # explicit feature phones
2303
+ - regex: '(?:SAMSUNG-)?GT-E2152'
2304
+ model: 'E2152'
2305
+ device: 'feature phone'
2175
2306
 
2176
2307
  # general detections
2177
2308
  - regex: '(?:SAMSUNG-)?(GT-(P|N8|N5)[0-9]+[a-z]?)'
@@ -2181,6 +2312,7 @@ Samsung:
2181
2312
  model: 'GALAXY S II'
2182
2313
  - regex: 'SC-01F'
2183
2314
  model: 'GALAXY Note 3'
2315
+ device: 'phablet'
2184
2316
  - regex: 'SC-04E'
2185
2317
  model: 'GALAXY S4'
2186
2318
  - regex: '(?:SAMSUNG-)?((?:SM-[TNP]|GT-P)[a-z0-9_\-]+)'
@@ -2441,16 +2573,16 @@ Softbank:
2441
2573
 
2442
2574
  # Kindle
2443
2575
  Kindle:
2444
- regex: 'KF(?:OT|TT|JWI|JWA|SOWI|APWI|THWI) Build|Kindle|Silk/\d+\.\d+'
2576
+ regex: 'KF(?:OT|TT|JWI|JWA|SOWI|APWI|THWI) Build|Kindle|Silk/\d+\.\d+|Amazon (?:Tate|Jem)'
2445
2577
  device: 'tablet'
2446
2578
  models:
2447
2579
  - regex: 'KFTT Build'
2448
2580
  model: 'Kindle Fire HD'
2449
- - regex: 'KFJWI Build'
2581
+ - regex: 'KFJWI Build|Amazon Jem'
2450
2582
  model: 'Kindle Fire HD 8.9" WiFi'
2451
2583
  - regex: 'KFJWA Build'
2452
2584
  model: 'Kindle Fire HD 8.9" 4G'
2453
- - regex: 'KFSOWI Build'
2585
+ - regex: 'KFSOWI Build|Amazon Tate'
2454
2586
  model: 'Kindle Fire HD 7" WiFi'
2455
2587
  - regex: 'KFTHWI Build'
2456
2588
  model: 'Kindle Fire HDX 7" WiFi'
@@ -2503,6 +2635,12 @@ Tecno Mobile:
2503
2635
  - regex: 'Tecno_?([a-z0-9_\-]+)'
2504
2636
  model: '$1'
2505
2637
 
2638
+ # Tesco
2639
+ Tesco:
2640
+ regex: 'Hudl ([^/;]+) Build'
2641
+ device: 'tablet'
2642
+ model: 'Hudl $1'
2643
+
2506
2644
  # teXet
2507
2645
  teXet:
2508
2646
  regex: '(NaviPad [^/;]*) Build'
@@ -2665,9 +2803,16 @@ Woxter:
2665
2803
 
2666
2804
  #Xiaomi
2667
2805
  Xiaomi:
2668
- regex: '(MI [a-z0-9]+|MI-One[ _]Plus) Build'
2806
+ regex: '(MI [a-z0-9]+|MI-One[ _]Plus) Build|HM ([^/;]+) Build'
2669
2807
  device: 'smartphone'
2670
- model: '$1'
2808
+ models:
2809
+ - regex: '(MI [a-z0-9]+|MI-One[ _]Plus) Build'
2810
+ model: '$1'
2811
+ - regex: 'HM Note ([^/;]+) Build'
2812
+ device: 'tablet'
2813
+ model: 'HM Note $1'
2814
+ - regex: 'HM ([^/;]+) Build'
2815
+ model: 'HM $1'
2671
2816
 
2672
2817
  #Yuandao
2673
2818
  Yuandao:
@@ -2749,4 +2894,3 @@ ZTE:
2749
2894
  #Nokia:
2750
2895
  # regex: 'Symbian'
2751
2896
  # device: 'feature phone'
2752
-