wurfl_device 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +2 -2
- data/README.md +31 -7
- data/config/unicorn.conf.rb +13 -7
- data/lib/wurfl_device/cache.rb +215 -0
- data/lib/wurfl_device/capability.rb +5 -1
- data/lib/wurfl_device/cli.rb +59 -67
- data/lib/wurfl_device/settings.rb +595 -0
- data/lib/wurfl_device/ui.rb +1 -0
- data/lib/wurfl_device/user_agent.rb +75 -8
- data/lib/wurfl_device/user_agent_matcher.rb +153 -191
- data/lib/wurfl_device/version.rb +1 -1
- data/lib/wurfl_device/web_service.rb +10 -44
- data/lib/wurfl_device/xml_loader.rb +44 -37
- data/lib/wurfl_device.rb +41 -236
- data/spec/cache/device_spec.rb +7 -31
- data/spec/cache/user_agents_spec.rb +27 -0
- data/spec/spec_helper.rb +6 -1
- data/wurfl_device.gemspec +6 -3
- metadata +52 -38
- data/lib/wurfl_device/constants.rb +0 -43
- data/lib/wurfl_device/device.rb +0 -83
data/.rvmrc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env bash
|
2
2
|
|
3
|
-
ruby_string="1.9.
|
3
|
+
ruby_string="1.9.3"
|
4
4
|
gemset_name="wurfl_device"
|
5
5
|
|
6
6
|
if rvm list strings | grep -q "${ruby_string}" ; then
|
@@ -9,7 +9,7 @@ if rvm list strings | grep -q "${ruby_string}" ; then
|
|
9
9
|
if [[ -d "${rvm_path:-$HOME/.rvm}/environments" && -s "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}" ]] ; then
|
10
10
|
\. "${rvm_path:-$HOME/.rvm}/environments/${ruby_string}@${gemset_name}"
|
11
11
|
else
|
12
|
-
rvm --create
|
12
|
+
rvm --create "${ruby_string}@${gemset_name}"
|
13
13
|
fi
|
14
14
|
|
15
15
|
if ! command -v bundle ; then
|
data/README.md
CHANGED
@@ -1,22 +1,46 @@
|
|
1
|
-
|
1
|
+
WurflDevice
|
2
|
+
===========
|
2
3
|
Ruby client library for mobile handset detection
|
3
4
|
|
4
5
|
|
5
|
-
|
6
|
+
Requirements
|
6
7
|
------------
|
7
|
-
|
8
|
+
* [redis server](http://redis.io/)
|
8
9
|
|
9
10
|
|
10
|
-
|
11
|
+
Installation
|
12
|
+
------------
|
13
|
+
install using rubygems
|
14
|
+
|
15
|
+
gem install wurfl_device
|
16
|
+
|
17
|
+
or add to your Gemfile:
|
18
|
+
|
19
|
+
gem wurfl_device
|
20
|
+
|
21
|
+
and install it via Bundler:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
|
26
|
+
Usage
|
11
27
|
-----
|
12
28
|
|
13
29
|
require 'wurfl_device'
|
14
30
|
|
31
|
+
get capabilities hash from user agent
|
32
|
+
|
15
33
|
user_agent = 'Mozilla/5.0 (SymbianOS/9.2; U; Series60/3.1 NokiaN95_8GB/20.0.016; Profile/MIDP-2.0 Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko) Safari/413'
|
34
|
+
capabilities = WurflDevice.capabilities_from_user_agent(user_agent)
|
35
|
+
|
36
|
+
get capabilities hash from device id
|
16
37
|
|
17
|
-
|
38
|
+
device_id = 'generic'
|
39
|
+
capabilities = WurflDevice.capabilities_from_id(device_id)
|
18
40
|
|
19
|
-
|
20
|
-
puts device.id
|
41
|
+
get capability from user agent
|
21
42
|
|
43
|
+
user_agent = 'generic'
|
44
|
+
capability_name = 'id'
|
45
|
+
capability = WurflDevice.capabilities(capability_name, user_agent)
|
22
46
|
|
data/config/unicorn.conf.rb
CHANGED
@@ -5,17 +5,23 @@ require 'raindrops'
|
|
5
5
|
|
6
6
|
$stats ||= Raindrops::Middleware::Stats.new
|
7
7
|
|
8
|
-
FileUtils.mkdir_p(WurflDevice::
|
8
|
+
FileUtils.mkdir_p(WurflDevice::Settings::BASE_DIR) unless File.directory?(WurflDevice::Settings::BASE_DIR)
|
9
9
|
|
10
10
|
app_env = ENV['RACK_ENV'] || 'production'
|
11
11
|
app_root = ::File.expand_path('../..', __FILE__)
|
12
12
|
|
13
|
-
|
13
|
+
app_timeout = 60
|
14
|
+
app_workers = WurflDevice::Settings::WEBSERVICE_WORKER
|
15
|
+
app_listen_socket = File.join(WurflDevice::Settings::BASE_DIR, WurflDevice::Settings::WEBSERVICE_SOCKET)
|
16
|
+
app_pid_file = File.join(WurflDevice::Settings::BASE_DIR, WurflDevice::Settings::WEBSERVICE_PID)
|
17
|
+
app_log_file = File.join(WurflDevice::Settings::BASE_DIR, WurflDevice::Settings::WEBSERVICE_LOG)
|
18
|
+
|
19
|
+
timeout app_timeout
|
14
20
|
working_directory app_root
|
15
|
-
worker_processes (app_env != 'development' ?
|
16
|
-
listen
|
17
|
-
pid
|
18
|
-
stderr_path
|
19
|
-
stdout_path
|
21
|
+
worker_processes (app_env != 'development' ? app_workers : 1)
|
22
|
+
listen app_listen_socket, :backlog => 64
|
23
|
+
pid app_pid_file
|
24
|
+
stderr_path app_log_file
|
25
|
+
stdout_path app_log_file
|
20
26
|
|
21
27
|
preload_app false
|
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'redis/connection/hiredis' unless defined?(FakeRedis)
|
2
|
+
require 'redis'
|
3
|
+
|
4
|
+
module WurflDevice
|
5
|
+
module Cache
|
6
|
+
class Entries
|
7
|
+
class << self
|
8
|
+
def clear
|
9
|
+
entries.each { |key| Cache.storage.del(build_cache_id(key)) }
|
10
|
+
end
|
11
|
+
|
12
|
+
def set(id, key, value)
|
13
|
+
Cache.storage.hset(build_cache_id(id), key, value)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get(id, key)
|
17
|
+
Cache.storage.hget(build_cache_id(id), key)
|
18
|
+
end
|
19
|
+
|
20
|
+
def keys(id)
|
21
|
+
Cache.storage.hkeys(build_cache_id(id))
|
22
|
+
end
|
23
|
+
|
24
|
+
def keys_values(id)
|
25
|
+
Cache.storage.hgetall(build_cache_id(id))
|
26
|
+
end
|
27
|
+
|
28
|
+
def entries
|
29
|
+
entry_ids = Array.new
|
30
|
+
Cache.storage.keys(build_cache_id('*')).each do |key|
|
31
|
+
entry_ids << key.gsub(build_cache_id(''), '')
|
32
|
+
end
|
33
|
+
entry_ids
|
34
|
+
end
|
35
|
+
|
36
|
+
def get_value(id)
|
37
|
+
Cache.storage.get(build_cache_id(id))
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_value(id, value)
|
41
|
+
Cache.storage.set(build_cache_id(id), value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_cache_id(id)
|
45
|
+
"#{self.name}:#{id}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Devices < Entries; end
|
51
|
+
class UserAgents < Entries; end
|
52
|
+
class UserAgentsManufacturers < Entries; end
|
53
|
+
|
54
|
+
class Status < Entries
|
55
|
+
def self.version
|
56
|
+
keys 'version' || ''
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.last_updated
|
60
|
+
get_value('last_updated') || ''
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class << self
|
65
|
+
attr_writer :storage
|
66
|
+
|
67
|
+
def storage
|
68
|
+
@storage ||= Redis.new(:db => 7)
|
69
|
+
end
|
70
|
+
|
71
|
+
def clear
|
72
|
+
Status.clear
|
73
|
+
Devices.clear
|
74
|
+
UserAgents.clear
|
75
|
+
UserAgentsManufacturers.clear
|
76
|
+
end
|
77
|
+
|
78
|
+
def initialized?
|
79
|
+
Status.get_value('initialized').to_actual_value
|
80
|
+
end
|
81
|
+
|
82
|
+
def initialize_cache(xml_file)
|
83
|
+
version_list = Array.new
|
84
|
+
|
85
|
+
XmlLoader.load_xml_file(xml_file) do |capabilities|
|
86
|
+
version = capabilities.delete(:version)
|
87
|
+
version_list << version unless version.nil?
|
88
|
+
|
89
|
+
device_id = capabilities.delete('id')
|
90
|
+
next if device_id.nil? || device_id.empty?
|
91
|
+
|
92
|
+
user_agent = capabilities.delete('user_agent')
|
93
|
+
user_agent = Settings::GENERIC if user_agent.nil? || user_agent.empty?
|
94
|
+
user_agent.strip!
|
95
|
+
|
96
|
+
fall_back = capabilities.delete('fall_back')
|
97
|
+
fall_back = '' if fall_back.nil?
|
98
|
+
fall_back.strip!
|
99
|
+
|
100
|
+
Devices.set device_id, 'id', device_id
|
101
|
+
Devices.set device_id, 'user_agent', user_agent
|
102
|
+
Devices.set device_id, 'fall_back', fall_back
|
103
|
+
|
104
|
+
user_agent = UserAgent.new user_agent
|
105
|
+
UserAgents.set user_agent, 'id', device_id
|
106
|
+
unless user_agent =~ /^DO_NOT_MATCH/i
|
107
|
+
UserAgentsManufacturers.set user_agent.manufacturer, user_agent, device_id
|
108
|
+
end
|
109
|
+
|
110
|
+
capabilities.each_pair do |key, value|
|
111
|
+
if value.is_a?(Hash)
|
112
|
+
value.each_pair do |k, v|
|
113
|
+
Devices.set device_id, "#{key.to_s}:#{k.to_s}", v
|
114
|
+
end
|
115
|
+
else
|
116
|
+
Devices.set device_id, key.to_s, value
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
version_list.each do |ver|
|
122
|
+
Status.set 'version', ver, Time.now
|
123
|
+
end
|
124
|
+
Status.set_value 'last_updated', Time.now
|
125
|
+
Status.set_value 'initialized', true
|
126
|
+
end
|
127
|
+
|
128
|
+
def rebuild_user_agents
|
129
|
+
UserAgents.clear
|
130
|
+
UserAgentsManufacturers.clear
|
131
|
+
Devices.entries.each do |device_id|
|
132
|
+
device = Devices.keys_values device_id
|
133
|
+
user_agent = UserAgent.new device['user_agent']
|
134
|
+
UserAgents.set user_agent, 'id', device_id
|
135
|
+
unless user_agent =~ /^DO_NOT_MATCH/i
|
136
|
+
UserAgentsManufacturers.set user_agent.manufacturer, user_agent, device_id
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def update_actual_capabilities(user_agent, capabilities)
|
142
|
+
capabilities.each_pair do |key, value|
|
143
|
+
if value.kind_of?(Hash)
|
144
|
+
value.each_pair do |k, v|
|
145
|
+
UserAgents.set user_agent, "#{key}:#{k}", v
|
146
|
+
end
|
147
|
+
elsif value.is_a?(Array)
|
148
|
+
value.each_with_index do |v, i|
|
149
|
+
UserAgents.set user_agent, "#{key}:#{i}", v
|
150
|
+
end
|
151
|
+
else
|
152
|
+
UserAgents.set user_agent, key, value
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def parse_actual_capabilities(actual_capabilities)
|
158
|
+
capabilities = Capability.new
|
159
|
+
|
160
|
+
actual_capabilities.each_pair do |key, value|
|
161
|
+
if key =~ /^(.+)\:(\d+)$/i
|
162
|
+
capabilities[$1] ||= Array.new
|
163
|
+
capabilities[$1][$2.to_i] = value.to_actual_value
|
164
|
+
elsif key =~ /^(.+)\:(.+)$/i
|
165
|
+
capabilities[$1] ||= Capability.new
|
166
|
+
capabilities[$1][$2] = value.to_actual_value
|
167
|
+
else
|
168
|
+
capabilities[key] = value.to_actual_value
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
capabilities
|
173
|
+
end
|
174
|
+
|
175
|
+
def build_capabilities(device_id)
|
176
|
+
capabilities = Capability.new
|
177
|
+
actual_capabilities = Devices.keys_values(device_id)
|
178
|
+
return capabilities if actual_capabilities.nil?
|
179
|
+
|
180
|
+
capabilities['fall_back_tree'] ||= Array.new
|
181
|
+
|
182
|
+
if !actual_capabilities['fall_back'].nil? && !actual_capabilities['fall_back'].empty? && actual_capabilities['fall_back'] != 'root'
|
183
|
+
fall_back = build_capabilities(actual_capabilities['fall_back'])
|
184
|
+
if !fall_back.nil? && !fall_back['id'].nil? && !fall_back['id'].empty?
|
185
|
+
capabilities['fall_back_tree'].unshift(fall_back['id'])
|
186
|
+
fall_back.each_pair do |key, value|
|
187
|
+
if value.kind_of?(Hash)
|
188
|
+
capabilities[key] ||= Capability.new
|
189
|
+
value.each_pair do |k, v|
|
190
|
+
capabilities[key][k] = v.to_actual_value
|
191
|
+
end
|
192
|
+
elsif value.is_a?(Array)
|
193
|
+
capabilities[key] ||= Array.new
|
194
|
+
capabilities[key] |= value.to_actual_value
|
195
|
+
else
|
196
|
+
capabilities[key] = value.to_actual_value
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
actual_capabilities.each_pair do |key, value|
|
203
|
+
if key =~ /^(.+)\:(.+)$/i
|
204
|
+
capabilities[$1] ||= Capability.new
|
205
|
+
capabilities[$1][$2] = value.to_actual_value
|
206
|
+
else
|
207
|
+
capabilities[key] = value.to_actual_value
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
capabilities
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
data/lib/wurfl_device/cli.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require 'thor'
|
2
|
-
require '
|
3
|
+
require 'benchmark'
|
3
4
|
require 'wurfl_device'
|
5
|
+
require 'yaml'
|
4
6
|
|
5
7
|
module WurflDevice
|
6
8
|
class CLI < Thor
|
@@ -25,18 +27,19 @@ module WurflDevice
|
|
25
27
|
super
|
26
28
|
end
|
27
29
|
|
28
|
-
desc "
|
29
|
-
method_option "base-dir", :type => :string, :banner => "set base directory for data files", :aliases => "-d", :default => WurflDevice::
|
30
|
-
method_option :host, :type => :string, :banner => "set webservice host", :aliases => "-h", :default => WurflDevice::
|
31
|
-
method_option :port, :type => :numeric, :banner => "set webservice port", :aliases => "-p", :default => WurflDevice::
|
32
|
-
method_option :
|
30
|
+
desc "webservice [start|stop|restart|status]", "start a wurfl_device server"
|
31
|
+
method_option "base-dir", :type => :string, :banner => "set base directory for data files", :aliases => "-d", :default => WurflDevice::Settings::BASE_DIR
|
32
|
+
method_option :host, :type => :string, :banner => "set webservice host", :aliases => "-h", :default => WurflDevice::Settings::WEBSERVICE_HOST
|
33
|
+
method_option :port, :type => :numeric, :banner => "set webservice port", :aliases => "-p", :default => WurflDevice::Settings::WEBSERVICE_PORT
|
34
|
+
method_option :worker, :type => :numeric, :banner => "set worker count", :aliases => "-w", :default => WurflDevice::Settings::WEBSERVICE_WORKER
|
35
|
+
method_option :socket, :type => :string, :banner => "use unix domain socket", :aliases => "-s", :default => File.join(WurflDevice::Settings::BASE_DIR, WurflDevice::Settings::WEBSERVICE_SOCKET)
|
33
36
|
method_option :socket_only, :type => :boolean, :banner => "start as unix domain socket listener only", :aliases => "-t", :default => false
|
34
|
-
def
|
37
|
+
def webservice(action=nil)
|
35
38
|
opts = options.dup
|
36
39
|
|
37
40
|
action ||= 'status'
|
38
41
|
|
39
|
-
pid_file = File.join(WurflDevice::
|
42
|
+
pid_file = File.join(WurflDevice::Settings::BASE_DIR, WurflDevice::Settings::WEBSERVICE_PID)
|
40
43
|
base_dir = opts['base-dir']
|
41
44
|
|
42
45
|
FileUtils.mkdir_p(base_dir) unless File.directory?(base_dir)
|
@@ -77,102 +80,90 @@ module WurflDevice
|
|
77
80
|
|
78
81
|
system(args.join(' '))
|
79
82
|
end
|
83
|
+
FileUtils.rm_f(pid_file)
|
80
84
|
elsif action == 'restart'
|
81
85
|
server('stop')
|
86
|
+
sleep(0.3)
|
82
87
|
server('start')
|
83
88
|
else
|
84
89
|
#status
|
85
90
|
end
|
86
91
|
end
|
92
|
+
map %w(server) => :webservice
|
87
93
|
|
88
94
|
desc "dump DEVICE_ID|USER_AGENT", "display capabilities DEVICE_ID|USER_AGENT"
|
89
95
|
method_option :json, :type => :boolean, :banner => "show the dump in json format", :aliases => "-j"
|
90
96
|
method_option :yaml, :type => :boolean, :banner => "show the dump in yaml format", :aliases => "-y"
|
91
97
|
def dump(device_id)
|
92
|
-
|
93
|
-
|
98
|
+
capabilities = WurflDevice.capabilities_from_id(device_id)
|
99
|
+
capabilities = WurflDevice.capabilities_from_user_agent(device_id) if capabilities['id'].nil?
|
94
100
|
|
95
|
-
if
|
96
|
-
WurflDevice.ui.info
|
101
|
+
if capabilities.nil?
|
102
|
+
WurflDevice.ui.info "Nothing to dump"
|
103
|
+
elsif options.json?
|
104
|
+
WurflDevice.ui.info capabilities.to_json
|
97
105
|
else
|
98
|
-
WurflDevice.ui.info
|
106
|
+
WurflDevice.ui.info capabilities.to_yaml
|
99
107
|
end
|
100
108
|
end
|
101
109
|
|
102
110
|
desc "list", "list user agent cache list"
|
111
|
+
method_option "matched-only", :type => :boolean, :banner => "show user agents that were matched", :aliases => "-m"
|
103
112
|
def list
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
WurflDevice.ui.info user_agent
|
113
|
+
matched_only = options['matched-only']
|
114
|
+
WurflDevice::Cache::UserAgents.entries.each do |user_agent|
|
115
|
+
kv = WurflDevice::Cache::UserAgents.keys_values user_agent
|
116
|
+
next if kv.count <= 1 && matched_only
|
117
|
+
WurflDevice.ui.info "#{user_agent}:#{kv['id']}"
|
109
118
|
end
|
110
119
|
end
|
111
120
|
|
112
|
-
desc "
|
113
|
-
method_option
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
WurflDevice.ui.info "clearing all cache entries."
|
120
|
-
WurflDevice.clear_devices
|
121
|
-
WurflDevice.clear_cache
|
121
|
+
desc "init [WURFL_XML_FILE]", "initialize the wurfl device cache"
|
122
|
+
method_option :update, :type => :boolean, :banner => "don't clear previous cache", :aliases => "-u", :default => false
|
123
|
+
def init(xml_file=nil)
|
124
|
+
xml_file ||= Settings.default_wurfl_xml_file
|
125
|
+
unless options.update?
|
126
|
+
WurflDevice.ui.info "clearing existing device cache."
|
127
|
+
WurflDevice::Cache.clear
|
122
128
|
end
|
123
|
-
|
124
|
-
|
125
|
-
WurflDevice.clear_user_agent_cache
|
126
|
-
end
|
127
|
-
if opts['clear-dev']
|
128
|
-
WurflDevice.ui.info "clearing device cache."
|
129
|
-
WurflDevice.clear_devices
|
130
|
-
end
|
131
|
-
WurflDevice.ui.info "updating wurfl devices cache."
|
132
|
-
WurflDevice.initialize_cache
|
133
|
-
WurflDevice.ui.info "rebuilding cache."
|
134
|
-
WurflDevice.rebuild_user_agent_cache
|
135
|
-
WurflDevice.ui.info "done."
|
136
|
-
WurflDevice.ui.info ""
|
129
|
+
WurflDevice.ui.info "initializing wurfl device cache."
|
130
|
+
WurflDevice::Cache.initialize_cache(xml_file)
|
137
131
|
status true
|
138
132
|
end
|
139
133
|
|
140
|
-
desc "rebuild", "rebuild the existing user_agents cache"
|
141
|
-
def rebuild
|
142
|
-
WurflDevice.ui.info "rebuilding the user_agents cache."
|
143
|
-
WurflDevice.rebuild_user_agent_cache
|
144
|
-
WurflDevice.ui.info "done."
|
145
|
-
end
|
146
|
-
|
147
134
|
desc "status", "show wurfl cache information"
|
148
135
|
def status(skip_version=false)
|
149
136
|
version unless skip_version
|
150
|
-
unless WurflDevice.
|
137
|
+
unless WurflDevice::Cache.initialized?
|
151
138
|
WurflDevice.ui.info "cache is not initialized"
|
152
139
|
return
|
153
140
|
end
|
154
|
-
info = WurflDevice.get_info
|
155
|
-
version = info['version'] || 'none'
|
156
|
-
last_update = info['last_updated'] || 'unknown'
|
157
141
|
WurflDevice.ui.info "cache info:"
|
158
|
-
WurflDevice.ui.info " wurfl-xml version: " + version
|
159
|
-
WurflDevice.ui.info " cache last updated: " +
|
160
|
-
devices = WurflDevice.
|
161
|
-
user_agents = WurflDevice.
|
142
|
+
WurflDevice.ui.info " wurfl-xml version: " + WurflDevice::Cache::Status.version.join(' ')
|
143
|
+
WurflDevice.ui.info " cache last updated: " + WurflDevice::Cache::Status.last_updated
|
144
|
+
devices = WurflDevice::Cache::Devices.entries
|
145
|
+
user_agents = WurflDevice::Cache::UserAgents.entries
|
162
146
|
user_agents_message = ''
|
163
|
-
user_agents_message = " (warning count should be equal to devices count)" if
|
147
|
+
user_agents_message = " (warning count should be greater than or equal to devices count)" if user_agents.length < devices.length
|
148
|
+
|
149
|
+
matched_count = 0
|
150
|
+
WurflDevice::Cache::UserAgents.entries.each do |user_agent|
|
151
|
+
kv = WurflDevice::Cache::UserAgents.keys_values user_agent
|
152
|
+
next if kv.count == 1
|
153
|
+
matched_count = matched_count + 1
|
154
|
+
end
|
164
155
|
WurflDevice.ui.info " " + commify(devices.length) + " device id's"
|
165
156
|
WurflDevice.ui.info " " + commify(user_agents.length) + " exact user agents" + user_agents_message
|
166
|
-
WurflDevice.ui.info " " + commify(
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
157
|
+
WurflDevice.ui.info " " + commify(matched_count) + " user agents matched found in cache"
|
158
|
+
|
159
|
+
user_agent_manufacturers = Array.new
|
160
|
+
WurflDevice::Cache::UserAgentsManufacturers.entries.each do |index|
|
161
|
+
user_agent_manufacturers << "#{index}(" + commify(WurflDevice::Cache::UserAgentsManufacturers.keys(index).length) + ")"
|
171
162
|
end
|
172
|
-
|
173
|
-
WurflDevice.ui.info "wurfl user agent
|
174
|
-
while !
|
175
|
-
sub =
|
163
|
+
user_agent_manufacturers.sort!
|
164
|
+
WurflDevice.ui.info "wurfl user agent manufacturers:"
|
165
|
+
while !user_agent_manufacturers.empty?
|
166
|
+
sub = user_agent_manufacturers.slice!(0, 7)
|
176
167
|
WurflDevice.ui.info " " + sub.join(', ')
|
177
168
|
end
|
178
169
|
WurflDevice.ui.info ""
|
@@ -184,6 +175,7 @@ module WurflDevice
|
|
184
175
|
WurflDevice.ui.info "wurfl_device version #{WurflDevice::VERSION.freeze}"
|
185
176
|
end
|
186
177
|
map %w(-v --version) => :version
|
178
|
+
|
187
179
|
private
|
188
180
|
def commify(n)
|
189
181
|
n.to_s =~ /([^\.]*)(\..*)?/
|