device_detector 1.0.7 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +25 -4
- data/lib/device_detector/browser.rb +178 -5
- data/lib/device_detector/client_hint.rb +166 -0
- data/lib/device_detector/device.rb +291 -2
- data/lib/device_detector/os.rb +33 -3
- data/lib/device_detector/version.rb +1 -1
- data/lib/device_detector.rb +50 -15
- data/regexes/bots.yml +594 -16
- data/regexes/client/browsers.yml +334 -40
- data/regexes/client/hints/apps.yml +102 -0
- data/regexes/client/hints/browsers.yml +190 -0
- data/regexes/client/libraries.yml +199 -2
- data/regexes/client/mobile_apps.yml +320 -12
- data/regexes/client/pim.yml +15 -0
- data/regexes/device/car_browsers.yml +1 -1
- data/regexes/device/consoles.yml +6 -1
- data/regexes/device/mobiles.yml +8406 -1948
- data/regexes/device/portable_media_player.yml +18 -2
- data/regexes/device/shell_tv.yml +11 -0
- data/regexes/device/televisions.yml +26 -4
- data/regexes/oss.yml +329 -47
- metadata +10 -7
data/lib/device_detector/os.rb
CHANGED
@@ -49,6 +49,8 @@ class DeviceDetector
|
|
49
49
|
OPERATING_SYSTEMS = {
|
50
50
|
'AIX' => 'AIX',
|
51
51
|
'AND' => 'Android',
|
52
|
+
'ADR' => 'Android TV',
|
53
|
+
'AMZ' => 'Amazon Linux',
|
52
54
|
'AMG' => 'AmigaOS',
|
53
55
|
'ATV' => 'tvOS',
|
54
56
|
'ARL' => 'Arch Linux',
|
@@ -57,10 +59,15 @@ class DeviceDetector
|
|
57
59
|
'BEO' => 'BeOS',
|
58
60
|
'BLB' => 'BlackBerry OS',
|
59
61
|
'QNX' => 'BlackBerry Tablet OS',
|
62
|
+
'BOS' => 'Bliss OS',
|
60
63
|
'BMP' => 'Brew',
|
61
64
|
'CAI' => 'Caixa Mágica',
|
62
65
|
'CES' => 'CentOS',
|
66
|
+
'CST' => 'CentOS Stream',
|
67
|
+
'CLR' => 'ClearOS Mobile',
|
63
68
|
'COS' => 'Chrome OS',
|
69
|
+
'CRS' => 'Chromium OS',
|
70
|
+
'CHN' => 'China OS',
|
64
71
|
'CYN' => 'CyanogenMod',
|
65
72
|
'DEB' => 'Debian',
|
66
73
|
'DEE' => 'Deepin',
|
@@ -70,9 +77,11 @@ class DeviceDetector
|
|
70
77
|
'FEN' => 'Fenix',
|
71
78
|
'FOS' => 'Firefox OS',
|
72
79
|
'FIR' => 'Fire OS',
|
80
|
+
'FOR' => 'Foresight Linux',
|
73
81
|
'FRE' => 'Freebox',
|
74
82
|
'BSD' => 'FreeBSD',
|
75
83
|
'FYD' => 'FydeOS',
|
84
|
+
'FUC' => 'Fuchsia',
|
76
85
|
'GNT' => 'Gentoo',
|
77
86
|
'GRI' => 'GridOS',
|
78
87
|
'GTV' => 'Google TV',
|
@@ -85,9 +94,14 @@ class DeviceDetector
|
|
85
94
|
'INF' => 'Inferno',
|
86
95
|
'JME' => 'Java ME',
|
87
96
|
'KOS' => 'KaiOS',
|
97
|
+
'KAN' => 'Kanotix',
|
88
98
|
'KNO' => 'Knoppix',
|
99
|
+
'KTV' => 'KreaTV',
|
89
100
|
'KBT' => 'Kubuntu',
|
90
101
|
'LIN' => 'GNU/Linux',
|
102
|
+
'LND' => 'LindowsOS',
|
103
|
+
'LNS' => 'Linspire',
|
104
|
+
'LEN' => 'Lineage OS',
|
91
105
|
'LBT' => 'Lubuntu',
|
92
106
|
'LOS' => 'Lumin OS',
|
93
107
|
'VLN' => 'VectorLinux',
|
@@ -97,6 +111,7 @@ class DeviceDetector
|
|
97
111
|
'MDR' => 'Mandriva',
|
98
112
|
'SMG' => 'MeeGo',
|
99
113
|
'MCD' => 'MocorDroid',
|
114
|
+
'MON' => 'moonOS',
|
100
115
|
'MIN' => 'Mint',
|
101
116
|
'MLD' => 'MildWild',
|
102
117
|
'MOR' => 'MorphOS',
|
@@ -105,25 +120,34 @@ class DeviceDetector
|
|
105
120
|
'MRE' => 'MRE',
|
106
121
|
'WII' => 'Nintendo',
|
107
122
|
'NDS' => 'Nintendo Mobile',
|
123
|
+
'NOV' => 'Nova',
|
108
124
|
'OS2' => 'OS/2',
|
109
125
|
'T64' => 'OSF1',
|
110
126
|
'OBS' => 'OpenBSD',
|
111
127
|
'OWR' => 'OpenWrt',
|
128
|
+
'OTV' => 'Opera TV',
|
112
129
|
'ORD' => 'Ordissimo',
|
130
|
+
'PAR' => 'Pardus',
|
113
131
|
'PCL' => 'PCLinuxOS',
|
132
|
+
'PLA' => 'Plasma Mobile',
|
114
133
|
'PSP' => 'PlayStation Portable',
|
115
134
|
'PS3' => 'PlayStation',
|
135
|
+
'PUR' => 'PureOS',
|
116
136
|
'RHT' => 'Red Hat',
|
137
|
+
'REV' => 'Revenge OS',
|
117
138
|
'ROS' => 'RISC OS',
|
118
139
|
'ROK' => 'Roku OS',
|
119
140
|
'RSO' => 'Rosa',
|
141
|
+
'ROU' => 'RouterOS',
|
120
142
|
'REM' => 'Remix OS',
|
143
|
+
'RRS' => 'Resurrection Remix OS',
|
121
144
|
'REX' => 'REX',
|
122
145
|
'RZD' => 'RazoDroiD',
|
123
146
|
'SAB' => 'Sabayon',
|
124
147
|
'SSE' => 'SUSE',
|
125
148
|
'SAF' => 'Sailfish OS',
|
126
149
|
'SEE' => 'SeewoOS',
|
150
|
+
'SIR' => 'Sirin OS',
|
127
151
|
'SLW' => 'Slackware',
|
128
152
|
'SOS' => 'Solaris',
|
129
153
|
'SYL' => 'Syllable',
|
@@ -132,6 +156,7 @@ class DeviceDetector
|
|
132
156
|
'S40' => 'Symbian OS Series 40',
|
133
157
|
'S60' => 'Symbian OS Series 60',
|
134
158
|
'SY3' => 'Symbian^3',
|
159
|
+
'TEN' => 'TencentOS',
|
135
160
|
'TDX' => 'ThreadX',
|
136
161
|
'TIZ' => 'Tizen',
|
137
162
|
'TOS' => 'TmaxOS',
|
@@ -148,6 +173,8 @@ class DeviceDetector
|
|
148
173
|
'XBX' => 'Xbox',
|
149
174
|
'XBT' => 'Xubuntu',
|
150
175
|
'YNS' => 'YunOS',
|
176
|
+
'ZEN' => 'Zenwalk',
|
177
|
+
'ZOR' => 'ZorinOS',
|
151
178
|
'IOS' => 'iOS',
|
152
179
|
'POS' => 'palmOS',
|
153
180
|
'WOS' => 'webOS'
|
@@ -158,12 +185,13 @@ class DeviceDetector
|
|
158
185
|
end.freeze
|
159
186
|
|
160
187
|
OS_FAMILIES = {
|
161
|
-
'Android' => %w[AND CYN FIR REM RZD MLD MCD YNS GRI HAR
|
188
|
+
'Android' => %w[ AND CYN FIR REM RZD MLD MCD YNS GRI HAR
|
189
|
+
ADR CLR BOS REV LEN SIR RRS],
|
162
190
|
'AmigaOS' => %w[AMG MOR],
|
163
191
|
'BlackBerry' => %w[BLB QNX],
|
164
192
|
'Brew' => ['BMP'],
|
165
193
|
'BeOS' => %w[BEO HAI],
|
166
|
-
'Chrome OS' => %w[COS FYD SEE],
|
194
|
+
'Chrome OS' => %w[COS CRS FYD SEE],
|
167
195
|
'Firefox OS' => %w[FOS KOS],
|
168
196
|
'Gaming Console' => %w[WII PS3],
|
169
197
|
'Google TV' => ['GTV'],
|
@@ -174,7 +202,9 @@ class DeviceDetector
|
|
174
202
|
LIN ARL DEB KNO MIN UBT KBT XBT LBT FED
|
175
203
|
RHT VLN MDR GNT SAB SLW SSE CES BTR SAF
|
176
204
|
ORD TOS RSO DEE FRE MAG FEN CAI PCL HAS
|
177
|
-
LOS DVK ROK OWR
|
205
|
+
LOS DVK ROK OWR OTV KTV PUR PLA FUC PAR
|
206
|
+
FOR MON KAN ZEN LND LNS CHN AMZ TEN CST
|
207
|
+
NOV ROU ZOR
|
178
208
|
],
|
179
209
|
'Mac' => ['MAC'],
|
180
210
|
'Mobile Gaming Console' => %w[PSP NDS XBX],
|
data/lib/device_detector.rb
CHANGED
@@ -14,36 +14,46 @@ require 'device_detector/client'
|
|
14
14
|
require 'device_detector/device'
|
15
15
|
require 'device_detector/os'
|
16
16
|
require 'device_detector/browser'
|
17
|
+
require 'device_detector/client_hint'
|
17
18
|
|
18
19
|
class DeviceDetector
|
19
|
-
attr_reader :user_agent
|
20
|
+
attr_reader :client_hint, :user_agent
|
20
21
|
|
21
|
-
def initialize(user_agent)
|
22
|
+
def initialize(user_agent, headers = nil)
|
23
|
+
@client_hint = ClientHint.new(headers)
|
22
24
|
@user_agent = user_agent
|
23
25
|
end
|
24
26
|
|
25
27
|
def name
|
26
|
-
client.name
|
28
|
+
return client.name if mobile_fix?
|
29
|
+
|
30
|
+
client_hint.browser_name || client.name
|
27
31
|
end
|
28
32
|
|
29
33
|
def full_version
|
30
|
-
client.full_version
|
34
|
+
client_hint.platform_version || client.full_version
|
31
35
|
end
|
32
36
|
|
33
37
|
def os_family
|
34
|
-
|
38
|
+
return 'GNU/Linux' if linux_fix?
|
39
|
+
|
40
|
+
client_hint.os_family || os.family || client_hint.platform
|
35
41
|
end
|
36
42
|
|
37
43
|
def os_name
|
38
|
-
|
44
|
+
return 'GNU/Linux' if linux_fix?
|
45
|
+
|
46
|
+
client_hint.os_name || os.name || client_hint.platform
|
39
47
|
end
|
40
48
|
|
41
49
|
def os_full_version
|
42
|
-
|
50
|
+
return if skip_os_version?
|
51
|
+
|
52
|
+
client_hint.os_version || os.full_version
|
43
53
|
end
|
44
54
|
|
45
55
|
def device_name
|
46
|
-
device.name
|
56
|
+
device.name || client_hint.model || fix_for_x_music
|
47
57
|
end
|
48
58
|
|
49
59
|
def device_brand
|
@@ -62,7 +72,7 @@ class DeviceDetector
|
|
62
72
|
# Note: We do not check for browser (family) here, as there might be mobile apps using Chrome,
|
63
73
|
# that won't have a detected browser, but can still be detected. So we check the useragent for
|
64
74
|
# Chrome instead.
|
65
|
-
if t.nil? &&
|
75
|
+
if t.nil? && os_family == 'Android' && user_agent =~ build_regex('Chrome\/[\.0-9]*')
|
66
76
|
if user_agent =~ build_regex('(?:Mobile|eliboM) Safari\/')
|
67
77
|
t = 'smartphone'
|
68
78
|
elsif user_agent =~ build_regex('(?!Mobile )Safari\/')
|
@@ -97,7 +107,7 @@ class DeviceDetector
|
|
97
107
|
end
|
98
108
|
|
99
109
|
# All detected feature phones running android are more likely a smartphone
|
100
|
-
t = 'smartphone' if t == 'feature phone' &&
|
110
|
+
t = 'smartphone' if t == 'feature phone' && os_family == 'Android'
|
101
111
|
|
102
112
|
# All unknown devices under running Java ME are more likely a features phones
|
103
113
|
t = 'feature phone' if t.nil? && os_name == 'Java ME'
|
@@ -111,19 +121,25 @@ class DeviceDetector
|
|
111
121
|
# assume that all Windows 8 touch devices are tablets.
|
112
122
|
if t.nil? && touch_enabled? &&
|
113
123
|
(os_name == 'Windows RT' ||
|
114
|
-
(os_name == 'Windows' &&
|
115
|
-
Gem::Version.new(
|
124
|
+
(os_name == 'Windows' && os_full_version &&
|
125
|
+
Gem::Version.new(os_full_version) >= VersionExtractor::MAJOR_VERSION_8))
|
116
126
|
t = 'tablet'
|
117
127
|
end
|
118
128
|
|
119
129
|
# All devices running Opera TV Store are assumed to be a tv
|
120
130
|
t = 'tv' if opera_tv_store?
|
121
131
|
|
132
|
+
# All devices that contain Andr0id in string are assumed to be a tv
|
133
|
+
t = 'tv' if user_agent =~ build_regex('Andr0id|Android TV')
|
134
|
+
|
122
135
|
# All devices running Tizen TV or SmartTV are assumed to be a tv
|
123
136
|
t = 'tv' if t.nil? && tizen_samsung_tv?
|
124
137
|
|
125
138
|
# Devices running Kylo or Espital TV Browsers are assumed to be a TV
|
126
|
-
t = 'tv' if t.nil? && ['Kylo', 'Espial TV Browser'].include?(
|
139
|
+
t = 'tv' if t.nil? && ['Kylo', 'Espial TV Browser'].include?(name)
|
140
|
+
|
141
|
+
# All devices containing TV fragment are assumed to be a tv
|
142
|
+
t = 'tv' if t.nil? && user_agent =~ build_regex('\(TV;')
|
127
143
|
|
128
144
|
has_desktop = t != 'desktop' && desktop_string? && desktop_fragment?
|
129
145
|
t = 'desktop' if has_desktop
|
@@ -190,12 +206,31 @@ class DeviceDetector
|
|
190
206
|
@os ||= OS.new(user_agent)
|
191
207
|
end
|
192
208
|
|
209
|
+
# https://github.com/matomo-org/device-detector/blob/be1c9ef486c247dc4886668da5ed0b1c49d90ba8/Parser/Client/Browser.php#L772
|
210
|
+
# Fix mobile browser names e.g. Chrome => Chrome Mobile
|
211
|
+
def mobile_fix?
|
212
|
+
client.name == "#{client_hint.browser_name} Mobile"
|
213
|
+
end
|
214
|
+
|
215
|
+
def linux_fix?
|
216
|
+
client_hint.platform == 'Linux' && os.name == 'Android' && client_hint.mobile == '?0'
|
217
|
+
end
|
218
|
+
|
219
|
+
# Related to issue mentionned in device.rb#1562
|
220
|
+
def fix_for_x_music
|
221
|
+
user_agent.include?('X-music Ⅲ') ? 'X-Music III' : nil
|
222
|
+
end
|
223
|
+
|
224
|
+
def skip_os_version?
|
225
|
+
!client_hint.os_family.nil? && client_hint.os_family != os.family
|
226
|
+
end
|
227
|
+
|
193
228
|
def android_tablet_fragment?
|
194
|
-
user_agent =~ build_regex('Android(
|
229
|
+
user_agent =~ build_regex('Android( [\.0-9]+)?; Tablet;')
|
195
230
|
end
|
196
231
|
|
197
232
|
def android_mobile_fragment?
|
198
|
-
user_agent =~ build_regex('Android(
|
233
|
+
user_agent =~ build_regex('Android( [\.0-9]+)?; Mobile;')
|
199
234
|
end
|
200
235
|
|
201
236
|
def desktop_fragment?
|