agentry 3.0.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 (119) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +93 -0
  3. data/LICENSE.md +21 -0
  4. data/README.md +552 -0
  5. data/data/bot_categories.json +1 -0
  6. data/data/bot_exceptions.json +1 -0
  7. data/data/bot_ip_ranges.json +1 -0
  8. data/data/bots.json +1 -0
  9. data/data/languages.json +1 -0
  10. data/data/samsung.json +1 -0
  11. data/data/search_engines.json +1 -0
  12. data/lib/agentry.rb +3 -0
  13. data/lib/browser/accept_language.rb +55 -0
  14. data/lib/browser/action_controller.rb +21 -0
  15. data/lib/browser/aliases.rb +33 -0
  16. data/lib/browser/alipay.rb +21 -0
  17. data/lib/browser/base.rb +307 -0
  18. data/lib/browser/blackberry.rb +23 -0
  19. data/lib/browser/bot/empty_user_agent_matcher.rb +11 -0
  20. data/lib/browser/bot/ip_ranges.rb +194 -0
  21. data/lib/browser/bot/keyword_matcher.rb +11 -0
  22. data/lib/browser/bot/known_bots_matcher.rb +11 -0
  23. data/lib/browser/bot.rb +221 -0
  24. data/lib/browser/browser.rb +200 -0
  25. data/lib/browser/cache.rb +92 -0
  26. data/lib/browser/chrome.rb +43 -0
  27. data/lib/browser/client_hints.rb +73 -0
  28. data/lib/browser/cloudflare.rb +65 -0
  29. data/lib/browser/detect_version.rb +22 -0
  30. data/lib/browser/detection.rb +25 -0
  31. data/lib/browser/device/android.rb +20 -0
  32. data/lib/browser/device/base.rb +13 -0
  33. data/lib/browser/device/blackberry_playbook.rb +19 -0
  34. data/lib/browser/device/ipad.rb +19 -0
  35. data/lib/browser/device/iphone.rb +19 -0
  36. data/lib/browser/device/ipod_touch.rb +19 -0
  37. data/lib/browser/device/kindle.rb +19 -0
  38. data/lib/browser/device/kindle_fire.rb +19 -0
  39. data/lib/browser/device/playstation3.rb +19 -0
  40. data/lib/browser/device/playstation4.rb +19 -0
  41. data/lib/browser/device/psp.rb +19 -0
  42. data/lib/browser/device/psvita.rb +19 -0
  43. data/lib/browser/device/samsung.rb +33 -0
  44. data/lib/browser/device/surface.rb +23 -0
  45. data/lib/browser/device/switch.rb +19 -0
  46. data/lib/browser/device/tv.rb +19 -0
  47. data/lib/browser/device/unknown.rb +19 -0
  48. data/lib/browser/device/wii.rb +19 -0
  49. data/lib/browser/device/wiiu.rb +19 -0
  50. data/lib/browser/device/xbox_360.rb +19 -0
  51. data/lib/browser/device/xbox_one.rb +19 -0
  52. data/lib/browser/device.rb +246 -0
  53. data/lib/browser/duck_duck_go.rb +22 -0
  54. data/lib/browser/edge.rb +25 -0
  55. data/lib/browser/electron.rb +22 -0
  56. data/lib/browser/epiphany.rb +21 -0
  57. data/lib/browser/facebook.rb +23 -0
  58. data/lib/browser/firefox.rb +21 -0
  59. data/lib/browser/google_search_app.rb +21 -0
  60. data/lib/browser/huawei_browser.rb +21 -0
  61. data/lib/browser/instagram.rb +21 -0
  62. data/lib/browser/internet_explorer.rb +63 -0
  63. data/lib/browser/maxthon.rb +21 -0
  64. data/lib/browser/meta/base.rb +42 -0
  65. data/lib/browser/meta/device.rb +11 -0
  66. data/lib/browser/meta/generic_browser.rb +15 -0
  67. data/lib/browser/meta/id.rb +11 -0
  68. data/lib/browser/meta/ie.rb +20 -0
  69. data/lib/browser/meta/ios.rb +11 -0
  70. data/lib/browser/meta/mobile.rb +11 -0
  71. data/lib/browser/meta/platform.rb +11 -0
  72. data/lib/browser/meta/proxy.rb +11 -0
  73. data/lib/browser/meta/safari.rb +11 -0
  74. data/lib/browser/meta/tablet.rb +11 -0
  75. data/lib/browser/meta/webkit.rb +11 -0
  76. data/lib/browser/meta.rb +14 -0
  77. data/lib/browser/micro_messenger.rb +21 -0
  78. data/lib/browser/middleware/context/additions.rb +18 -0
  79. data/lib/browser/middleware/context/url_methods.rb +15 -0
  80. data/lib/browser/middleware/context.rb +23 -0
  81. data/lib/browser/middleware.rb +70 -0
  82. data/lib/browser/miui_browser.rb +21 -0
  83. data/lib/browser/nokia.rb +21 -0
  84. data/lib/browser/opera.rb +21 -0
  85. data/lib/browser/otter.rb +21 -0
  86. data/lib/browser/phantom_js.rb +21 -0
  87. data/lib/browser/platform/adobe_air.rb +23 -0
  88. data/lib/browser/platform/android.rb +23 -0
  89. data/lib/browser/platform/base.rb +18 -0
  90. data/lib/browser/platform/blackberry.rb +23 -0
  91. data/lib/browser/platform/chrome_os.rb +23 -0
  92. data/lib/browser/platform/firefox_os.rb +23 -0
  93. data/lib/browser/platform/ios.rb +36 -0
  94. data/lib/browser/platform/kai_os.rb +23 -0
  95. data/lib/browser/platform/linux.rb +23 -0
  96. data/lib/browser/platform/mac.rb +25 -0
  97. data/lib/browser/platform/unknown.rb +23 -0
  98. data/lib/browser/platform/windows.rb +23 -0
  99. data/lib/browser/platform/windows_mobile.rb +23 -0
  100. data/lib/browser/platform/windows_phone.rb +23 -0
  101. data/lib/browser/platform.rb +220 -0
  102. data/lib/browser/qq.rb +25 -0
  103. data/lib/browser/rails.rb +24 -0
  104. data/lib/browser/safari.rb +40 -0
  105. data/lib/browser/samsung_browser.rb +21 -0
  106. data/lib/browser/snapchat.rb +21 -0
  107. data/lib/browser/sougou_browser.rb +24 -0
  108. data/lib/browser/sputnik.rb +21 -0
  109. data/lib/browser/testing.rb +29 -0
  110. data/lib/browser/uc_browser.rb +21 -0
  111. data/lib/browser/unknown.rb +32 -0
  112. data/lib/browser/version.rb +5 -0
  113. data/lib/browser/weibo.rb +21 -0
  114. data/lib/browser/yandex.rb +21 -0
  115. data/lib/browser.rb +4 -0
  116. data/test/ua.yml +181 -0
  117. data/test/ua_bots.yml +121 -0
  118. data/test/ua_search_engines.yml +7 -0
  119. metadata +274 -0
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ module Meta
5
+ class Safari < Base
6
+ def meta
7
+ "safari safari#{browser.version}" if browser.safari?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ module Meta
5
+ class Tablet < Base
6
+ def meta
7
+ "tablet" if browser.device.tablet?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ module Meta
5
+ class Webkit < Base
6
+ def meta
7
+ "webkit" if browser.webkit?
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "meta/base"
4
+ require_relative "meta/generic_browser"
5
+ require_relative "meta/id"
6
+ require_relative "meta/ie"
7
+ require_relative "meta/ios"
8
+ require_relative "meta/mobile"
9
+ require_relative "meta/platform"
10
+ require_relative "meta/proxy"
11
+ require_relative "meta/safari"
12
+ require_relative "meta/webkit"
13
+ require_relative "meta/tablet"
14
+ require_relative "meta/device"
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class MicroMessenger < Base
5
+ def id
6
+ :micro_messenger
7
+ end
8
+
9
+ def name
10
+ "MicroMessenger"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r{(?:MicroMessenger)/([\d.]+)}i, 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua.match?(/MicroMessenger/i)
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "url_methods"
4
+
5
+ module Browser
6
+ class Middleware
7
+ class Context
8
+ module Additions
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Rails.application.routes.url_helpers
13
+ include UrlMethods
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Middleware
5
+ class Context
6
+ module UrlMethods
7
+ def default_url_options
8
+ Rails.configuration.browser.default_url_options ||
9
+ Rails.configuration.action_mailer.default_url_options ||
10
+ {}
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Middleware
5
+ class Context
6
+ attr_reader :browser, :request
7
+
8
+ def initialize(request)
9
+ @request = request
10
+
11
+ @browser = Browser.new(
12
+ request.user_agent,
13
+ accept_language: request.env["HTTP_ACCEPT_LANGUAGE"],
14
+ headers: request.env
15
+ )
16
+ end
17
+
18
+ def redirect_to(path)
19
+ throw :redirected, path.to_s
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require_relative "middleware/context"
5
+
6
+ module Browser
7
+ class Middleware
8
+ # Detect the most common assets.
9
+ ASSETS_REGEX =
10
+ /\.(css|png|jpe?g|gif|js|svg|ico|flv|mov|m4v|ogg|swf)\z/i
11
+
12
+ # Detect the ACCEPT header. IE8 send */*.
13
+ ACCEPT_REGEX = %r{(text/html|\*/\*)}
14
+
15
+ def initialize(app, &block)
16
+ raise ArgumentError, "Browser::Middleware requires a block" unless block
17
+
18
+ @app = app
19
+ @block = block
20
+ end
21
+
22
+ def call(env)
23
+ request = Rack::Request.new(env)
24
+
25
+ # Only apply verification on HTML requests.
26
+ # This ensures that images, CSS and JavaScript
27
+ # will be rendered.
28
+ return run_app(env) unless process?(request)
29
+
30
+ path = catch(:redirected) do
31
+ Context.new(request).instance_eval(&@block)
32
+ end
33
+
34
+ # No path, no match.
35
+ return run_app(env) unless path
36
+
37
+ resolve_redirection(env, request.path, path)
38
+ end
39
+
40
+ def resolve_redirection(env, current_path, path)
41
+ uri = URI.parse(path)
42
+
43
+ if uri.path == current_path
44
+ run_app(env)
45
+ else
46
+ redirect(path)
47
+ end
48
+ end
49
+
50
+ def redirect(path)
51
+ [302, {"Content-Type" => "text/html", "Location" => path}, []]
52
+ end
53
+
54
+ def run_app(env)
55
+ @app.call(env)
56
+ end
57
+
58
+ def process?(request)
59
+ html?(request) && !assets?(request)
60
+ end
61
+
62
+ def html?(request)
63
+ request.env["HTTP_ACCEPT"].to_s.match(ACCEPT_REGEX)
64
+ end
65
+
66
+ def assets?(request)
67
+ request.path.match(ASSETS_REGEX)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class MiuiBrowser < Base
5
+ def id
6
+ :miui_browser
7
+ end
8
+
9
+ def name
10
+ "Miui Browser"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r{MiuiBrowser/([\d.]+)}, 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua.include?("MiuiBrowser")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Nokia < Base
5
+ def id
6
+ :nokia
7
+ end
8
+
9
+ def name
10
+ "Nokia S40 Ovi Browser"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r{S40OviBrowser/([\d.]+)}, 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua.include?("S40OviBrowser")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Opera < Base
5
+ def id
6
+ :opera
7
+ end
8
+
9
+ def name
10
+ "Opera"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r{OPR/([\d.]+)}, 1] || ua[%r{Version/([\d.]+)}, 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua.match?(%r{(Opera|OPR/)})
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Otter < Base
5
+ def id
6
+ :otter
7
+ end
8
+
9
+ def name
10
+ "Otter"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r{Otter/([\d.]+)}, 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua.include?("Otter")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class PhantomJS < Base
5
+ def id
6
+ :phantom_js
7
+ end
8
+
9
+ def name
10
+ "PhantomJS"
11
+ end
12
+
13
+ def full_version
14
+ ua[%r{PhantomJS/([\d.]+)}, 1] || "0.0"
15
+ end
16
+
17
+ def match?
18
+ ua.include?("PhantomJS")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class AdobeAir < Base
6
+ def match?
7
+ ua.include?("AdobeAIR")
8
+ end
9
+
10
+ def version
11
+ ua[%r{AdobeAIR/([\d.]+)}, 1]
12
+ end
13
+
14
+ def name
15
+ "Adobe AIR"
16
+ end
17
+
18
+ def id
19
+ :adobe_air
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class Android < Base
6
+ def match?
7
+ ua.include?("Android") && !ua.include?("KAIOS")
8
+ end
9
+
10
+ def name
11
+ "Android"
12
+ end
13
+
14
+ def id
15
+ :android
16
+ end
17
+
18
+ def version
19
+ ua[/Android ([\d.]+)/, 1]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class Base
6
+ attr_reader :ua, :platform
7
+
8
+ def initialize(ua, platform = nil)
9
+ @ua = ua
10
+ @platform = platform
11
+ end
12
+
13
+ def match?
14
+ false
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class BlackBerry < Base
6
+ def match?
7
+ ua.match?(/BB10|BlackBerry/)
8
+ end
9
+
10
+ def name
11
+ "BlackBerry"
12
+ end
13
+
14
+ def id
15
+ :blackberry
16
+ end
17
+
18
+ def version
19
+ ua[%r{(?:Version|BlackBerry[\da-z]+)/([\d.]+)}, 1]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class ChromeOS < Base
6
+ def match?
7
+ ua.include?("CrOS")
8
+ end
9
+
10
+ def name
11
+ "Chrome OS"
12
+ end
13
+
14
+ def id
15
+ :chrome_os
16
+ end
17
+
18
+ def version
19
+ ua[/CrOS(?: x86_64)? ([\d.]+)/, 1]
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class FirefoxOS < Base
6
+ def version
7
+ "0"
8
+ end
9
+
10
+ def name
11
+ "Firefox OS"
12
+ end
13
+
14
+ def id
15
+ :firefox_os
16
+ end
17
+
18
+ def match?
19
+ !ua.match?(/(Android|Linux|BlackBerry|Windows|Mac)/) && ua.include?("Firefox")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class IOS < Base
6
+ MATCHER = /(iPhone|iPad|iPod|CriOS)/
7
+ VERSION_MATCHER =
8
+ /OS (?<major>\d+)_(?<minor>\d+)_?(?<patch>\d+)?/
9
+
10
+ def version
11
+ case VERSION_MATCHER.match(ua)
12
+ in nil then "0"
13
+ in {major:, minor:, patch: String => patch} then "#{major}.#{minor}.#{patch}"
14
+ in {major:, minor: "0"} then major
15
+ in {major:, minor:} then "#{major}.#{minor}"
16
+ end
17
+ end
18
+
19
+ def name
20
+ "iOS (#{device})"
21
+ end
22
+
23
+ def id
24
+ :ios
25
+ end
26
+
27
+ def match?
28
+ ua.match?(MATCHER)
29
+ end
30
+
31
+ def device
32
+ ua[MATCHER, 1]
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class KaiOS < Base
6
+ def version
7
+ ua[%r{KAIOS/([\d.]+)}, 1]
8
+ end
9
+
10
+ def name
11
+ "KaiOS"
12
+ end
13
+
14
+ def id
15
+ :kai_os
16
+ end
17
+
18
+ def match?
19
+ ua.include?("KAIOS")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class Linux < Base
6
+ def version
7
+ "0"
8
+ end
9
+
10
+ def name
11
+ "Generic Linux"
12
+ end
13
+
14
+ def id
15
+ :linux
16
+ end
17
+
18
+ def match?
19
+ ua.include?("Linux")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class Mac < Base
6
+ def version
7
+ (ua[/Mac OS X\s*([0-9_.]+)?/, 1] || "0").tr("_", ".")
8
+ end
9
+
10
+ def name
11
+ return "macOS" if platform.mac?(">= 10.12")
12
+
13
+ "Mac OS X"
14
+ end
15
+
16
+ def id
17
+ :mac
18
+ end
19
+
20
+ def match?
21
+ ua.include?("Mac")
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class Unknown < Base
6
+ def version
7
+ "0"
8
+ end
9
+
10
+ def name
11
+ "Unknown"
12
+ end
13
+
14
+ def id
15
+ :unknown_platform
16
+ end
17
+
18
+ def match?
19
+ true
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class Windows < Base
6
+ def version
7
+ ua[/Windows NT\s*([0-9_.]+)?/, 1] || "0"
8
+ end
9
+
10
+ def name
11
+ "Windows"
12
+ end
13
+
14
+ def id
15
+ :windows
16
+ end
17
+
18
+ def match?
19
+ ua.include?("Windows")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class WindowsMobile < Base
6
+ def version
7
+ "0"
8
+ end
9
+
10
+ def name
11
+ "Windows Mobile"
12
+ end
13
+
14
+ def id
15
+ :windows_mobile
16
+ end
17
+
18
+ def match?
19
+ ua.include?("Windows CE")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Browser
4
+ class Platform
5
+ class WindowsPhone < Base
6
+ def version
7
+ ua[/Windows Phone ([\d.]+)/, 1]
8
+ end
9
+
10
+ def name
11
+ "Windows Phone"
12
+ end
13
+
14
+ def id
15
+ :windows_phone
16
+ end
17
+
18
+ def match?
19
+ ua.include?("Windows Phone")
20
+ end
21
+ end
22
+ end
23
+ end