browserino 4.3.0 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -3
- data/CHANGELOG.md +4 -0
- data/README.md +261 -118
- data/browserino.gemspec +12 -11
- data/lib/browserino/client.rb +5 -7
- data/lib/browserino/config.rb +5 -0
- data/lib/browserino/definitions/aliasses.rb +4 -0
- data/lib/browserino/definitions/filters.rb +30 -22
- data/lib/browserino/definitions/labels.rb +1 -0
- data/lib/browserino/definitions/matchers/bots.rb +4 -0
- data/lib/browserino/definitions/matchers/browsers.rb +56 -8
- data/lib/browserino/definitions/matchers/emails.rb +1 -0
- data/lib/browserino/definitions/matchers/global.rb +15 -4
- data/lib/browserino/definitions/missing_props.rb +24 -0
- data/lib/browserino/integrate/action_controller.rb +4 -1
- data/lib/browserino/methods.rb +56 -11
- data/lib/browserino/options.rb +2 -1
- data/lib/browserino/version.rb +1 -1
- data/lib/browserino.rb +5 -4
- metadata +4 -3
data/browserino.gemspec
CHANGED
@@ -5,18 +5,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
require 'browserino/version'
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.
|
9
|
-
spec.
|
10
|
-
spec.
|
11
|
-
spec.
|
12
|
-
spec.
|
13
|
-
spec.
|
14
|
-
spec.
|
8
|
+
spec.required_ruby_version = '>= 2.0'
|
9
|
+
spec.name = "browserino"
|
10
|
+
spec.version = Browserino.version.full
|
11
|
+
spec.authors = ["Sidney Liebrand"]
|
12
|
+
spec.email = ["sidneyliebrand@gmail.com"]
|
13
|
+
spec.summary = %q{A browser identification gem with command line and Rails (>= 3.2.0) integration}
|
14
|
+
spec.homepage = "https://github.com/sidofc/browserino"
|
15
|
+
spec.license = "MIT"
|
15
16
|
|
16
|
-
spec.files
|
17
|
-
spec.bindir
|
18
|
-
spec.executables
|
19
|
-
spec.require_paths
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "bin"
|
19
|
+
spec.executables = ['browserino']
|
20
|
+
spec.require_paths = ["lib"]
|
20
21
|
|
21
22
|
spec.add_development_dependency "bundler"
|
22
23
|
spec.add_development_dependency "rake"
|
data/lib/browserino/client.rb
CHANGED
@@ -50,6 +50,7 @@ module Browserino
|
|
50
50
|
|
51
51
|
def is?(sym, opt = {})
|
52
52
|
return invertable send("#{sym}?", opt[:version]) if opt && opt[:version]
|
53
|
+
|
53
54
|
invertable send("#{sym}?")
|
54
55
|
end
|
55
56
|
|
@@ -125,7 +126,7 @@ module Browserino
|
|
125
126
|
# if you wish for a method to respond to the #not method,
|
126
127
|
# you'll have to return the result of a function using the `invertable`
|
127
128
|
# method as seen in `method_missing` - this will apply the state of the
|
128
|
-
# instance variable and invert the state
|
129
|
+
# instance variable and invert the state as well as the result if set,
|
129
130
|
# otherwise it will just return the value without touching it
|
130
131
|
def not
|
131
132
|
@not = true && self
|
@@ -139,16 +140,19 @@ module Browserino
|
|
139
140
|
|
140
141
|
def label_for(sym, from = properties)
|
141
142
|
return from[:label] if %i[version label name].include? sym
|
143
|
+
|
142
144
|
from["#{sym}_label".to_sym]
|
143
145
|
end
|
144
146
|
|
145
147
|
def name_for(sym, from = properties)
|
146
148
|
return from[:name] if %i[version label name].include? sym
|
149
|
+
|
147
150
|
from["#{sym}_name".to_sym]
|
148
151
|
end
|
149
152
|
|
150
153
|
def version_for(sym, from = properties)
|
151
154
|
return from[:version] if %i[version label name].include? sym
|
155
|
+
|
152
156
|
from["#{sym}_version".to_sym]
|
153
157
|
end
|
154
158
|
|
@@ -196,11 +200,5 @@ module Browserino
|
|
196
200
|
end
|
197
201
|
end
|
198
202
|
end
|
199
|
-
|
200
|
-
def get_answer(mtd, res, ver = nil, val = nil)
|
201
|
-
return res.is_a?(Version) ? res > '0.0.0' : res && true unless val
|
202
|
-
incl = res == val
|
203
|
-
ver && incl ? version_for(mtd) == ver : incl
|
204
|
-
end
|
205
203
|
end
|
206
204
|
end
|
data/lib/browserino/config.rb
CHANGED
@@ -9,8 +9,8 @@ Browserino.config.define do
|
|
9
9
|
# the returned result will be used as the user agent to parse so make
|
10
10
|
# sure to return the final ua at the end
|
11
11
|
before_parse do |ua|
|
12
|
-
subs = [[%r{applewebkit}i, 'webkit'], [%r{
|
13
|
-
[%r{\
|
12
|
+
subs = [[%r{applewebkit}i, 'webkit'], [%r{\sAdr\s}, 'Android '],
|
13
|
+
[%r{(Mozilla/[\d\.]+|X11|PVR DL)}i, '']]
|
14
14
|
subs << [%r{Chrome|Safari}, ''] if ua =~ %r{nichrome|digg\sfeed|quiterss}i
|
15
15
|
subs << [%r{9\.80}, ''] if ua =~ %r{opera}i
|
16
16
|
subs << [%r{webkit/}i, ''] if ua =~ %r{presto}i
|
@@ -42,41 +42,49 @@ Browserino.config.define do
|
|
42
42
|
# before any named filters
|
43
43
|
filter do |val|
|
44
44
|
case val
|
45
|
-
when TrueClass, FalseClass, NilClass, Proc then val
|
46
|
-
when %r{\A[\d_\.]+\z}i
|
45
|
+
when TrueClass, FalseClass, NilClass, Proc, Array then val
|
46
|
+
when %r{\A[\d_\.]+\z}i then val.to_s.strip.tr '_', '.'
|
47
47
|
else val.to_s.downcase.strip.gsub(%r{[\s-]+}i, '_').to_sym
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
# this is a named filter, it defines the same filter for 3 properties
|
52
|
-
# multiple name filters for the same property can be created, they
|
53
|
-
# executed in order of
|
52
|
+
# multiple name filters for the same property can be created, they
|
53
|
+
# will be executed in order of definition
|
54
54
|
filter :version, :engine_version, :platform_version do |val|
|
55
55
|
Browserino::Version.new val
|
56
56
|
end
|
57
57
|
|
58
|
+
filter :locales do |locales|
|
59
|
+
locales.map do |(locale, _quality)|
|
60
|
+
locale.downcase.strip.tr('-', '_').to_sym
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
58
64
|
filter :platform do |val|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
65
|
+
case val
|
66
|
+
when %r{ip(?:[ao]d|hone)}i then :ios
|
67
|
+
when %r{^symbian$}i then :symbianos
|
68
|
+
when %r{w(?:eb)?os}i then :webos
|
69
|
+
when %r{ubuntu|debian}i then :linux
|
70
|
+
when %r{mac_os_x}i then :macintosh
|
71
|
+
when %r{s(?:unos|olaris)}i then :solaris
|
72
|
+
when %r{cros}i then :chromeos
|
73
|
+
when %r{kindle|kf\w+}i then :fire_os
|
74
|
+
when %r{fxos}i then :firefox_os
|
68
75
|
else val
|
69
76
|
end
|
70
77
|
end
|
71
78
|
|
72
79
|
filter :device do |val|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
+
case val
|
81
|
+
when %r{kf\w*}i then :kindle
|
82
|
+
when %r{lg[-l_]}i then :lg
|
83
|
+
when %r{\w+tab}i then :lenovo
|
84
|
+
when %r{lumia}i then :nokia
|
85
|
+
when %r{^moto}i then :motorola
|
86
|
+
when %r{\d+dl|venue}i then :dell
|
87
|
+
when %r{me\d+x|a\df;|transformer|slider}i then :asus
|
80
88
|
else val
|
81
89
|
end
|
82
90
|
end
|
@@ -25,6 +25,7 @@ Browserino.config.define do
|
|
25
25
|
label :marshmallow, for: :android, range: '6'..'6.9.9'
|
26
26
|
label :nougat, for: :android, range: '7'..'7.9.9'
|
27
27
|
label :oreo, for: :android, range: '8'..'8.9.9'
|
28
|
+
label :pie, for: :android, range: '9'..'9.9.9'
|
28
29
|
|
29
30
|
# support android up to the letter Z by following their version scheme which
|
30
31
|
# uses versions X.0.0 up to X.9.9. the callable methods will be named like
|
@@ -161,6 +161,7 @@ Browserino.config.bots text: true, good: proc { !bad },
|
|
161
161
|
match %r{nutch}i, name: :nutch
|
162
162
|
match %r{ia_archiver}i, name: :alexa
|
163
163
|
match %r{atomz}i, name: :atomz
|
164
|
+
match %r{ntent}i, name: :ntent
|
164
165
|
match %r{htdig}i, name: :htdig
|
165
166
|
match %r{peew}i, name: :peew
|
166
167
|
match %r{yeti}i, name: :yeti
|
@@ -173,6 +174,9 @@ Browserino.config.bots text: true, good: proc { !bad },
|
|
173
174
|
match %r{ipd/}i, name: :ipd
|
174
175
|
match %r{zao}i, name: :zao
|
175
176
|
|
177
|
+
match %r{sheenbot}i, name: :sheenbot,
|
178
|
+
version: %r{sheenbot\-([\d\.]+)}i
|
179
|
+
|
176
180
|
match %r{furlbot}i, name: :furlbot,
|
177
181
|
version: %r{rl\ssearch\s([\d\.]+)}i
|
178
182
|
|
@@ -40,8 +40,9 @@ Browserino.config.browsers do
|
|
40
40
|
engine %r{(presto|webkit)}i
|
41
41
|
end
|
42
42
|
|
43
|
-
#
|
44
|
-
match %r{escape}i,
|
43
|
+
# these come before IE
|
44
|
+
match %r{escape}i, name: :escape
|
45
|
+
match %r{juzi(?:browser)}i, name: :orange_browser, engine: :trident
|
45
46
|
|
46
47
|
match %r{flock}i, name: :flock, engine: %r{(webkit|gecko|servo)}i,
|
47
48
|
engine_version: %r{(?:webkit|rv:|servo)[\s/]?([\d\.]+)}i
|
@@ -56,14 +57,31 @@ Browserino.config.browsers do
|
|
56
57
|
modern { version >= 10 }
|
57
58
|
end
|
58
59
|
|
60
|
+
match %r{alohabrowser}i, name: :alohabrowser, engine: :webkit
|
59
61
|
match %r{origyn\sweb\sbrowser}i, name: :origyn, engine: :webkit
|
60
62
|
match %r{webpositive}i, name: :webpositive, engine: :webkit
|
61
63
|
match %r{nintendobrowser}i, name: :nintendobrowser, engine: :webkit
|
62
64
|
match %r{deskbrowse}i, name: :deskbrowse, engine: :webkit
|
63
|
-
match %r{qupzilla}i, name: :qupzilla, engine: :webkit
|
64
65
|
match %r{midori}i, name: :midori, engine: :webkit
|
65
66
|
match %r{shiira}i, name: :shiira, engine: :webkit
|
66
67
|
match %r{element\sbrowser}i, name: :element_browser, engine: :webkit
|
68
|
+
match %r{iris}i, name: :iris, engine: :webkit
|
69
|
+
match %r{otter}i, name: :otter, engine: :webkit
|
70
|
+
match %r{chedot}i, name: :chedot, engine: :webkit
|
71
|
+
match %r{acheetahi}i, name: :cm_browser, engine: :webkit
|
72
|
+
match %r{diglo}i, name: :diglo, engine: :webkit
|
73
|
+
match %r{diigo(?:browser)}i, name: :diigo_browser, engine: :webkit
|
74
|
+
match %r{flyflow}i, name: :flyflow, engine: :webkit
|
75
|
+
match %r{freebox}i, name: :freebox, engine: :webkit
|
76
|
+
match %r{kuaiso}i, name: :kuaiso, engine: :webkit
|
77
|
+
match %r{lovense}i, name: :lovense, engine: :webkit
|
78
|
+
match %r{slimjet}i, name: :slimjet, engine: :webkit
|
79
|
+
match %r{zetakey}i, name: :zetakey, engine: :webkit
|
80
|
+
match %r{wkbrowser}i, name: :wkbrowser, engine: :webkit
|
81
|
+
match %r{yolobrowser}i, name: :yolobrowser, engine: :webkit
|
82
|
+
match %r{whale}i, name: :whale, engine: :webkit
|
83
|
+
match %r{vivo}i, name: :vivo, engine: :webkit
|
84
|
+
match %r{jasmine}i, name: :jasmine
|
67
85
|
match %r{amigavoyager}i, name: :amigavoyager
|
68
86
|
match %r{acorn\sbrowse}i, name: :browse
|
69
87
|
match %r{mothra}i, name: :mothra
|
@@ -71,6 +89,24 @@ Browserino.config.browsers do
|
|
71
89
|
match %r{spray\-can}i, name: :spray_can
|
72
90
|
match %r{bunjalloo}i, name: :bunjalloo
|
73
91
|
|
92
|
+
match %r{sraf}i, name: :seraphic_sraf,
|
93
|
+
version: %r{sraf/([\d\.]+)}i
|
94
|
+
|
95
|
+
match %r{phantomjs}i, name: :phantomjs,
|
96
|
+
engine: %r{(webkit|gecko|servo|trident|blink)}i
|
97
|
+
|
98
|
+
match %r{slimerjs}i, name: :slimerjs,
|
99
|
+
engine: %r{(webkit|gecko|servo|trident|blink)}i,
|
100
|
+
engine_version: %r{(?:webkit|gecko|servo|
|
101
|
+
trident|blink|rv)
|
102
|
+
[:/]([\d\.]+)}xi
|
103
|
+
|
104
|
+
match %r{liebao}i, name: :liebao, engine: :webkit,
|
105
|
+
version: %r{liebao(?:fast)/([\d\.]+)}i
|
106
|
+
|
107
|
+
match %r{qupzilla|falkon}i, name: :qupzilla, engine: :webkit,
|
108
|
+
version: %r{(?:qupzilla|falkon)/([\d\.]+)}i
|
109
|
+
|
74
110
|
match %r{inet\sbrowser}i, name: :inet_browser,
|
75
111
|
platform: :star_blade_os
|
76
112
|
|
@@ -119,6 +155,7 @@ Browserino.config.browsers do
|
|
119
155
|
match %r{osb\-browser}i, name: :osb_browser, engine: :webkit
|
120
156
|
match %r{edbrowse}i, name: :edbrowse, text: true
|
121
157
|
match %r{amaya}i, name: :amaya, text: true
|
158
|
+
match %r{w3m}i, name: :w3m, text: true
|
122
159
|
match %r{lynx}i, name: :lynx, text: true
|
123
160
|
match %r{linemode}i, name: :linemode, text: true
|
124
161
|
match %r{elinks}i, name: :elinks, text: true
|
@@ -129,14 +166,18 @@ Browserino.config.browsers do
|
|
129
166
|
match %r{konqueror}i, name: :konqueror
|
130
167
|
match %r{cyberdog}i, name: :cyberdog
|
131
168
|
match %r{offbyone}i, name: :offbyone
|
132
|
-
match %r{hotjava}i, name: :hotjava
|
133
169
|
match %r{netsurf}i, name: :netsurf
|
134
170
|
match %r{contiki}i, name: :contiki
|
135
171
|
match %r{mosaic|ibrowse[^r]}i, name: :mosaic
|
136
172
|
match %r{netbox}i, name: :netbox
|
173
|
+
match %r{charon}i, name: :charon
|
137
174
|
match %r{dillo}i, name: :dillo
|
138
175
|
match %r{ice\sbrowser}i, name: :ice_browser
|
139
176
|
|
177
|
+
match %r{hotjava|webrunner}i, name: :hotjava, engine: %r{(gecko)}i,
|
178
|
+
version: %r{(?:hotjava|webrunner)/([\d\.]+)}i,
|
179
|
+
engine_version: %r{rv:\s?([\d\.]+)}i
|
180
|
+
|
140
181
|
match %r{emacs}i, name: :emacs, text: true,
|
141
182
|
version: %r{emacs(?:\-\w+)?/([\d\.]+)}i
|
142
183
|
|
@@ -201,6 +242,7 @@ Browserino.config.browsers do
|
|
201
242
|
match %r{perk}i, name: :perk
|
202
243
|
match %r{hana}i, name: :hana
|
203
244
|
match %r{(?<!env)iron}i, name: :iron
|
245
|
+
match %r{cent\b}i, name: :cent, engine: :blink
|
204
246
|
|
205
247
|
match %r{nichrome}i, name: :nichrome, engine: :webkit,
|
206
248
|
version: %r{chrome[\s/]\w+[\s/]([\d\.]+)}i
|
@@ -346,11 +388,16 @@ Browserino.config.browsers do
|
|
346
388
|
|
347
389
|
# below are special cases where we need to manually
|
348
390
|
# supply the version pattern
|
349
|
-
match %r{flexnetdesktopclient}i,
|
350
|
-
|
391
|
+
match %r{flexnetdesktopclient}i, name: :netflix_desktop,
|
392
|
+
version: %r{pclient_([\d\.\_]+)}i
|
393
|
+
|
394
|
+
match %r{MetaSr}, name: :sogou_browser,
|
395
|
+
version: %r{metasr\s([\d\.\_]+)}i
|
351
396
|
|
352
|
-
match %r{
|
353
|
-
|
397
|
+
match %r{jig(?:\sbrowser\sweb)}i, name: :jig_browser_web,
|
398
|
+
engine: %r{webkit|trident|gecko},
|
399
|
+
version: %r{jig(?:\sbrowser\sweb);
|
400
|
+
\s?([\d\.]+)}xi
|
354
401
|
|
355
402
|
# we can exclude the default version which will then be replaced by
|
356
403
|
# the smart_matcher for :version which uses the :name token automatically
|
@@ -367,6 +414,7 @@ Browserino.config.browsers do
|
|
367
414
|
match %r{netcaptor}i, name: :netcaptor
|
368
415
|
match %r{sleipnir}i, name: :sleipnir
|
369
416
|
match %r{irider}i, name: :irider
|
417
|
+
match %r{blazer}i, name: :blazer
|
370
418
|
match %r{kkman}i, name: :kkman
|
371
419
|
match %r{lobo}i, name: :lobo
|
372
420
|
match %r{foxy}i, name: :foxy
|
@@ -17,9 +17,19 @@ Browserino.config.define do
|
|
17
17
|
# a simple set of global matchers that will be merged and scanned
|
18
18
|
# with a specific matcher when the final client object is created
|
19
19
|
match do
|
20
|
-
locale %r{(?<!nintendo)[;\s(]([a-z]{2}(?:[-_][a-z]{2})?)
|
20
|
+
locale %r{(?<!nintendo)[;\s(](?!nt)([a-z]{2}(?:[-_][a-z]{2})?)
|
21
|
+
\-?[;)/](?!\d)}xi
|
21
22
|
architecture %r{((?:(?:x|x86_|amd|wow|win)64)|i[36]86|arm)}i
|
22
23
|
|
24
|
+
# set locales prop which will be populated with accept-language header
|
25
|
+
# locales sorted by quality when Browserino.parse receives
|
26
|
+
# a hash of http headers as second argument
|
27
|
+
locales []
|
28
|
+
|
29
|
+
# overwrite client-generated locales? method
|
30
|
+
# to make the correct comparison for arrays
|
31
|
+
locales? { locales.any? }
|
32
|
+
|
23
33
|
smarttv %r{(?:smart[\-\s]|hbb|apple\s|google|g)(tv)}i
|
24
34
|
|
25
35
|
tablet %r{(ipad|transformer|slider|a\d+f;|tablet|lenovo
|
@@ -35,7 +45,8 @@ Browserino.config.define do
|
|
35
45
|
|blackberry|linux|ubuntu|beos|unix|bsd|s(?:unos|olaris)
|
36
46
|
|tizen|xbox|amigaos|w(?:eb)?os|(?<!mi)cros|bada|palmos
|
37
47
|
|kindle|symbiano?s?|sailfish|meego|darwin|syllable|fxos
|
38
|
-
|(?<!en)risc|rim\stablet\sos|haiku|morphos|debian
|
48
|
+
|(?<!en)risc|rim\stablet\sos|haiku|morphos|debian
|
49
|
+
|inferno)}xi
|
39
50
|
|
40
51
|
platform_version %r{(?:windows(?:\sphone(?:\sos)?)?|nt|android|linux/?|fxos
|
41
52
|
|mac\sos\sx(?:\s\w+\s)?|(?:cpu\s|ip(?:[ao]d|hone)\s)os
|
@@ -46,7 +57,7 @@ Browserino.config.define do
|
|
46
57
|
device %r{(alcatel|all(?:tell|view)|htc|kindle|kf\w\w|apple\s?tv
|
47
58
|
|iphone|ipad|a\d+f;|archos|transformer|slider|me\d+x|zte
|
48
59
|
|blackberry|\d+dl|venue|desire|oneplus|lenovo|lumia|moto
|
49
|
-
|huawei\b|motorola|nokia|nexus|\b\w+tab\b|lg[-l]
|
50
|
-
|
60
|
+
|huawei\b|motorola|nokia|nexus|\b\w+tab\b|lg[-l]|oppo
|
61
|
+
|\b(?<!p)hp)}xi
|
51
62
|
end
|
52
63
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Browserino.config.define do
|
4
|
+
# when a property like :locale cannot be found and
|
5
|
+
# Browserino.parse is called with a headers hash in addition to the ua,
|
6
|
+
# prop_missing method allows you to define a fallback block which
|
7
|
+
# receives all gathered props so far and the headers as arguments.
|
8
|
+
# the return value of this block will then be used as value for that property.
|
9
|
+
|
10
|
+
# prop_missing calls are executed in order of definition,
|
11
|
+
# this allows you to leverage properties found in prior prop_missing calls
|
12
|
+
# as seen with :locales and :locale below
|
13
|
+
prop_missing :locales do |http_headers|
|
14
|
+
http_headers[:accept_language]
|
15
|
+
.to_s.scan(/(\w{2}(?:[_\-]\w{2})?)(?:;q=([\d.]+))?/i)
|
16
|
+
.map { |(locale, quality)| [locale, (quality || 1).to_f] }
|
17
|
+
.sort_by { |a| -a[1] }
|
18
|
+
.map(&:first)
|
19
|
+
end
|
20
|
+
|
21
|
+
prop_missing :locale do |_http_headers, props|
|
22
|
+
props[:locales].first
|
23
|
+
end
|
24
|
+
end
|
@@ -6,7 +6,10 @@ module Browserino
|
|
6
6
|
class ActionController
|
7
7
|
module Base
|
8
8
|
def client
|
9
|
-
@client ||= Browserino.parse
|
9
|
+
@client ||= Browserino.parse(
|
10
|
+
request.headers['User-Agent'],
|
11
|
+
request.headers.env.reject { |k| k.include? '.' }
|
12
|
+
)
|
10
13
|
end
|
11
14
|
end
|
12
15
|
end
|
data/lib/browserino/methods.rb
CHANGED
@@ -1,17 +1,58 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Browserino
|
4
|
-
def self.analyze(uas, matcher = nil)
|
4
|
+
def self.analyze(uas, matcher = nil, headers = nil)
|
5
5
|
@defaults ||= config.global_matchers.map(&:properties).reduce(&:merge)
|
6
6
|
|
7
7
|
props = @defaults.merge(matcher && matcher.properties || {})
|
8
8
|
like = props.delete :like
|
9
9
|
props = mass_collect props, uas
|
10
|
-
|
10
|
+
|
11
|
+
if headers.is_a? Hash
|
12
|
+
headers = normalize_header_keys headers
|
13
|
+
props = fill_missing_with_headers headers, props
|
14
|
+
end
|
15
|
+
|
16
|
+
props = fix_inconsistent_props props
|
17
|
+
|
18
|
+
like = Client.new props.merge(like_attrs(props, like, uas)) if like
|
11
19
|
|
12
20
|
Client.new props, like
|
13
21
|
end
|
14
22
|
|
23
|
+
def self.fix_inconsistent_props(hsh)
|
24
|
+
# patch locale and locales props
|
25
|
+
if hsh[:locales].any?
|
26
|
+
# when locale is not present in locales, append it
|
27
|
+
hsh[:locales] << hsh[:locale] unless hsh[:locales].include? hsh[:locale]
|
28
|
+
|
29
|
+
# ensure locales.first == locale when locale present in locales
|
30
|
+
hsh[:locale] = hsh[:locales].first
|
31
|
+
elsif hsh[:locale]
|
32
|
+
# no locales from header but locale is found in UA, append locale
|
33
|
+
# to locales to ensure expected output
|
34
|
+
hsh[:locales] << hsh[:locale]
|
35
|
+
end
|
36
|
+
|
37
|
+
hsh
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.normalize_header_keys(headers)
|
41
|
+
headers.each_with_object({}) do |(header, value), normalized|
|
42
|
+
header = header.gsub(/^HTTP_/i, '').tr('-', '_').downcase.to_sym
|
43
|
+
normalized[header] = value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.fill_missing_with_headers(headers, props)
|
48
|
+
config.missing_props.each_with_object props do |(prop, blk), res|
|
49
|
+
if props.key?(prop) && (!props[prop] ||
|
50
|
+
(props[prop].respond_to?(:empty?) && props[prop].empty?))
|
51
|
+
res[prop] = convert blk.call(headers, res), format: prop
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
15
56
|
def self.like_attrs(props, like, user_agent)
|
16
57
|
version = config.matchers.select { |m| m == like }
|
17
58
|
.first.properties[:version]
|
@@ -23,22 +64,25 @@ module Browserino
|
|
23
64
|
end
|
24
65
|
|
25
66
|
def self.config
|
26
|
-
@config ||= Config.new
|
67
|
+
@config ||= Config.new before_parse: [],
|
27
68
|
global_matchers: [],
|
28
|
-
properties:
|
29
|
-
types:
|
30
|
-
names:
|
31
|
-
smart_matchers:
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
69
|
+
properties: [],
|
70
|
+
types: [:unknown],
|
71
|
+
names: [],
|
72
|
+
smart_matchers: {},
|
73
|
+
missing_props: {},
|
74
|
+
matchers: [],
|
75
|
+
labels: Hash.new { |h, k| h[k] = [] },
|
76
|
+
filters: Hash.new { |h, k| h[k] = [] },
|
77
|
+
aliasses: Hash.new { |h, k| h[k] = [] }
|
36
78
|
end
|
37
79
|
|
38
80
|
def self.label_for(target_name, version = nil)
|
39
81
|
return unless config.labels.key?(target_name) && version
|
82
|
+
|
40
83
|
version = Version.new version unless version.is_a? Version
|
41
84
|
return unless version > 0
|
85
|
+
|
42
86
|
config.labels[target_name].each do |candidate|
|
43
87
|
return candidate[:name] if version.between? candidate[:range]
|
44
88
|
end
|
@@ -62,6 +106,7 @@ module Browserino
|
|
62
106
|
def self.smart_matchers(properties)
|
63
107
|
config.smart_matchers.each_with_object({}) do |(prop, detector), props|
|
64
108
|
next if properties.key? prop
|
109
|
+
|
65
110
|
props[prop] = parse_detector detector, properties
|
66
111
|
end
|
67
112
|
end
|
data/lib/browserino/options.rb
CHANGED
@@ -8,6 +8,7 @@ module Browserino
|
|
8
8
|
|
9
9
|
def method_missing(sym, *args)
|
10
10
|
return @options[opt(sym)] == args.first if args.any?
|
11
|
+
|
11
12
|
@options[opt(sym)]
|
12
13
|
end
|
13
14
|
|
@@ -47,7 +48,7 @@ module Browserino
|
|
47
48
|
end
|
48
49
|
|
49
50
|
def option?(sym)
|
50
|
-
@options.
|
51
|
+
@options.key? opt(sym)
|
51
52
|
end
|
52
53
|
end
|
53
54
|
end
|
data/lib/browserino/version.rb
CHANGED
data/lib/browserino.rb
CHANGED
@@ -13,13 +13,14 @@ require_relative 'browserino/definitions/matchers'
|
|
13
13
|
require_relative 'browserino/definitions/aliasses'
|
14
14
|
require_relative 'browserino/definitions/filters'
|
15
15
|
require_relative 'browserino/definitions/labels'
|
16
|
+
require_relative 'browserino/definitions/missing_props'
|
16
17
|
|
17
18
|
module Browserino
|
18
|
-
def self.parse(uas)
|
19
|
-
config.before_parse.
|
19
|
+
def self.parse(uas, headers = nil)
|
20
|
+
uas = config.before_parse.reduce(uas) { |u, b| b.call u }
|
20
21
|
config.matchers.each do |matcher|
|
21
|
-
return analyze uas, matcher if matcher.matches? uas
|
22
|
+
return analyze uas, matcher, headers if matcher.matches? uas
|
22
23
|
end
|
23
|
-
analyze uas
|
24
|
+
analyze uas, nil, headers
|
24
25
|
end
|
25
26
|
end
|
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: 4.
|
4
|
+
version: 4.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sidney Liebrand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -147,6 +147,7 @@ files:
|
|
147
147
|
- lib/browserino/definitions/matchers/mediaplayers.rb
|
148
148
|
- lib/browserino/definitions/matchers/rss.rb
|
149
149
|
- lib/browserino/definitions/matchers/validators.rb
|
150
|
+
- lib/browserino/definitions/missing_props.rb
|
150
151
|
- lib/browserino/integrate/action_controller.rb
|
151
152
|
- lib/browserino/integrate/rails.rb
|
152
153
|
- lib/browserino/matcher.rb
|
@@ -165,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
165
166
|
requirements:
|
166
167
|
- - ">="
|
167
168
|
- !ruby/object:Gem::Version
|
168
|
-
version: '0'
|
169
|
+
version: '2.0'
|
169
170
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
171
|
requirements:
|
171
172
|
- - ">="
|