browserino 2.5.4 → 2.6.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 +7 -1
- data/README.md +345 -277
- data/bin/console +1 -2
- data/browserino.gemspec +1 -1
- data/lib/browserino/agent.rb +30 -55
- data/lib/browserino/core/alias.rb +1 -1
- data/lib/browserino/core/helpers.rb +3 -1
- data/lib/browserino/core/lies.rb +1 -1
- data/lib/browserino/core/patterns.rb +18 -7
- data/lib/browserino/core/questions.rb +76 -0
- data/lib/browserino/version.rb +1 -1
- data/lib/browserino.rb +1 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65c289d5a5a9bb3ee5e43234561564fa822bf171
|
4
|
+
data.tar.gz: 9cf47123d4f1a3c63dbee10faa9a66cff2a60052
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0235e781e44e41a482e742c25df79b4d3fe007fbfe8b3c346e708634b31fd7af619458329cb0e918c84e3386313ef1ee3ff921a051f25695ddc5c11a7cf75dc1
|
7
|
+
data.tar.gz: 290781a005d1f0d2b9b1d3e23568787e1ea6f8770b33c65ec0b8a05f98b9fe466eb2daf4e6fd742bd38786686a89c078a5524056fb6e7643ebfa6a77649c09da
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
## CHANGELOG
|
2
|
-
_dates are in dd-mm-yyyy format_
|
2
|
+
_dates are in dd-mm-yyyy format_
|
3
|
+
|
4
|
+
#### 15-01-2016 VERSION 2.5.2
|
5
|
+
|
6
|
+
- **DEPRECATE** Custom return values (passed through `Browserino.parse`) will no longer alter the output of the agent object
|
7
|
+
- Added support for windows phone detection
|
8
|
+
- Added `windows_phone?` method
|
3
9
|
|
4
10
|
#### 12-01-2016 VERSION 2.5.1
|
5
11
|
|
data/README.md
CHANGED
@@ -1,14 +1,39 @@
|
|
1
1
|
# Browserino
|
2
2
|
|
3
|
+
A UserAgent sniffer with Rails >= 3.2.0 integration
|
4
|
+
|
5
|
+
## Status
|
6
|
+
|
3
7
|
[![Gem Version](https://badge.fury.io/rb/browserino.svg)](http://badge.fury.io/rb/browserino)
|
4
8
|
[![Build Status](https://travis-ci.org/SidOfc/browserino.svg?branch=master)](https://travis-ci.org/SidOfc/browserino)
|
5
9
|
[![Coverage Status](https://coveralls.io/repos/SidOfc/browserino/badge.svg?branch=master&service=github)](https://coveralls.io/github/SidOfc/browserino?branch=master)
|
6
10
|
|
7
|
-
This gem aims to provide information about the browser that your visitor is using, it's main goal is not to let you exclude any browser from partying on your website (e.g. sniffing) but to provide you with more flexibility towards designing maybe a browser-themed website or knowledge of what your visitors are using to check out your website!
|
8
|
-
|
9
11
|
## Changelog
|
12
|
+
|
10
13
|
_dates are in dd-mm-yyyy format_
|
11
|
-
_older changes can be found in the [CHANGELOG.md](
|
14
|
+
_older changes can be found in the [CHANGELOG.md](/CHANGELOG.md)_
|
15
|
+
|
16
|
+
#### 22-01-2016 VERSION 2.6.0
|
17
|
+
|
18
|
+
- Fixed `to_a` method
|
19
|
+
- Fixed `to_s` method
|
20
|
+
- Removed **bot** suffixes from every bot name
|
21
|
+
- Replaced `googlebot?` with `google?`
|
22
|
+
- Replaced `msnbot?` with `msn?`
|
23
|
+
- Replaced `bingbot?` with `bing?`
|
24
|
+
- Replaced `yandexbot?` with `yandex?`
|
25
|
+
- Replaced `exabot?` with `exa?`
|
26
|
+
- Added `platform?` method
|
27
|
+
- Added `browser?` method
|
28
|
+
- Added `social_media?` method
|
29
|
+
- Added `facebook?` and `fb?` methods
|
30
|
+
- Added `twitter?` method
|
31
|
+
- Added `linkedin?` method
|
32
|
+
- Added `instagram?` method
|
33
|
+
- Added `pinterest?` method
|
34
|
+
- Added `tumblr?` method
|
35
|
+
- Added support for the Brave browser and the `brave?` method
|
36
|
+
- Added `ff?` method
|
12
37
|
|
13
38
|
#### 20-01-2016 VERSION 2.5.4
|
14
39
|
|
@@ -19,16 +44,9 @@ _older changes can be found in the [CHANGELOG.md](https://github.com/SidOfc/brow
|
|
19
44
|
|
20
45
|
- Minor refactoring of code
|
21
46
|
|
22
|
-
#### 15-01-2016 VERSION 2.5.2
|
23
|
-
|
24
|
-
- **DEPRECATE** Custom return values (passed through `Browserino.parse`) will no longer alter the output of the agent object
|
25
|
-
- Added support for windows phone detection
|
26
|
-
- Added `windows_phone?` method
|
27
|
-
|
28
47
|
## Installation
|
29
48
|
|
30
|
-
|
31
|
-
Add this line to your application's Gemfile:
|
49
|
+
Add the following to your applications Gemfile:
|
32
50
|
|
33
51
|
```ruby
|
34
52
|
gem 'browserino'
|
@@ -36,11 +54,23 @@ gem 'browserino'
|
|
36
54
|
|
37
55
|
And then execute:
|
38
56
|
|
39
|
-
|
57
|
+
```
|
58
|
+
$ bundle
|
59
|
+
```
|
60
|
+
|
61
|
+
Or install it yourself with:
|
62
|
+
|
63
|
+
```
|
64
|
+
$ gem install browserino
|
65
|
+
```
|
40
66
|
|
41
|
-
|
67
|
+
Browserino is tested with the following ruby versions
|
42
68
|
|
43
|
-
|
69
|
+
* 1.9.3
|
70
|
+
* 2.0.0
|
71
|
+
* 2.1.0
|
72
|
+
* 2.2.1
|
73
|
+
* 2.3.0
|
44
74
|
|
45
75
|
## Usage
|
46
76
|
|
@@ -49,413 +79,451 @@ After installing the gem globally or in your application you'll have to `require
|
|
49
79
|
```ruby
|
50
80
|
require 'browserino'
|
51
81
|
```
|
52
|
-
|
53
|
-
Afterwards you can simply call
|
82
|
+
Afterwards, the gem is loaded and you can proceed by calling:
|
54
83
|
|
55
84
|
```ruby
|
56
|
-
Browserino.parse
|
85
|
+
Browserino.parse '<user agent>'
|
57
86
|
```
|
58
87
|
|
59
|
-
|
88
|
+
### Rails (>= 3.2.0)
|
89
|
+
|
90
|
+
If you're using Rails (>= 3.2.0) you'll have access to an `agent` object. Browserino will initialize itself using the `request.headers['User-Agent']`
|
91
|
+
|
60
92
|
|
93
|
+
A quick example on how to get going:
|
61
94
|
```ruby
|
62
|
-
class
|
63
|
-
def
|
95
|
+
class ApplicationController < ActionController::Base
|
96
|
+
def some_method
|
64
97
|
render json: agent
|
65
98
|
end
|
66
99
|
end
|
67
100
|
```
|
68
101
|
|
69
|
-
|
102
|
+
### General
|
70
103
|
|
71
|
-
`
|
72
|
-
On this object there are a few method calls you can do to retrieve information.
|
104
|
+
the `parse` method will **always** return a `Browserino::Agent` object.
|
73
105
|
|
74
106
|
```ruby
|
75
|
-
|
107
|
+
Browserino.parse '<user agent>' # => #<Browserino::Agent:0x007f9b09b1fae8 ... >
|
108
|
+
```
|
109
|
+
|
110
|
+
### Default return values
|
111
|
+
|
112
|
+
If a property isn't available or not known to Browserino it's return value will always be `nil`, this can be tested by supplying an empty string (`''`) to `parse`:
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
agent = Browserino.parse ''
|
116
|
+
agent.browser_name
|
117
|
+
# => nil
|
118
|
+
```
|
76
119
|
|
77
|
-
|
120
|
+
If a value *is* found then you'll recieve a *lowercase string* containing the information:
|
121
|
+
|
122
|
+
```ruby
|
123
|
+
agent = Browserino.parse 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) brave/0.7.7 Chrome/47.0.2526.73 Electron/0.36.2 Safari/537.36'
|
78
124
|
|
79
125
|
agent.browser_name
|
80
|
-
# => '
|
126
|
+
# => 'brave'
|
81
127
|
|
82
|
-
# always returns the real version (also with IE in compat)
|
83
128
|
agent.browser_version
|
84
|
-
# => '7.
|
85
|
-
|
86
|
-
# if a user is running IE in compat mode this will return the compat version
|
87
|
-
agent.browser_version compat: true
|
88
|
-
# => '7.0'
|
129
|
+
# => '0.7.7'
|
89
130
|
|
90
131
|
agent.engine_name
|
91
132
|
# => 'webkit'
|
133
|
+
```
|
92
134
|
|
93
|
-
|
94
|
-
# => '537.75.14'
|
135
|
+
Browserino also has some question methods, these will always return either `true` or `false`. The exceptions to this rule are methods that can take a name, for instance the `bot?` method:
|
95
136
|
|
96
|
-
|
97
|
-
|
98
|
-
|
137
|
+
```ruby
|
138
|
+
agent = Browserino.parse ''
|
139
|
+
agent.bot?
|
140
|
+
# => true (empty UA's count as anonymous bots)
|
99
141
|
|
100
|
-
|
101
|
-
|
102
|
-
# => ['macintosh', 'mavericks']
|
142
|
+
agent.googlebot?
|
143
|
+
# => false
|
103
144
|
|
104
|
-
agent.
|
105
|
-
# =>
|
145
|
+
agent.non_supported_bot?
|
146
|
+
# => NoMethodError
|
106
147
|
|
107
|
-
agent.
|
108
|
-
# =>
|
148
|
+
agent.bot? :non_supported_bot
|
149
|
+
# => NoMethodError
|
150
|
+
```
|
109
151
|
|
110
|
-
|
111
|
-
agent.x32?
|
112
|
-
# => true
|
152
|
+
### Functions
|
113
153
|
|
114
|
-
agent.
|
115
|
-
# => false
|
154
|
+
The samples below are all valid calls with their respective outputs, using the `agent` defined below.
|
116
155
|
|
117
|
-
|
118
|
-
agent.
|
119
|
-
|
120
|
-
# or if the UA supplies the information
|
121
|
-
# => 'en-us'
|
156
|
+
```ruby
|
157
|
+
agent = Browserino.parse 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'
|
158
|
+
```
|
122
159
|
|
160
|
+
##### Quick usage
|
123
161
|
|
124
|
-
|
125
|
-
agent.
|
126
|
-
# => '
|
162
|
+
```ruby
|
163
|
+
agent.browser_name
|
164
|
+
# => 'ie'
|
127
165
|
|
128
|
-
# returns
|
129
|
-
agent.
|
130
|
-
# =>
|
166
|
+
# always returns real version, also when IE is in compat
|
167
|
+
agent.browser_version
|
168
|
+
# => '11.0'
|
131
169
|
|
132
|
-
#
|
133
|
-
|
134
|
-
|
170
|
+
# to get the compat version that IE is running in
|
171
|
+
# returns real version if not in compat mode
|
172
|
+
agent.browser_version compat: true
|
173
|
+
# => '11.0'
|
135
174
|
|
136
|
-
|
137
|
-
|
138
|
-
# => true
|
175
|
+
agent.engine_name
|
176
|
+
# => 'trident'
|
139
177
|
|
140
|
-
|
141
|
-
|
142
|
-
# => true
|
178
|
+
agent.engine_version
|
179
|
+
# => '7.0'
|
143
180
|
|
144
|
-
|
145
|
-
|
146
|
-
# => true
|
181
|
+
agent.system_name
|
182
|
+
# => 'windows'
|
147
183
|
|
148
|
-
#
|
149
|
-
|
150
|
-
#
|
184
|
+
# system_name attempts to find the operating systems version name
|
185
|
+
# when full: true is used
|
186
|
+
# returning an array with either the version name or nil if not found
|
187
|
+
agent.system_name full: true
|
188
|
+
# => ['windows', '7']
|
151
189
|
|
152
|
-
|
153
|
-
|
154
|
-
# => 'safari safari-7 webkit webkit-537 macintosh macintosh-10 en-us'
|
190
|
+
agent.system_version
|
191
|
+
# => '6.1'
|
155
192
|
|
156
|
-
agent.
|
157
|
-
# =>
|
158
|
-
# [:browser_name, 'safari'],
|
159
|
-
# [:browser_version, '7.0.3'],
|
160
|
-
# [:engine_name, 'webkit'],
|
161
|
-
# [:engine_version, '537.75.14'],
|
162
|
-
# [:system_name, 'macintosh'],
|
163
|
-
# [:system_version, '10'],
|
164
|
-
# [:system_architecture, nil],
|
165
|
-
# [:locale, nil],
|
166
|
-
# [:bot_name, nil]
|
167
|
-
# ]
|
193
|
+
agent.system_architecture
|
194
|
+
# => 'x64'
|
168
195
|
|
169
|
-
|
170
|
-
|
171
|
-
#
|
172
|
-
# browser_version: '7.0.3',
|
173
|
-
# engine_name: 'webkit',
|
174
|
-
# engine_version: '537.75.14',
|
175
|
-
# system_name: 'macintosh',
|
176
|
-
# system_version: '10',
|
177
|
-
# system_architecture: nil,
|
178
|
-
# locale: nil,
|
179
|
-
# bot_name: nil
|
180
|
-
# }
|
196
|
+
# two formats possible: 'aa' or `aa-bb`
|
197
|
+
agent.locale
|
198
|
+
# => 'as'
|
181
199
|
```
|
182
200
|
|
183
|
-
|
184
|
-
The function uses the names of the `Browserino::Mapping` constants and the `Browserino::Core::PATTERNS` hashes `:browser` and `:bot` output to identify wether or not to throw this exception.
|
185
|
-
Versions are also supported as an argument to the function, for operating systems versions could include a string, symbol or float / integer to indicate a version.
|
186
|
-
_(examples given for windows, android and ios, for a full list of versions check the **maps** folder)_
|
187
|
-
Browsers can also accept a float / integer to check for a specific version.
|
188
|
-
|
189
|
-
### DEPRECATION NOTICE
|
190
|
-
|
191
|
-
**Methods that include a version number in their name (`agent.android4?`) are deprecated as of version 2.0.0. Supply the version as argument instead `agent.android?(4)` or `agent.android('Ice Cream Sandwich')`**
|
201
|
+
##### Question methods
|
192
202
|
|
193
|
-
|
203
|
+
Browserino also provides some question methods.
|
194
204
|
|
195
205
|
```ruby
|
196
|
-
|
206
|
+
# only for Internet Explorer
|
207
|
+
agent.compat?
|
208
|
+
# => false
|
197
209
|
|
198
|
-
#
|
199
|
-
|
210
|
+
# returns true if browser_name or bot_name are present
|
211
|
+
agent.known?
|
212
|
+
# => true
|
200
213
|
|
201
|
-
|
214
|
+
# returns true if browser is known
|
215
|
+
agent.browser?
|
216
|
+
# => true
|
202
217
|
|
203
|
-
#
|
204
|
-
|
218
|
+
# returns true if specific browser
|
219
|
+
agent.browser? :ie
|
220
|
+
# => true
|
205
221
|
|
206
|
-
#
|
207
|
-
|
222
|
+
# returns true if specific browser and version
|
223
|
+
agent.browser? :ie, version: '11.0'
|
208
224
|
|
209
|
-
|
225
|
+
# returns true if there is a social media bot on your website
|
226
|
+
agent.social_media?
|
227
|
+
# => false
|
210
228
|
|
211
|
-
#
|
212
|
-
|
229
|
+
# returns true if platform is known
|
230
|
+
agent.platform?
|
231
|
+
# => true
|
213
232
|
|
214
|
-
#
|
215
|
-
|
216
|
-
#
|
217
|
-
# agent.windows?(:vista) or agent.windows?('vista')
|
233
|
+
# returns true if specific platform
|
234
|
+
agent.platform? :windows
|
235
|
+
# => true
|
218
236
|
|
219
|
-
|
237
|
+
# returns true if specific platform and version
|
238
|
+
agent.platform? :windows, version: '7'
|
239
|
+
# => true
|
220
240
|
|
221
|
-
agent
|
241
|
+
# returns true if user agent is empty or a bot is recognized
|
242
|
+
agent.bot?
|
243
|
+
# => false
|
222
244
|
|
223
|
-
agent.
|
245
|
+
agent.x64?
|
246
|
+
# => true
|
224
247
|
|
225
|
-
agent.
|
248
|
+
agent.x32?
|
249
|
+
# => false
|
226
250
|
|
227
|
-
agent.
|
251
|
+
agent.mobile?
|
252
|
+
# => false
|
228
253
|
```
|
229
254
|
|
230
|
-
|
255
|
+
The above methods are the base questions you can ask but there are a lot more methods you can call on the `agent`. Every supported browser, operating system or bot is basically a question method so you could do this:
|
231
256
|
|
232
257
|
```ruby
|
233
|
-
agent.
|
234
|
-
|
235
|
-
# check for android jellybean
|
236
|
-
# agent.not.android?(:jelly_bean) or agent.not.android?('jelly bean') or agent.not.android?(4.1)
|
237
|
-
|
238
|
-
agent.not.ios?
|
239
|
-
|
240
|
-
# check if iOS version isn't 9 (>= 1.4.0)
|
241
|
-
# agent.not.ios9?
|
242
|
-
|
243
|
-
# check if iOS version isn't 9 (>= 2.0.0)
|
244
|
-
# agent.not.ios?(9)
|
258
|
+
agent.windows?
|
259
|
+
# => true
|
245
260
|
|
246
|
-
|
261
|
+
# based on full name
|
262
|
+
agent.windows? '7'
|
263
|
+
# => true
|
247
264
|
|
248
|
-
#
|
249
|
-
|
265
|
+
# NT versions also work
|
266
|
+
agent.windows? 6.1
|
267
|
+
# => true
|
268
|
+
```
|
250
269
|
|
251
|
-
|
252
|
-
# agent.not.windows?(6) - based on NT version
|
253
|
-
# agent.not.windows?(6.0) - based on NT version
|
254
|
-
# agent.not.windows?(:vista) or agent.not.windows?('vista')
|
270
|
+
##### Transformation
|
255
271
|
|
256
|
-
|
272
|
+
Browserino implements `to_a`, `to_h` and `to_s` to allow for collected data to be moved around without attaching the entire object with methods.
|
257
273
|
|
258
|
-
|
274
|
+
**to_s**
|
259
275
|
|
260
|
-
|
276
|
+
Returns a compiled string of properties based on available information.
|
261
277
|
|
262
|
-
|
278
|
+
```ruby
|
279
|
+
agent.to_s
|
280
|
+
# => 'ie ie11 trident trident7 windows x64'
|
263
281
|
|
264
|
-
|
282
|
+
# a seperator can be passed to format the name + version combo's
|
283
|
+
agent.to_s '-'
|
284
|
+
# => 'ie ie-11 trident trident-7 windows x64'
|
265
285
|
```
|
266
286
|
|
267
|
-
|
268
|
-
|
269
|
-
##### Supported browsers
|
287
|
+
If the agent object can't find a property in the user agent, that property will be excluded from the string.
|
288
|
+
For instance, if the `browser_version` and `engine_version` of the `agent` object are `nil` then the following will be returned:
|
270
289
|
|
271
290
|
```ruby
|
272
|
-
agent.
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
agent.opera_mini?
|
277
|
-
|
278
|
-
agent.bolt?
|
279
|
-
|
280
|
-
agent.ucbrowser?
|
291
|
+
agent.to_s
|
292
|
+
# => ie trident windows x64
|
293
|
+
```
|
281
294
|
|
282
|
-
|
295
|
+
**to_a**
|
283
296
|
|
284
|
-
|
297
|
+
Returns an array with key => value pairs.
|
285
298
|
|
286
|
-
|
299
|
+
```ruby
|
300
|
+
agent.to_a
|
301
|
+
# => [[:browser_name, "ie"],
|
302
|
+
# [:browser_version, "11.0"],
|
303
|
+
# [:engine_name, "trident"],
|
304
|
+
# [:engine_version, "7.0"],
|
305
|
+
# [:system_name, "windows"],
|
306
|
+
# [:system_version, "6.1"],
|
307
|
+
# [:system_architecture, "x64"],
|
308
|
+
# [:locale, "as"],
|
309
|
+
# [:bot_name, nil]]
|
310
|
+
```
|
287
311
|
|
288
|
-
|
312
|
+
**to_h**
|
289
313
|
|
290
|
-
|
314
|
+
Returns a hash with key => value pairs.
|
291
315
|
|
292
|
-
|
316
|
+
```ruby
|
317
|
+
agent.to_h
|
318
|
+
# => {:browser_name=>"ie",
|
319
|
+
# :browser_version=>"11.0",
|
320
|
+
# :engine_name=>"trident",
|
321
|
+
# :engine_version=>"7.0",
|
322
|
+
# :system_name=>"windows",
|
323
|
+
# :system_version=>"6.1",
|
324
|
+
# :system_architecture=>"x64",
|
325
|
+
# :locale=>"as",
|
326
|
+
# :bot_name=>nil}
|
327
|
+
```
|
293
328
|
|
294
|
-
|
329
|
+
##### Supplying versions
|
295
330
|
|
296
|
-
|
297
|
-
agent.not.vivaldi?
|
331
|
+
Consider this parsed string:
|
298
332
|
|
299
|
-
|
333
|
+
```ruby
|
334
|
+
agent = Browserino.parse 'Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; SM-T210R Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30 UCBrowser/2.3.2.300'
|
300
335
|
|
301
|
-
|
336
|
+
# output for system_name
|
337
|
+
agent.system_name
|
338
|
+
# => 'android'
|
302
339
|
|
303
|
-
#
|
340
|
+
# output for system_name full: true
|
341
|
+
agent.system_name full: true
|
342
|
+
# => ['android', 'Jelly Bean 16']
|
304
343
|
```
|
305
344
|
|
306
|
-
|
307
|
-
```ruby
|
308
|
-
agent.msnbot?
|
309
|
-
|
310
|
-
agent.yahoo_slurp?
|
311
|
-
|
312
|
-
agent.googlebot?
|
345
|
+
When supplying a version to a method that supports it, you have multiple options for the format of that version.
|
313
346
|
|
314
|
-
|
347
|
+
* Using a symbol or string without version: `:jelly_bean` or `'jelly_bean'`
|
348
|
+
* Using a symbol or string with version: `:jelly_bean_16` or `'jelly_bean_16'`
|
349
|
+
* Using a string: `'4.1.2'`
|
350
|
+
* Using a float: `4.1`
|
351
|
+
* Using an int: `4`
|
315
352
|
|
316
|
-
|
353
|
+
When calling the `platform?` or `android?` functions with the above examples, they would all match since the method that compares versions also checks how specific the version is that you want to compare against.
|
317
354
|
|
318
|
-
|
355
|
+
If you pass in `4.1` as a version the matcher will look for `x.x` in the extracted version and discard the unspecified value, this allows for you to be explicitly less specific to allow for a greater range of systems to be matched.
|
319
356
|
|
320
|
-
|
357
|
+
* `4.1.2` will match `4.1.2`
|
358
|
+
* `4.1` will match `4.1.x`
|
359
|
+
* `4` will match `4.x.x`
|
321
360
|
|
322
|
-
|
361
|
+
**Examples using `platform?`**
|
323
362
|
|
324
|
-
|
363
|
+
```ruby
|
364
|
+
agent.platform? :android, version: '4.1.2'
|
365
|
+
# => true
|
325
366
|
|
326
|
-
|
367
|
+
agent.platform? :android, version: 4.1
|
368
|
+
# => true
|
327
369
|
|
328
|
-
agent.
|
370
|
+
agent.platform? :android, version: 4
|
371
|
+
# => true
|
329
372
|
|
330
|
-
agent.
|
373
|
+
agent.platform? :android, version: :jelly_bean
|
374
|
+
# => true
|
331
375
|
|
332
|
-
|
376
|
+
agent.platform? :android, version: :jelly_bean_16
|
377
|
+
# => true
|
333
378
|
```
|
334
379
|
|
335
|
-
|
336
|
-
|
337
|
-
The tests are dynamically produced and quite easy to write.
|
380
|
+
##### `platform?`, `browser?`, `bot?` and `social_media?` methods
|
338
381
|
|
339
|
-
|
340
|
-
the tests will lowercase most of the input to make sure there's no case mismatches, this happens mainly on the `*_name` properties
|
382
|
+
As you've seen above, the `platform?` function can take two arguments, a symbol with the system name and optionally a hash with a `:version` key to supply a version, the `browser?` method works in exactly the same way.
|
341
383
|
|
342
|
-
|
343
|
-
|
344
|
-
```ruby
|
345
|
-
module UserAgents
|
346
|
-
module Browsers
|
347
|
-
FIREFOX = {
|
348
|
-
win: {
|
349
|
-
'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1' => {
|
350
|
-
browser_name: 'Firefox',
|
351
|
-
browser_version: '40.1',
|
352
|
-
engine_name: 'Gecko',
|
353
|
-
engine_version: '40.0',
|
354
|
-
system_name: ['windows', '7'],
|
355
|
-
system_version: '6.1',
|
356
|
-
system_architecture: 'x64',
|
357
|
-
locale: nil,
|
358
|
-
x64?: true,
|
359
|
-
x32?: false,
|
360
|
-
known?: true,
|
361
|
-
mobile: false
|
362
|
-
}
|
363
|
-
}
|
364
|
-
}
|
365
|
-
end
|
366
|
-
end
|
367
|
-
```
|
384
|
+
The `bot?` and `social_media?` methods however aren't that complex since you don't need to know a bot / social media version or anything other than it's name so inside these methods, only a name can be passed:
|
368
385
|
|
369
|
-
|
386
|
+
*Every social media match is automatically a bot, but a bot isn't automatically social media*
|
370
387
|
|
371
|
-
#### browser_name examples
|
372
388
|
```ruby
|
373
|
-
|
389
|
+
# when a bot UA gets parsed
|
390
|
+
agent = Browserino.parse 'facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)'
|
374
391
|
|
375
|
-
|
392
|
+
agent.bot?
|
393
|
+
# => true
|
376
394
|
|
377
|
-
|
395
|
+
agent.social_media?
|
396
|
+
# => true
|
378
397
|
|
379
|
-
|
398
|
+
agent.bot? :facebook
|
399
|
+
# => true
|
380
400
|
|
381
|
-
|
401
|
+
agent.social_media? :facebook
|
402
|
+
# => true
|
382
403
|
|
383
|
-
|
404
|
+
agent.bot? :facebook, version: 1.1
|
405
|
+
# => ArgumentError
|
406
|
+
```
|
384
407
|
|
385
|
-
|
408
|
+
##### Checking a specific browser, system, bot or social media
|
386
409
|
|
387
|
-
|
410
|
+
Every name you see in the below lists can be passed as symbol or string to their respective method
|
388
411
|
|
389
|
-
|
412
|
+
**social media**
|
390
413
|
|
391
|
-
|
414
|
+
* `facebook` or `fb`
|
415
|
+
* `twitter`
|
416
|
+
* `linkedin`
|
417
|
+
* `instagram`
|
418
|
+
* `pinterest`
|
419
|
+
* `tumblr`
|
392
420
|
|
393
|
-
|
394
|
-
```
|
421
|
+
Examples:
|
395
422
|
|
396
|
-
#### engine_name examples
|
397
423
|
```ruby
|
424
|
+
agent.facebook?
|
425
|
+
agent.tumblr?
|
398
426
|
|
399
|
-
|
427
|
+
# using the social_media? method
|
428
|
+
agent.social_media? :facebook
|
400
429
|
|
401
|
-
|
430
|
+
# using shorthand
|
431
|
+
agent.social_media? :fb
|
402
432
|
|
403
|
-
|
433
|
+
agent.social_media? :tumblr
|
404
434
|
```
|
405
435
|
|
406
|
-
|
407
|
-
```ruby
|
408
|
-
'googlebot'
|
436
|
+
**bot**
|
409
437
|
|
410
|
-
|
438
|
+
* `google`
|
439
|
+
* `msn`
|
440
|
+
* `bing`
|
441
|
+
* `yahoo_slurp`
|
442
|
+
* `baiduspider`
|
443
|
+
* `yandex`
|
444
|
+
* `sosospider`
|
445
|
+
* `exa`
|
446
|
+
* `sogou_spider`
|
411
447
|
|
412
|
-
|
448
|
+
Examples:
|
413
449
|
|
414
|
-
|
450
|
+
```ruby
|
451
|
+
agent.google?
|
452
|
+
agent.exa?
|
415
453
|
|
416
|
-
|
454
|
+
# using the bot? method
|
455
|
+
agent.bot? :google
|
456
|
+
agent.bot? :exa
|
457
|
+
```
|
417
458
|
|
418
|
-
|
459
|
+
**browser**
|
419
460
|
|
420
|
-
|
461
|
+
* `chrome`
|
462
|
+
* `firefox` or `ff`
|
463
|
+
* `seamonkey`
|
464
|
+
* `opera`
|
465
|
+
* `opera_mini`
|
466
|
+
* `vivaldi`
|
467
|
+
* `ucbrowser`
|
468
|
+
* `maxthon`
|
469
|
+
* `bolt`
|
470
|
+
* `brave`
|
471
|
+
* `safari`
|
472
|
+
* `ie`
|
473
|
+
* `edge`
|
421
474
|
|
422
|
-
|
475
|
+
Examples:
|
423
476
|
|
424
|
-
|
425
|
-
|
477
|
+
```ruby
|
478
|
+
agent.firefox?
|
479
|
+
agent.chrome? 42
|
426
480
|
|
427
|
-
|
481
|
+
# using the browser? method
|
482
|
+
agent.browser? :firefox
|
428
483
|
|
429
|
-
|
430
|
-
|
484
|
+
# using shorthand
|
485
|
+
agent.browser? :ff
|
431
486
|
|
432
|
-
|
487
|
+
agent.browser? :chrome, version: 42
|
488
|
+
```
|
433
489
|
|
434
|
-
|
490
|
+
**operating system**
|
435
491
|
|
436
|
-
|
492
|
+
* `windows` or `win`
|
493
|
+
* `macintosh` or `osx`
|
494
|
+
* `linux`
|
495
|
+
* `bsd`
|
496
|
+
* `android`
|
497
|
+
* `ios`
|
498
|
+
* `blackberry` or `bb`
|
499
|
+
* `windows_phone`
|
437
500
|
|
438
|
-
|
501
|
+
Examples:
|
439
502
|
|
440
|
-
|
503
|
+
```ruby
|
504
|
+
agent.macintosh?
|
505
|
+
agent.windows_phone? 7
|
441
506
|
|
442
|
-
|
507
|
+
# to check for windows vista one could do
|
508
|
+
agent.windows? 6
|
443
509
|
|
444
|
-
|
510
|
+
# a more readable equivelant
|
511
|
+
agent.windows? :vista
|
445
512
|
|
446
|
-
|
513
|
+
# using the platform? method
|
514
|
+
agent.platform? :macintosh
|
447
515
|
|
448
|
-
|
516
|
+
# using shorthand
|
517
|
+
agent.platform? :osx
|
449
518
|
|
450
|
-
|
519
|
+
agent.platform? :windows_phone, version: 7
|
451
520
|
```
|
452
521
|
|
453
|
-
|
454
|
-
```ruby
|
455
|
-
'x32'
|
522
|
+
Notes:
|
456
523
|
|
457
|
-
'
|
458
|
-
|
524
|
+
* `linux?` doesn't support any versions
|
525
|
+
* `bsd?` doesn't support any versions
|
526
|
+
* *named versions* are only supported if they are present in a [map](/lib/browserino/maps)
|
459
527
|
|
460
528
|
## Contributing
|
461
529
|
|
data/bin/console
CHANGED
@@ -3,8 +3,7 @@
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
require 'browserino'
|
5
5
|
require 'pry'
|
6
|
-
ua = 'Mozilla/5.0 (
|
7
|
-
(KHTML, like Gecko) Version/9.0.2 Safari/601.3.9'
|
6
|
+
ua = 'Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko'
|
8
7
|
@agent = Browserino.parse(ua)
|
9
8
|
|
10
9
|
puts "> @agent variable available parsed with: '#{ua}'\n\n"
|
data/browserino.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Sidney Liebrand"]
|
10
10
|
spec.email = ["sidneyliebrand@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{A browser identification gem}
|
12
|
+
spec.summary = %q{A browser identification gem with Rails (>= 3.2.0) integration}
|
13
13
|
spec.homepage = "https://github.com/SidOfc/browserino"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/browserino/agent.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Browserino
|
2
2
|
class Agent
|
3
|
-
include Core::Helpers
|
3
|
+
include Core::Helpers, Core::Questions
|
4
4
|
attr_reader :ua
|
5
5
|
|
6
6
|
def initialize(info, ua = nil)
|
@@ -53,76 +53,51 @@ module Browserino
|
|
53
53
|
@info[:bot_name]
|
54
54
|
end
|
55
55
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
def known?
|
61
|
-
invert_if_not !browser_name.nil? || !bot_name.nil?
|
62
|
-
end
|
63
|
-
|
64
|
-
def mobile?
|
65
|
-
invert_if_not !ua.match(Core::PATTERNS[:operating_system][:mobile]).nil?
|
66
|
-
end
|
67
|
-
|
68
|
-
def x64?
|
69
|
-
invert_if_not system_architecture == 'x64'
|
70
|
-
end
|
71
|
-
|
72
|
-
def x32?
|
73
|
-
invert_if_not system_architecture == 'x32'
|
56
|
+
def not
|
57
|
+
@not = true
|
58
|
+
self
|
74
59
|
end
|
75
60
|
|
76
|
-
def
|
77
|
-
|
61
|
+
def to_s(sep = '')
|
62
|
+
prev = ''
|
63
|
+
s = hash_for_to_s.each_with_object([]) do |v, a|
|
64
|
+
a << case v[0]
|
65
|
+
when :browser_version, :engine_version
|
66
|
+
prev + sep + (v[1].split('.').first || '')
|
67
|
+
else v[1]
|
68
|
+
end
|
69
|
+
prev = v[1]
|
70
|
+
end
|
71
|
+
s.reject { |str| str == '' }.join ' '
|
78
72
|
end
|
79
73
|
|
80
|
-
def
|
81
|
-
|
74
|
+
def hash_for_to_s
|
75
|
+
out = to_h.each_with_object({}) do |a, h|
|
76
|
+
h[a[0]] = a[1].to_s.gsub(/[\s_]/, '-')
|
77
|
+
end
|
78
|
+
[:locale, :system_version].each { |k| out.delete(k) }
|
79
|
+
out
|
82
80
|
end
|
83
81
|
|
84
|
-
def
|
85
|
-
|
82
|
+
def to_a
|
83
|
+
@info.keys.each_with_object([]) { |f, a| a.push([f, send(f)]) }.compact
|
86
84
|
end
|
87
85
|
|
88
|
-
def
|
89
|
-
|
90
|
-
is_name = name.nil? || name.to_s.downcase.tr('_', ' ') == bot_name
|
91
|
-
invert_if_not is_bot && is_name
|
86
|
+
def to_h
|
87
|
+
to_a.each_with_object({}) { |a, h| h[a[0]] = a[1] }
|
92
88
|
end
|
93
89
|
|
94
90
|
def method_missing(method_sym, *args, &block)
|
95
91
|
name = method_sym.to_s.tr('?', '')
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
92
|
+
invertable case agent_or_system?(method_sym)
|
93
|
+
when :system then correct_system?(name, *args)
|
94
|
+
when :agent then correct_agent?(name, *args)
|
95
|
+
else super
|
96
|
+
end
|
101
97
|
end
|
102
98
|
|
103
99
|
def respond_to?(method_sym)
|
104
100
|
agent_or_system?(method_sym).nil? ? false : true
|
105
101
|
end
|
106
|
-
|
107
|
-
def not
|
108
|
-
@not = true
|
109
|
-
self
|
110
|
-
end
|
111
|
-
|
112
|
-
def to_s(sep = '')
|
113
|
-
props = @info.map do |k, _|
|
114
|
-
y = [:system_version, :engine_version, :browser_version].include?(k)
|
115
|
-
y ? send(k) + sep + send(k).to_s.split('.').first : send(k)
|
116
|
-
end
|
117
|
-
props.compact.map { |v| v.tr(' ', '-') }.join(' ')
|
118
|
-
end
|
119
|
-
|
120
|
-
def to_a
|
121
|
-
@info.each_with_object([]) { |v, a| a.push(v) }
|
122
|
-
end
|
123
|
-
|
124
|
-
def to_h
|
125
|
-
to_a.each_with_object({}) { |v, h| h[v[0].to_sym] = v[1] }
|
126
|
-
end
|
127
102
|
end
|
128
103
|
end
|
data/lib/browserino/core/lies.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Browserino
|
2
2
|
module Core
|
3
|
-
|
3
|
+
PATTERNS = {
|
4
4
|
browser: {
|
5
5
|
vivaldi: {
|
6
6
|
name: /(?<name>vivaldi)/i,
|
@@ -54,6 +54,11 @@ module Browserino
|
|
54
54
|
|netscape)/?(?<version>[\d\.]+)}xi
|
55
55
|
},
|
56
56
|
|
57
|
+
brave: {
|
58
|
+
name: /(?<name>brave)/i,
|
59
|
+
version: %r{brave/(?<version>[\d\.]+)}i
|
60
|
+
},
|
61
|
+
|
57
62
|
chrome: {
|
58
63
|
name: /(?<name>chrome?(ium|plus)?)/i,
|
59
64
|
version: %r{chrome?(?:ium|plus)?/(?<version>[\d\.]+)}i
|
@@ -66,19 +71,25 @@ module Browserino
|
|
66
71
|
},
|
67
72
|
|
68
73
|
bot: {
|
69
|
-
|
74
|
+
google: { name: /(?<name>googlebot)/i },
|
70
75
|
yahoo_slurp: { name: /(?<name>yahoo\!\sslurp)/i },
|
71
|
-
|
72
|
-
|
76
|
+
msn: { name: /(?<name>msnbot)/i },
|
77
|
+
bing: { name: /(?<name>bingbot)/i },
|
73
78
|
baiduspider: { name: /(?<name>baiduspider)/i },
|
74
|
-
|
79
|
+
yandex: { name: /(?<name>yandexbot)/i },
|
75
80
|
sosospider: { name: /(?<name>sosospider)/i },
|
76
|
-
|
81
|
+
exa: { name: /(?<name>exabot)/i },
|
77
82
|
sogou_spider: { name: /(?<name>sogou\s?spider)/i },
|
78
83
|
nutch: { name: /(?<name>nutch)/i },
|
79
84
|
scrapy: { name: /(?<name>scrapy)/i },
|
80
85
|
dataparksearch: { name: /(?<name>dataparksearch)/i },
|
81
|
-
|
86
|
+
beslist: { name: /(?<name>beslistbot)/i },
|
87
|
+
facebook: { name: /(?<name>face(?:bookexternalhit|bot))/i },
|
88
|
+
twitter: { name: /(?<name>twitterbot)/i },
|
89
|
+
linkedin: { name: /(?<name>linkedinbot)/i },
|
90
|
+
instagram: { name: /(?<name>instagram)/i },
|
91
|
+
pinterest: { name: /(?<name>pinterest)/i },
|
92
|
+
tumblr: { name: /(?<name>tumblr)/i }
|
82
93
|
},
|
83
94
|
|
84
95
|
engine: {
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Browserino
|
2
|
+
module Core
|
3
|
+
module Questions
|
4
|
+
SHORT_SYSTEM_NAMES = {
|
5
|
+
'osx' => 'macintosh',
|
6
|
+
'win' => 'windows',
|
7
|
+
'bb' => 'blackberry'
|
8
|
+
}.freeze
|
9
|
+
|
10
|
+
SOCIAL_MEDIA = [:facebook, :twitter, :linkedin,
|
11
|
+
:instagram, :pinterest, :tumblr].freeze
|
12
|
+
|
13
|
+
def compat?
|
14
|
+
invertable ie? && browser_version != browser_version(compat: true)
|
15
|
+
end
|
16
|
+
|
17
|
+
def known?
|
18
|
+
invertable !browser_name.nil? || !bot_name.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def mobile?
|
22
|
+
invertable !ua.match(Core::PATTERNS[:operating_system][:mobile]).nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def x64?
|
26
|
+
invertable system_architecture == 'x64'
|
27
|
+
end
|
28
|
+
|
29
|
+
def x32?
|
30
|
+
invertable system_architecture == 'x32'
|
31
|
+
end
|
32
|
+
|
33
|
+
def osx?(*arg)
|
34
|
+
macintosh?(*arg)
|
35
|
+
end
|
36
|
+
|
37
|
+
def win?(*arg)
|
38
|
+
windows?(*arg)
|
39
|
+
end
|
40
|
+
|
41
|
+
def bb?(*arg)
|
42
|
+
blackberry?(*arg)
|
43
|
+
end
|
44
|
+
|
45
|
+
def fb?(*arg)
|
46
|
+
facebook?(*arg)
|
47
|
+
end
|
48
|
+
|
49
|
+
def ff?(*arg)
|
50
|
+
firefox?(*arg)
|
51
|
+
end
|
52
|
+
|
53
|
+
def bot?(name = nil)
|
54
|
+
is_bot = ua.strip.empty? || !bot_name.nil?
|
55
|
+
is_name = name.nil? || name.to_s.downcase.tr('_', ' ') == bot_name
|
56
|
+
invertable is_bot && is_name
|
57
|
+
end
|
58
|
+
|
59
|
+
def social_media?(name = nil)
|
60
|
+
if name
|
61
|
+
invertable send("#{name}?")
|
62
|
+
else
|
63
|
+
invertable SOCIAL_MEDIA.include?(bot_name.to_s.to_sym)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def platform?(name = nil, opts = {})
|
68
|
+
invertable name ? send("#{name}?", opts[:version]) : !system_name.nil?
|
69
|
+
end
|
70
|
+
|
71
|
+
def browser?(name = nil, opts = {})
|
72
|
+
invertable name ? send("#{name}?", opts[:version]) : !browser_name.nil?
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/browserino/version.rb
CHANGED
data/lib/browserino.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: browserino
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sidney Liebrand
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -137,6 +137,7 @@ files:
|
|
137
137
|
- lib/browserino/core/helpers.rb
|
138
138
|
- lib/browserino/core/lies.rb
|
139
139
|
- lib/browserino/core/patterns.rb
|
140
|
+
- lib/browserino/core/questions.rb
|
140
141
|
- lib/browserino/engine.rb
|
141
142
|
- lib/browserino/integrate/action_controller.rb
|
142
143
|
- lib/browserino/integrate/rails.rb
|
@@ -175,5 +176,5 @@ rubyforge_project:
|
|
175
176
|
rubygems_version: 2.5.1
|
176
177
|
signing_key:
|
177
178
|
specification_version: 4
|
178
|
-
summary: A browser identification gem
|
179
|
+
summary: A browser identification gem with Rails (>= 3.2.0) integration
|
179
180
|
test_files: []
|