diff --git a/mix.exs b/mix.exs index 7199a9c..6f6bd8b 100644 --- a/mix.exs +++ b/mix.exs @@ -1,14 +1,14 @@ defmodule UAParser.Mixfile do use Mix.Project - @version "1.2.1" + @version "1.3.0" def project do [ app: :ua_parser, description: "Parse user-agent strings with BrowserScope patterns", version: @version, - elixir: "~> 1.3", + elixir: "~> 1.4", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, package: package(), @@ -17,17 +17,15 @@ defmodule UAParser.Mixfile do end def application do - [ - applications: [:logger, :yamerl] - ] + [extra_aplications: [:logger, :yamerl]] end defp deps do [ - {:yamerl, "~> 0.4.0"}, + {:yamerl, "~> 0.5"}, # Development & Test dependencies - {:credo, "~> 0.5", only: [:dev, :test]}, + {:credo, "~> 0.8", only: [:dev, :test]}, {:ex_doc, ">= 0.0.0", only: :dev}, ] end @@ -40,6 +38,4 @@ defmodule UAParser.Mixfile do links: %{github: "https://github.com/doomspork/ua_parser"} ] end - - end diff --git a/mix.lock b/mix.lock index 783374f..f8129b0 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,8 @@ -%{"bunt": {:hex, :bunt, "0.1.6", "5d95a6882f73f3b9969fdfd1953798046664e6f77ec4e486e6fafc7caad97c6f", [:mix], []}, - "credo": {:hex, :credo, "0.5.3", "0c405b36e7651245a8ed63c09e2d52c2e2b89b6d02b1570c4d611e0fcbecf4a2", [:mix], [{:bunt, "~> 0.1.6", [hex: :bunt, optional: false]}]}, - "earmark": {:hex, :earmark, "1.0.3", "89bdbaf2aca8bbb5c97d8b3b55c5dd0cff517ecc78d417e87f1d0982e514557b", [:mix], []}, - "ex_doc": {:hex, :ex_doc, "0.14.4", "a0a79a6896075814f4bc6802b74ccbed6549f47cc5ab34c71eaee2303170b8ef", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, - "yamerl": {:hex, :yamerl, "0.4.0", "ae215b1242810a9bc07716b88062f1bfe06f6bc7cf68372091f630baa536df79", [:rebar3], []}, - "yomel": {:hex, :yomel, "0.5.0", "c5a42d1818deda3f85ae14b1f01f6ece22b9ed8e8087012359fc04b59d85f621", [:make, :mix], []}} +%{ + "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, + "credo": {:hex, :credo, "0.8.10", "261862bb7363247762e1063713bb85df2bbd84af8d8610d1272cd9c1943bba63", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "yamerl": {:hex, :yamerl, "0.5.0", "6ec55a5d830f6f0d65a4030f5c5db24b0e72b813dfbde32fea44b4951ed9417c", [:rebar3], [], "hexpm"}, + "yomel": {:hex, :yomel, "0.5.0", "c5a42d1818deda3f85ae14b1f01f6ece22b9ed8e8087012359fc04b59d85f621", [:make, :mix], []}, +} diff --git a/priv/patterns.yml b/priv/patterns.yml index f710127..0151b73 100644 --- a/priv/patterns.yml +++ b/priv/patterns.yml @@ -1,6 +1,27 @@ user_agent_parsers: #### SPECIAL CASES TOP #### + # CFNetwork Podcast catcher Applications + - regex: '(ESPN)[%20| ]+Radio/(\d+)\.(\d+)\.(\d+) CFNetwork' + - regex: '(Antenna)/(\d+) CFNetwork' + family_replacement: 'AntennaPod' + - regex: '(TopPodcasts)Pro/(\d+) CFNetwork' + - regex: '(MusicDownloader)Lite/(\d+)\.(\d+)\.(\d+) CFNetwork' + - regex: '^(.*)-iPad/(\d+)\.?(\d+)?.?(\d+)?.?(\d+)? CFNetwork' + - regex: '^(.*)-iPhone/(\d+)\.?(\d+)?.?(\d+)?.?(\d+)? CFNetwork' + - regex: '^(.*)/(\d+)\.?(\d+)?.?(\d+)?.?(\d+)? CFNetwork' + + # Podcast catchers + - regex: '(espn\.go)' + family_replacement: 'ESPN' + - regex: '(espnradio\.com)' + family_replacement: 'ESPN' + - regex: 'ESPN APP$' + family_replacement: 'ESPN' + - regex: '(audioboom\.com)' + family_replacement: 'AudioBoom' + - regex: ' (Rivo) RHYTHM' + # @note: iOS / OSX Applications - regex: '(CFNetwork)(?:/(\d+)\.(\d+)\.?(\d+)?)?' family_replacement: 'CFNetwork' @@ -8,6 +29,17 @@ user_agent_parsers: # Pingdom - regex: '(Pingdom.com_bot_version_)(\d+)\.(\d+)' family_replacement: 'PingdomBot' + # 'Mozilla/5.0 (Unknown; Linux x86_64) AppleWebKit/534.34 (KHTML, like Gecko) PingdomTMS/0.8.5 Safari/534.34' + - regex: '(PingdomTMS)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'PingdomBot' + + # New Relic Pinger + - regex: '(NewRelicPinger)/(\d+)\.(\d+)' + family_replacement: 'NewRelicPingerBot' + + #StatusCake + - regex: '(\(StatusCake\))' + family_replacement: 'StatusCakeBot' # Facebook - regex: '(facebookexternalhit)/(\d+)\.(\d+)' @@ -28,17 +60,24 @@ user_agent_parsers: # Bots Pattern '/name-0.0' - regex: '/((?:Ant-)?Nutch|[A-z]+[Bb]ot|[A-z]+[Ss]pider|Axtaris|fetchurl|Isara|ShopSalad|Tailsweep)[ \-](\d+)(?:\.(\d+)(?:\.(\d+))?)?' # Bots Pattern 'name/0.0' - - regex: '(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?' + - regex: '\b(008|Altresium|Argus|BaiduMobaider|BoardReader|DNSGroup|DataparkSearch|EDI|Goodzer|Grub|INGRID|Infohelfer|LinkedInBot|LOOQ|Nutch|PathDefender|Peew|PostPost|Steeler|Twitterbot|VSE|WebCrunch|WebZIP|Y!J-BR[A-Z]|YahooSeeker|envolk|sproose|wminer)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?' # MSIECrawler - regex: '(MSIE) (\d+)\.(\d+)([a-z]\d?)?;.* MSIECrawler' family_replacement: 'MSIECrawler' + # DAVdroid + - regex: '(DAVdroid)/(\d+)\.(\d+)(?:\.(\d+))?' + # Downloader ... - regex: '(Google-HTTP-Java-Client|Apache-HttpClient|http%20client|Python-urllib|HttpMonitor|TLSProber|WinHTTP|JNLP|okhttp)(?:[ /](\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' + # Pinterestbot + - regex: '(Pinterest(?:bot)?)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?[;\s\(]+\+https://www.pinterest.com/bot.html' + family_replacement: 'Pinterestbot' + # Bots - - regex: '(1470\.net crawler|50\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]+-Agent|AdsBot-Google(?:-[a-z]+)?|altavista|AppEngine-Google|archive.*?\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]+)*|bingbot|BingPreview|blitzbot|BlogBridge|BoardReader(?: [A-Za-z]+)*|boitho.com-dc|BotSeer|\b\w*favicon\w*\b|\bYeti(?:-[a-z]+)?|Catchpoint bot|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\(S\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher)?|Feed Seeker Bot|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]+-)?Googlebot(?:-[a-zA-Z]+)?|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile)?|IconSurf|IlTrovatore(?:-Setaccio)?|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]+Bot|jbot\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\.RU_Bot|masidani_bot|Mediapartners-Google|Microsoft .*? Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media *)?|msrbot|netresearch|Netvibes|NewsGator[^/]*|^NING|Nutch[^/]*|Nymesis|ObjectsSearch|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|TheUsefulbot|ThumbShotsBot|Thumbshots\.ru|TwitterBot|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]+|WhatWeb|WIRE|WordPress|Wotbox|www\.almaden\.ibm\.com|Xenu(?:.s)? Link Sleuth|Xerka [A-z]+Bot|yacy(?:bot)?|Yahoo[a-z]*Seeker|Yahoo! Slurp|Yandex\w+|YodaoBot(?:-[A-z]+)?|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\.ze\.bz|ZooShot|ZyBorg)(?:[ /]v?(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' + - regex: '(1470\.net crawler|50\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]+-Agent|AdsBot-Google(?:-[a-z]+)?|altavista|AppEngine-Google|archive.*?\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]+)*|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader(?: [A-Za-z]+)*|boitho.com-dc|BotSeer|\b\w*favicon\w*\b|\bYeti(?:-[a-z]+)?|Catchpoint(?: bot)?|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\(S\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher)?|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]+-)?Googlebot(?:-[a-zA-Z]+)?|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile)?|IconSurf|IlTrovatore(?:-Setaccio)?|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]+Bot|jbot\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .*? Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media *)?|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]*|^NING|Nutch[^/]*|Nymesis|ObjectsSearch|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\.ru|Tiny Tiny RSS|TwitterBot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]+|WhatWeb|WIRE|WordPress|Wotbox|www\.almaden\.ibm\.com|Xenu(?:.s)? Link Sleuth|Xerka [A-z]+Bot|yacy(?:bot)?|Yahoo[a-z]*Seeker|Yahoo! Slurp|Yandex\w+|YodaoBot(?:-[A-z]+)?|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\.ze\.bz|ZooShot|ZyBorg)(?:[ /]v?(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' # Bots General matcher 'name/0.0' - regex: '(?:\/[A-Za-z0-9\.]+)? *([A-Za-z0-9 \-_\!\[\]:]*(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]*))/(\d+)(?:\.(\d+)(?:\.(\d+))?)?' @@ -57,15 +96,17 @@ user_agent_parsers: # Social Networks # Facebook - - regex: '\[FB.*;(FBAV)/(\d+)(?:\.(\d+)(?:\.(\d)+)?)?' + - regex: '\[FB.*;(FBAV)/(\d+)(?:\.(\d+)(?:\.(\d+))?)?' family_replacement: 'Facebook' # Pinterest - regex: '\[(Pinterest)/[^\]]+\]' - - regex: '(Pinterest)(?: for Android(?: Tablet)?)?/(\d+)(?:\.(\d+)(?:\.(\d)+)?)?' + - regex: '(Pinterest)(?: for Android(?: Tablet)?)?/(\d+)(?:\.(\d+)(?:\.(\d+))?)?' + + # Pale Moon + - regex: '(PaleMoon)/(\d+)\.(\d+)\.?(\d+)?' + family_replacement: 'Pale Moon' # Firefox - - regex: '(Pale[Mm]oon)/(\d+)\.(\d+)\.?(\d+)?' - family_replacement: 'Pale Moon (Firefox Variant)' - regex: '(Fennec)/(\d+)\.(\d+)\.?([ab]?\d+[a-z]*)' family_replacement: 'Firefox Mobile' - regex: '(Fennec)/(\d+)\.(\d+)(pre)' @@ -146,6 +187,10 @@ user_agent_parsers: - regex: '(OPiOS)/(\d+).(\d+).(\d+)' family_replacement: 'Opera Mini' + # Opera Neon + - regex: 'Chrome/.+( MMS)/(\d+).(\d+).(\d+)' + family_replacement: 'Opera Neon' + # Palm WebOS looks a lot like Safari. - regex: '(hpw|web)OS/(\d+)\.(\d+)(?:\.(\d+))?' family_replacement: 'webOS Browser' @@ -190,8 +235,6 @@ user_agent_parsers: - regex: '(Symphony) (\d+).(\d+)' - - regex: '(Minimo)' - - regex: 'PLAYSTATION 3.+WebKit' family_replacement: 'NetFront NX' - regex: 'PLAYSTATION 3' @@ -210,7 +253,6 @@ user_agent_parsers: - regex: '(Silk)/(\d+)\.(\d+)(?:\.([0-9\-]+))?' family_replacement: 'Amazon Silk' - # @ref: http://www.puffinbrowser.com - regex: '(Puffin)/(\d+)\.(\d+)(?:\.(\d+))?' @@ -222,7 +264,30 @@ user_agent_parsers: - regex: '(SamsungBrowser)/(\d+)\.(\d+)' family_replacement: 'Samsung Internet' + # Seznam.cz browser (based on WebKit) + - regex: '(SznProhlizec)/(\d+)\.(\d+)(?:\.(\d+))?' + family_replacement: 'Seznam.cz' + + # Coc Coc browser, based on Chrome (used in Vietnam) + - regex: '(coc_coc_browser)/(\d+)\.(\d+)(?:\.(\d+))?' + family_replacement: 'Coc Coc' + + # Baidu Browsers (desktop spoofs chrome & IE, explorer is mobile) + - regex: '(baidubrowser)[/\s](\d+)(?:\.(\d+)(?:\.(\d+))?)?' + family_replacement: 'Baidu Browser' + - regex: '(FlyFlow)/(\d+)\.(\d+)' + family_replacement: 'Baidu Explorer' + + # MxBrowser is Maxthon. Must go before Mobile Chrome for Android + - regex: '(MxBrowser)/(\d+)\.(\d+)(?:\.(\d+))?' + family_replacement: 'Maxthon' + + # Crosswalk must go before Mobile Chrome for Android + - regex: '(Crosswalk)/(\d+)\.(\d+)\.(\d+)\.(\d+)' + # Chrome Mobile + - regex: '; wv\).+(Chrome)/(\d+)\.(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Chrome Mobile WebView' - regex: '(CrMo)/(\d+)\.(\d+)\.(\d+)\.(\d+)' family_replacement: 'Chrome Mobile' - regex: '(CriOS)/(\d+)\.(\d+)\.(\d+)\.(\d+)' @@ -244,12 +309,6 @@ user_agent_parsers: - regex: '(SE 2\.X) MetaSr (\d+)\.(\d+)' family_replacement: 'Sogou Explorer' - # Baidu Browsers (desktop spoofs chrome & IE, explorer is mobile) - - regex: '(baidubrowser)[/\s](\d+)' - family_replacement: 'Baidu Browser' - - regex: '(FlyFlow)/(\d+)\.(\d+)' - family_replacement: 'Baidu Explorer' - # QQ Browsers - regex: '(MQQBrowser/Mini)(?:(\d+)(?:\.(\d+)(?:\.(\d+))?)?)?' family_replacement: 'QQ Browser Mini' @@ -276,16 +335,29 @@ user_agent_parsers: # AOL Browser (IE-based) - regex: '(AOL) (\d+)\.(\d+); AOLBuild (\d+)' - # MxBrowser is Maxthon - - regex: '(MxBrowser)/(\d+)\.(\d+)(?:\.(\d+))?' - family_replacement: 'Maxthon' + # Podcast catcher Applications using iTunes + - regex: '(PodCruncher|Downcast)[ /]?(\d+)\.?(\d+)?\.?(\d+)?\.?(\d+)?' + + # Box Notes https://www.box.com/resources/downloads + # Must be before Electron + - regex: ' (BoxNotes)/(\d+)\.(\d+)\.(\d+)' #### END SPECIAL CASES TOP #### #### MAIN CASES - this catches > 50% of all browsers #### + + # Slack desktop client (needs to be before Apple Mail, Electron, and Chrome as it gets wrongly detected on Mac OS otherwise) + - regex: '(Slack_SSB)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Slack Desktop Client' + + # HipChat provides a version on Mac, but not on Windows. + # Needs to be before Chrome on Windows, and AppleMail on Mac. + - regex: '(HipChat)/?(\d+)?' + family_replacement: 'HipChat Desktop Client' + # Browser/major_version.minor_version.beta_version - - regex: '\b(MobileIron|Crosswalk|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Spotify|Flock|Netscape|Lunascape|WebPilot|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|MacOutlook|Electron)/(\d+)\.(\d+)\.(\d+)' + - regex: '\b(MobileIron|FireWeb|Jasmine|ANTGalio|Midori|Fresco|Lobo|PaleMoon|Maxthon|Lynx|OmniWeb|Dillo|Camino|Demeter|Fluid|Fennec|Epiphany|Shiira|Sunrise|Spotify|Flock|Netscape|Lunascape|WebPilot|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|MacOutlook|Electron)/(\d+)\.(\d+)\.(\d+)' # Outlook 2007 - regex: 'Microsoft Office Outlook 12\.\d+\.\d+|MSOffice 12' @@ -334,7 +406,7 @@ user_agent_parsers: - regex: '(Vivaldi)/(\d+)\.(\d+)\.(\d+)' # Edge/major_version.minor_version - - regex: '(Edge)/(\d+)\.(\d+)' + - regex: '(Edge)/(\d+)(?:\.(\d+))?' # Brave Browser https://brave.com/ - regex: '(brave)/(\d+)\.(\d+)\.(\d+) Chrome' @@ -348,8 +420,18 @@ user_agent_parsers: # @ref: http://www.dolphin.com - regex: '\b(Dolphin)(?: |HDCN/|/INT\-)(\d+)\.(\d+)\.?(\d+)?' + # Headless Chrome + # https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md + - regex: '(HeadlessChrome)(?:/(\d+)\.(\d+)\.(\d+))?' + + # Evolution Mail CardDav/CalDav integration + - regex: '(Evolution)/(\d+)\.(\d+)\.(\d+\.\d+)' + + # Roundcube Mail CardDav plugin + - regex: '(RCM CardDAV plugin)/(\d+)\.(\d+)\.(\d+(?:-dev)?)' + # Browser/major_version.minor_version - - regex: '(bingbot|Bolt|AdobeAIR|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|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|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla|MailBar|kmail2|YahooMobileMail|ExchangeWebServices|ExchangeServicesClient)/(\d+)\.(\d+)(?:\.(\d+))?' + - regex: '(bingbot|Bolt|AdobeAIR|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|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|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla|MailBar|kmail2|YahooMobileMail|ExchangeWebServices|ExchangeServicesClient|Dragon|Outlook-iOS-Android)/(\d+)\.(\d+)(?:\.(\d+))?' # Chrome/Chromium/major_version.minor_version - regex: '(Chromium|Chrome)/(\d+)\.(\d+)(?:\.(\d+))?' @@ -369,6 +451,54 @@ user_agent_parsers: # Baca Berita App News Reader - regex: '(BacaBerita App)\/(\d+)\.(\d+)\.(\d+)' + # Podcast catchers + - regex: '^(bPod|Pocket Casts|Player FM)$' + - regex: '^(AlexaMediaPlayer|VLC)/(\d+)\.(\d+)\.([^.\s]+)' + - regex: '^(AntennaPod|WMPlayer|Zune|Podkicker|Radio|ExoPlayerDemo|Overcast|PocketTunes|NSPlayer|okhttp|DoggCatcher|QuickNews|QuickTime|Peapod|Podcasts|GoldenPod|VLC|Spotify|Miro|MediaGo|Juice|iPodder|gPodder|Banshee)/(\d+)\.(\d+)\.?(\d+)?\.?(\d+)?' + - regex: '^(Peapod|Liferea)/([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?' + - regex: '^(bPod|Player FM) BMID/(\S+)' + - regex: '^(Podcast ?Addict)/v(\d+) ' + - regex: '^(Podcast ?Addict) ' + family_replacement: 'PodcastAddict' + - regex: '(Replay) AV' + - regex: '(VOX) Music Player' + - regex: '(CITA) RSS Aggregator/(\d+)\.(\d+)' + - regex: '(Pocket Casts)$' + - regex: '(Player FM)$' + - regex: '(LG Player|Doppler|FancyMusic|MediaMonkey|Clementine) (\d+)\.(\d+)\.?([^.\s]+)?\.?([^.\s]+)?' + - regex: '(philpodder)/(\d+)\.(\d+)\.?([^.\s]+)?\.?([^.\s]+)?' + - regex: '(Player FM|Pocket Casts|DoggCatcher|Spotify|MediaMonkey|MediaGo|BashPodder)' + - regex: '(QuickTime)\.(\d+)\.(\d+)\.(\d+)' + - regex: '(Kinoma)(\d+)' + - regex: '(Fancy) Cloud Music (\d+)\.(\d+)' + family_replacement: 'FancyMusic' + - regex: 'EspnDownloadManager' + family_replacement: 'ESPN' + - regex: '(ESPN) Radio (\d+)\.(\d+)\.?(\d+)? ?[rv:]?(\d+)? ' + - regex: '(podracer|jPodder) v ?(\d+)\.(\d+)\.?(\d+)?' + - regex: '(ZDM)/(\d+)\.(\d+)[; ]?' + - regex: '(Zune|BeyondPod) (\d+)\.?(\d+)?[\);]' + - regex: '(WMPlayer)/(\d+)\.(\d+)\.(\d+)\.(\d+)' + - regex: '^(Lavf)' + family_replacement: 'WMPlayer' + - regex: '^(RSSRadio)[ /]?(\d+)?' + - regex: '(RSS_Radio) (\d+)\.(\d+)' + family_replacement: 'RSSRadio' + - regex: '(Podkicker) \S+/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Podkicker' + - regex: '^(HTC) Streaming Player \S+ / \S+ / \S+ / (\d+)\.(\d+)\.?(\d+)?' + - regex: '^(Stitcher)/iOS' + - regex: '^(Stitcher)/Android' + - regex: '^(VLC) .*version (\d+)\.(\d+)\.(\d+)' + - regex: ' (VLC) for' + - regex: '(vlc)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'VLC' + - regex: '^(foobar)\S+/([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?' + - regex: '^(Clementine)\S+ ([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?' + - regex: '(amarok)/([^.\s]+)\.([^.\s]+)?\.?([^.\s]+)?' + family_replacement: 'Amarok' + - regex: '(Custom)-Feed Reader' + # Browser major_version.minor_version.beta_version (space instead of slash) - regex: '(iRider|Crazy Browser|SkipStone|iCab|Lunascape|Sleipnir|Maemo Browser) (\d+)\.(\d+)\.(\d+)' # Browser major_version.minor_version (space instead of slash) @@ -402,9 +532,15 @@ user_agent_parsers: - regex: '(MSIE) (\d+)\.(\d+).*XBLWP7' family_replacement: 'IE Large Screen' - # Slack desktop client (needs to be before Apple Mail as it gets wrongly detected on Mac OS otherwise) - - regex: '(Slack_SSB)/(\d+)\.(\d+)\.(\d+)' - family_replacement: 'Slack Desktop Client' + # Nextcloud desktop sync client + - regex: '(Nextcloud)' + + # Generic mirall client + - regex: '(mirall)/(\d+)\.(\d+)\.(\d+)' + + # Nextcloud/Owncloud android client + - regex: '(ownCloud-android)/(\d+)\.(\d+)\.(\d+)' + family_replacement: 'Owncloud' #### END MAIN CASES #### @@ -573,6 +709,8 @@ user_agent_parsers: - regex: '(Kurio)\/(\d+)\.(\d+)\.(\d+)' family_replacement: 'Kurio App' + # Box Drive and Box Sync https://www.box.com/resources/downloads + - regex: '^(Box(?: Sync)?)/(\d+)\.(\d+)\.(\d+)' os_parsers: ########## @@ -643,6 +781,10 @@ os_parsers: - regex: '(Windows Phone) (?:OS[ /])?(\d+)\.(\d+)' + # Again a MS-special one: iPhone.*Outlook-iOS-Android/x.x is erroneously detected as Android + - regex: '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\d+)[_\.](\d+)(?:[_\.](\d+))?.*Outlook-iOS-Android' + os_replacement: 'iOS' + ########## # Android # can actually detect rooted android os. do we care? @@ -750,6 +892,10 @@ os_parsers: - regex: 'Win32' os_replacement: 'Windows 95' + # Box apps (Drive, Sync, Notes) on Windows https://www.box.com/resources/downloads + - regex: '^Box.*Windows/([\d.]+);' + os_replacement: 'Windows $1' + ########## # Tizen OS from Samsung # spoofs Android so pushing it above @@ -761,7 +907,7 @@ os_parsers: # @ref: http://en.wikipedia.org/wiki/Mac_OS_X#Versions # @ref: http://www.puredarwin.org/curious/versions ########## - - regex: '((?:Mac ?|; )OS X)[\s/](?:(\d+)[_.](\d+)(?:[_.](\d+))?|Mach-O)' + - regex: '((?:Mac[ +]?|; )OS[ +]X)[\s+/](?:(\d+)[_.](\d+)(?:[_.](\d+))?|Mach-O)' os_replacement: 'Mac OS X' # Leopard - regex: ' (Dar)(win)/(9).(\d+).*\((?:i386|x86_64|Power Macintosh)\)' @@ -800,6 +946,10 @@ os_parsers: # ios devices spoof (mac os x), so including intel/ppc prefixes - regex: '(?:PPC|Intel) (Mac OS X)' + # Box Drive and Box Sync on Mac OS X use OSX version numbers, not Darwin + - regex: '^Box.*;(Darwin)/(10)\.(1\d)(?:\.(\d+))?' + os_replacement: 'Mac OS X' + ########## # iOS # http://en.wikipedia.org/wiki/IOS_version_history @@ -808,7 +958,7 @@ os_parsers: - regex: '(Apple\s?TV)(?:/(\d+)\.(\d+))?' os_replacement: 'ATV OS X' - - regex: '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone)[ +]+(\d+)[_\.](\d+)(?:[_\.](\d+))?' + - regex: '(CPU[ +]OS|iPhone[ +]OS|CPU[ +]iPhone|CPU IPhone OS)[ +]+(\d+)[_\.](\d+)(?:[_\.](\d+))?' os_replacement: 'iOS' # remaining cases are mostly only opera uas, so catch opera as to not catch iphone spoofs @@ -855,11 +1005,30 @@ os_parsers: os_replacement: 'Mac OS X' os_v1_replacement: '10' os_v2_replacement: '10' + - regex: '(CF)(Network)/(760)\.(\d)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '11' - regex: '(CF)(Network)/758\.(\d)' os_replacement: 'iOS' os_v1_replacement: '9' + - regex: '(CF)(Network)/808\.(\d)' + os_replacement: 'iOS' + os_v1_replacement: '10' ########## + # CFNetwork macOS Apps (must be before CFNetwork iOS Apps + # @ref: https://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history + ########## + - regex: 'CFNetwork/.* Darwin/16\.\d+.*\(x86_64\)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '12' + - regex: 'CFNetwork/8.* Darwin/15\.\d+.*\(x86_64\)' + os_replacement: 'Mac OS X' + os_v1_replacement: '10' + os_v2_replacement: '11' + ########## # CFNetwork iOS Apps # @ref: https://en.wikipedia.org/wiki/Darwin_(operating_system)#Release_history ########## @@ -889,7 +1058,6 @@ os_parsers: - regex: 'CFNetwork/8.* Darwin/(16)\.\d+' os_replacement: 'iOS' os_v1_replacement: '10' - os_v2_replacement: '0' # iOS Apps - regex: '\b(iOS[ /]|iOS; |iPhone(?:/| v|[ _]OS[/,]|; | OS : |\d,\d/|\d,\d; )|iPad/)(\d{1,2})[_\.](\d{1,2})(?:[_\.](\d+))?' os_replacement: 'iOS' @@ -1018,6 +1186,12 @@ os_parsers: - regex: '(WebTV)/(\d+).(\d+)' + ########## + # Chromecast + ########## + - regex: '(CrKey)(?:[/](\d+)\.(\d+)(?:\.(\d+))?)?' + os_replacement: 'Chromecast' + ########## # Misc mobile ########## @@ -1927,6 +2101,11 @@ device_parsers: device_replacement: 'Gionee $1' brand_replacement: 'Gionee' model_replacement: '$1' + - regex: '\sGIONEE[-\s_](\w*)' + regex_flag: 'i' + device_replacement: 'Gionee $1' + brand_replacement: 'Gionee' + model_replacement: '$1' ######### # GoClever @@ -1949,6 +2128,10 @@ device_parsers: device_replacement: '$1' brand_replacement: 'Google' model_replacement: '$1' + - regex: '; *(Pixel \w+) Build' + device_replacement: '$1' + brand_replacement: 'Google' + model_replacement: '$1' ######### # Gigabyte @@ -2101,7 +2284,7 @@ device_parsers: device_replacement: '$1' brand_replacement: 'Huawei' model_replacement: '$1' - - regex: '; *([^;]+) Build/Huawei' + - regex: '; *([^;]+) Build/(?:Huawei|HUAWEI)' device_replacement: '$1' brand_replacement: 'Huawei' model_replacement: '$1' @@ -2117,7 +2300,7 @@ device_parsers: device_replacement: 'Huawei Ideos$1' brand_replacement: 'Huawei' model_replacement: 'Ideos$1' - - regex: '; *(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660|Nexus 6P) Build' + - regex: '; *(Orange Daytona|Pulse|Pulse Mini|Vodafone 858|C8500|C8600|C8650|C8660|Nexus 6P|ATH-.+?) Build[/ ]' device_replacement: 'Huawei $1' brand_replacement: 'Huawei' model_replacement: '$1' @@ -3035,6 +3218,19 @@ device_parsers: brand_replacement: 'Odys' model_replacement: '$1' + ######### + # OnePlus + # @ref https://oneplus.net/ + ######### + - regex: '; (ONE [a-zA-Z]\d+) Build/' + device_replacement: 'OnePlus $1' + brand_replacement: 'OnePlus' + model_replacement: '$1' + - regex: '; (ONEPLUS [a-zA-Z]\d+) Build/' + device_replacement: 'OnePlus $1' + brand_replacement: 'OnePlus' + model_replacement: '$1' + ######### # Orion # @ref: http://www.orion.ua/en/products/computer-products/tablet-pcs.html @@ -3275,6 +3471,15 @@ device_parsers: brand_replacement: 'Quanta' model_replacement: '$1' + ######### + # RCA + # @ref: http://rcamobilephone.com/ + ######### + - regex: '; (RCT\w+) Build/' + device_replacement: '$1' + brand_replacement: 'RCA' + model_replacement: '$1' + ######### # Rockchip # @ref: http://www.rock-chips.com/a/cn/product/index.html @@ -4180,7 +4385,7 @@ device_parsers: ######### # Noka Windows Phones ######### - - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*(\d{3,}[^;\)]*)' + - regex: 'Windows Phone [^;]+; .*?IEMobile/[^;\)]+[;\)] ?(?:ARM; ?Touch; ?|Touch; ?)?(?:rv:11; )?(?:NOKIA|Nokia)[^;]*; *(?:NOKIA ?|Nokia ?|LUMIA ?|[Ll]umia ?)*(\d{3,}[^;\)]*)' device_replacement: 'Lumia $1' brand_replacement: 'Nokia' model_replacement: 'Lumia $1' @@ -4380,6 +4585,12 @@ device_parsers: device_replacement: '$1$2,$3' brand_replacement: 'Apple' model_replacement: '$1$2,$3' + # @note: newer desktop applications don't show device info + # This is here so as to not have them recorded as iOS-Device + - regex: 'CFNetwork/.* Darwin/\d+\.\d+\.\d+ \(x86_64\)' + device_replacement: 'Mac' + brand_replacement: 'Apple' + model_replacement: 'Mac' # @note: iOS applications do not show device info - regex: 'CFNetwork/.* Darwin/\d' device_replacement: 'iOS-Device' @@ -4740,27 +4951,27 @@ device_parsers: ######### # Android General Device Matching (far from perfect) ######### - - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; WOWMobile (.+) Build' + - regex: 'Android[\- ][\d]+\.[\d]+; [A-Za-z]{2}\-[A-Za-z]{0,2}; WOWMobile (.+) Build[/ ]' brand_replacement: 'Generic_Android' model_replacement: '$1' - - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{0,2} *; *(.+?) Build' + - regex: 'Android[\- ][\d]+\.[\d]+\-update1; [A-Za-z]{2}\-[A-Za-z]{0,2} *; *(.+?) Build[/ ]' brand_replacement: 'Generic_Android' model_replacement: '$1' - - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{2}[_\-][A-Za-z]{0,2}\-? *; *(.+?) Build' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{2}[_\-][A-Za-z]{0,2}\-? *; *(.+?) Build[/ ]' brand_replacement: 'Generic_Android' model_replacement: '$1' - - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{0,2}\- *; *(.+?) Build' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[A-Za-z]{0,2}\- *; *(.+?) Build[/ ]' brand_replacement: 'Generic_Android' model_replacement: '$1' # No build info at all - "Build" follows locale immediately - - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[a-z]{0,2}[_\-]?[A-Za-z]{0,2};? Build' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *[a-z]{0,2}[_\-]?[A-Za-z]{0,2};? Build[/ ]' device_replacement: 'Generic Smartphone' brand_replacement: 'Generic' model_replacement: 'Smartphone' - - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *\-?[A-Za-z]{2}; *(.+?) Build' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}; *\-?[A-Za-z]{2}; *(.+?) Build[/ ]' brand_replacement: 'Generic_Android' model_replacement: '$1' - - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}(?:;.*)?; *(.+?) Build' + - regex: 'Android[\- ][\d]+(?:\.[\d]+){1,2}(?:;.*)?; *(.+?) Build[/ ]' brand_replacement: 'Generic_Android' model_replacement: '$1' @@ -4807,7 +5018,7 @@ device_parsers: ########## # Spiders (this is hack...) ########## - - regex: '(bot|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|BingPreview|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.*/\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes|NL-Crawler)' + - regex: '(bot|zao|borg|DBot|oegp|silk|Xenu|zeal|^NING|CCBot|crawl|htdig|lycos|slurp|teoma|voila|yahoo|Sogou|CiBra|Nutch|^Java/|^JNLP/|Daumoa|Genieo|ichiro|larbin|pompos|Scrapy|snappy|speedy|spider|msnbot|msrbot|vortex|^vortex|crawler|favicon|indexer|Riddler|scooter|scraper|scrubby|WhatWeb|WinHTTP|bingbot|BingPreview|openbot|gigabot|furlbot|polybot|seekbot|^voyager|archiver|Icarus6j|mogimogi|Netvibes|blitzbot|altavista|charlotte|findlinks|Retreiver|TLSProber|WordPress|SeznamBot|ProoXiBot|wsr\-agent|Squrl Java|EtaoSpider|PaperLiBot|SputnikBot|A6\-Indexer|netresearch|searchsight|baiduspider|YisouSpider|ICC\-Crawler|http%20client|Python-urllib|dataparksearch|converacrawler|Screaming Frog|AppEngine-Google|YahooCacheSystem|fast\-webcrawler|Sogou Pic Spider|semanticdiscovery|Innovazion Crawler|facebookexternalhit|Google.*/\+/web/snippet|Google-HTTP-Java-Client|BlogBridge|IlTrovatore-Setaccio|InternetArchive|GomezAgent|WebThumbnail|heritrix|NewsGator|PagePeeker|Reaper|ZooShot|holmes|NL-Crawler|Pingdom|StatusCake|WhatsApp|masscan|Google Web Preview|Qwantify)' regex_flag: 'i' device_replacement: 'Spider' brand_replacement: 'Spider'