device_detector 1.0.7 → 1.1.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 +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?
|