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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +93 -0
- data/LICENSE.md +21 -0
- data/README.md +552 -0
- data/data/bot_categories.json +1 -0
- data/data/bot_exceptions.json +1 -0
- data/data/bot_ip_ranges.json +1 -0
- data/data/bots.json +1 -0
- data/data/languages.json +1 -0
- data/data/samsung.json +1 -0
- data/data/search_engines.json +1 -0
- data/lib/agentry.rb +3 -0
- data/lib/browser/accept_language.rb +55 -0
- data/lib/browser/action_controller.rb +21 -0
- data/lib/browser/aliases.rb +33 -0
- data/lib/browser/alipay.rb +21 -0
- data/lib/browser/base.rb +307 -0
- data/lib/browser/blackberry.rb +23 -0
- data/lib/browser/bot/empty_user_agent_matcher.rb +11 -0
- data/lib/browser/bot/ip_ranges.rb +194 -0
- data/lib/browser/bot/keyword_matcher.rb +11 -0
- data/lib/browser/bot/known_bots_matcher.rb +11 -0
- data/lib/browser/bot.rb +221 -0
- data/lib/browser/browser.rb +200 -0
- data/lib/browser/cache.rb +92 -0
- data/lib/browser/chrome.rb +43 -0
- data/lib/browser/client_hints.rb +73 -0
- data/lib/browser/cloudflare.rb +65 -0
- data/lib/browser/detect_version.rb +22 -0
- data/lib/browser/detection.rb +25 -0
- data/lib/browser/device/android.rb +20 -0
- data/lib/browser/device/base.rb +13 -0
- data/lib/browser/device/blackberry_playbook.rb +19 -0
- data/lib/browser/device/ipad.rb +19 -0
- data/lib/browser/device/iphone.rb +19 -0
- data/lib/browser/device/ipod_touch.rb +19 -0
- data/lib/browser/device/kindle.rb +19 -0
- data/lib/browser/device/kindle_fire.rb +19 -0
- data/lib/browser/device/playstation3.rb +19 -0
- data/lib/browser/device/playstation4.rb +19 -0
- data/lib/browser/device/psp.rb +19 -0
- data/lib/browser/device/psvita.rb +19 -0
- data/lib/browser/device/samsung.rb +33 -0
- data/lib/browser/device/surface.rb +23 -0
- data/lib/browser/device/switch.rb +19 -0
- data/lib/browser/device/tv.rb +19 -0
- data/lib/browser/device/unknown.rb +19 -0
- data/lib/browser/device/wii.rb +19 -0
- data/lib/browser/device/wiiu.rb +19 -0
- data/lib/browser/device/xbox_360.rb +19 -0
- data/lib/browser/device/xbox_one.rb +19 -0
- data/lib/browser/device.rb +246 -0
- data/lib/browser/duck_duck_go.rb +22 -0
- data/lib/browser/edge.rb +25 -0
- data/lib/browser/electron.rb +22 -0
- data/lib/browser/epiphany.rb +21 -0
- data/lib/browser/facebook.rb +23 -0
- data/lib/browser/firefox.rb +21 -0
- data/lib/browser/google_search_app.rb +21 -0
- data/lib/browser/huawei_browser.rb +21 -0
- data/lib/browser/instagram.rb +21 -0
- data/lib/browser/internet_explorer.rb +63 -0
- data/lib/browser/maxthon.rb +21 -0
- data/lib/browser/meta/base.rb +42 -0
- data/lib/browser/meta/device.rb +11 -0
- data/lib/browser/meta/generic_browser.rb +15 -0
- data/lib/browser/meta/id.rb +11 -0
- data/lib/browser/meta/ie.rb +20 -0
- data/lib/browser/meta/ios.rb +11 -0
- data/lib/browser/meta/mobile.rb +11 -0
- data/lib/browser/meta/platform.rb +11 -0
- data/lib/browser/meta/proxy.rb +11 -0
- data/lib/browser/meta/safari.rb +11 -0
- data/lib/browser/meta/tablet.rb +11 -0
- data/lib/browser/meta/webkit.rb +11 -0
- data/lib/browser/meta.rb +14 -0
- data/lib/browser/micro_messenger.rb +21 -0
- data/lib/browser/middleware/context/additions.rb +18 -0
- data/lib/browser/middleware/context/url_methods.rb +15 -0
- data/lib/browser/middleware/context.rb +23 -0
- data/lib/browser/middleware.rb +70 -0
- data/lib/browser/miui_browser.rb +21 -0
- data/lib/browser/nokia.rb +21 -0
- data/lib/browser/opera.rb +21 -0
- data/lib/browser/otter.rb +21 -0
- data/lib/browser/phantom_js.rb +21 -0
- data/lib/browser/platform/adobe_air.rb +23 -0
- data/lib/browser/platform/android.rb +23 -0
- data/lib/browser/platform/base.rb +18 -0
- data/lib/browser/platform/blackberry.rb +23 -0
- data/lib/browser/platform/chrome_os.rb +23 -0
- data/lib/browser/platform/firefox_os.rb +23 -0
- data/lib/browser/platform/ios.rb +36 -0
- data/lib/browser/platform/kai_os.rb +23 -0
- data/lib/browser/platform/linux.rb +23 -0
- data/lib/browser/platform/mac.rb +25 -0
- data/lib/browser/platform/unknown.rb +23 -0
- data/lib/browser/platform/windows.rb +23 -0
- data/lib/browser/platform/windows_mobile.rb +23 -0
- data/lib/browser/platform/windows_phone.rb +23 -0
- data/lib/browser/platform.rb +220 -0
- data/lib/browser/qq.rb +25 -0
- data/lib/browser/rails.rb +24 -0
- data/lib/browser/safari.rb +40 -0
- data/lib/browser/samsung_browser.rb +21 -0
- data/lib/browser/snapchat.rb +21 -0
- data/lib/browser/sougou_browser.rb +24 -0
- data/lib/browser/sputnik.rb +21 -0
- data/lib/browser/testing.rb +29 -0
- data/lib/browser/uc_browser.rb +21 -0
- data/lib/browser/unknown.rb +32 -0
- data/lib/browser/version.rb +5 -0
- data/lib/browser/weibo.rb +21 -0
- data/lib/browser/yandex.rb +21 -0
- data/lib/browser.rb +4 -0
- data/test/ua.yml +181 -0
- data/test/ua_bots.yml +121 -0
- data/test/ua_search_engines.yml +7 -0
- metadata +274 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "platform/base"
|
|
4
|
+
require_relative "platform/ios"
|
|
5
|
+
require_relative "platform/linux"
|
|
6
|
+
require_relative "platform/windows"
|
|
7
|
+
require_relative "platform/mac"
|
|
8
|
+
require_relative "platform/windows_phone"
|
|
9
|
+
require_relative "platform/windows_mobile"
|
|
10
|
+
require_relative "platform/firefox_os"
|
|
11
|
+
require_relative "platform/blackberry"
|
|
12
|
+
require_relative "platform/android"
|
|
13
|
+
require_relative "platform/unknown"
|
|
14
|
+
require_relative "platform/chrome_os"
|
|
15
|
+
require_relative "platform/adobe_air"
|
|
16
|
+
require_relative "platform/kai_os"
|
|
17
|
+
|
|
18
|
+
module Browser
|
|
19
|
+
class Platform
|
|
20
|
+
include DetectVersion
|
|
21
|
+
|
|
22
|
+
attr_reader :ua
|
|
23
|
+
|
|
24
|
+
# Hold the list of platform matchers.
|
|
25
|
+
# Order is important.
|
|
26
|
+
def self.matchers
|
|
27
|
+
@matchers ||= [
|
|
28
|
+
AdobeAir,
|
|
29
|
+
ChromeOS,
|
|
30
|
+
WindowsMobile,
|
|
31
|
+
WindowsPhone,
|
|
32
|
+
Android,
|
|
33
|
+
BlackBerry,
|
|
34
|
+
IOS,
|
|
35
|
+
Mac,
|
|
36
|
+
KaiOS,
|
|
37
|
+
FirefoxOS,
|
|
38
|
+
Windows,
|
|
39
|
+
Linux,
|
|
40
|
+
Unknown
|
|
41
|
+
]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def initialize(ua, client_hints: nil)
|
|
45
|
+
@ua = ua
|
|
46
|
+
@client_hints = client_hints
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# This platform, or one built with the client hints when they tell more
|
|
50
|
+
# than the user agent: the cached platform of a user agent ignores them.
|
|
51
|
+
def with_client_hints(client_hints)
|
|
52
|
+
hinted_class = client_hints.platform_class
|
|
53
|
+
return self unless hinted_class
|
|
54
|
+
return self if subject.instance_of?(hinted_class) && client_hints.platform_version.nil?
|
|
55
|
+
|
|
56
|
+
self.class.new(ua, client_hints:)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def subject
|
|
60
|
+
@subject ||= @client_hints&.platform_class&.new(ua, self) || detect_subject
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def adobe_air?(expected_version = nil)
|
|
64
|
+
id == :adobe_air && detect_version?(version, expected_version)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def chrome_os?(expected_version = nil)
|
|
68
|
+
id == :chrome_os && detect_version?(version, expected_version)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def android?(expected_version = nil)
|
|
72
|
+
id == :android && detect_version?(version, expected_version)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def unknown?
|
|
76
|
+
id == :unknown_platform
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def linux?
|
|
80
|
+
id == :linux
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def mac?(expected_version = nil)
|
|
84
|
+
id == :mac && detect_version?(version, expected_version)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def windows?(expected_version = nil)
|
|
88
|
+
id == :windows && detect_version?(version, expected_version)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def firefox_os?
|
|
92
|
+
id == :firefox_os
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def kai_os?
|
|
96
|
+
id == :kai_os
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def ios?(expected_version = nil)
|
|
100
|
+
id == :ios && detect_version?(version, expected_version)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def blackberry?(expected_version = nil)
|
|
104
|
+
id == :blackberry && detect_version?(version, expected_version)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def windows_phone?(expected_version = nil)
|
|
108
|
+
id == :windows_phone && detect_version?(version, expected_version)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def windows_mobile?(expected_version = nil)
|
|
112
|
+
id == :windows_mobile && detect_version?(version, expected_version)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def id
|
|
116
|
+
subject.id
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def version
|
|
120
|
+
@version ||= hinted_version || subject.version
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def name
|
|
124
|
+
subject.name
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def to_s
|
|
128
|
+
id.to_s
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def ==(other)
|
|
132
|
+
id == other
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Detect if running on iOS app webview.
|
|
136
|
+
def ios_app?
|
|
137
|
+
ios? && !ua.include?("Safari")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Detect if is iOS webview.
|
|
141
|
+
def ios_webview?
|
|
142
|
+
ios_app?
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Detect if in an Android app webview (Lollipop and newer)
|
|
146
|
+
# https://developer.chrome.com/multidevice/user-agent#webview_user_agent
|
|
147
|
+
def android_app?
|
|
148
|
+
android? && ua.match?(/\bwv\b/)
|
|
149
|
+
end
|
|
150
|
+
alias_method :android_webview?, :android_app?
|
|
151
|
+
|
|
152
|
+
# http://msdn.microsoft.com/fr-FR/library/ms537503.aspx#PltToken
|
|
153
|
+
def windows_xp?
|
|
154
|
+
windows? && ua.match?(/Windows NT 5\.[12]/)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def windows_vista?
|
|
158
|
+
windows? && ua.include?("Windows NT 6.0")
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def windows7?
|
|
162
|
+
windows? && ua.include?("Windows NT 6.1")
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def windows8?
|
|
166
|
+
windows? && ua.match?(/Windows NT 6\.[2-3]/)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def windows8_1?
|
|
170
|
+
windows? && ua.include?("Windows NT 6.3")
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def windows10?
|
|
174
|
+
windows? && ua.include?("Windows NT 10") && !windows11?
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Only the client hints tell Windows 11 apart (ClientHints#windows11?).
|
|
178
|
+
def windows11?
|
|
179
|
+
windows? && version == "11"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def windows_rt?
|
|
183
|
+
windows8? && ua.include?("ARM")
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Detect if current platform is Windows in 64-bit architecture.
|
|
187
|
+
def windows_x64?
|
|
188
|
+
windows? && ua.match?(/(Win64|x64|Windows NT 5\.2)/)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def windows_wow64?
|
|
192
|
+
windows? && ua.match?(/WOW64/i)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def windows_x64_inclusive?
|
|
196
|
+
windows_x64? || windows_wow64?
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def windows_touchscreen_desktop?
|
|
200
|
+
windows? && ua.include?("Touch")
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
private def detect_subject
|
|
204
|
+
self.class.matchers.each do |matcher|
|
|
205
|
+
candidate = matcher.new(ua, self)
|
|
206
|
+
break candidate if candidate.match?
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
private def hinted_version
|
|
211
|
+
return unless @client_hints&.platform_class
|
|
212
|
+
return @client_hints.platform_version unless id == :windows
|
|
213
|
+
|
|
214
|
+
"11" if @client_hints.windows11?
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
private :subject
|
|
218
|
+
private :ua
|
|
219
|
+
end
|
|
220
|
+
end
|
data/lib/browser/qq.rb
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class QQ < Base
|
|
5
|
+
def id
|
|
6
|
+
:qq
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"QQ Browser"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{(?:Mobile MQQBrowser)/([\d.]+)}i, 1] ||
|
|
15
|
+
ua[%r{(?:QQBrowserLite)/([\d.]+)}i, 1] ||
|
|
16
|
+
ua[%r{(?:QQBrowser)/([\d.]+)}i, 1] ||
|
|
17
|
+
ua[%r{(?:QQ)/([\d.]+)}i, 1] ||
|
|
18
|
+
"0.0"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def match?
|
|
22
|
+
ua.match?(%r{QQ/|QQBrowser}i)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails"
|
|
4
|
+
require_relative "action_controller"
|
|
5
|
+
require_relative "middleware/context/additions"
|
|
6
|
+
|
|
7
|
+
module Browser
|
|
8
|
+
class Railtie < Rails::Railtie
|
|
9
|
+
config.browser = ActiveSupport::OrderedOptions.new
|
|
10
|
+
config.eager_load_namespaces << Browser
|
|
11
|
+
|
|
12
|
+
initializer "browser" do
|
|
13
|
+
ActiveSupport.on_load(:action_controller) do
|
|
14
|
+
::ActionController::Base.include(Browser::ActionController)
|
|
15
|
+
|
|
16
|
+
::ActionController::Metal.include(Browser::ActionController) if defined?(::ActionController::Metal) # rubocop:disable Layout/LineLength
|
|
17
|
+
|
|
18
|
+
Browser::Middleware::Context.include(
|
|
19
|
+
Browser::Middleware::Context::Additions
|
|
20
|
+
)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Safari < Base
|
|
5
|
+
def id
|
|
6
|
+
:safari
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Safari"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{Version/([\d.]+)}, 1] ||
|
|
15
|
+
ua[%r{Safari/([\d.]+)}, 1] ||
|
|
16
|
+
ua[%r{AppleWebKit/([\d.]+)}, 1] ||
|
|
17
|
+
"0.0"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def match?
|
|
21
|
+
ua.include?("Safari") &&
|
|
22
|
+
!platform.linux? &&
|
|
23
|
+
!ua.match?(/PhantomJS|FxiOS/) &&
|
|
24
|
+
!edge? &&
|
|
25
|
+
!chrome? &&
|
|
26
|
+
!opera? &&
|
|
27
|
+
!samsung_browser? &&
|
|
28
|
+
!huawei_browser? &&
|
|
29
|
+
!miui_browser? &&
|
|
30
|
+
!duck_duck_go? &&
|
|
31
|
+
!yandex? &&
|
|
32
|
+
!sputnik? &&
|
|
33
|
+
!maxthon? &&
|
|
34
|
+
!qq? &&
|
|
35
|
+
!alipay? &&
|
|
36
|
+
!sougou_browser? &&
|
|
37
|
+
!google_search_app?
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class SamsungBrowser < Chrome
|
|
5
|
+
def id
|
|
6
|
+
:samsung_browser
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Samsung Browser"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{SamsungBrowser/([\d.]+)}, 1] || super
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.include?("SamsungBrowser")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Snapchat < Base
|
|
5
|
+
def id
|
|
6
|
+
:snapchat
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Snapchat"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{Snapchat( ?|/)([\d.]+)}, 2] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.include?("Snapchat")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class SougouBrowser < Base
|
|
5
|
+
def id
|
|
6
|
+
:sougou_browser
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Sougou Browser"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# We can't get the real version on desktop device from the ua string
|
|
14
|
+
def full_version
|
|
15
|
+
ua[%r{(?:SogouMobileBrowser)/([\d.]+)}, 1] || "0.0"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# SogouMobileBrowser for mobile device
|
|
19
|
+
# SE for desktop device
|
|
20
|
+
def match?
|
|
21
|
+
ua.match?(/SogouMobileBrowser/i) || ua.match?(/\bSE\b/)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Sputnik < Base
|
|
5
|
+
def id
|
|
6
|
+
:sputnik
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Sputnik"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{SputnikBrowser/([\d.]+)}, 1] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.include?("SputnikBrowser")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "yaml"
|
|
4
|
+
|
|
5
|
+
module Browser
|
|
6
|
+
def self.user_agents
|
|
7
|
+
@user_agents ||= browser_user_agents
|
|
8
|
+
.merge(bot_user_agents)
|
|
9
|
+
.merge(search_engine_user_agents)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.browser_user_agents
|
|
13
|
+
@browser_user_agents ||= YAML.load_file(Browser.root.join("test/ua.yml"))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.bot_user_agents
|
|
17
|
+
@bot_user_agents ||= YAML.load_file(Browser.root.join("test/ua_bots.yml"))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.search_engine_user_agents
|
|
21
|
+
@search_engine_user_agents ||= YAML.load_file(
|
|
22
|
+
Browser.root.join("test/ua_search_engines.yml")
|
|
23
|
+
)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.[](key)
|
|
27
|
+
user_agents.fetch(key)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class UCBrowser < Base
|
|
5
|
+
def id
|
|
6
|
+
:uc_browser
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"UCBrowser"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{UCBrowser/([\d.]+)}, 1] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.include?("UCBrowser")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Unknown < Base
|
|
5
|
+
NAMES = {
|
|
6
|
+
"QuickTime" => "QuickTime",
|
|
7
|
+
"CoreMedia" => "Apple CoreMedia"
|
|
8
|
+
}.freeze
|
|
9
|
+
|
|
10
|
+
def id
|
|
11
|
+
:unknown_browser
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def name
|
|
15
|
+
infer_name || "Unknown Browser"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def full_version
|
|
19
|
+
ua[%r{(?:QuickTime)/([\d.]+)}, 1] ||
|
|
20
|
+
ua[/CoreMedia v([\d.]+)/, 1] ||
|
|
21
|
+
"0.0"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def match?
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private def infer_name
|
|
29
|
+
NAMES.find { |key, _| ua.include?(key) }&.last
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Weibo < Base
|
|
5
|
+
def id
|
|
6
|
+
:weibo
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Weibo"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[/(?:__weibo__)([\d.]+)/i, 1] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.match?(/__weibo__/i)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Browser
|
|
4
|
+
class Yandex < Base
|
|
5
|
+
def id
|
|
6
|
+
:yandex
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def name
|
|
10
|
+
"Yandex"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def full_version
|
|
14
|
+
ua[%r{YaBrowser/([\d.]+)}, 1] || "0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def match?
|
|
18
|
+
ua.include?("YaBrowser")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
data/lib/browser.rb
ADDED