browserino 4.3.0 → 4.4.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/.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
|
- - ">="
|