browserino 2.5.3 → 2.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3625bb25aba01e627a8bd14d19971350f039c2f2
4
- data.tar.gz: 15d14f30031beec4d0ae944b38a37600c19d57e9
3
+ metadata.gz: e08c3808d746044e878ba7737b86d38b65e1c76a
4
+ data.tar.gz: 3eff20f91f4768ecd53ff13dc1678b0ee2bb7573
5
5
  SHA512:
6
- metadata.gz: 7bded8f6898e7a644bb021d78716cdf26becec40c6171887ef2ae55bd9da8898b65773636604f958cf3c559f57c9513b92ff19c59bbc2d302eba8b4cd6ea4df5
7
- data.tar.gz: 844f0b75b0ebbdaaeee98e6bff3aa9e09bd2634789d3fc266b942c28bf0435fcd23f29c1d684420942e576a1e3f06c3783f3568bbd0bd50335ce09ab77071f68
6
+ metadata.gz: 806f7ea91c5ada6d329bc371d2f3fcddc1876ceb1210479b2b875f86ddaab5961f16e1006599eabdd503a1ff3aee9e190d9c376c5f765dbae994bea8b23a1b85
7
+ data.tar.gz: a07a4116f54d82fd693535f9b0a876fe10d8ad4bbd31c1a0a537f0b3a50a15353340da04a9d74f9af9c13ec8401745d7db2385305b3e5253c505b77b7ad0ba3f
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'spec/*'
4
+ - 'Guardfile'
5
+ - '*.gemspec'
6
+ - 'Rakefile'
7
+
8
+ Documentation:
9
+ Enabled: false
data/.travis.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  language: ruby
2
2
  cache: bundler
3
3
  rvm:
4
+ - 2.3.0
4
5
  - 2.2.1
5
6
  - 2.1.0
6
7
  - 2.0.0
data/CHANGELOG.md CHANGED
@@ -1,6 +1,10 @@
1
1
  ## CHANGELOG
2
2
  _dates are in dd-mm-yyyy format_
3
3
 
4
+ #### 12-01-2016 VERSION 2.5.1
5
+
6
+ - Patched blackberry mapping, this used to be done by model number instead but is now corrected
7
+
4
8
  #### 12-01-2016 VERSION 2.5.0
5
9
 
6
10
  - Added support for the Vivaldi browser
data/README.md CHANGED
@@ -10,6 +10,11 @@ This gem aims to provide information about the browser that your visitor is usin
10
10
  _dates are in dd-mm-yyyy format_
11
11
  _older changes can be found in the [CHANGELOG.md](https://github.com/SidOfc/browserino/blob/master/CHANGELOG.md)_
12
12
 
13
+ #### 20-01-2016 VERSION 2.5.4
14
+
15
+ - formatted / refactored code with rubocop
16
+ - iOS `system_name full: true` returns the version no. of iOS if found
17
+
13
18
  #### 19-01-2016 VERSION 2.5.3
14
19
 
15
20
  - Minor refactoring of code
@@ -20,10 +25,6 @@ _older changes can be found in the [CHANGELOG.md](https://github.com/SidOfc/brow
20
25
  - Added support for windows phone detection
21
26
  - Added `windows_phone?` method
22
27
 
23
- #### 12-01-2016 VERSION 2.5.1
24
-
25
- - Patched blackberry mapping, this used to be done by model number instead but is now corrected
26
-
27
28
  ## Installation
28
29
 
29
30
  *supports ruby 1.9.3+*
@@ -180,7 +181,7 @@ agent.to_h
180
181
  ```
181
182
 
182
183
  It is now also possible to call methods to determine a specific OS or browser if it's supported, a `noMethodError` will be thrown otherwise
183
- The function uses the names of the `Browserino::Mapping` constants and the `Browserino::PATTERNS` hashes `:browser` and `:bot` output to identify wether or not to throw this exception.
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.
184
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.
185
186
  _(examples given for windows, android and ios, for a full list of versions check the **maps** folder)_
186
187
  Browsers can also accept a float / integer to check for a specific version.
data/bin/console CHANGED
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "browserino"
5
- require "pry"
6
- ua = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)'
3
+ require 'bundler/setup'
4
+ require 'browserino'
5
+ require 'pry'
6
+ ua = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/601.3.9 \
7
+ (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9'
7
8
  @agent = Browserino.parse(ua)
8
9
 
9
10
  puts "> @agent variable available parsed with: '#{ua}'\n\n"
@@ -1,33 +1,12 @@
1
1
  module Browserino
2
2
  class Agent
3
- def initialize(ua)
3
+ include Core::Helpers
4
+ attr_reader :ua
5
+
6
+ def initialize(info, ua = nil)
4
7
  @ua = ua
5
8
  @not = false
6
-
7
- cleansed_ua = Browserino.strip_lies(@ua)
8
- pat_name = Browser::name(cleansed_ua)
9
- name = pat_name.to_s.downcase.gsub(/_/, ' ')
10
- name = nil if name == ''
11
-
12
- info = {
13
- browser_name: name,
14
- browser_version: Browser::version(cleansed_ua, PATTERNS[:browser][pat_name]),
15
- engine_name: Engine::name(cleansed_ua),
16
- engine_version: Engine::version(cleansed_ua),
17
- system_name: OperatingSystem::name(cleansed_ua),
18
- system_version: OperatingSystem::version(cleansed_ua),
19
- system_architecture: OperatingSystem::architecture(cleansed_ua),
20
- locale: OperatingSystem::locale(cleansed_ua),
21
- bot_name: nil
22
- }
23
-
24
- if Browserino::PATTERNS[:bot].include? pat_name
25
- info.merge!(browser_name: nil,
26
- browser_version: nil,
27
- bot_name: name)
28
- end
29
-
30
- @info = Browserino.check_for_aliases(info)
9
+ @info = info
31
10
  end
32
11
 
33
12
  def browser_name
@@ -51,7 +30,6 @@ module Browserino
51
30
  end
52
31
 
53
32
  def system_name(opts = {})
54
- opts = {full: false}.merge(opts)
55
33
  if opts[:full]
56
34
  [@info[:system_name], fetch_system_version_name(@info[:system_name])]
57
35
  else
@@ -75,55 +53,51 @@ module Browserino
75
53
  @info[:bot_name]
76
54
  end
77
55
 
78
- def ua
79
- @ua
80
- end
81
-
82
56
  def compat?
83
- allow_inverted_return (ie? && browser_version != browser_version(compat: true))
57
+ invert_if_not ie? && browser_version != browser_version(compat: true)
84
58
  end
85
59
 
86
60
  def known?
87
- allow_inverted_return (!browser_name.nil? || !bot_name.nil?)
61
+ invert_if_not !browser_name.nil? || !bot_name.nil?
88
62
  end
89
63
 
90
64
  def mobile?
91
- allow_inverted_return !!(ua =~ Browserino::PATTERNS[:operating_system][:mobile])
65
+ invert_if_not !ua.match(Core::PATTERNS[:operating_system][:mobile]).nil?
92
66
  end
93
67
 
94
68
  def x64?
95
- allow_inverted_return system_architecture == 'x64'
69
+ invert_if_not system_architecture == 'x64'
96
70
  end
97
71
 
98
72
  def x32?
99
- allow_inverted_return system_architecture == 'x32'
73
+ invert_if_not system_architecture == 'x32'
100
74
  end
101
75
 
102
76
  def osx?(*arg)
103
- allow_inverted_return macintosh?(*arg)
77
+ invert_if_not macintosh?(*arg)
104
78
  end
105
79
 
106
80
  def win?(*arg)
107
- allow_inverted_return windows?(*arg)
81
+ invert_if_not windows?(*arg)
108
82
  end
109
83
 
110
84
  def bb?(*arg)
111
- allow_inverted_return blackberry?(*arg)
85
+ invert_if_not blackberry?(*arg)
112
86
  end
113
87
 
114
88
  def bot?(name = nil)
115
- is_bot = ((bot_name.nil? ? false : true) ? true : ua.strip.empty?)
116
- is_name = (name.nil? ? true : (name.to_s.downcase.gsub(/_/, ' ') == bot_name))
117
- allow_inverted_return (is_bot && is_name)
89
+ is_bot = ua.strip.empty? || !bot_name.nil?
90
+ is_name = name.nil? || name.to_s.downcase.tr('_', ' ') == bot_name
91
+ invert_if_not is_bot && is_name
118
92
  end
119
93
 
120
94
  def method_missing(method_sym, *args, &block)
121
- name = method_sym.to_s.gsub('?', '')
122
- allow_inverted_return case agent_or_system?(method_sym)
123
- when :system then correct_system?(name, *args)
124
- when :agent then correct_agent?(name, *args)
125
- else super
126
- end
95
+ name = method_sym.to_s.tr('?', '')
96
+ invert_if_not case agent_or_system?(method_sym)
97
+ when :system then correct_system?(name, *args)
98
+ when :agent then correct_agent?(name, *args)
99
+ else super
100
+ end
127
101
  end
128
102
 
129
103
  def respond_to?(method_sym)
@@ -137,105 +111,18 @@ module Browserino
137
111
 
138
112
  def to_s(sep = '')
139
113
  props = @info.map do |k, _|
140
- case k
141
- when :system_version
142
- system_name + sep + send(k).to_s.split('.').first.to_s
143
- when :engine_version
144
- engine_name + sep + send(k).to_s.split('.').first.to_s
145
- when :browser_version
146
- browser_name + sep + send(k).to_s.split('.').first.to_s
147
- else send(k)
148
- end
114
+ y = [:system_version, :engine_version, :browser_version].include?(k)
115
+ y ? send(k) + sep + send(k).to_s.split('.').first : send(k)
149
116
  end
150
- props.compact.map { |v| v.gsub(/\s/, '-') }.join(' ')
117
+ props.compact.map { |v| v.tr(' ', '-') }.join(' ')
151
118
  end
152
119
 
153
120
  def to_a
154
- @info.inject([]) do |memo, arr|
155
- memo.push [arr.first, send(arr.first)]
156
- memo
157
- end
121
+ @info.each_with_object([]) { |v, a| a.push(v) }
158
122
  end
159
123
 
160
124
  def to_h
161
- to_a.inject({}) do |memo, arr|
162
- memo[arr[0].to_sym] = arr[1]
163
- memo
164
- end
165
- end
166
-
167
- private
168
-
169
- def allow_inverted_return(res)
170
- if @not
171
- @not = false
172
- !res
173
- else
174
- res
175
- end
176
- end
177
-
178
- def compare_versions(a, b)
179
- b = b.to_s.split('.')
180
- !a.to_s.split('.').map { |v| v == b.shift }.include?(false)
181
- end
182
-
183
- def correct_system?(name, version = nil)
184
- sys_name = name.to_s.downcase.gsub(/\s/, '_')
185
- sys_name_compare = system_name(full: true).join.downcase.gsub(/\s/, '_')
186
- name_variations = [sys_name_compare, sys_name_compare.gsub(/^[\s_]+|[\d\.\s_]+$/, '')]
187
- if (name_variations.include?((sys_name + version.to_s).gsub(/\s/, '_').downcase) ||
188
- (sys_name == system_name.gsub(/\s/, '_') && compare_versions(version, system_version)) ||
189
- (!version && sys_name == system_name.gsub(/\s/, '_')))
190
- true
191
- else
192
- false
193
- end
194
- end
195
-
196
- def correct_agent?(name, version = nil)
197
- name = name.gsub(/_/, ' ')
198
- browser_equal = (name == browser_name || name == bot_name)
199
- if version
200
- browser_equal && compare_versions(version, browser_version)
201
- else
202
- browser_equal
203
- end
204
- end
205
-
206
- def agent_or_system?(method_sym)
207
- name = method_sym.to_s.gsub('?', '')
208
- sys = Browserino::Mapping.constants(true).include?(name.upcase.to_sym)
209
- agent = Browserino::PATTERNS[:browser].merge(Browserino::PATTERNS[:bot]).keys.include?(name.to_sym)
210
- if sys
211
- :system
212
- elsif agent
213
- :agent
214
- else
215
- nil
216
- end
217
- end
218
-
219
- def fetch_system_version_name(name)
220
- return Browserino::UNKNOWN if name.nil? || name == '' || !name
221
- const = name.dup.upcase.gsub(/\s/, '_')
222
- version = if system_version == Browserino::UNKNOWN
223
- nil
224
- elsif name.match(/mac|ios|blackberry/i)
225
- system_version.split('.').first(2).join.to_i
226
- elsif name.match(/win|android/i)
227
- system_version.gsub('.', '').to_i
228
- else
229
- system_version.to_i
230
- end
231
- if version && defined? const
232
- version_names = Browserino::Mapping.const_get(const).select do |_, versions|
233
- true if versions.include?(version)
234
- end
235
- version_names.keys.first || system_version.split('.').first(2).join('.')
236
- else
237
- Browserino::UNKNOWN
238
- end
125
+ to_a.each_with_object({}) { |v, h| h[v[0].to_sym] = v[1] }
239
126
  end
240
127
  end
241
128
  end
@@ -2,12 +2,12 @@ module Browserino
2
2
  module Browser
3
3
  def self.name(ua)
4
4
  name = nil
5
- patterns = PATTERNS[:browser].merge(PATTERNS[:bot])
5
+ patterns = Core::PATTERNS[:browser].merge(Core::PATTERNS[:bot])
6
6
  agents = patterns.keys
7
7
 
8
8
  until agents.empty? || !name.nil?
9
9
  tmp = agents.shift
10
- name = tmp if (ua.match(patterns[tmp][:name]))
10
+ name = tmp if ua.match(patterns[tmp][:name])
11
11
  end
12
12
 
13
13
  name
@@ -15,8 +15,8 @@ module Browserino
15
15
 
16
16
  def self.version(ua, patterns)
17
17
  if patterns
18
- Browserino::extract_match(ua.match(patterns[:version]), :version) do |v|
19
- v.gsub('_', '.')
18
+ Browserino.extract_match(ua.match(patterns[:version]), :version) do |v|
19
+ v.tr('_', '.')
20
20
  end
21
21
  else
22
22
  UNKNOWN
@@ -0,0 +1,17 @@
1
+ module Browserino
2
+ module Core
3
+ Core::ALIAS = {
4
+ browser_name: { 'ie' => /msie/ },
5
+ engine_name: { 'webkit' => /applewebkit/ },
6
+ system_name: {
7
+ 'linux' => /ubuntu|x11/,
8
+ 'windows_phone' => /windows\sphone/,
9
+ 'ios' => /ip(?:[ao]d|hone)/
10
+ },
11
+ system_architecture: {
12
+ 'x64' => /(?:x86_|amd|wow)?64/,
13
+ 'x32' => /(?:(?:x86_)?32|i[36]8[36])/
14
+ }
15
+ }.freeze
16
+ end
17
+ end
@@ -0,0 +1,83 @@
1
+ module Browserino
2
+ module Core
3
+ module Helpers
4
+ def invert_if_not(res)
5
+ if @not
6
+ @not = false
7
+ !res
8
+ else
9
+ res
10
+ end
11
+ end
12
+
13
+ def compare_versions(a, b)
14
+ b = b.to_s.split('.')
15
+ !a.to_s.split('.').map { |v| v == b.shift }.include?(false)
16
+ end
17
+
18
+ def compare_sys_name_variations_with(name, version = nil)
19
+ v = version.to_s.tr(' ', '_').downcase
20
+ n = system_name(full: true).join.downcase.tr(' ', '_')
21
+ [n, n.gsub(/[\d\.\s_]+$/, '')].include?((name + v))
22
+ end
23
+
24
+ def correct_system?(name, version = nil)
25
+ sys_name = name.to_s.tr(' ', '_').downcase
26
+ if compare_sys_name_variations_with(sys_name, version) ||
27
+ (sys_name == system_name.tr(' ', '_') &&
28
+ compare_versions(version, system_version)) ||
29
+ (!version && sys_name == system_name.tr(' ', '_'))
30
+ true
31
+ else
32
+ false
33
+ end
34
+ end
35
+
36
+ def correct_agent?(name, version = nil)
37
+ name = name.tr('_', ' ')
38
+ browser_equal = (name == browser_name || name == bot_name)
39
+ if version
40
+ browser_equal && compare_versions(version, browser_version)
41
+ else
42
+ browser_equal
43
+ end
44
+ end
45
+
46
+ def agent_or_system?(method_sym)
47
+ name = method_sym.to_s.tr('?', '')
48
+ supported = Core::PATTERNS[:browser].merge(Core::PATTERNS[:bot]).keys
49
+ if supported.include?(name.to_sym)
50
+ :agent
51
+ elsif Mapping.const?(name.upcase.to_sym)
52
+ :system
53
+ end
54
+ end
55
+
56
+ def fetch_system_version_name(name)
57
+ const = to_const_sym(name)
58
+ version = parse_system_version(const)
59
+ if version && Mapping.const?(const)
60
+ res = Mapping.const_get(const)
61
+ .select { |_, v| true if v.include?(version) }.keys.first
62
+ res || system_version.split('.').first(2).join('.').downcase
63
+ end
64
+ end
65
+
66
+ def parse_system_version(name)
67
+ if system_version
68
+ if name =~ /mac|blackberry/i
69
+ system_version.split('.').first(2).join.to_i
70
+ elsif name =~ /win|android/i
71
+ system_version.tr('.', '').to_i
72
+ else
73
+ system_version.to_i
74
+ end
75
+ end
76
+ end
77
+
78
+ def to_const_sym(s)
79
+ s.to_s.tr(' ', '_').upcase.to_sym
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,13 @@
1
+ module Browserino
2
+ module Core
3
+ Core::LIES = [
4
+ [%r{(Mozilla/[\d\.]+)}i, true],
5
+ [/9\.80/, /opera/i],
6
+ [%r{(?:apple)?webkit/[\d\.]+}i, /presto/i],
7
+ [/(?:ms)?ie/i, /rv:/i],
8
+ [/linux/i, /android/i],
9
+ [/x11/i, /bsd/i],
10
+ [/windows\snt/i, /windows\sphone/i]
11
+ ].freeze
12
+ end
13
+ end
@@ -0,0 +1,104 @@
1
+ module Browserino
2
+ module Core
3
+ Core::PATTERNS = {
4
+ browser: {
5
+ vivaldi: {
6
+ name: /(?<name>vivaldi)/i,
7
+ version: %r{vivaldi/(?<version>[\d\.]+)}i
8
+ },
9
+
10
+ ucbrowser: {
11
+ name: /(?<name>ucbrowser)/i,
12
+ version: %r{ucbrowser/?(?<version>[\d\.]+)}i
13
+ },
14
+
15
+ bolt: {
16
+ name: /(?<name>bolt)/i,
17
+ version: %r{bolt/(?<version>[\d\.]+)}i
18
+ },
19
+
20
+ opera_mini: {
21
+ name: /(?<name>ope?ra?\smini)/i,
22
+ version: %r{(?:ope?ra?\smini)/(?<version>[\d\.]+)}i
23
+ },
24
+
25
+ opera: {
26
+ name: /(?<name>ope?ra?)/i,
27
+ version: %r{(?:ope?ra?|version)[/\s](?<version>[\d\.]+)}i
28
+ },
29
+
30
+ maxthon: {
31
+ name: /(?<name>maxthon)/i,
32
+ version: %r{maxthon[\s/](?<version>[\d\.]+)}i
33
+ },
34
+
35
+ edge: {
36
+ name: /(?<name>edge)/i,
37
+ version: %r{edge/(?<version>[\d\.]+)}i
38
+ },
39
+
40
+ ie: {
41
+ name: /(?<name>msie|trident)/i,
42
+ version: /(?:(?:ms)?ie\s|rv:)(?<version>[\d\.]+)/i
43
+ },
44
+
45
+ seamonkey: {
46
+ name: /(?<name>seamonkey)/i,
47
+ version: %r{seamonkey/(?<version>[\d\.]+)}i
48
+ },
49
+
50
+ firefox: {
51
+ name: /(?<name>(?:fire|water)(?:fox|bird)
52
+ |ice(?:weasel|cat)|netscape)/xi,
53
+ version: %r{(?:(?:fire|water)(?:fox|bird)|ice(?:weasel|cat)
54
+ |netscape)/?(?<version>[\d\.]+)}xi
55
+ },
56
+
57
+ chrome: {
58
+ name: /(?<name>chrome?(ium|plus)?)/i,
59
+ version: %r{chrome?(?:ium|plus)?/(?<version>[\d\.]+)}i
60
+ },
61
+
62
+ safari: {
63
+ name: /(?<name>safari)/i,
64
+ version: %r{(?:version|safari)/(?<version>[\d\.]+)}i
65
+ }
66
+ },
67
+
68
+ bot: {
69
+ googlebot: { name: /(?<name>googlebot)/i },
70
+ yahoo_slurp: { name: /(?<name>yahoo\!\sslurp)/i },
71
+ msnbot: { name: /(?<name>msnbot)/i },
72
+ bingbot: { name: /(?<name>bingbot)/i },
73
+ baiduspider: { name: /(?<name>baiduspider)/i },
74
+ yandexbot: { name: /(?<name>yandexbot)/i },
75
+ sosospider: { name: /(?<name>sosospider)/i },
76
+ exabot: { name: /(?<name>exabot)/i },
77
+ sogou_spider: { name: /(?<name>sogou\s?spider)/i },
78
+ nutch: { name: /(?<name>nutch)/i },
79
+ scrapy: { name: /(?<name>scrapy)/i },
80
+ dataparksearch: { name: /(?<name>dataparksearch)/i },
81
+ beslistbot: { name: /(?<name>beslistbot)/i }
82
+ },
83
+
84
+ engine: {
85
+ name: /(?<name>((apple)?webkit|presto|gecko|trident))/i,
86
+ version: %r{(?:(?:apple)?webkit|presto|rv:|trident)
87
+ [/\s]?(?<version>[\d\.]+)}xi
88
+ },
89
+
90
+ operating_system: {
91
+ name: /(?<name>windows(?:\sphone(?:\sos)?)?|macintosh|android
92
+ |ip(?:[ao]d|hone)|blackberry|linux|ubuntu|x11|bsd)/xi,
93
+ version: %r{(?:windows(?:\sphone(?:\sos)?)?|nt|mac\sos\sx|android
94
+ |(cpu\s|ip([ao]d|hone)\s)os|blackberry.*?version/|bb)
95
+ \s?(?<version>[\d\._]+)}xi,
96
+ architecture: /(?<architecture>((?:x|x86_|amd|wow)64)|i(3|6)86)/i,
97
+ mobile: /bolt|nokia|samsung|mobi(?:le)?|android|i?p(?:[ao]d|hone)|bb\d+
98
+ |blackberry|iemobile|fennec|bada|meego|vodafone
99
+ |t\-mobile|opera\sm(?:ob|in)i/xi,
100
+ locale: /\s(?<locale>\w{2}(?:\-\w{2})?)[;\)]/
101
+ }
102
+ }.freeze
103
+ end
104
+ end
@@ -1,12 +1,15 @@
1
1
  module Browserino
2
2
  module Engine
3
3
  def self.name(ua)
4
- Browserino::extract_match(ua.match(PATTERNS[:engine][:name]), :name)
4
+ Browserino.extract_match(ua.match(Core::PATTERNS[:engine][:name]), :name)
5
5
  end
6
6
 
7
7
  def self.version(ua)
8
- Browserino::extract_match(ua.match(PATTERNS[:engine][:version]), :version) do |v|
9
- v.gsub('_', '.')
8
+ Browserino.extract_match(
9
+ ua.match(Core::PATTERNS[:engine][:version]),
10
+ :version
11
+ ) do |v|
12
+ v.tr('_', '.')
10
13
  end
11
14
  end
12
15
  end
@@ -24,7 +24,8 @@ module Browserino
24
24
  'Jelly Bean 18' => [43, 431],
25
25
  'KitKat 19' => [44, 441, 442, 443, 444],
26
26
  'Lollipop 21' => [50, 501, 502],
27
- 'Lollipop 22' => [51, 511]
28
- }
27
+ 'Lollipop 22' => [51, 511],
28
+ 'Marshmallow 23' => [60, 601]
29
+ }.freeze
29
30
  end
30
31
  end
@@ -1,5 +1,5 @@
1
1
  module Browserino
2
2
  module Mapping
3
- BLACKBERRY = {}
3
+ BLACKBERRY = {}.freeze
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Browserino
2
2
  module Mapping
3
- BSD = {}
3
+ BSD = {}.freeze
4
4
  end
5
5
  end
@@ -1,11 +1,5 @@
1
- # Taken from http://www.thinkybits.com/blog/iOS-versions/
2
- # 15 - 09 - 2015
3
-
4
1
  module Browserino
5
2
  module Mapping
6
- IOS = {
7
- 'iPhone OS' => [20, 21, 22, 30, 31],
8
- 'iOS' => [40, 41, 42, 43, 50, 51, 60, 61, 70, 71, 80, 81, 82, 83, 84, 90, 91]
9
- }
3
+ IOS = {}.freeze
10
4
  end
11
5
  end
@@ -1,5 +1,5 @@
1
1
  module Browserino
2
2
  module Mapping
3
- LINUX = {}
3
+ LINUX = {}.freeze
4
4
  end
5
5
  end
@@ -16,6 +16,6 @@ module Browserino
16
16
  'Mavericks' => [109],
17
17
  'Yosemite' => [1010],
18
18
  'El Capitan' => [1011]
19
- }
19
+ }.freeze
20
20
  end
21
21
  end
@@ -0,0 +1,9 @@
1
+ module Browserino
2
+ module Mapping
3
+ module_function
4
+
5
+ def const?(const)
6
+ constants(true).include?(const)
7
+ end
8
+ end
9
+ end
@@ -13,6 +13,6 @@ module Browserino
13
13
  '8' => [62],
14
14
  '8.1' => [63],
15
15
  '10' => [100]
16
- }
16
+ }.freeze
17
17
  end
18
18
  end
@@ -1,5 +1,5 @@
1
1
  module Browserino
2
2
  module Mapping
3
- WINDOWS_PHONE = {}
3
+ WINDOWS_PHONE = {}.freeze
4
4
  end
5
5
  end
@@ -1,21 +1,33 @@
1
1
  module Browserino
2
2
  module OperatingSystem
3
3
  def self.name(ua)
4
- Browserino::extract_match(ua.match(PATTERNS[:operating_system][:name]), :name)
4
+ Browserino.extract_match(
5
+ ua.match(Core::PATTERNS[:operating_system][:name]),
6
+ :name
7
+ )
5
8
  end
6
9
 
7
10
  def self.version(ua)
8
- Browserino::extract_match(ua.match(PATTERNS[:operating_system][:version]), :version) do |v|
9
- v.gsub('_', '.')
11
+ Browserino.extract_match(
12
+ ua.match(Core::PATTERNS[:operating_system][:version]),
13
+ :version
14
+ ) do |v|
15
+ v.tr('_', '.')
10
16
  end
11
17
  end
12
18
 
13
19
  def self.architecture(ua)
14
- Browserino::extract_match(ua.match(PATTERNS[:operating_system][:architecture]), :architecture)
20
+ Browserino.extract_match(
21
+ ua.match(Core::PATTERNS[:operating_system][:architecture]),
22
+ :architecture
23
+ )
15
24
  end
16
25
 
17
26
  def self.locale(ua)
18
- Browserino::extract_match(ua.match(PATTERNS[:operating_system][:locale]), :locale)
27
+ Browserino.extract_match(
28
+ ua.match(Core::PATTERNS[:operating_system][:locale]),
29
+ :locale
30
+ )
19
31
  end
20
32
  end
21
33
  end
@@ -1,3 +1,3 @@
1
1
  module Browserino
2
- UNKNOWN = nil
2
+ UNKNOWN = nil
3
3
  end
@@ -1,3 +1,3 @@
1
1
  module Browserino
2
- VERSION = "2.5.3"
2
+ VERSION = '2.5.4'.freeze
3
3
  end
data/lib/browserino.rb CHANGED
@@ -1,62 +1,85 @@
1
- require "browserino/maps/macintosh"
2
- require "browserino/maps/blackberry"
3
- require "browserino/maps/ios"
4
- require "browserino/maps/bsd"
5
- require "browserino/maps/linux"
6
- require "browserino/maps/android"
7
- require "browserino/maps/windows"
8
- require "browserino/maps/windows_phone"
1
+ require 'browserino/core/helpers'
2
+ require 'browserino/core/lies'
3
+ require 'browserino/core/alias'
4
+ require 'browserino/core/patterns'
9
5
 
10
- require "browserino/integrate/rails" if defined?(::Rails)
6
+ require 'browserino/maps/mapping'
7
+ require 'browserino/maps/macintosh'
8
+ require 'browserino/maps/blackberry'
9
+ require 'browserino/maps/ios'
10
+ require 'browserino/maps/bsd'
11
+ require 'browserino/maps/linux'
12
+ require 'browserino/maps/android'
13
+ require 'browserino/maps/windows'
14
+ require 'browserino/maps/windows_phone'
11
15
 
12
- require "browserino/unknown"
13
- require "browserino/agent"
16
+ require 'browserino/integrate/rails' if defined?(::Rails)
14
17
 
15
- require "browserino/alias"
16
- require "browserino/version"
17
- require "browserino/patterns"
18
- require "browserino/browser"
19
- require "browserino/engine"
20
- require "browserino/operating_system"
18
+ require 'browserino/unknown'
19
+ require 'browserino/agent'
20
+
21
+ require 'browserino/version'
22
+ require 'browserino/browser'
23
+ require 'browserino/engine'
24
+ require 'browserino/operating_system'
21
25
 
22
26
  # require_relative "../spec/user_agents"
23
27
  # require_relative "../spec/user_agents_bots"
24
28
  # require_relative "../spec/user_agents_browsers"
25
29
 
26
30
  module Browserino
27
- def self.parse(ua, _ = nil) # _ = nil maintains backwards compatibility
28
- Agent.new ua
31
+ module_function
32
+
33
+ def parse(ua, _ = nil) # _ = nil maintains backwards compatibility
34
+ name = Browser.name(ua)
35
+ info = fetch_info(strip_lies(ua), name)
36
+ tmp = info[:browser_name].to_s.tr('_', ' ')
37
+ info[:browser_name] = tmp.strip == '' ? nil : tmp
38
+ info = check_if_bot(name, info)
39
+
40
+ Agent.new check_for_aliases(info), ua
41
+ end
42
+
43
+ def fetch_info(ua, name)
44
+ { browser_name: name,
45
+ browser_version: Browser.version(ua, Core::PATTERNS[:browser][name]),
46
+ engine_name: Engine.name(ua),
47
+ engine_version: Engine.version(ua),
48
+ system_name: OperatingSystem.name(ua),
49
+ system_version: OperatingSystem.version(ua),
50
+ system_architecture: OperatingSystem.architecture(ua),
51
+ locale: OperatingSystem.locale(ua),
52
+ bot_name: nil }
29
53
  end
30
54
 
31
- private
55
+ def check_if_bot(name, info)
56
+ if Core::PATTERNS[:bot].include?(name)
57
+ info[:bot_name] = info[:browser_name]
58
+ info[:browser_name] = nil
59
+ info[:browser_version] = nil
60
+ end
61
+ info
62
+ end
32
63
 
33
- def self.strip_lies(ua)
34
- ua = ua.gsub(/(Mozilla\/[\d\.]+)/i, '')
35
- ua = ua.gsub(/9\.80/, '') if /opera/i =~ ua
36
- ua = ua.gsub(/(?:apple)?webkit\/[\d\.]+/i, '') if /presto/i =~ ua
37
- ua = ua.gsub(/(?:ms)?ie/i, '') if /rv\:/i =~ ua
38
- ua = ua.gsub(/linux/i, '') if /android/i =~ ua
39
- ua = ua.gsub(/x11/i, '') if /bsd/i =~ ua
40
- ua = ua.gsub(/windows\snt/i, '') if /windows\sphone/i =~ ua
41
- ua
64
+ def strip_lies(ua)
65
+ Core::LIES.inject(ua) do |s, arr|
66
+ s = s.gsub(arr[0], '') if arr[1] == true || s =~ arr[1]
67
+ s
68
+ end
42
69
  end
43
70
 
44
- def self.check_for_aliases(h)
45
- ALIAS.each do |k, v|
71
+ def check_for_aliases(h)
72
+ Core::ALIAS.each do |k, v|
46
73
  h[k] = v.select { |n, re| n if h[k] =~ re }.keys.first || h[k]
47
74
  end
48
75
  h
49
76
  end
50
77
 
51
- def self.extract_match(match, sym)
78
+ def extract_match(match, sym)
52
79
  if match && match.names.include?(sym.to_s)
53
80
  m = match[sym].to_s.downcase.strip
54
81
  m = yield(m) if block_given?
55
- if m && m.strip != ''
56
- m
57
- else
58
- UNKNOWN
59
- end
82
+ m
60
83
  else
61
84
  UNKNOWN
62
85
  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: 2.5.3
4
+ version: 2.5.4
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-19 00:00:00.000000000 Z
11
+ date: 2016-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -118,6 +118,7 @@ files:
118
118
  - ".coveralls.yml"
119
119
  - ".gitignore"
120
120
  - ".rspec"
121
+ - ".rubocop.yml"
121
122
  - ".travis.yml"
122
123
  - CHANGELOG.md
123
124
  - CODE_OF_CONDUCT.md
@@ -131,8 +132,11 @@ files:
131
132
  - browserino.gemspec
132
133
  - lib/browserino.rb
133
134
  - lib/browserino/agent.rb
134
- - lib/browserino/alias.rb
135
135
  - lib/browserino/browser.rb
136
+ - lib/browserino/core/alias.rb
137
+ - lib/browserino/core/helpers.rb
138
+ - lib/browserino/core/lies.rb
139
+ - lib/browserino/core/patterns.rb
136
140
  - lib/browserino/engine.rb
137
141
  - lib/browserino/integrate/action_controller.rb
138
142
  - lib/browserino/integrate/rails.rb
@@ -142,10 +146,10 @@ files:
142
146
  - lib/browserino/maps/ios.rb
143
147
  - lib/browserino/maps/linux.rb
144
148
  - lib/browserino/maps/macintosh.rb
149
+ - lib/browserino/maps/mapping.rb
145
150
  - lib/browserino/maps/windows.rb
146
151
  - lib/browserino/maps/windows_phone.rb
147
152
  - lib/browserino/operating_system.rb
148
- - lib/browserino/patterns.rb
149
153
  - lib/browserino/unknown.rb
150
154
  - lib/browserino/version.rb
151
155
  homepage: https://github.com/SidOfc/browserino
@@ -1,15 +0,0 @@
1
- module Browserino
2
- ALIAS = {
3
- browser_name: { 'ie' => /msie/ },
4
- engine_name: { 'webkit' => /applewebkit/ },
5
- system_name: {
6
- 'linux' => /ubuntu|x11/,
7
- 'windows_phone' => /windows\sphone/,
8
- 'ios' => /ip(?:[ao]d|hone)/
9
- },
10
- system_architecture: {
11
- 'x64' => /(?:x86_|amd|wow)?64/,
12
- 'x32' => /(?:(?:x86_)?32|i[36]8[36])/
13
- }
14
- }
15
- end
@@ -1,94 +0,0 @@
1
- module Browserino
2
- PATTERNS = {
3
- browser: {
4
- vivaldi: {
5
- name: /(?<name>vivaldi)/i,
6
- version: /vivaldi\/(?<version>[\d\.]+)/i
7
- },
8
-
9
- ucbrowser: {
10
- name: /(?<name>ucbrowser)/i,
11
- version: /ucbrowser\/?(?<version>[\d\.]+)/i
12
- },
13
-
14
- bolt: {
15
- name: /(?<name>bolt)/i,
16
- version: /bolt\/(?<version>[\d\.]+)/i
17
- },
18
-
19
- opera_mini: {
20
- name: /(?<name>ope?ra?\smini)/i,
21
- version: /(?:ope?ra?\smini)\/(?<version>[\d\.]+)/i
22
- },
23
-
24
- opera: {
25
- name: /(?<name>ope?ra?)/i,
26
- version: /(?:ope?ra?|version)(\/|\s)(?<version>[\d\.]+)/i
27
- },
28
-
29
- maxthon: {
30
- name: /(?<name>maxthon)/i,
31
- version: /maxthon(?:\s|\/)(?<version>[\d\.]+)/i
32
- },
33
-
34
- edge: {
35
- name: /(?<name>edge)/i,
36
- version: /(?:edge\/)(?<version>[\d\.]+)/i
37
- },
38
-
39
- ie: {
40
- name: /(?<name>msie|trident)/i,
41
- version: /(?:(?:ms)?ie\s|rv\:)(?<version>[\d\.]+)/i
42
- },
43
-
44
- seamonkey: {
45
- name: /(?<name>seamonkey)/i,
46
- version: /seamonkey\/(?<version>[\d\.]+)/i
47
- },
48
-
49
- firefox: {
50
- name: /(?<name>(?:fire|water)(?:fox|bird)|ice(?:weasel|cat)|netscape)/i,
51
- version: /(?:(?:fire|water)(?:fox|bird)|ice(?:weasel|cat)|netscape)[\/]?(?<version>[\d\.]+)/i
52
- },
53
-
54
- chrome: {
55
- name: /(?<name>chrome?(ium|plus)?)/i,
56
- version: /chrome?(?:ium|plus)?\/(?<version>[\d\.]+)/i
57
- },
58
-
59
- safari: {
60
- name: /(?<name>safari)/i,
61
- version: /(?:version|safari)\/(?<version>[\d\.]+)/i
62
- }
63
- },
64
-
65
- bot: {
66
- googlebot: { name: /(?<name>googlebot)/i },
67
- yahoo_slurp: { name: /(?<name>yahoo\!\sslurp)/i },
68
- msnbot: { name: /(?<name>msnbot)/i },
69
- bingbot: { name: /(?<name>bingbot)/i },
70
- baiduspider: { name: /(?<name>baiduspider)/i },
71
- yandexbot: { name: /(?<name>yandexbot)/i },
72
- sosospider: { name: /(?<name>sosospider)/i },
73
- exabot: { name: /(?<name>exabot)/i },
74
- sogou_spider: { name: /(?<name>sogou\s?spider)/i },
75
- nutch: { name: /(?<name>nutch)/i },
76
- scrapy: { name: /(?<name>scrapy)/i },
77
- dataparksearch: { name: /(?<name>dataparksearch)/i },
78
- beslistbot: { name: /(?<name>beslistbot)/i }
79
- },
80
-
81
- engine: {
82
- name: /(?<name>((apple)?webkit|presto|gecko|trident))/i,
83
- version: /(?:(?:apple)?webkit|presto|rv:|trident)[\/\s]?(?<version>[\d\.]+)/i
84
- },
85
-
86
- operating_system: {
87
- name: /(?<name>windows(?:\sphone(?:\sos)?)?|macintosh|android|ip(?:[ao]d|hone)|blackberry|linux|ubuntu|x11|bsd)/i,
88
- version: /(?:windows(?:\sphone(?:\sos)?)?|nt|mac\sos\sx|android|(cpu\s|i)os|blackberry.*?version\/|bb)\s?(?<version>[\d\._]+)/i,
89
- architecture: /(?<architecture>((?:x|x86_|amd|wow)64)|i(3|6)86)/i,
90
- mobile: /bolt|nokia|samsung|mobi(?:le)?|android|i?p(?:[ao]d|hone)|bb\d+|blackberry|iemobile|fennec|bada|meego|vodafone|t\-mobile|opera\sm(?:ob|in)i/i,
91
- locale: /\s(?<locale>\w{2}(?:\-\w{2})?)[;\)]/
92
- }
93
- }
94
- end