device_detector 1.0.0 → 1.1.3

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 (89) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +58 -4
  3. data/README.md +57 -21
  4. data/lib/device_detector/bot.rb +2 -2
  5. data/lib/device_detector/browser.rb +691 -0
  6. data/lib/device_detector/client.rb +11 -2
  7. data/lib/device_detector/client_hint.rb +249 -0
  8. data/lib/device_detector/device.rb +1954 -23
  9. data/lib/device_detector/memory_cache.rb +26 -19
  10. data/lib/device_detector/metadata_extractor.rb +7 -8
  11. data/lib/device_detector/model_extractor.rb +3 -3
  12. data/lib/device_detector/name_extractor.rb +2 -2
  13. data/lib/device_detector/os.rb +289 -112
  14. data/lib/device_detector/parser.rb +49 -13
  15. data/lib/device_detector/vendor_fragment.rb +25 -0
  16. data/lib/device_detector/version.rb +3 -1
  17. data/lib/device_detector/version_extractor.rb +29 -2
  18. data/lib/device_detector.rb +192 -44
  19. data/regexes/bots.yml +3399 -91
  20. data/regexes/client/browser_engine.yml +28 -4
  21. data/regexes/client/browsers.yml +2697 -408
  22. data/regexes/client/feed_readers.yml +60 -22
  23. data/regexes/client/hints/apps.yml +150 -0
  24. data/regexes/client/hints/browsers.yml +292 -0
  25. data/regexes/client/libraries.yml +598 -4
  26. data/regexes/client/mediaplayers.yml +110 -5
  27. data/regexes/client/mobile_apps.yml +2451 -14
  28. data/regexes/client/pim.yml +128 -3
  29. data/regexes/device/cameras.yml +6 -6
  30. data/regexes/device/car_browsers.yml +39 -3
  31. data/regexes/device/consoles.yml +40 -6
  32. data/regexes/device/mobiles.yml +38844 -2907
  33. data/regexes/device/notebooks.yml +127 -0
  34. data/regexes/device/portable_media_player.yml +75 -12
  35. data/regexes/device/shell_tv.yml +145 -0
  36. data/regexes/device/televisions.yml +981 -40
  37. data/regexes/oss.yml +1560 -311
  38. data/regexes/vendorfragments.yml +6 -2
  39. metadata +31 -105
  40. data/.gitignore +0 -14
  41. data/.travis.yml +0 -18
  42. data/Gemfile +0 -8
  43. data/Rakefile +0 -79
  44. data/device_detector.gemspec +0 -26
  45. data/spec/device_detector/bot_fixtures_spec.rb +0 -30
  46. data/spec/device_detector/client_fixtures_spec.rb +0 -31
  47. data/spec/device_detector/concrete_user_agent_spec.rb +0 -136
  48. data/spec/device_detector/detector_fixtures_spec.rb +0 -60
  49. data/spec/device_detector/device_fixtures_spec.rb +0 -36
  50. data/spec/device_detector/device_spec.rb +0 -151
  51. data/spec/device_detector/memory_cache_spec.rb +0 -116
  52. data/spec/device_detector/model_extractor_spec.rb +0 -63
  53. data/spec/device_detector/os_fixtures_spec.rb +0 -26
  54. data/spec/device_detector/version_extractor_spec.rb +0 -80
  55. data/spec/device_detector_spec.rb +0 -198
  56. data/spec/fixtures/client/browser.yml +0 -1313
  57. data/spec/fixtures/client/feed_reader.yml +0 -187
  58. data/spec/fixtures/client/library.yml +0 -84
  59. data/spec/fixtures/client/mediaplayer.yml +0 -168
  60. data/spec/fixtures/client/mobile_app.yml +0 -30
  61. data/spec/fixtures/client/pim.yml +0 -96
  62. data/spec/fixtures/detector/bots.yml +0 -2418
  63. data/spec/fixtures/detector/camera.yml +0 -115
  64. data/spec/fixtures/detector/car_browser.yml +0 -20
  65. data/spec/fixtures/detector/console.yml +0 -267
  66. data/spec/fixtures/detector/desktop.yml +0 -4828
  67. data/spec/fixtures/detector/feature_phone.yml +0 -782
  68. data/spec/fixtures/detector/feed_reader.yml +0 -486
  69. data/spec/fixtures/detector/mediaplayer.yml +0 -179
  70. data/spec/fixtures/detector/mobile_apps.yml +0 -149
  71. data/spec/fixtures/detector/phablet.yml +0 -2140
  72. data/spec/fixtures/detector/portable_media_player.yml +0 -153
  73. data/spec/fixtures/detector/smart_display.yml +0 -58
  74. data/spec/fixtures/detector/smartphone-1.yml +0 -9469
  75. data/spec/fixtures/detector/smartphone-2.yml +0 -9414
  76. data/spec/fixtures/detector/smartphone-3.yml +0 -9396
  77. data/spec/fixtures/detector/smartphone-4.yml +0 -5742
  78. data/spec/fixtures/detector/smartphone.yml +0 -9411
  79. data/spec/fixtures/detector/tablet-1.yml +0 -9495
  80. data/spec/fixtures/detector/tablet-2.yml +0 -248
  81. data/spec/fixtures/detector/tablet.yml +0 -9484
  82. data/spec/fixtures/detector/tv.yml +0 -2582
  83. data/spec/fixtures/detector/unknown.yml +0 -3196
  84. data/spec/fixtures/device/camera.yml +0 -18
  85. data/spec/fixtures/device/car_browser.yml +0 -6
  86. data/spec/fixtures/device/console.yml +0 -78
  87. data/spec/fixtures/parser/oss.yml +0 -800
  88. data/spec/fixtures/parser/vendorfragments.yml +0 -162
  89. data/spec/spec_helper.rb +0 -9
@@ -1,151 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe DeviceDetector::Device do
4
-
5
- subject { DeviceDetector::Device.new(user_agent) }
6
-
7
- alias :device :subject
8
-
9
- describe '#name' do
10
-
11
- describe 'when models are nested' do
12
- let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]' }
13
-
14
- it 'finds an Apple iPhone 6' do
15
- device.name.must_equal 'iPhone 6'
16
- end
17
- end
18
-
19
- describe 'when models are NOT nested' do
20
- let(:user_agent) { 'AIRNESS-AIR99/REV 2.2.1/Teleca Q03B1' }
21
-
22
- it 'finds an Airness AIR99' do
23
- device.name.must_equal 'AIR99'
24
- end
25
- end
26
-
27
- describe 'when it cannot find a device name' do
28
- let(:user_agent) { 'UNKNOWN MODEL NAME' }
29
-
30
- it 'returns nil' do
31
- device.name.must_be_nil
32
- end
33
- end
34
-
35
- end
36
-
37
- describe '#type' do
38
-
39
- describe 'when models are nested' do
40
- let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]' }
41
-
42
- it 'finds device of Apple iPhone 6' do
43
- device.type.must_equal 'smartphone'
44
- end
45
- end
46
-
47
- describe 'when models are NOT nested' do
48
- let(:user_agent) { 'AIRNESS-AIR99/REV 2.2.1/Teleca Q03B1' }
49
-
50
- it 'finds the device of Airness AIR99' do
51
- device.type.must_equal 'feature phone'
52
- end
53
- end
54
-
55
- describe 'when it cannot find a device type' do
56
- let(:user_agent) { 'UNKNOWN MODEL TYPE' }
57
-
58
- it 'returns nil' do
59
- device.type.must_be_nil
60
- end
61
-
62
- end
63
-
64
- describe 'device not specified in nested block' do
65
-
66
- let(:user_agent) { 'Mozilla/5.0 (Linux; Android 4.4.2; es-us; SAMSUNG SM-G900F Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)' }
67
-
68
- it 'falls back to top-level device' do
69
- device.type.must_equal 'smartphone'
70
- end
71
-
72
- end
73
-
74
- end
75
-
76
- describe 'concrete device types' do
77
-
78
- describe 'mobiles' do
79
-
80
- let(:user_agent) { 'Mozilla/5.0 (Linux; Android 4.4.2; es-us; SAMSUNG SM-G900F Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)' }
81
-
82
- it 'identifies the device' do
83
- device.name.must_equal 'GALAXY S5'
84
- device.type.must_equal 'smartphone'
85
- device.brand.must_equal 'Samsung'
86
- end
87
-
88
- end
89
-
90
- describe 'cameras' do
91
-
92
- let(:user_agent) { 'Mozilla/5.0 (Linux; U; Android 4.0; xx-xx; EK-GC100 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30' }
93
-
94
- it 'identifies the device' do
95
- device.name.must_equal 'GALAXY Camera'
96
- device.type.must_equal 'camera'
97
- device.brand.must_equal 'Samsung'
98
- end
99
-
100
- end
101
-
102
- describe 'car browsers' do
103
-
104
- let(:user_agent) { 'Mozilla/5.0 (X11; Linux) AppleWebKit/534.34 (KHTML, like Gecko) QtCarBrowser Safari/534.34' }
105
-
106
- it 'identifies the device' do
107
- device.name.must_equal 'Model S'
108
- device.type.must_equal 'car browser'
109
- device.brand.must_be_nil
110
- end
111
-
112
- end
113
-
114
- describe '(gaming) consoles' do
115
-
116
- let(:user_agent) { 'Opera/9.30 (Nintendo Wii; U; ; 2047-7;en)' }
117
-
118
- it 'identifies the device' do
119
- device.name.must_equal 'Wii'
120
- device.type.must_equal 'console'
121
- device.brand.must_be_nil
122
- end
123
-
124
- end
125
-
126
- describe 'portable media players' do
127
-
128
- let(:user_agent) { 'Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_6 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B651 Safari/9537.53' }
129
-
130
- it 'identifies the device' do
131
- device.name.must_equal 'iPod Touch'
132
- device.type.must_equal 'portable media player'
133
- device.brand.must_equal 'Apple'
134
- end
135
-
136
- end
137
-
138
- describe 'televisions' do
139
-
140
- let(:user_agent) { 'Mozilla/5.0 (Unknown; Linux armv7l) AppleWebKit/537.1+ (KHTML, like Gecko) Safari/537.1+ HbbTV/1.1.1 ( ;LGE ;NetCast 4.0 ;03.10.81 ;1.0M ;)' }
141
-
142
- it 'identifies the device' do
143
- device.name.must_equal 'NetCast 4.0'
144
- device.type.must_equal 'tv'
145
- device.brand.must_equal 'LG'
146
- end
147
-
148
- end
149
- end
150
-
151
- end
@@ -1,116 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe DeviceDetector::MemoryCache do
4
-
5
- let(:subject) { DeviceDetector::MemoryCache.new(config) }
6
-
7
- let(:config) { {} }
8
-
9
- describe '#set' do
10
-
11
- describe 'string key' do
12
-
13
- let(:key) { 'string' }
14
-
15
- it 'sets the value under the key' do
16
- subject.set(key, 'value')
17
-
18
- subject.data[key].must_equal 'value'
19
- end
20
-
21
- end
22
-
23
- describe 'array key' do
24
-
25
- let(:key) { ['string1', 'string2'] }
26
-
27
- it 'sets the value under the key' do
28
- subject.set(key, 'value')
29
-
30
- subject.data[String(key)].must_equal 'value'
31
- end
32
-
33
- end
34
-
35
- end
36
-
37
- describe '#get' do
38
-
39
- describe 'string key' do
40
-
41
- let(:key) { 'string' }
42
-
43
- it 'gets the value for the key' do
44
- subject.data[key] = 'value'
45
-
46
- subject.get(key).must_equal 'value'
47
- end
48
-
49
- end
50
-
51
- describe 'array key' do
52
-
53
- let(:key) { ['string1', 'string2'] }
54
-
55
- it 'gets the value for the key' do
56
- subject.data[String(key)] = 'value'
57
-
58
- subject.get(key).must_equal 'value'
59
- end
60
-
61
- end
62
-
63
- end
64
-
65
- describe '#get_or_set' do
66
-
67
- let(:key) { 'string' }
68
-
69
- describe 'value already present' do
70
-
71
- it 'gets the value for the key from cache' do
72
- subject.data[key] = 'value'
73
-
74
- block_called = false
75
- value = subject.get_or_set(key) do
76
- block_called = true
77
- end
78
-
79
- value.must_equal 'value'
80
- block_called.must_equal false
81
- end
82
-
83
- end
84
-
85
- describe 'value not yet present' do
86
-
87
- it 'evaluates the block and sets the result' do
88
- block_called = false
89
- subject.get_or_set(key) do
90
- block_called = true
91
- end
92
-
93
- block_called.must_equal true
94
- subject.data[key].must_equal true
95
- end
96
-
97
- end
98
-
99
- end
100
-
101
- describe 'cache purging' do
102
-
103
- let(:config) { { max_cache_keys: 3 } }
104
-
105
- it 'purges the cache when key size arrives at max' do
106
- subject.set('1', 'foo')
107
- subject.set('2', 'bar')
108
- subject.set('3', 'baz')
109
- subject.set('4', 'boz')
110
-
111
- subject.data.keys.size.must_equal 3
112
- end
113
-
114
- end
115
-
116
- end
@@ -1,63 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe DeviceDetector::ModelExtractor do
4
-
5
- subject { DeviceDetector::ModelExtractor.new(user_agent, regex_meta) }
6
-
7
- alias :extractor :subject
8
-
9
- describe '#call' do
10
-
11
- describe 'when matching against dynamic model' do
12
-
13
- let(:regex_meta) do
14
- {
15
- :regex => '(?:Apple-)?iPhone ?(3GS?|4S?|5[CS]?|6(:? Plus)?)?',
16
- :model => 'iPhone $1',
17
- :device => 'smartphone'
18
- }
19
- end
20
-
21
- describe 'when no dynamic match is found' do
22
- let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4' }
23
- let(:device_name) { 'iPhone' }
24
-
25
- it 'returns the textual portion without trailing whitespace' do
26
- extractor.call.must_equal device_name
27
- end
28
-
29
- end
30
-
31
- describe 'when a dynamic match is found' do
32
- let(:user_agent) { 'Mozilla/5.0 (iPhone 5S; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4' }
33
- let(:device_name) { 'iPhone 5S' }
34
-
35
- it 'returns the full device name' do
36
- extractor.call.must_equal device_name
37
- end
38
-
39
- end
40
-
41
- end
42
-
43
- describe 'when matching against static model' do
44
-
45
- let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12A365 Weibo (iPhone7,2)' }
46
- let(:device_name) { 'iPhone 6' }
47
- let(:regex_meta) do
48
- {
49
- :regex => '(?:Apple-)?iPhone7[C,]2',
50
- :model => 'iPhone 6',
51
- :device => 'smartphone'
52
- }
53
- end
54
-
55
- it 'returns the model name' do
56
- extractor.call.must_equal device_name
57
- end
58
-
59
- end
60
-
61
- end
62
-
63
- end
@@ -1,26 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe DeviceDetector::OS do
4
-
5
- fixture_dir = File.expand_path('../../fixtures/parser', __FILE__)
6
- fixture_files = Dir["#{fixture_dir}/oss.yml"]
7
- fixture_files.each do |fixture_file|
8
-
9
- describe File.basename(fixture_file) do
10
-
11
- fixtures = YAML.load(File.read(fixture_file))
12
- fixtures.each do |f|
13
- user_agent = f["user_agent"]
14
-
15
- describe user_agent do
16
-
17
- it "should have the expected name" do
18
- os = DeviceDetector::OS.new(user_agent)
19
- assert_equal f["os"]["name"], os.name, "failed OS name detection"
20
- end
21
-
22
- end
23
- end
24
- end
25
- end
26
- end
@@ -1,80 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- describe DeviceDetector::VersionExtractor do
4
-
5
- subject { DeviceDetector::VersionExtractor.new(user_agent, regex_meta) }
6
-
7
- alias :extractor :subject
8
-
9
- describe '#call' do
10
-
11
- describe 'extractor without version' do
12
-
13
- let(:user_agent) { 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; Avant Browser; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)' }
14
-
15
- let(:regex_meta) do
16
- {
17
- :regex => 'Avant Browser',
18
- :name => 'Avant Browser',
19
- :version => ''
20
- }
21
- end
22
-
23
- it 'returns nil' do
24
- extractor.call.must_equal ''
25
- end
26
-
27
- end
28
-
29
- describe 'regex with dynamic matching' do
30
-
31
- let(:user_agent) { 'Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.8.1b2) Gecko/20060821 BonEcho/2.0b2 (Debian-1.99+2.0b2+dfsg-1)' }
32
- let(:version) { 'BonEcho (2.0)' }
33
- let(:regex_meta) do
34
- {
35
- :regex => '(BonEcho|GranParadiso|Lorentz|Minefield|Namoroka|Shiretoko)/(\d+[\.\d]+)',
36
- :name => 'Firefox',
37
- :version => '$1 ($2)'
38
- }
39
- end
40
-
41
- it 'returns the correct version' do
42
- extractor.call.must_equal version
43
- end
44
-
45
- it 'removes trailing white spaces' do
46
- regex_meta[:version] = regex_meta[:version] + ' '
47
- extractor.call.must_equal version
48
- end
49
-
50
- end
51
-
52
- describe 'extractor with fixed version' do
53
-
54
- let(:user_agent) { 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)' }
55
- let(:regex_meta) do
56
- {
57
- :regex => 'MSIE.*Trident/4.0',
58
- :version => '8.0'
59
- }
60
- end
61
-
62
- it 'returns the correct version' do
63
- extractor.call.must_equal '8.0'
64
- end
65
-
66
- end
67
-
68
- describe 'unknown user agent' do
69
-
70
- let(:user_agent) { 'garbage' }
71
- let(:regex_meta) { {} }
72
-
73
- it 'returns nil' do
74
- extractor.call.must_be_nil
75
- end
76
-
77
- end
78
- end
79
- end
80
-
@@ -1,198 +0,0 @@
1
- require_relative 'spec_helper'
2
-
3
- describe DeviceDetector do
4
-
5
- subject { DeviceDetector.new(user_agent) }
6
-
7
- alias :client :subject
8
-
9
- describe 'known user agent' do
10
-
11
- describe 'desktop chrome browser' do
12
-
13
- let(:user_agent) { 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69' }
14
-
15
- describe '#name' do
16
-
17
- it 'returns the name' do
18
- client.name.must_equal 'Chrome'
19
- end
20
-
21
- end
22
-
23
- describe '#full_version' do
24
-
25
- it 'returns the full version' do
26
- client.full_version.must_equal '30.0.1599.69'
27
- end
28
-
29
- end
30
-
31
- describe '#os_name' do
32
-
33
- it 'returns the operating system name' do
34
- client.os_name.must_equal 'Mac'
35
- end
36
-
37
- end
38
-
39
- describe '#os_full_version' do
40
-
41
- it 'returns the operating system full version' do
42
- client.os_full_version.must_equal '10.8.5'
43
- end
44
-
45
- end
46
-
47
- describe '#known?' do
48
-
49
- it 'returns true' do
50
- client.known?.must_equal true
51
- end
52
-
53
- end
54
-
55
- describe '#bot?' do
56
-
57
- it 'returns false' do
58
- client.bot?.must_equal false
59
- end
60
-
61
- end
62
-
63
- describe '#bot_name' do
64
-
65
- it 'returns nil' do
66
- client.bot_name.must_be_nil
67
- end
68
-
69
- end
70
-
71
- end
72
-
73
- end
74
-
75
- describe 'unknown user agent' do
76
-
77
- let(:user_agent) { 'garbage123' }
78
-
79
- describe '#name' do
80
-
81
- it 'returns nil' do
82
- client.name.must_be_nil
83
- end
84
-
85
- end
86
-
87
- describe '#full_version' do
88
-
89
- it 'returns nil' do
90
- client.full_version.must_be_nil
91
- end
92
-
93
- end
94
-
95
- describe '#os_name' do
96
-
97
- it 'returns nil' do
98
- client.os_name.must_be_nil
99
- end
100
-
101
- end
102
-
103
- describe '#os_full_version' do
104
-
105
- it 'returns nil' do
106
- client.os_full_version.must_be_nil
107
- end
108
-
109
- end
110
-
111
- describe '#known?' do
112
-
113
- it 'returns false' do
114
- client.known?.must_equal false
115
- end
116
-
117
- end
118
-
119
- describe '#bot?' do
120
-
121
- it 'returns false' do
122
- client.bot?.must_equal false
123
- end
124
-
125
- end
126
-
127
- describe '#bot_name' do
128
-
129
- it 'returns nil' do
130
- client.bot_name.must_be_nil
131
- end
132
-
133
- end
134
-
135
- end
136
-
137
- describe 'bot' do
138
-
139
- let(:user_agent) { 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' }
140
-
141
- describe '#name' do
142
-
143
- it 'returns nil' do
144
- client.name.must_be_nil
145
- end
146
-
147
- end
148
-
149
- describe '#full_version' do
150
-
151
- it 'returns nil' do
152
- client.full_version.must_be_nil
153
- end
154
-
155
- end
156
-
157
- describe '#os_name' do
158
-
159
- it 'returns nil' do
160
- client.os_name.must_be_nil
161
- end
162
-
163
- end
164
-
165
- describe '#os_full_version' do
166
-
167
- it 'returns nil' do
168
- client.os_full_version.must_be_nil
169
- end
170
-
171
- end
172
-
173
- describe '#known?' do
174
-
175
- it 'returns false' do
176
- client.known?.must_equal false
177
- end
178
-
179
- end
180
-
181
- describe '#bot?' do
182
-
183
- it 'returns true' do
184
- client.bot?.must_equal true
185
- end
186
-
187
- end
188
-
189
- describe '#bot_name' do
190
-
191
- it 'returns the name of the bot' do
192
- client.bot_name.must_equal 'Googlebot'
193
- end
194
-
195
- end
196
-
197
- end
198
- end