browserino 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
- class Identity
4
+ class Matcher
4
5
  attr_reader :pattern, :properties
5
6
 
6
7
  SETTINGS = { name: nil, type: :unknown }.freeze
@@ -14,7 +15,11 @@ module Browserino
14
15
  end
15
16
 
16
17
  def matches?(user_agent)
17
- pattern =~ user_agent if pattern.is_a? Regexp
18
+ pattern =~ user_agent
19
+ end
20
+
21
+ def =~(other)
22
+ pattern =~ other
18
23
  end
19
24
 
20
25
  def ===(other)
@@ -24,7 +29,7 @@ module Browserino
24
29
  when Regexp then other =~ properties[:name]
25
30
  when String then other.to_sym == properties[:name]
26
31
  when Symbol then other == properties[:name]
27
- when Identity then other.properties[:name] == properties[:name]
32
+ when Matcher then other.properties[:name] == properties[:name]
28
33
  else false
29
34
  end
30
35
  end
@@ -33,17 +38,13 @@ module Browserino
33
38
  properties[:name].to_s
34
39
  end
35
40
 
36
- def =~(other)
37
- self === other
38
- end
39
-
40
41
  def ==(other)
41
42
  self === other
42
43
  end
43
44
 
44
45
  def method_missing(sym, *args, &block)
45
- return @properties[sym] = block if block
46
46
  return @properties[sym] = args.shift if args.any?
47
+ return @properties[sym] = block if block
47
48
 
48
49
  @properties[sym]
49
50
  end
@@ -1,35 +1,39 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
- def self.analyze(user_agent, identity = nil)
4
- props = [*config.global_identities, identity].compact.map(&:properties)
5
- .reduce(&:merge)
6
- like = props.delete :like if props.key? :like
7
- props = collect(props, user_agent)
8
- props = normalize props
9
- props = with_smart_matchers props
10
- left = props.select { |_, val| val.is_a? Regexp }
11
- props = props.merge normalize(collect(left, user_agent)) if left.any?
12
- props = with_labels props
13
-
14
- if like
15
- repl = user_agent =~ %r{#{like}}i && '' || like.to_s
16
- like = parse user_agent.gsub identity.pattern, repl
17
- end
4
+ def self.analyze(ua, matcher = nil)
5
+ @defaults ||= config.global_matchers.map(&:properties).reduce(&:merge)
6
+
7
+ props = @defaults.merge(matcher && matcher.properties || {})
8
+ like = props.delete :like
9
+ props = collect props, ua
10
+ props = collect_with_smart_watchers props, ua
11
+ props = with_labels props
12
+ like = Client.new props.merge(like_attrs(props, like, ua)) if like
18
13
 
19
14
  Client.new props, like
20
15
  end
21
16
 
17
+ def self.like_attrs(props, like, user_agent)
18
+ lattrs = config.matchers.select { |m| m == like }.first.properties
19
+ fattrs = { name: like }
20
+ fattrs[:version] = lattrs[:version] if lattrs[:version].is_a? Regexp
21
+ fattrs[:version] ||= smart_matchers(fattrs)[:version]
22
+
23
+ props.dup.merge collect(fattrs, user_agent)
24
+ end
25
+
22
26
  def self.config
23
- @config ||= Config.new({ before_parse: [],
24
- global_identities: [],
25
- properties: [],
26
- types: [:unknown],
27
- names: [],
28
- smart_matchers: {},
29
- identities: [],
30
- labels: Hash.new { |h, k| h[k] = [] },
31
- filters: Hash.new { |h, k| h[k] = [] },
32
- aliasses: Hash.new { |h, k| h[k] = [] } })
27
+ @config ||= Config.new(before_parse: [],
28
+ global_matchers: [],
29
+ properties: [],
30
+ types: [:unknown],
31
+ names: [],
32
+ smart_matchers: {},
33
+ matchers: [],
34
+ labels: Hash.new { |h, k| h[k] = [] },
35
+ filters: Hash.new { |h, k| h[k] = [] },
36
+ aliasses: Hash.new { |h, k| h[k] = [] })
33
37
  end
34
38
 
35
39
  def self.label_for(target_name, version = nil)
@@ -37,16 +41,13 @@ module Browserino
37
41
  version = Version.new version unless version.is_a? Version
38
42
  return unless version > 0
39
43
  config.labels[target_name].each do |candidate|
40
- min = Version.new candidate[:range].min
41
- max = Version.new candidate[:range].max
42
-
43
- return candidate[:name] if version >= min && version <= max
44
+ return candidate[:name] if version.between? candidate[:range]
44
45
  end
45
46
  nil
46
47
  end
47
48
 
48
49
  def self.with_labels(properties)
49
- [:name, :engine, :platform].each do |prop|
50
+ %i[name engine platform].each do |prop|
50
51
  lbl_prop = (prop == :name) && :label || "#{prop}_label".to_sym
51
52
  ver_prop = (prop == :name) && :version || "#{prop}_version".to_sym
52
53
  properties[lbl_prop] ||= label_for properties[prop], properties[ver_prop]
@@ -55,9 +56,14 @@ module Browserino
55
56
  properties
56
57
  end
57
58
 
58
- def self.with_smart_matchers(properties)
59
- config.smart_matchers.each_with_object properties do |(prop, detector), props|
60
- props[prop] ||= parse_detector detector, properties
59
+ def self.collect_with_smart_watchers(properties, user_agent)
60
+ properties.merge collect(smart_matchers(properties), user_agent)
61
+ end
62
+
63
+ def self.smart_matchers(properties)
64
+ config.smart_matchers.each_with_object({}) do |(prop, detector), props|
65
+ next if properties.key? prop
66
+ props[prop] = parse_detector detector, properties
61
67
  end
62
68
  end
63
69
 
@@ -71,23 +77,14 @@ module Browserino
71
77
  end
72
78
 
73
79
  def self.collect(properties, ua)
74
- properties.each_with_object({}) do |(prop, value), res|
75
- res[prop] = case value
76
- when Regexp then value.match(ua).to_a[1]
77
- else value
78
- end
79
- end
80
- end
81
-
82
- def self.normalize(properties)
83
- properties.each_with_object({}) do |(prop, value), store|
84
- store[prop] = convert value, format: prop
80
+ properties.each_with_object({}) do |(n, v), r|
81
+ r[n] = convert (v.is_a?(Regexp) ? v.match(ua).to_a[1] : v), format: n
85
82
  end
86
83
  end
87
84
 
88
85
  def self.convert(val, **opts)
89
86
  filters = config.filters[:global] + config.filters[opts[:format]]
90
- filters.compact.each do |fmt|
87
+ filters.each do |fmt|
91
88
  val = fmt.call val
92
89
  end
93
90
 
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
4
  class Options
4
5
  def initialize(options = {})
5
6
  @options = options
6
7
  end
7
8
 
8
- def method_missing(sym, *args, &block)
9
+ def method_missing(sym, *args, &___)
9
10
  return @options[opt(sym)] == args.first if args.any?
10
11
  @options[opt(sym)]
11
12
  end
12
13
 
13
- def respond_to_missing?(sym, *args, &block)
14
+ def respond_to_missing?(sym, *_, &___)
14
15
  option? sym
15
16
  end
16
17
 
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
- VERSION = '4.0.0'.freeze
4
+ VERSION = '4.1.0'.freeze
4
5
 
5
6
  def self.version
6
- @verion ||= Version.new VERSION.dup
7
+ @version ||= Version.new VERSION.dup
7
8
  end
8
9
 
9
10
  # This class makes versions easily comparable using logical operators
@@ -50,11 +51,19 @@ module Browserino
50
51
  compare :!=, other
51
52
  end
52
53
 
54
+ def between?(min, max = nil)
55
+ if min.is_a? Range
56
+ max = min.max
57
+ min = min.min
58
+ end
59
+
60
+ (self >= Version.new(min)) && (self <= Version.new(max))
61
+ end
62
+
53
63
  private
54
64
 
55
65
  def parse_params(val, *rest)
56
66
  case val
57
- when Float then val.to_s.split '.'
58
67
  when Integer then [val, *rest]
59
68
  when String then val.tr('_', '.').split '.'
60
69
  when Array then val
data/lib/browserino.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'browserino/integrate/rails' if defined?(::Rails)
3
4
 
4
5
  require_relative 'browserino/options'
@@ -6,7 +7,7 @@ require_relative 'browserino/config'
6
7
  require_relative 'browserino/methods'
7
8
  require_relative 'browserino/client'
8
9
  require_relative 'browserino/version'
9
- require_relative 'browserino/identity'
10
+ require_relative 'browserino/matcher'
10
11
 
11
12
  require_relative 'browserino/definitions/matchers'
12
13
  require_relative 'browserino/definitions/aliasses'
@@ -16,10 +17,9 @@ require_relative 'browserino/definitions/labels'
16
17
  module Browserino
17
18
  def self.parse(ua)
18
19
  config.before_parse.each { |b| ua = b.call ua } if config.before_parse.any?
19
- config.identities.each do |identity|
20
- return analyze ua, identity if identity.matches? ua
20
+ config.matchers.each do |matcher|
21
+ return analyze ua, matcher if matcher.matches? ua
21
22
  end
22
-
23
23
  analyze ua
24
24
  end
25
25
  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.0.0
4
+ version: 4.1.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: 2017-04-23 00:00:00.000000000 Z
11
+ date: 2017-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: coveralls
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -109,9 +123,9 @@ files:
109
123
  - lib/browserino/definitions/filters.rb
110
124
  - lib/browserino/definitions/labels.rb
111
125
  - lib/browserino/definitions/matchers.rb
112
- - lib/browserino/identity.rb
113
126
  - lib/browserino/integrate/action_controller.rb
114
127
  - lib/browserino/integrate/rails.rb
128
+ - lib/browserino/matcher.rb
115
129
  - lib/browserino/methods.rb
116
130
  - lib/browserino/options.rb
117
131
  - lib/browserino/version.rb