woothee 0.4.2 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9cd84ea6750dd3090ec24f2675afce80bf01c79d
4
- data.tar.gz: 160d90a091231343e606087baba391704997fce2
3
+ metadata.gz: 8d02d577c470c8ee9b7204b5f7bdc48dd3af1dae
4
+ data.tar.gz: 7fd13c2c702219ee6f8ce5b059b64da041fcb55c
5
5
  SHA512:
6
- metadata.gz: 0de822e9c1f39fd382b9cace5747eec947d165fdc1009e82dcfbc477b211e5ca1b304a32a8fc46bd2266a5535835e6619d986607964faef201a2cde46aef97d5
7
- data.tar.gz: 47e5968cc10abca1a296c1be9c2d038e516ee872a7d5fe74d44eb251c7abdcee773b90616ea2ef9967e0b6cbc9824fdeda754aefcb314973907f36f89f040283
6
+ metadata.gz: 4622d9e21b6105f977d4bba8f508b851fa8a52963ec4bb0c9186cd72b43c6fcf1582a3a1fc9bca03f75c6f5777c6059ef6b1ba670e892b8b7878d4f9a443e691
7
+ data.tar.gz: 8c4d48ea2764cacfcdb311e623e574e6d7bc77f5a11527ddfaf7333bd537d961508bc559bd38eae66b1010d6825d174c713f9faefc1aa8d3414e11b46839e638
data/README.md CHANGED
@@ -27,7 +27,7 @@ Class 'Woothee' have no instance methods.
27
27
  ```ruby
28
28
  require 'woothee'
29
29
  Woothee.parse("Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0)")
30
- # => {:name=>"Internet Explorer", :category=>:pc, :os=>"Windows 7", :version=>"8.0", :vendor=>"Microsoft"}
30
+ # => {:name=>"Internet Explorer", :category=>:pc, :os=>"Windows 7", :version=>"8.0", :vendor=>"Microsoft", :os_version=>"NT 6.1"}
31
31
  ```
32
32
 
33
33
  Parse user-agent string and returns Hash instance with keys `:name`, `:category`, `:os`, `:version` and `:vendor`.
@@ -45,6 +45,8 @@ For unknown user-agent (or partially failed to parse), result Hash instance may
45
45
  * This field used to indicate cellar phone carrier for category 'mobilephone'
46
46
  * `:vendor`
47
47
  * optional field, shows browser vendor
48
+ * `:os_version`
49
+ * optional field, shows version of operating systems
48
50
 
49
51
  ### Finding crawlers (almost all, not all) in fast
50
52
 
data/lib/woothee.rb CHANGED
@@ -152,6 +152,7 @@ module Woothee
152
152
  Woothee::ATTRIBUTE_NAME => Woothee::VALUE_UNKNOWN,
153
153
  Woothee::ATTRIBUTE_CATEGORY => Woothee::VALUE_UNKNOWN,
154
154
  Woothee::ATTRIBUTE_OS => Woothee::VALUE_UNKNOWN,
155
+ Woothee::ATTRIBUTE_OS_VERSION => Woothee::VALUE_UNKNOWN,
155
156
  Woothee::ATTRIBUTE_VERSION => Woothee::VALUE_UNKNOWN,
156
157
  Woothee::ATTRIBUTE_VENDOR => Woothee::VALUE_UNKNOWN,
157
158
  }.freeze
@@ -7,16 +7,36 @@ module Woothee::Appliance
7
7
  extend Woothee::Util
8
8
 
9
9
  def self.challenge_playstation(ua, result)
10
- data = case
11
- when ua.index('PSP (PlayStation Portable);') then Woothee::DataSet.get('PSP')
12
- when ua.index('PlayStation Vita') then Woothee::DataSet.get('PSVita')
13
- when ua.index('PLAYSTATION 3 ') || ua.index('PLAYSTATION 3;') then Woothee::DataSet.get('PS3')
14
- when ua.index('PlayStation 4 ') then Woothee::DataSet.get('PS4')
15
- else nil
16
- end
10
+ data = nil
11
+ os_version = nil
12
+ case
13
+ when ua.index('PSP (PlayStation Portable);')
14
+ data = Woothee::DataSet.get('PSP')
15
+ if ua =~ /PSP \(PlayStation Portable\); ([.0-9]+)\)/
16
+ os_version = $1
17
+ end
18
+ when ua.index('PlayStation Vita')
19
+ data = Woothee::DataSet.get('PSVita')
20
+ if ua =~ /PlayStation Vita ([.0-9]+)\)/
21
+ os_version = $1
22
+ end
23
+ when ua.index('PLAYSTATION 3 ') || ua.index('PLAYSTATION 3;')
24
+ data = Woothee::DataSet.get('PS3')
25
+ if ua =~ /PLAYSTATION 3;? ([.0-9]+)\)/
26
+ os_version = $1
27
+ end
28
+ when ua.index('PlayStation 4 ')
29
+ data = Woothee::DataSet.get('PS4')
30
+ if ua =~ /PlayStation 4 ([.0-9]+)\)/
31
+ os_version = $1
32
+ end
33
+ end
17
34
  return false unless data
18
35
 
19
36
  update_map(result, data)
37
+ if os_version
38
+ update_os_version(result, os_version)
39
+ end
20
40
  true
21
41
  end
22
42
 
@@ -7,12 +7,14 @@ module Woothee::Browser
7
7
  extend Woothee::Util
8
8
 
9
9
  def self.challenge_msie(ua, result)
10
- return false if ua.index("compatible; MSIE").nil? && ua.index("Trident/").nil?
10
+ return false if ua.index("compatible; MSIE").nil? && ua.index("Trident/").nil? && ua.index("IEMobile").nil?
11
11
 
12
12
  version = if ua =~ /MSIE ([.0-9]+);/o
13
13
  $1
14
14
  elsif ua =~ /Trident\/([.0-9]+);(?: BOIE[0-9]+;[A-Z]+;)? rv:([.0-9]+)/o
15
15
  $2
16
+ elsif ua =~ /IEMobile\/([.0-9]+);/o
17
+ $1
16
18
  else
17
19
  Woothee::VALUE_UNKNOWN
18
20
  end
@@ -5,6 +5,7 @@ module Woothee
5
5
  KEY_TYPE = :type
6
6
  KEY_CATEGORY = :category
7
7
  KEY_OS = :os
8
+ KEY_OS_VERSION = :os_version
8
9
  KEY_VENDOR = :vendor
9
10
  KEY_VERSION = :version
10
11
 
@@ -22,18 +23,19 @@ module Woothee
22
23
  ATTRIBUTE_NAME = :name
23
24
  ATTRIBUTE_CATEGORY = :category
24
25
  ATTRIBUTE_OS = :os
26
+ ATTRIBUTE_OS_VERSION = :os_version
25
27
  ATTRIBUTE_VENDOR = :vendor
26
28
  ATTRIBUTE_VERSION = :version
27
29
 
28
30
  VALUE_UNKNOWN = "UNKNOWN"
29
31
 
30
32
  CATEGORY_LIST = [CATEGORY_PC,CATEGORY_SMARTPHONE,CATEGORY_MOBILEPHONE,CATEGORY_CRAWLER,CATEGORY_APPLIANCE,CATEGORY_MISC,VALUE_UNKNOWN]
31
- ATTRIBUTE_LIST = [ATTRIBUTE_NAME,ATTRIBUTE_CATEGORY,ATTRIBUTE_OS,ATTRIBUTE_VENDOR,ATTRIBUTE_VERSION]
33
+ ATTRIBUTE_LIST = [ATTRIBUTE_NAME,ATTRIBUTE_CATEGORY,ATTRIBUTE_OS,ATTRIBUTE_VENDOR,ATTRIBUTE_VERSION,ATTRIBUTE_OS_VERSION]
32
34
  end
33
35
 
34
36
  module Woothee::DataSet
35
37
  DATASET = {}
36
- # GENERATED from dataset.yaml at Sat Jul 5 01:54:48 JST 2014 by h_nakamura
38
+ # GENERATED from dataset.yaml at Wed Oct 22 20:17:46 JST 2014 by tagomoris
37
39
  obj = {:label => 'MSIE', :name => 'Internet Explorer', :type => :browser}
38
40
  obj[:vendor] = 'Microsoft'
39
41
  DATASET[obj[:label]] = obj
data/lib/woothee/os.rb CHANGED
@@ -36,7 +36,9 @@ module Woothee::OS
36
36
  when version == 'NT 6.1' then Woothee::DataSet.get('Win7')
37
37
  when version == 'NT 6.0' then Woothee::DataSet.get('WinVista')
38
38
  when version == 'NT 5.1' then Woothee::DataSet.get('WinXP')
39
- when version =~ /^Phone OS/o then Woothee::DataSet.get('WinPhone')
39
+ when version =~ /^Phone(?: OS)? ([.0-9]+)/o
40
+ version = $1
41
+ Woothee::DataSet.get('WinPhone')
40
42
  when version == 'NT 5.0' then Woothee::DataSet.get('Win2000')
41
43
  when version == 'NT 4.0' then Woothee::DataSet.get('WinNT4')
42
44
  when version == '98' then Woothee::DataSet.get('Win98') # wow, WinMe is shown as 'Windows 98; Win9x 4.90', fxxxk
@@ -47,6 +49,7 @@ module Woothee::OS
47
49
  end
48
50
  update_category(result, data[Woothee::KEY_CATEGORY])
49
51
  update_os(result, data[Woothee::KEY_NAME])
52
+ update_os_version(result, version)
50
53
  true
51
54
  end
52
55
 
@@ -54,6 +57,7 @@ module Woothee::OS
54
57
  return false if ua.index('Mac OS X').nil?
55
58
 
56
59
  data = Woothee::DataSet.get('OSX')
60
+ version = nil
57
61
  if ua.index('like Mac OS X')
58
62
  data = case
59
63
  when ua.index('iPhone;') then Woothee::DataSet.get('iPhone')
@@ -61,42 +65,71 @@ module Woothee::OS
61
65
  when ua.index('iPod') then Woothee::DataSet.get('iPod')
62
66
  else data
63
67
  end
68
+ if ua =~ /; CPU(?: iPhone)? OS (\d+_\d+(?:_\d+)?) like Mac OS X/
69
+ version = $1.gsub(/_/, '.')
70
+ end
71
+ else
72
+ if ua =~ /Mac OS X (10[._]\d+(?:[._]\d+)?)(?:\)|;)/
73
+ version = $1.gsub(/_/, '.')
74
+ end
64
75
  end
65
76
  update_category(result, data[Woothee::KEY_CATEGORY])
66
77
  update_os(result, data[Woothee::KEY_NAME])
78
+ if version
79
+ update_os_version(result, version)
80
+ end
67
81
  true
68
82
  end
69
83
 
70
84
  def self.challenge_linux(ua, result)
71
85
  return false if ua.index('Linux').nil?
72
86
 
73
- data = if ua.index('Android')
74
- Woothee::DataSet.get('Android')
75
- else
76
- Woothee::DataSet.get('Linux')
77
- end
87
+ data = nil
88
+ os_version = nil
89
+ if ua.index('Android')
90
+ data = Woothee::DataSet.get('Android')
91
+ if ua =~ /Android[- ](\d+\.\d+(?:\.\d+)?)/
92
+ os_version = $1
93
+ end
94
+ else
95
+ data = Woothee::DataSet.get('Linux')
96
+ end
78
97
  update_category(result, data[Woothee::KEY_CATEGORY])
79
98
  update_os(result, data[Woothee::KEY_NAME])
99
+ if os_version
100
+ update_os_version(result, os_version)
101
+ end
80
102
  true
81
103
  end
82
104
 
83
105
  def self.challenge_smartphone(ua, result)
84
- data = case
85
- when ua.index('iPhone') then Woothee::DataSet.get('iPhone')
86
- when ua.index('iPad') then Woothee::DataSet.get('iPad')
87
- when ua.index('iPod') then Woothee::DataSet.get('iPod')
88
- when ua.index('Android') then Woothee::DataSet.get('Android')
89
- when ua.index('CFNetwork') then Woothee::DataSet.get('iOS')
90
- when ua.index('BlackBerry') then Woothee::DataSet.get('BlackBerry')
91
- else nil
92
- end
106
+ data = nil
107
+ os_version = nil
108
+ case
109
+ when ua.index('iPhone')
110
+ data = Woothee::DataSet.get('iPhone')
111
+ when ua.index('iPad')
112
+ data = Woothee::DataSet.get('iPad')
113
+ when ua.index('iPod')
114
+ data = Woothee::DataSet.get('iPod')
115
+ when ua.index('Android')
116
+ data = Woothee::DataSet.get('Android')
117
+ when ua.index('CFNetwork')
118
+ data = Woothee::DataSet.get('iOS')
119
+ when ua.index('BlackBerry')
120
+ data = Woothee::DataSet.get('BlackBerry')
121
+ if ua =~ /BlackBerry(?:\d+)\/([.0-9]+) /
122
+ os_version = $1
123
+ end
124
+ end
93
125
 
94
126
  if result[Woothee::KEY_NAME] && result[Woothee::KEY_NAME] == Woothee::DataSet.get('Firefox')[Woothee::KEY_NAME]
95
127
  # Firefox OS specific pattern
96
128
  # http://lawrencemandel.com/2012/07/27/decision-made-firefox-os-user-agent-string/
97
129
  # https://github.com/woothee/woothee/issues/2
98
- if ua =~ /^Mozilla\/[.0-9]+ \((?:Mobile|Tablet);(.*;)? rv:[.0-9]+\) Gecko\/[.0-9]+ Firefox\/[.0-9]+$/
130
+ if ua =~ /^Mozilla\/[.0-9]+ \((?:Mobile|Tablet);(?:.*;)? rv:([.0-9]+)\) Gecko\/[.0-9]+ Firefox\/[.0-9]+$/
99
131
  data = Woothee::DataSet.get('FirefoxOS')
132
+ os_version = $1
100
133
  end
101
134
  end
102
135
 
@@ -104,6 +137,9 @@ module Woothee::OS
104
137
 
105
138
  update_category(result, data[Woothee::KEY_CATEGORY])
106
139
  update_os(result, data[Woothee::KEY_NAME])
140
+ if os_version
141
+ update_os_version(result, os_version)
142
+ end
107
143
  true
108
144
  end
109
145
 
@@ -166,23 +202,39 @@ module Woothee::OS
166
202
  end
167
203
 
168
204
  def self.challenge_misc(ua, result)
169
- data = case
170
- when ua.index('(Win98;')
171
- Woothee::DataSet.get('Win98')
172
- when ua.index('Macintosh; U; PPC;')
173
- Woothee::DataSet.get('MacOS')
174
- when ua.index('Mac_PowerPC')
175
- Woothee::DataSet.get('MacOS')
176
- when ua.index('X11; FreeBSD ')
177
- Woothee::DataSet.get('BSD')
178
- when ua.index('X11; CrOS ')
179
- Woothee::DataSet.get('ChromeOS')
180
- else
181
- nil
182
- end
205
+ data = nil
206
+ os_version = nil
207
+ case
208
+ when ua.index('(Win98;')
209
+ data = Woothee::DataSet.get('Win98')
210
+ os_version = "98"
211
+ when ua.index('Macintosh; U; PPC;')
212
+ data = Woothee::DataSet.get('MacOS')
213
+ if ua =~ /rv:(\d+\.\d+\.\d+)/
214
+ os_version = $1
215
+ end
216
+ when ua.index('Mac_PowerPC')
217
+ data = Woothee::DataSet.get('MacOS')
218
+ when ua.index('X11; FreeBSD ')
219
+ data = Woothee::DataSet.get('BSD')
220
+ if ua =~ /FreeBSD ([^;\)]+);/
221
+ os_version = $1
222
+ end
223
+ when ua.index('X11; CrOS ')
224
+ data = Woothee::DataSet.get('ChromeOS')
225
+ if ua =~ /CrOS ([^\)]+)\)/
226
+ os_version = $1
227
+ end
228
+ else
229
+ nil
230
+ end
231
+
183
232
  if data
184
233
  update_category(result, data[Woothee::KEY_CATEGORY])
185
234
  update_os(result, data[Woothee::KEY_NAME])
235
+ if os_version
236
+ update_os_version(result, os_version)
237
+ end
186
238
  return true
187
239
  end
188
240
 
data/lib/woothee/util.rb CHANGED
@@ -21,4 +21,8 @@ module Woothee::Util
21
21
  def update_os(target, os)
22
22
  target[Woothee::ATTRIBUTE_OS] = os
23
23
  end
24
+
25
+ def update_os_version(target, version)
26
+ target[Woothee::ATTRIBUTE_OS_VERSION] = version
27
+ end
24
28
  end
@@ -1,3 +1,3 @@
1
1
  module Woothee
2
- VERSION = "0.4.2"
2
+ VERSION = "1.0.0"
3
3
  end
@@ -53,6 +53,7 @@ module Woothee
53
53
  KEY_TYPE = :type
54
54
  KEY_CATEGORY = :category
55
55
  KEY_OS = :os
56
+ KEY_OS_VERSION = :os_version
56
57
  KEY_VENDOR = :vendor
57
58
  KEY_VERSION = :version
58
59
 
@@ -70,13 +71,14 @@ module Woothee
70
71
  ATTRIBUTE_NAME = :name
71
72
  ATTRIBUTE_CATEGORY = :category
72
73
  ATTRIBUTE_OS = :os
74
+ ATTRIBUTE_OS_VERSION = :os_version
73
75
  ATTRIBUTE_VENDOR = :vendor
74
76
  ATTRIBUTE_VERSION = :version
75
77
 
76
78
  VALUE_UNKNOWN = "UNKNOWN"
77
79
 
78
80
  CATEGORY_LIST = [CATEGORY_PC,CATEGORY_SMARTPHONE,CATEGORY_MOBILEPHONE,CATEGORY_CRAWLER,CATEGORY_APPLIANCE,CATEGORY_MISC,VALUE_UNKNOWN]
79
- ATTRIBUTE_LIST = [ATTRIBUTE_NAME,ATTRIBUTE_CATEGORY,ATTRIBUTE_OS,ATTRIBUTE_VENDOR,ATTRIBUTE_VERSION]
81
+ ATTRIBUTE_LIST = [ATTRIBUTE_NAME,ATTRIBUTE_CATEGORY,ATTRIBUTE_OS,ATTRIBUTE_VENDOR,ATTRIBUTE_VERSION,ATTRIBUTE_OS_VERSION]
80
82
  end
81
83
 
82
84
  module Woothee::DataSet
@@ -15,7 +15,7 @@ describe Woothee::DataSet do
15
15
  expect { Woothee::CATEGORY_LIST }.not_to raise_error()
16
16
  expect(Woothee::ATTRIBUTE_LIST).to eql([
17
17
  Woothee::ATTRIBUTE_NAME, Woothee::ATTRIBUTE_CATEGORY, Woothee::ATTRIBUTE_OS,
18
- Woothee::ATTRIBUTE_VENDOR, Woothee::ATTRIBUTE_VERSION,
18
+ Woothee::ATTRIBUTE_VENDOR, Woothee::ATTRIBUTE_VERSION, Woothee::ATTRIBUTE_OS_VERSION,
19
19
  ])
20
20
  expect(Woothee::CATEGORY_LIST).to eql([
21
21
  Woothee::CATEGORY_PC, Woothee::CATEGORY_SMARTPHONE, Woothee::CATEGORY_MOBILEPHONE,
@@ -25,9 +25,9 @@ describe Woothee do
25
25
  TARGETS.each do |filename,groupname|
26
26
  YAML.load_file(TESTSET_DIR + filename).each do |e|
27
27
  r = Woothee.parse(e['target'])
28
- [:name, :category, :os, :version, :vendor].each do |attribute|
28
+ [:name, :category, :os, :version, :vendor, :os_version].each do |attribute|
29
29
  it groupname + ("test(%s): %s" % [attribute, e['target']]) do
30
- if [:name, :category].include?(attribute) or ([:os, :version, :vendor].include?(attribute) and e.has_key?(attribute.to_s))
30
+ if [:name, :category].include?(attribute) or ([:os, :version, :vendor, :os_version].include?(attribute) and e.has_key?(attribute.to_s))
31
31
  expect(r[attribute].to_s).to eql(e[attribute.to_s])
32
32
  end
33
33
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: woothee
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - TAGOMORI Satoshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-11 00:00:00.000000000 Z
11
+ date: 2014-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake