device_detector 0.9.1 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +49 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +5 -9
  5. data/CHANGELOG.md +16 -3
  6. data/README.md +7 -9
  7. data/Rakefile +19 -13
  8. data/device_detector.gemspec +1 -0
  9. data/lib/device_detector.rb +32 -28
  10. data/lib/device_detector/bot.rb +2 -2
  11. data/lib/device_detector/client.rb +3 -2
  12. data/lib/device_detector/device.rb +44 -21
  13. data/lib/device_detector/memory_cache.rb +26 -19
  14. data/lib/device_detector/metadata_extractor.rb +7 -8
  15. data/lib/device_detector/model_extractor.rb +3 -3
  16. data/lib/device_detector/name_extractor.rb +2 -2
  17. data/lib/device_detector/os.rb +121 -111
  18. data/lib/device_detector/parser.rb +22 -9
  19. data/lib/device_detector/version.rb +3 -1
  20. data/lib/device_detector/version_extractor.rb +2 -3
  21. data/regexes/bots.yml +840 -20
  22. data/regexes/client/browser_engine.yml +11 -2
  23. data/regexes/client/browsers.yml +909 -108
  24. data/regexes/client/feed_readers.yml +38 -2
  25. data/regexes/client/libraries.yml +76 -2
  26. data/regexes/client/mediaplayers.yml +25 -5
  27. data/regexes/client/mobile_apps.yml +167 -2
  28. data/regexes/client/pim.yml +10 -1
  29. data/regexes/device/cameras.yml +1 -1
  30. data/regexes/device/car_browsers.yml +7 -3
  31. data/regexes/device/consoles.yml +3 -3
  32. data/regexes/device/mobiles.yml +10123 -465
  33. data/regexes/device/portable_media_player.yml +4 -6
  34. data/regexes/device/televisions.yml +18 -4
  35. data/regexes/oss.yml +115 -21
  36. data/regexes/vendorfragments.yml +6 -2
  37. data/spec/device_detector/concrete_user_agent_spec.rb +16 -17
  38. data/spec/device_detector/detector_fixtures_spec.rb +51 -11
  39. data/spec/device_detector/device_spec.rb +28 -48
  40. data/spec/device_detector/memory_cache_spec.rb +60 -28
  41. data/spec/device_detector/model_extractor_spec.rb +3 -3
  42. data/spec/device_detector/version_extractor_spec.rb +5 -6
  43. data/spec/device_detector_spec.rb +60 -69
  44. data/spec/fixtures/client/browser.yml +1785 -262
  45. data/spec/fixtures/client/feed_reader.yml +47 -35
  46. data/spec/fixtures/client/library.yml +112 -3
  47. data/spec/fixtures/client/mediaplayer.yml +32 -37
  48. data/spec/fixtures/client/mobile_app.yml +193 -6
  49. data/spec/fixtures/client/pim.yml +37 -18
  50. data/spec/fixtures/detector/bots.yml +1426 -118
  51. data/spec/fixtures/detector/camera.yml +36 -10
  52. data/spec/fixtures/detector/car_browser.yml +64 -3
  53. data/spec/fixtures/detector/console.yml +80 -26
  54. data/spec/fixtures/detector/desktop.yml +2222 -1589
  55. data/spec/fixtures/detector/feature_phone.yml +151 -42
  56. data/spec/fixtures/detector/feed_reader.yml +186 -121
  57. data/spec/fixtures/detector/mediaplayer.yml +113 -39
  58. data/spec/fixtures/detector/mobile_apps.yml +366 -21
  59. data/spec/fixtures/detector/phablet.yml +2597 -570
  60. data/spec/fixtures/detector/portable_media_player.yml +41 -16
  61. data/spec/fixtures/detector/smart_display.yml +8 -5
  62. data/spec/fixtures/detector/smart_speaker.yml +55 -0
  63. data/spec/fixtures/detector/smartphone-1.yml +5468 -5010
  64. data/spec/fixtures/detector/smartphone-10.yml +9977 -0
  65. data/spec/fixtures/detector/smartphone-11.yml +9891 -0
  66. data/spec/fixtures/detector/smartphone-12.yml +9906 -0
  67. data/spec/fixtures/detector/smartphone-13.yml +9920 -0
  68. data/spec/fixtures/detector/smartphone-14.yml +2662 -0
  69. data/spec/fixtures/detector/smartphone-2.yml +5213 -4635
  70. data/spec/fixtures/detector/smartphone-3.yml +5082 -4533
  71. data/spec/fixtures/detector/smartphone-4.yml +6806 -2625
  72. data/spec/fixtures/detector/smartphone-5.yml +9914 -0
  73. data/spec/fixtures/detector/smartphone-6.yml +9962 -0
  74. data/spec/fixtures/detector/smartphone-7.yml +9899 -0
  75. data/spec/fixtures/detector/smartphone-8.yml +9931 -0
  76. data/spec/fixtures/detector/smartphone-9.yml +9899 -0
  77. data/spec/fixtures/detector/smartphone.yml +5225 -4652
  78. data/spec/fixtures/detector/tablet-1.yml +4691 -4191
  79. data/spec/fixtures/detector/tablet-2.yml +9800 -71
  80. data/spec/fixtures/detector/tablet-3.yml +9959 -0
  81. data/spec/fixtures/detector/tablet-4.yml +4528 -0
  82. data/spec/fixtures/detector/tablet.yml +4664 -4177
  83. data/spec/fixtures/detector/tv.yml +3399 -1048
  84. data/spec/fixtures/detector/unknown.yml +1017 -977
  85. data/spec/fixtures/detector/wearable.yml +61 -0
  86. data/spec/fixtures/device/camera.yml +4 -3
  87. data/spec/fixtures/device/car_browser.yml +9 -2
  88. data/spec/fixtures/device/console.yml +15 -14
  89. data/spec/fixtures/parser/oss.yml +284 -2
  90. data/spec/fixtures/parser/vendorfragments.yml +8 -2
  91. metadata +50 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 09c952f196436a80a8fd715b5e288150a5c57b60
4
- data.tar.gz: 6d76a5d6205fc496dce0620b9ba9a61d7b701c56
2
+ SHA256:
3
+ metadata.gz: 5b73863bdb837708cf4e4e202747535e275823acbf14abf506174717980763bb
4
+ data.tar.gz: dad905ef5c510e73f3c5450d65ee231eff9c2a6815af171124081eaa380c26a4
5
5
  SHA512:
6
- metadata.gz: 57244e7078da923413102dade915b10b8b0e3287d3f3b41fd111302ee48d64713295d11a5f68a0f6e7cc5faf623b0caf773094eca5e44349d3b388e07b402f61
7
- data.tar.gz: bc96dae6295d954e8b40ba1591c6bd1049b1e64f3aa853fda10c99c5d79a59e3db947feecd3f23466a151e13a2d02f898c6980e37c08e696adcaf83e86e4e14f
6
+ metadata.gz: e738d06e2ce209367d4783d84480078ea0c44bac8e6cfc563a01af4257d85de109fc1f4be66d67feb0d64800905eb59c4604e9d5bb6f7d3d4645ddafa849d3e0
7
+ data.tar.gz: de39db15cb9ab997ee2c362cda93cd29876d06ac913f6aba283d90c164599d43d7c53ea39c003964fe1e3f1cd83440d95d22c72202b2a7396912689c1c233e87
@@ -0,0 +1,49 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+ Exclude:
4
+ - 'db/schema.rb'
5
+ - 'Gemfile'
6
+ - 'bin/'
7
+ Style/Documentation:
8
+ Enabled: false
9
+ Style/EmptyMethod:
10
+ EnforcedStyle: expanded
11
+ Style/HashEachMethods:
12
+ Enabled: true
13
+ Style/HashTransformKeys:
14
+ Enabled: true
15
+ Style/HashTransformValues:
16
+ Enabled: true
17
+ Style/RedundantRegexpCharacterClass:
18
+ Enabled: true
19
+ Style/RedundantRegexpEscape:
20
+ Enabled: true
21
+ Style/StructInheritance:
22
+ Enabled: false
23
+ Style/ExponentialNotation:
24
+ Enabled: true
25
+ Style/SlicingWithRange:
26
+ Enabled: true
27
+ Layout/EmptyLinesAroundAttributeAccessor:
28
+ Enabled: true
29
+ Layout/LineLength:
30
+ Max: 100
31
+ Layout/SpaceAroundMethodCallOperator:
32
+ Enabled: true
33
+ Metrics/MethodLength:
34
+ Max: 15
35
+ Metrics/BlockLength:
36
+ Exclude:
37
+ - 'Rakefile'
38
+ - '**/*.rake'
39
+ - 'spec/**/*.rb'
40
+ Lint/DeprecatedOpenSSLConstant:
41
+ Enabled: true
42
+ Lint/MixedRegexpCaptureTypes:
43
+ Enabled: true
44
+ Lint/RedundantCopDisableDirective:
45
+ Enabled: false
46
+ Lint/RaiseException:
47
+ Enabled: true
48
+ Lint/StructNewOverride:
49
+ Enabled: true
@@ -0,0 +1 @@
1
+ 2.6.6
@@ -1,18 +1,14 @@
1
1
  language: ruby
2
- sudo: false
2
+ dist: bionic
3
3
  rvm:
4
- - 1.9.3
5
- - 2.0.0-p648
6
- - 2.1.10
7
- - 2.2.5
8
- - 2.3.1
9
- - ruby-head
10
- - rbx-2
4
+ - 2.4
5
+ - 2.5
6
+ - 2.6
11
7
  before_install:
12
8
  - gem update --system
13
9
  - gem --version
14
10
  - gem update bundler
15
- - bundler --version
11
+ - bundle --version
16
12
  cache: bundler
17
13
  script:
18
14
  bundle exec rake test
@@ -1,7 +1,21 @@
1
1
  # Change Log
2
2
 
3
- ## [0.9.1]
4
- - Removed regexp warnings in Ruby 2.2.4+. Thanks to [mkdynamic](https://github.com/mkdynamic)
3
+ ## [1.0.4]
4
+ - Updated detection rules from upstream on 2020-06-23
5
+ - [Issue #69](https://github.com/podigee/device_detector/issues/69): Performance: RegExp definitions are only loaded once.
6
+ - [Issue #74](https://github.com/podigee/device_detector/issues/74): Development: Added Rubocop
7
+
8
+ ## [1.0.3]
9
+ - Updated detection rules from upstream on 2019-12-09
10
+
11
+ ## [1.0.2]
12
+ - Updated detection rules from upstream on 2019-08-05
13
+
14
+ ## [1.0.1]
15
+ - Updated detection rules from upstream on 2018-04-27
16
+
17
+ ## [1.0.0]
18
+ - Boom! The 1.0.0 has landed :)
5
19
 
6
20
  ## [0.9.0]
7
21
  - Preparing for the 1.0.0 release. This version (with minor bumps) will be promoted to 1.0.0 once the release has been proven stable
@@ -37,4 +51,3 @@
37
51
  - Added rake task for automatic generation of supported and detectable clients and devices
38
52
  - Updated detection rules
39
53
  - Fixed device type detection, when type is specified on top level of a nested regex
40
-
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # DeviceDetector
2
2
 
3
- ![Podigee DeviceDetector Travisci Badge](https://travis-ci.org/podigee/device_detector.svg)
3
+ [![Build Status](https://travis-ci.org/podigee/device_detector.svg?branch=develop)](https://travis-ci.org/podigee/device_detector)
4
4
 
5
5
  DeviceDetector is a precise and fast user agent parser and device detector written in Ruby, backed by the largest and most up-to-date user agent database.
6
6
 
@@ -47,7 +47,7 @@ client.os_full_version # => '8'
47
47
 
48
48
  # For many devices, you can also query the device name (usually the model name)
49
49
  client.device_name # => 'iPhone 5'
50
- # Device types can be one of the following: smartphone, tablet, console,
50
+ # Device types can be one of the following: desktop, smartphone, tablet, console,
51
51
  # portable media player, tv, car browser, camera
52
52
  client.device_type # => 'smartphone'
53
53
  ```
@@ -134,32 +134,30 @@ useragent 4.450000 0.000000 4.450000 ( 4.452741)
134
134
 
135
135
  ## Detectable clients, bots and devices
136
136
 
137
- Updated on 2016-07-16
137
+ Updated on 2020-06-23
138
138
 
139
139
  ### Bots
140
140
 
141
- 360Spider, Aboundexbot, Acoon, AddThis.com, ADMantX, aHrefs Bot, Alexa Crawler, Amorank Spider, Analytics SEO Crawler, Applebot, archive.org bot, Ask Jeeves, Backlink-Ceck.de, BacklinkCrawler, Baidu Spider, BazQux Reader, BingBot, Blekkobot, BLEXBot Crawler, Bloglovin, Blogtrottr, Bountii Bot, Browsershots, BUbiNG, Butterfly Robot, CareerBot, ccBot crawler, Charlotte, Cliqzbot, CloudFlare Always Online, CommaFeed, Cốc Cốc Bot, Daum, Dazoobot, Discobot, Domain Re-Animator Bot, DotBot, Easou Spider, EMail Exractor, EmailWolf, ExaBot, ExactSeek Crawler, Ezooms, Facebook External Hit, Feed Wrangler, Feedbin, FeedBurner, Feedly, Feedspot, Fever, Generic Bot, Genieo Web filter, Gigabot, Gluten Free Crawler, Gmail Image Proxy, Goo, Google PageSpeed Insights, Google Partner Monitoring, Googlebot, Heritrix, HTTPMon, HubPages, ICC-Crawler, ichiro, IIS Site Analysis, Inktomi Slurp, Kouio, Larbin web crawler, Linkdex Bot, LinkedIn Bot, LTX71, Lycos, Magpie-Crawler, MagpieRSS, Mail.Ru Bot, Meanpath Bot, Mixrank Bot, MJ12 Bot, MojeekBot, Monitor.Us, NalezenCzBot, Netcraft Survey Bot, NetLyzer FastProbe, NetResearchServer, Netvibes, NewsBlur, NewsGator, NLCrawler, Nutch-based Bot, Omgili bot, Openindex Spider, OpenLinkProfiler, OpenWebSpider, Orange Bot, Outbrain, PagePeeker, PaperLiBot, PHP Server Monitor, Picsearch bot, Pingdom Bot, Pinterest, Pompos, QuerySeekerSpider, Reddit Bot, Rogerbot, ROI Hunter, Scooter, ScoutJet, Scrapy, Screaming Frog SEO Spider, ScreenerBot, Semrush Bot, Sensika Bot, SEOENGBot, Server Density, Seznam Bot, ShopWiki, SilverReader, SimplePie, SISTRIX Crawler, Site24x7 Website Monitoring, Skype URI Preview, Slackbot, Sogou Spider, Soso Spider, Speedy, Spinn3r, Sputnik Bot, Superfeedr Bot, Survey Bot, TelgramBot, TinEye Crawler, Tiny Tiny RSS, TurnitinBot, TweetedTimes Bot, Tweetmeme Bot, Twitterbot, Uptime Robot, URLAppendBot, Visual Site Mapper Crawler, W3C CSS Validator, W3C I18N Checker, W3C Link Checker, W3C Markup Validation Service, W3C MobileOK Checker, W3C Unified Validator, WebbCrawler, WebSitePulse, WebThumbnail, WeSEE:Search, Willow Internet Crawler, Wotbox, YaCy, Yahoo Gemini, Yahoo! Cache System, Yahoo! Link Preview, Yahoo! Slurp, Yandex Bot, Yeti/Naverbot, Yottaa Site Monitor, Youdao Bot, Yourls, Yunyun Bot, Zao, Zookabot, ZumBot
141
+ 360Spider, Aboundexbot, Acoon, AddThis.com, ADMantX, aHrefs Bot, Alexa Crawler, Alexa Site Audit, Amazon Route53 Health Check, Amorank Spider, Analytics SEO Crawler, ApacheBench, Applebot, Arachni, archive.org bot, Ask Jeeves, AspiegelBot, Awario, Backlink-Check.de, BacklinkCrawler, Baidu Spider, BazQux Reader, BingBot, BitlyBot, Blekkobot, BLEXBot Crawler, Bloglovin, Blogtrottr, BoardReader, BoardReader Blog Indexer, Bountii Bot, BrandVerity, Browsershots, BUbiNG, Buck, Butterfly Robot, Bytespider, CareerBot, Castro 2, Catchpoint, CATExplorador, ccBot crawler, Charlotte, Cliqzbot, CloudFlare Always Online, CloudFlare AMP Fetcher, Collectd, CommaFeed, CSS Certificate Spider, Cốc Cốc Bot, Datadog Agent, Datanyze, Dataprovider, Daum, Dazoobot, Discobot, Domain Re-Animator Bot, DotBot, DuckDuckGo Bot, Easou Spider, eCairn-Grabber, EMail Exractor, EmailWolf, Embedly, evc-batch, ExaBot, ExactSeek Crawler, eZ Publish Link Validator, Ezooms, Facebook External Hit, Feed Wrangler, Feedbin, FeedBurner, Feedly, Feedspot, Fever, Findxbot, Flipboard, FreshRSS, Generic Bot, Genieo Web filter, Gigablast, Gigabot, Gluten Free Crawler, Gmail Image Proxy, Goo, Google Cloud Scheduler, Google Favicon, Google PageSpeed Insights, Google Partner Monitoring, Google Search Console, Google Stackdriver Monitoring, Google Structured Data Testing Tool, Googlebot, Grapeshot, GTmetrix, Heritrix, Heureka Feed, HTTPMon, HubPages, HubSpot, ICC-Crawler, ichiro, IDG/IT, IIS Site Analysis, Inktomi Slurp, inoreader, IP-Guide Crawler, IPS Agent, Kaspersky, Kouio, Larbin web crawler, LCC, Let's Encrypt Validation, Lighthouse, Linkdex Bot, LinkedIn Bot, LTX71, Lycos, Magpie-Crawler, MagpieRSS, Mail.Ru Bot, masscan, Mastodon Bot, Meanpath Bot, MetaInspector, MetaJobBot, Mixrank Bot, MJ12 Bot, Mnogosearch, MojeekBot, Monitor.Us, Munin, Nagios check_http, NalezenCzBot, nbertaupete95, Netcraft Survey Bot, netEstate, NetLyzer FastProbe, NetResearchServer, Netvibes, NewsBlur, NewsGator, NLCrawler, Nmap, Nutch-based Bot, Nuzzel, oBot, Octopus, Omgili bot, Openindex Spider, OpenLinkProfiler, OpenWebSpider, Orange Bot, Outbrain, PagePeeker, PaperLiBot, Phantomas, PHP Server Monitor, Picsearch bot, Pingdom Bot, Pinterest, PocketParser, Pompos, PritTorrent, QuerySeekerSpider, Quora Link Preview, Qwantify, Rainmeter, RamblerMail Image Proxy, Reddit Bot, Riddler, Rogerbot, ROI Hunter, RSSRadio Bot, SafeDNSBot, Scooter, ScoutJet, Scrapy, Screaming Frog SEO Spider, ScreenerBot, Semrush Bot, Sensika Bot, Sentry Bot, SEOENGBot, SEOkicks-Robot, Seoscanners.net, Server Density, Seznam Bot, Seznam Email Proxy, Seznam Zbozi.cz, ShopAlike, Shopify Partner, ShopWiki, SilverReader, SimplePie, SISTRIX Crawler, SISTRIX Optimizer, Site24x7 Website Monitoring, Siteimprove, SiteSucker, Sixy.ch, Skype URI Preview, Slackbot, SMTBot, Snapchat Proxy, Sogou Spider, Soso Spider, Sparkler, Speedy, Spinn3r, Spotify, Sputnik Bot, sqlmap, SSL Labs, Startpagina Linkchecker, StatusCake, Superfeedr Bot, Survey Bot, Tarmot Gezgin, TelegramBot, The Knowledge AI, theoldreader, TinEye Crawler, Tiny Tiny RSS, TLSProbe, TraceMyFile, Trendiction Bot, TurnitinBot, TweetedTimes Bot, Tweetmeme Bot, Twingly Recon, Twitterbot, UkrNet Mail Proxy, UniversalFeedParser, Uptime Robot, Uptimebot, URLAppendBot, Vagabondo, Visual Site Mapper Crawler, VK Share Button, W3C CSS Validator, W3C I18N Checker, W3C Link Checker, W3C Markup Validation Service, W3C MobileOK Checker, W3C Unified Validator, Wappalyzer, WebbCrawler, Weborama, WebPageTest, WebSitePulse, WebThumbnail, WeSEE:Search, WikiDo, Willow Internet Crawler, WooRank, WordPress, Wotbox, XenForo, YaCy, Yahoo Gemini, Yahoo! Cache System, Yahoo! Japan BRW, Yahoo! Link Preview, Yahoo! Slurp, Yandex Bot, Yeti/Naverbot, Yottaa Site Monitor, Youdao Bot, Yourls, Yunyun Bot, Zao, Ze List, zgrab, Zookabot, ZumBot
142
142
 
143
143
  ### Clients
144
144
 
145
- 360 Browser, 360 Phone Browser, ABrowse, Airmail, Akregator, Amaya, Amiga Aweb, Amiga Voyager, Amigo, Android Browser, AndroidDownloadManager, ANT Fresco, ANTGalio, Apple PubSub, Arora, Atomic Web Browser, Avant Browser, Baidu Browser, Baidu Spark, Banshee, Barca, Beonex, BlackBerry Browser, Boxee, Brave, BrowseX, Bunjalloo, Camino, Charon, Cheshire, Chrome, Chrome Frame, Chrome Mobile, Chrome Mobile iOS, ChromePlus, Chromium, Clementine, Coc Coc, CometBird, Comodo Dragon, Conkeror, CoolNovo, curl, Deepnet Explorer, Dillo, Dolphin, Element Browser, Elinks, Epiphany, Espial TV Browser, Facebook, FeedDemon, Feeddler RSS Reader, FeedR, Fennec, Firebird, Firefox, Fireweb, Fireweb Navigator, Flock, Fluid, FlyCast, Galeon, Google Earth, Google Play Newsstand, Google Plus, Guzzle (PHP HTTP Client), HotJava, IBrowse, iCab, IceDragon, Iceweasel, IE Mobile, Instacast, Internet Explorer, Iron, iTunes, Jasmine, Java, JetBrains Omea Reader, Jig Browser, K-meleon, Kapiko, Kazehakase, Kindle Browser, Kodi, Konqueror, Kylo, LG Browser, Liebao, Liferea, Line, Links, Lotus Notes, LuaKit, Lunascape, Lynx, MailBar, Maxthon, MediaMonkey, Mercury, MicroB, Microsoft Edge, Microsoft Outlook, Midori, Miro, MIUI Browser, Mobile Safari, Mobile Silk, NCSA Mosaic, NetFront, NetFront Life, NetNewsWire, NetPositive, Netscape, Newsbeuter, NewsBlur, NewsBlur Mobile App, NexPlayer, Nightingale, Nokia Browser, Nokia OSS Browser, Nokia Ovi Browser, Obigo, Odyssey Web Browser, Off By One, OmniWeb, ONE Browser, Openwave Mobile Browser, Opera, Opera Mini, Opera Mobile, Opera Next, Oregano, Otter Browser, Outlook Express, Pale Moon, Palm Blazer, Palm Pre, Palm WebPro, Palmscape, Perl, Phoenix, Pinterest, Polaris, Postbox, Puffin, Pulp, Python Requests, Python urllib, QQ Browser, QuickTime, ReadKit, Reeder, Rekonq, RockMelt, RSS Bandit, RSS Junkie, RSSOwl, Safari, Sailfish Browser, Samsung Browser, SEMC-Browser, Seraphic Sraf, Shiira, Sina Weibo, Skyfire, Sleipnir, Snowshoe, Sogou Explorer, Songbird, Stagefright, Stringer, SubStream, Sunrise, SuperBird, Swiftfox, The Bat!, Thunderbird, Tizen Browser, TweakStyle, UC Browser, Vision Mobile Browser, Vivaldi, VLC, WebPositive, WeChat, WeTab Browser, Wget, WhatsApp, Winamp, Windows Media Player, wOSBrowser, XBMC, Xiino, Yandex Browser, YouTube
145
+ 115 Browser, 2345 Browser, 360 Browser, 360 Phone Browser, ABrowse, aiohttp, Airmail, Akregator, Aloha Browser, Aloha Browser Lite, Amaya, Amiga Aweb, Amiga Voyager, Amigo, Android Browser, AndroidDownloadManager, ANT Fresco, AntennaPod, ANTGalio, AOL Desktop, AOL Shield, Apple News, Apple PubSub, Arctic Fox, Arora, Atom, Atomic Web Browser, Audacious, Avant Browser, Avast Secure Browser, AVG Secure Browser, B-Line, Baidu Box App, Baidu Browser, Baidu Spark, Banshee, Barca, BashPodder, Basilisk, Beaker Browser, Beamrise, Beonex, BeyondPod, BingWebApp, BlackBerry Browser, BlackHawk, Boxee, bPod, Brave, Breaker, BriskBard, BrowseX, Bunjalloo, Camino, CastBox, Castro, Castro 2, CCleaner, Centaury, Charon, Cheetah Browser, Cheshire, Chrome, Chrome Frame, Chrome Mobile, Chrome Mobile iOS, Chrome Webview, ChromePlus, Chromium, Clementine, CM Browser, Coast, Coc Coc, Colibri, CometBird, Comodo Dragon, Conkeror, CoolNovo, COS Browser, CrosswalkApp, Crusta, Cunaguaro, curl, Cyberfox, DAVdroid, dbrowser, Deepnet Explorer, Deezer, Delta Browser, Dillo, DoggCatcher, Dolphin, Dooble, Dorado, douban App, Downcast, DuckDuckGo Privacy Browser, Ecosia, Element Browser, Elements Browser, Elinks, Epic, Espial TV Browser, EUI Browser, eZ Browser, Facebook, Facebook Messenger, Falkon, Faraday, Faux Browser, FeedDemon, Feeddler RSS Reader, FeedR, Fennec, Firebird, Firefox, Firefox Focus, Firefox Mobile, Firefox Mobile iOS, Firefox Reality, Firefox Rocket, Fireweb, Fireweb Navigator, Flipboard App, Flock, Fluid, FlyCast, Foobar2000, FreeU, Galeon, Glass Browser, GNOME Web, Go-http-client, Google Earth, Google Go, Google HTTP Java Client, Google Play Newsstand, Google Plus, Google Podcasts, Google Search App, gPodder, Guzzle (PHP HTTP Client), Hawk Turbo Browser, Headless Chrome, hola! Browser, HotJava, HTTP_Request2, HTTPie, Huawei Browser, IBrowse, iCab, iCab Mobile, iCatcher, IceCat, IceDragon, Iceweasel, IE Mobile, Instacast, Instagram App, Internet Explorer, Iridium, Iron, Iron Mobile, Isivioo, iTunes, Jasmine, Java, JetBrains Omea Reader, Jig Browser, Jig Browser Plus, Jio Browser, K-meleon, K.Browser, Kapiko, Kazehakase, Kindle Browser, Kinza, Kiwi, Kodi, Konqueror, Kylo, LG Browser, libdnf, LieBaoFast, Liferea, Light, Line, Links, Lotus Notes, Lovense Browser, LuaKit, Lulumi, Lunascape, Lunascape Lite, Lynx, MailBar, Maxthon, mCent, Mechanize, MediaMonkey, Meizu Browser, Mercury, MicroB, Microsoft Edge, Microsoft Outlook, Midori, Minimo, Mint Browser, Miro, MIUI Browser, Mobicip, Mobile Safari, Mobile Silk, mpv, Music Player Daemon, Mypal, NCSA Mosaic, NetFront, NetFront Life, NetNewsWire, NetPositive, Netscape, NetSurf, NewsArticle App, Newsbeuter, NewsBlur, NewsBlur Mobile App, NexPlayer, Nightingale, Node Fetch, Nokia Browser, Nokia OSS Browser, Nokia Ovi Browser, Nox Browser, NTENT Browser, Obigo, Oculus Browser, Odyssey Web Browser, Off By One, OhHai Browser, OkHttp, OmniWeb, ONE Browser, Openwave Mobile Browser, Opera, Opera Devices, Opera GX, Opera Mini, Opera Mini iOS, Opera Mobile, Opera Neon, Opera Next, Opera Touch, Oppo Browser, Ordissimo, Oregano, Origin In-Game Overlay, Origyn Web Browser, Otter Browser, Outlook Express, Overcast, Pale Moon, Palm Blazer, Palm Pre, Palm WebPro, Palmscape, Perl, Perl REST::Client, Phoenix, Pinterest, Player FM, Pocket Casts, Podcast & Radio Addict, Podcast Republic, Podcasts, Podcat, Podcatcher Deluxe, Podkicker, Polaris, Polarity, Polypane, Postbox, PritTorrent, Puffin, Pulp, Python Requests, Python urllib, QQ Browser, QQ Browser Mini, QtWebEngine, Quark, QuickTime, QuiteRSS, QupZilla, Qutebrowser, Qwant Mobile, ReadKit, Realme Browser, Reeder, Rekonq, REST Client for Ruby, RestSharp, RockMelt, RSS Bandit, RSS Junkie, RSSOwl, RSSRadio, Safari, Safe Exam Browser, Sailfish Browser, SalamWeb, Samsung Browser, ScalaJ HTTP, SeaMonkey, SEMC-Browser, Seraphic Sraf, Seznam Browser, Shiira, SimpleBrowser, Sina Weibo, Sizzy, Skyfire, Sleipnir, Snapchat, Snowshoe, Sogou Explorer, Sogou Mobile Browser, SogouSearch App, Songbird, Splash, Sputnik Browser, Stagefright, START Internet Browser, Steam In-Game Overlay, Streamy, Stringer, SubStream, Sunrise, Super Fast Browser, SuperBird, surf, Swiftfox, t-online.de Browser, Tao Browser, TenFourFox, Tenta Browser, The Bat!, Thunderbird, tieba, Tizen Browser, ToGate, TopBuzz, Tungsten, TV Bro, TweakStyle, Twitter, UBrowser, UC Browser, UC Browser Mini, UC Browser Turbo, urlgrabber (yum), Uzbl, Vision Mobile Browser, Vivaldi, vivo Browser, VLC, VMware AirWatch, Waterfox, Wear Internet Browser, Web Explorer, WebPositive, WeChat, WeTab Browser, Wget, Whale Browser, WhatsApp, Winamp, Windows Media Player, wOSBrowser, WWW-Mechanize, XBMC, Xiino, Xvast, Yahoo! Japan, Yahoo! Japan Browser, Yandex Browser, Yandex Browser Lite, Yelp Mobile, YouTube, Zvu
146
146
 
147
147
  ### Devices
148
148
 
149
- 3Q, Acer, Ainol, Airness, Airties, Alcatel, Allview, Altech UEC, Amazon, Amoi, Apple, Archos, Arnova, ARRIS, Asus, Audiovox, Avvio, Axxion, BangOlufsen, Barnes & Noble, Becker, Beetel, BenQ, BenQ-Siemens, Bird, Blu, Bmobile, Boway, bq, Brondi, Bush, Capitel, Captiva, Carrefour, Casio, Cat, Celkon, Changhong, Cherry Mobile, CnM, Coby Kyros, Compal, ConCorde, Coolpad, Cowon, CreNova, Cricket, Crius Mea, Crosscall, Cube, CUBOT, Danew, Datang, Dbtel, Dell, Denver, Desay, Dicam, DMM, DNS, DoCoMo, Doogee, Doov, Dopod, Dune HD, E-Boda, Easypix, EBEST, ECS, Elephone, Energy Sistem, Ericsson, Ericy, Eton, eTouch, Evertek, Ezio, Ezze, Fairphone, Fly, Foxconn, Fujitsu, Garmin-Asus, Gemini, Gigabyte, Gigaset, Gionee, GOCLEVER, Goly, Google, Gradiente, Grundig, Haier, Hasee, Hi-Level, Hisense, Hosin, HP, HTC, Huawei, Humax, Hyundai, i-Joy, i-mate, i-mobile, iBall, iBerry, Ikea, iKoMo, iNew, Infinix, Inkti, Innostream, INQ, Intek, Intex, Inverto, iOcean, iTel, Jiayu, Jolla, K-Touch, Karbonn, Kazam, KDDI, Kingsun, Komu, Konka, Koobee, KOPO, Koridy, KT-Tech, Kumai, Kyocera, Lanix, Lava, LCT, Le Pan, Lenco, Lenovo, Lexibook, LG, Lingwin, Loewe, Logicom, M.T.T., Majestic, Manta Multimedia, Mecer, Mediacom, MediaTek, Medion, MEEG, Meizu, Memup, Metz, MEU, MicroMax, Microsoft, Mio, Mitsubishi, MLLED, Mobistel, Mofut, Motorola, Mpman, MSI, MyPhone, NEC, Netgear, Newgen, Nexian, NextBook, NGM, Nikon, Nintendo, Noain, Nokia, Nomi, O2, Onda, OnePlus, OPPO, Opsson, Orange, Ouki, OUYA, Overmax, Oysters, Palm, Panasonic, Pantech, PEAQ, Philips, phoneOne, Pioneer, Ployer, Point of View, Polaroid, PolyPad, Pomp, Positivo, Prestigio, ProScan, PULID, Qilive, QMobile, Qtek, Quechua, Ramos, RCA Tablets, Readboy, Rikomagic, RIM, Roku, Rover, Sagem, Samsung, Sanyo, Sega, Selevision, Sencor, Sendo, SFR, Sharp, Siemens, Skyworth, Smart, Smartfren, Softbank, Sony, Spice, Star, Stonex, Storex, Sumvision, SunVan, SuperSonic, Symphony, T-Mobile, TCL, TechniSat, TechnoTrend, Tecno Mobile, Telefunken, Telenor, Telit, Tesco, Tesla, teXet, ThL, Thomson, TIANYU, TiPhone, Tolino, Toplux, Toshiba, Trevi, Tunisie Telecom, Turbo-X, TVC, Uniscope, Unknown, Unowhy, UTStarcom, Vastking, Vertu, Vestel, Videocon, Videoweb, ViewSonic, Vitelcom, Vivo, Vizio, VK Mobile, Vodafone, Voto, Voxtel, Walton, WellcoM, Wexler, Wiko, Wolder, Wonu, Woxter, Xiaomi, Xolo, Yarvik, Ytone, Yuandao, Yusun, Zeemi, Zonda, Zopo, ZTE
149
+ 3Q, 4Good, Ace, Acer, Advan, Advance, AGM, Ainol, Airness, Airties, AIS, Aiwa, Akai, Alba, Alcatel, Aligator, AllCall, AllDocube, Allview, Allwinner, Altech UEC, altron, Amazon, AMGOO, Amoi, ANS, Apple, Archos, Arian Space, Ark, ArmPhone, Arnova, ARRIS, Ask, Assistant, Asus, Atom, Audiovox, AVH, Avvio, Axxion, Azumi Mobile, BangOlufsen, Barnes & Noble, BDF, Becker, Beeline, Beetel, BenQ, BenQ-Siemens, Bezkam, BGH, Bird, Bitel, Bitmore, Black Fox, Blackview, Blaupunkt, Blu, Bluboo, Bluegood, Bmobile, bogo, Boway, bq, Bravis, Brondi, Bush, CAGI, Capitel, Captiva, Carrefour, Casio, Casper, Cat, Celkon, Changhong, Cherry Mobile, China Mobile, Chuwi, Clarmin, CnM, Coby Kyros, Comio, Compal, ComTrade Tesla, Concord, ConCorde, Condor, Coolpad, Cowon, CreNova, Crescent, Cricket, Crius Mea, Crosscall, Cube, CUBOT, CVTE, Cyrus, Daewoo, Danew, Datang, Datawind, Datsun, Dbtel, Dell, Denver, Desay, DeWalt, DEXP, Dialog, Dicam, Digi, Digicel, Digiland, Digma, Divisat, DMM, DNS, DoCoMo, Doogee, Doov, Dopod, Doro, Droxio, Dune HD, E-Boda, E-tel, Easypix, EBEST, Echo Mobiles, ECS, EE, EKO, Eks Mobility, Element, Elenberg, Elephone, Energizer, Energy Sistem, Ergo, Ericsson, Ericy, Essential, Essentielb, Eton, eTouch, Etuline, Eurostar, Evercoss, Evertek, Evolio, Evolveo, EvroMedia, Explay, Extrem, Ezio, Ezze, Fairphone, Famoco, Fengxiang, FiGO, FinePower, Fly, FNB, Fondi, FORME, Forstar, Foxconn, Freetel, Fujitsu, G-TiDE, Garmin-Asus, Gemini, General Mobile, Geotel, Ghia, Ghong, Gigabyte, Gigaset, Ginzzu, Gionee, Globex, GOCLEVER, Goly, Gome, GoMobile, Google, Goophone, Gradiente, Grape, Gree, Grundig, Hafury, Haier, HannSpree, Hasee, Hi-Level, Highscreen, Hisense, Hoffmann, Homtom, Hoozo, Hosin, HP, HTC, Huadoo, Huawei, Humax, Hyundai, i-Joy, i-mate, i-mobile, iBall, iBerry, IconBIT, iGet, iHunt, Ikea, iKoMo, iLA, IMO Mobile, Impression, iNew, Infinix, InFocus, Inkti, InnJoo, Innostream, Inoi, INQ, Insignia, Intek, Intex, Inverto, iOcean, iPro, Irbis, iRola, iRulu, iTel, iVA, iView, iZotron, JAY-Tech, JFone, Jiayu, JKL, Jolla, Just5, K-Touch, Kaan, Kaiomy, Kalley, Kanji, Karbonn, KATV1, Kazam, KDDI, Kempler & Strauss, Keneksi, Kiano, Kingsun, Kivi, Kocaso, Kodak, Kogan, Komu, Konka, Konrow, Koobee, KOPO, Koridy, KRONO, Krüger&Matz, KT-Tech, Kuliao, Kumai, Kyocera, LAIQ, Land Rover, Landvo, Lanix, Lark, Lava, LCT, Le Pan, Leagoo, Ledstar, LeEco, Lemhoov, Lenco, Lenovo, Leotec, Lephone, Lexand, Lexibook, LG, Lingwin, Loewe, Logicom, Lumus, Luna, LYF, M.T.T., M4tel, Macoox, Majestic, Mann, Manta Multimedia, Masstel, Maxcom, Maxwest, Maze, Mecer, Mecool, Mediacom, MediaTek, Medion, MEEG, MegaFon, Meitu, Meizu, Memup, Metz, MEU, MicroMax, Microsoft, Mio, Miray, Mito, Mitsubishi, MIXC, MLLED, Mobicel, Mobiistar, Mobiola, Mobistel, Mobo, Modecom, Mofut, Motorola, Movic, Mpman, MSI, MTC, MTN, MYFON, MyPhone, Myria, Mystery, MyWigo, National, Navon, NEC, Neffos, Netgear, NeuImage, Newgen, NewsMy, NEXBOX, Nexian, NEXON, Nextbit, NextBook, NG Optics, NGM, Nikon, Nintendo, NOA, Noain, Nobby, Noblex, Nokia, Nomi, Nous, NUU Mobile, Nuvo, Nvidia, NYX Mobile, O+, O2, Obi, Odys, Onda, OnePlus, Onix, ONN, OPPO, Opsson, Orange, Ouki, Oukitel, OUYA, Overmax, Oysters, Palm, Panacom, Panasonic, Pantech, PCBOX, PCD, PCD Argentina, PEAQ, Pentagram, Phicomm, Philips, phoneOne, Pioneer, Pixus, Ployer, Plum, PocketBook, Point of View, Polaroid, PolyPad, Polytron, Pomp, Positivo, PPTV, Prestigio, Primepad, Proline, ProScan, Protruly, PULID, Q-Touch, Q.Bell, Qilive, QMobile, Qtek, Quantum, Quechua, Qumo, R-TV, Ramos, Razer, RCA Tablets, Readboy, Realme, Rikomagic, RIM, Rinno, Ritmix, Ritzviva, Riviera, Roadrover, Rokit, Roku, Rombica, Ross&Moor, Rover, RoverPad, RT Project, RugGear, Runbo, Ryte, Safaricom, Sagem, Samsung, Sanei, Santin, Sanyo, Savio, Sega, Selevision, Selfix, Sencor, Sendo, Senseit, Senwa, SFR, Sharp, Shift Phones, Shuttle, Siemens, Sigma, Silent Circle, Simbans, Sky, Skyworth, Smart, Smartfren, Smartisan, Softbank, Sonim, Sony, Soyes, Spectrum, Spice, Star, Starway, STF Mobile, STK, Stonex, Storex, Sugar, Sumvision, SunVan, Sunvell, SuperSonic, Supra, SWISSMOBILITY, Symphony, Syrox, T-Mobile, TB Touch, TCL, TechniSat, TechnoTrend, TechPad, Teclast, Tecno Mobile, Telefunken, Telego, Telenor, Telit, Tesco, Tesla, teXet, ThL, Thomson, TIANYU, Timovi, TiPhone, Tolino, Tooky, Top House, Toplux, Toshiba, Touchmate, TrekStor, Trevi, True, Tunisie Telecom, Turbo, Turbo-X, TVC, TWM, U.S. Cellular, Ugoos, Uhans, Uhappy, Ulefone, Umax, UMIDIGI, Unihertz, Unimax, Uniscope, Unknown, Unnecto, Unonu, Unowhy, UTOK, UTStarcom, Vastking, Venso, Verizon, Vernee, Vertex, Vertu, Verykool, Vesta, Vestel, VGO TEL, Videocon, Videoweb, ViewSonic, Vinga, Vinsoc, Vitelcom, Vivax, Vivo, Vizio, VK Mobile, VKworld, Vodacom, Vodafone, Vonino, Vontar, Vorago, Vorke, Voto, Voxtel, Voyo, Vsun, Vulcan, Walton, Weimei, WellcoM, Wexler, Wieppo, Wigor, Wiko, Wileyfox, Wink, Wolder, Wolfgang, Wonu, Woo, Woxter, X-TIGI, X-View, Xiaolajiao, Xiaomi, Xion, Xolo, Xoro, Xshitou, Yandex, Yarvik, Yes, Yezz, Yota, Ytone, Yu, Yuandao, Yusun, Yxtel, Zeemi, Zen, Zenek, Zfiner, Zidoo, Zonda, Zopo, ZTE, Zuum, Zync, ZYQ, öwn
150
150
 
151
151
  ## Maintainers
152
152
 
153
153
  - Mati Sojka: https://github.com/yagooar
154
154
  - Ben Zimmer: https://github.com/benzimmer
155
- - Peter Gao: https://github.com/peteygao
156
155
 
157
156
  ## Contributors
158
157
 
159
158
  Thanks a lot to the following contributors:
160
159
 
161
- - Dennis Wu: https://github.com/dnswus
162
- - Mark Dodwell: https://github.com/mkdynamic
160
+ - Peter Gao: https://github.com/peteygao
163
161
 
164
162
  ## Contributing
165
163
 
data/Rakefile CHANGED
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake'
2
4
  require 'rake/testtask'
3
5
 
4
- $:.unshift 'lib'
6
+ $LOAD_PATH.unshift 'lib'
5
7
  require 'device_detector'
6
8
 
7
9
  Rake::TestTask.new do |t|
@@ -12,14 +14,18 @@ end
12
14
  task default: :test
13
15
 
14
16
  task :detectable_names do
15
- bot_names = DeviceDetector::Bot.new.send(:regexes).map { |r| r[:name] }.uniq.sort_by { |n| n.downcase }
17
+ require 'date'
18
+
19
+ bot_names = DeviceDetector::Bot.new('').send(:regexes)
20
+ .map { |r| r[:name] }.uniq.sort_by(&:downcase)
16
21
  bot_names.delete('$1')
17
- client_names = DeviceDetector::Client.new.send(:regexes).map { |r| r[:name] }.uniq.sort_by { |n| n.downcase }
22
+ client_names = DeviceDetector::Client.new('').send(:regexes)
23
+ .map { |r| r[:name] }.uniq.sort_by(&:downcase)
18
24
  client_names.delete('$1')
19
- device = DeviceDetector::Device.new
25
+ device = DeviceDetector::Device.new('')
20
26
  device_paths = device.send(:filepaths)
21
27
  device_regexes = device.send(:load_regexes, device_paths)
22
- device_names = device_regexes.flat_map { |dn| dn[1].keys }.uniq.sort_by { |n| n.downcase }
28
+ device_names = device_regexes.flat_map { |dn| dn[1].keys }.uniq.sort_by(&:downcase)
23
29
 
24
30
  today = Date.today.strftime
25
31
 
@@ -41,8 +47,8 @@ task :detectable_names do
41
47
  puts
42
48
  end
43
49
 
44
- PIWIK_REPO_URL = 'https://github.com/piwik/device-detector.git'.freeze
45
- PIWIK_CHECKOUT_LOCATION = '/tmp/piwik_device_detector'.freeze
50
+ PIWIK_REPO_URL = 'https://github.com/matomo-org/device-detector'
51
+ PIWIK_CHECKOUT_LOCATION = '/tmp/matomo_device_detector'
46
52
 
47
53
  def get_latest_piwik_checkout
48
54
  if File.exist?(PIWIK_CHECKOUT_LOCATION)
@@ -54,21 +60,21 @@ end
54
60
 
55
61
  desc 'update regex database from piwik project'
56
62
  task :update_regexes do
57
- top = File.expand_path('..', __FILE__)
63
+ top = File.expand_path(__dir__)
58
64
  get_latest_piwik_checkout
59
65
  system "cp -R #{PIWIK_CHECKOUT_LOCATION}/regexes/* #{top}/regexes"
60
66
  end
61
67
 
62
68
  desc 'update fixtures from piwik project'
63
69
  task :update_fixtures do
64
- top = File.expand_path('..', __FILE__)
70
+ top = File.expand_path(__dir__)
65
71
  get_latest_piwik_checkout
66
72
 
67
73
  fixture_mappings = [
68
- {target_path: "#{top}/spec/fixtures/detector", source_path: 'Tests/fixtures/*.yml'},
69
- {target_path: "#{top}/spec/fixtures/client", source_path: 'Tests/Parser/Client/fixtures/*.yml'},
70
- {target_path: "#{top}/spec/fixtures/parser", source_path: 'Tests/Parser/fixtures/*.yml'},
71
- {target_path: "#{top}/spec/fixtures/device", source_path: 'Tests/Parser/Devices/fixtures/*.yml'},
74
+ { target_path: "#{top}/spec/fixtures/detector", source_path: 'Tests/fixtures/*.yml' },
75
+ { target_path: "#{top}/spec/fixtures/client", source_path: 'Tests/Parser/Client/fixtures/*.yml' },
76
+ { target_path: "#{top}/spec/fixtures/parser", source_path: 'Tests/Parser/fixtures/*.yml' },
77
+ { target_path: "#{top}/spec/fixtures/device", source_path: 'Tests/Parser/Devices/fixtures/*.yml' }
72
78
  ]
73
79
 
74
80
  fixture_mappings.each do |mapping|
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'minitest'
24
24
  spec.add_development_dependency 'rake'
25
25
  spec.add_development_dependency 'pry', '>= 0.10'
26
+ spec.add_development_dependency 'rubocop', '0.85.1'
26
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'yaml'
2
4
 
3
5
  require 'device_detector/version'
@@ -13,7 +15,6 @@ require 'device_detector/device'
13
15
  require 'device_detector/os'
14
16
 
15
17
  class DeviceDetector
16
-
17
18
  attr_reader :user_agent
18
19
 
19
20
  def initialize(user_agent)
@@ -28,6 +29,10 @@ class DeviceDetector
28
29
  client.full_version
29
30
  end
30
31
 
32
+ def os_family
33
+ os.family
34
+ end
35
+
31
36
  def os_name
32
37
  os.name
33
38
  end
@@ -47,13 +52,23 @@ class DeviceDetector
47
52
  def device_type
48
53
  t = device.type
49
54
 
50
- if t.nil? && android_tablet_fragment? || opera_tablet?
51
- t = 'tablet'
55
+ # Chrome on Android passes the device type based on the keyword 'Mobile'
56
+ # If it is present the device should be a smartphone, otherwise it's a tablet
57
+ # See https://developer.chrome.com/multidevice/user-agent#chrome_for_android_user_agent
58
+ # Note: We do not check for browser (family) here, as there might be mobile apps using Chrome,
59
+ # that won't have a detected browser, but can still be detected. So we check the useragent for
60
+ # Chrome instead.
61
+ if t.nil? && os.family == 'Android' && user_agent =~ build_regex('Chrome\/[\.0-9]*')
62
+ if user_agent =~ build_regex('Chrome\/[\.0-9]* Mobile')
63
+ t = 'smartphone'
64
+ elsif user_agent =~ build_regex('Chrome\/[\.0-9]* (?!Mobile)')
65
+ t = 'tablet'
66
+ end
52
67
  end
53
68
 
54
- if t.nil? && android_mobile_fragment?
55
- t = 'smartphone'
56
- end
69
+ t = 'tablet' if t.nil? && android_tablet_fragment? || opera_tablet?
70
+
71
+ t = 'smartphone' if t.nil? && android_mobile_fragment?
57
72
 
58
73
  # Android up to 3.0 was designed for smartphones only. But as 3.0,
59
74
  # which was tablet only, was published too late, there were a
@@ -72,35 +87,27 @@ class DeviceDetector
72
87
  end
73
88
 
74
89
  # All detected feature phones running android are more likely a smartphone
75
- if t == 'feature phone' && os.family == 'Android'
76
- t = 'smartphone'
77
- end
90
+ t = 'smartphone' if t == 'feature phone' && os.family == 'Android'
78
91
 
79
92
  # According to http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
80
- # Internet Explorer 10 introduces the "Touch" UA string token. If this token is present at the end of the
81
- # UA string, the computer has touch capability, and is running Windows 8 (or later).
93
+ # Internet Explorer 10 introduces the "Touch" UA string token. If this token is present at the
94
+ # end of the UA string, the computer has touch capability, and is running Windows 8 (or later).
82
95
  # This UA string will be transmitted on a touch-enabled system running Windows 8 (RT)
83
96
  #
84
- # As most touch enabled devices are tablets and only a smaller part are desktops/notebooks we assume that
85
- # all Windows 8 touch devices are tablets.
97
+ # As most touch enabled devices are tablets and only a smaller part are desktops/notebooks we
98
+ # assume that all Windows 8 touch devices are tablets.
86
99
  if t.nil? && touch_enabled? &&
87
100
  (os.short_name == 'WRT' || (os.short_name == 'WIN' && os.full_version && os.full_version >= '8'))
88
101
  t = 'tablet'
89
102
  end
90
103
 
91
- if opera_tv_store?
92
- t = 'tv'
93
- end
104
+ t = 'tv' if opera_tv_store?
94
105
 
95
- if t.nil? && ['Kylo', 'Espial TV Browser'].include?(client.name)
96
- t = 'tv'
97
- end
106
+ t = 'tv' if t.nil? && ['Kylo', 'Espial TV Browser'].include?(client.name)
98
107
 
99
108
  # set device type to desktop for all devices running a desktop os that were
100
109
  # not detected as an other device type
101
- if t.nil? && os.desktop? && !puffin_browser?
102
- t = 'desktop'
103
- end
110
+ t = 'desktop' if t.nil? && os.desktop? && !puffin_browser?
104
111
 
105
112
  t
106
113
  end
@@ -118,7 +125,6 @@ class DeviceDetector
118
125
  end
119
126
 
120
127
  class << self
121
-
122
128
  class Configuration
123
129
  attr_accessor :max_cache_keys
124
130
 
@@ -137,11 +143,10 @@ class DeviceDetector
137
143
  @cache ||= MemoryCache.new(config.to_hash)
138
144
  end
139
145
 
140
- def configure(&block)
146
+ def configure
141
147
  @config = Configuration.new
142
148
  yield(config)
143
149
  end
144
-
145
150
  end
146
151
 
147
152
  private
@@ -163,11 +168,11 @@ class DeviceDetector
163
168
  end
164
169
 
165
170
  def android_tablet_fragment?
166
- user_agent =~ build_regex('Android; Tablet;')
171
+ user_agent =~ build_regex('Android(?: \d.\d(?:.\d)?)?; Tablet;')
167
172
  end
168
173
 
169
174
  def android_mobile_fragment?
170
- user_agent =~ build_regex('Android; Mobile;')
175
+ user_agent =~ build_regex('Android(?: \d.\d(?:.\d)?)?; Mobile;')
171
176
  end
172
177
 
173
178
  def touch_enabled?
@@ -190,5 +195,4 @@ class DeviceDetector
190
195
  def build_regex(src)
191
196
  Regexp.new('(?:^|[^A-Z0-9\_\-])(?:' + src + ')', Regexp::IGNORECASE)
192
197
  end
193
-
194
198
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DeviceDetector
2
4
  class Bot < Parser
3
-
4
5
  def bot?
5
6
  regex_meta.any?
6
7
  end
@@ -10,6 +11,5 @@ class DeviceDetector
10
11
  def filenames
11
12
  ['bots.yml']
12
13
  end
13
-
14
14
  end
15
15
  end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DeviceDetector
2
4
  class Client < Parser
3
-
4
5
  def known?
5
6
  regex_meta.any?
6
7
  end
@@ -14,7 +15,7 @@ class DeviceDetector
14
15
  'client/mediaplayers.yml',
15
16
  'client/pim.yml',
16
17
  'client/browsers.yml',
17
- 'client/libraries.yml',
18
+ 'client/libraries.yml'
18
19
  ]
19
20
  end
20
21
  end
@@ -1,20 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class DeviceDetector
2
4
  class Device < Parser
3
-
4
5
  # order is relevant for testing with fixtures
5
6
  DEVICE_NAMES = [
6
- 'desktop',
7
- 'smartphone',
8
- 'tablet',
9
- 'feature phone',
10
- 'console',
11
- 'tv',
12
- 'car browser',
13
- 'smart display',
14
- 'camera',
15
- 'portable media player',
16
- 'phablet'
17
- ]
7
+ 'desktop',
8
+ 'smartphone',
9
+ 'tablet',
10
+ 'feature phone',
11
+ 'console',
12
+ 'tv',
13
+ 'car browser',
14
+ 'smart display',
15
+ 'camera',
16
+ 'portable media player',
17
+ 'phablet'
18
+ ].freeze
18
19
 
19
20
  def known?
20
21
  regex_meta.any?
@@ -43,18 +44,22 @@ class DeviceDetector
43
44
  'device/car_browsers.yml',
44
45
  'device/cameras.yml',
45
46
  'device/portable_media_player.yml',
46
- 'device/mobiles.yml',
47
+ 'device/mobiles.yml'
47
48
  ]
48
49
  end
49
50
 
50
51
  def matching_regex
51
52
  from_cache([self.class.name, user_agent]) do
52
53
  regex_list = hbbtv? ? regexes_for_hbbtv : regexes_other
53
- regex = regex_list.find { |r| user_agent =~ r[:regex] }
54
+ regex = regex_find(user_agent, regex_list)
54
55
  if regex && regex[:models]
55
- model_regex = regex[:models].find { |m| user_agent =~ m[:regex]}
56
+ model_regex = regex[:models].find { |m| user_agent =~ m[:regex] }
56
57
  if model_regex
57
- regex = regex.merge(:regex_model => model_regex[:regex], :model => model_regex[:model], :brand => model_regex[:brand])
58
+ regex = regex.merge({
59
+ regex_model: model_regex[:regex],
60
+ model: model_regex[:model],
61
+ brand: model_regex[:brand]
62
+ })
58
63
  regex[:device] = model_regex[:device] if model_regex.key?(:device)
59
64
  regex.delete(:models)
60
65
  end
@@ -63,6 +68,23 @@ class DeviceDetector
63
68
  end
64
69
  end
65
70
 
71
+ # Finds the first match of the string in a list of regexes.
72
+ # Handles exception with special characters caused by bug in Ruby regex
73
+ # @param user_agent [String] User Agent string
74
+ # @param regex_list [Array<Regex>] List of regexes
75
+ #
76
+ # @return [MatchData, nil] MatchData if string matches any regexp, nil otherwise
77
+ def regex_find(user_agent, regex_list)
78
+ regex_list.find { |r| user_agent =~ r[:regex] }
79
+ rescue RegexpError
80
+ # Bug in ruby regex and special characters, retry with clean
81
+ # https://bugs.ruby-lang.org/issues/13671
82
+ user_agent = user_agent.encode(
83
+ ::Encoding::ASCII, invalid: :replace, undef: :replace, replace: ''
84
+ )
85
+ regex_list.find { |r| user_agent =~ r[:regex] }
86
+ end
87
+
66
88
  def hbbtv?
67
89
  @regex_hbbtv ||= build_regex('HbbTV/([1-9]{1}(?:\.[0-9]{1}){1,2})')
68
90
  user_agent =~ @regex_hbbtv
@@ -73,16 +95,18 @@ class DeviceDetector
73
95
  end
74
96
 
75
97
  def regexes_other
76
- regexes.select { |r| r[:path] != :'device/televisions.yml' }
98
+ regexes.reject { |r| r[:path] == :'device/televisions.yml' }
77
99
  end
78
100
 
79
101
  def parse_regexes(path, raw_regexes)
80
102
  raw_regexes.map do |brand, meta|
81
- fail "invalid device spec: #{meta.inspect}" unless meta[:regex].is_a? String
103
+ raise "invalid device spec: #{meta.inspect}" unless meta[:regex].is_a? String
104
+
82
105
  meta[:regex] = build_regex(meta[:regex])
83
106
  if meta.key?(:models)
84
107
  meta[:models].each do |model|
85
- fail "invalid model spec: #{model.inspect}" unless model[:regex].is_a? String
108
+ raise "invalid model spec: #{model.inspect}" unless model[:regex].is_a? String
109
+
86
110
  model[:regex] = build_regex(model[:regex])
87
111
  model[:brand] = brand.to_s unless model[:brand]
88
112
  end
@@ -91,6 +115,5 @@ class DeviceDetector
91
115
  meta
92
116
  end
93
117
  end
94
-
95
118
  end
96
119
  end