wurfl 1.0.2
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.
- data/.gitignore +2 -0
- data/LICENSE +35 -0
- data/README.rdoc +144 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/bin/uaproftowurfl.rb +28 -0
- data/bin/uaprofwurflcomparator.rb +223 -0
- data/bin/wurflcomparator.rb +86 -0
- data/bin/wurflinspector.rb +141 -0
- data/bin/wurflloader.rb +127 -0
- data/bin/wurflsanitycheck.rb +39 -0
- data/lib/wurfl/handset.rb +117 -0
- data/lib/wurfl/loader.rb +130 -0
- data/lib/wurfl/uaproftowurfl.rb +1013 -0
- data/lib/wurfl/utils.rb +31 -0
- data/test/data/wurfl.simple.xml +38 -0
- data/test/handset_test.rb +70 -0
- data/test/loader_test.rb +29 -0
- data/wurfl.gemspec +59 -0
- metadata +79 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
Copyright (c) 2009, mobalean (http://www.mobalean.com/)
|
2
|
+
|
3
|
+
Copyright (c) 2003, Ubiquitous Business Technology (http://ubit.com)
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
|
7
|
+
Redistribution and use in source and binary forms, with or without
|
8
|
+
modification, are permitted provided that the following conditions are
|
9
|
+
met:
|
10
|
+
|
11
|
+
|
12
|
+
* Redistributions of source code must retain the above copyright
|
13
|
+
notice, this list of conditions and the following disclaimer.
|
14
|
+
|
15
|
+
* Redistributions in binary form must reproduce the above
|
16
|
+
copyright notice, this list of conditions and the following
|
17
|
+
disclaimer in the documentation and/or other materials provided
|
18
|
+
with the distribution.
|
19
|
+
|
20
|
+
* Neither the name of the WURFL nor the names of its
|
21
|
+
contributors may be used to endorse or promote products derived
|
22
|
+
from this software without specific prior written permission.
|
23
|
+
|
24
|
+
|
25
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
26
|
+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
27
|
+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
28
|
+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
29
|
+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
30
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
31
|
+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
32
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
33
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
34
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
35
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
= WURFL
|
2
|
+
|
3
|
+
WURFL is a collection of libraries and command line tools for using and manipulating the WURFL. To start using it, simply install the gem:
|
4
|
+
|
5
|
+
sudo gem install wurfl
|
6
|
+
|
7
|
+
== Tools
|
8
|
+
|
9
|
+
=== wurflloader.rb
|
10
|
+
|
11
|
+
Is used to parse and load a WURFL XML file into memory or save a
|
12
|
+
PStore database that is used by most of the other tools. This
|
13
|
+
application creates WURFL PStore databases that are essential for use
|
14
|
+
with the other Ruby applications.
|
15
|
+
|
16
|
+
=== wurflinspector.rb
|
17
|
+
|
18
|
+
Is a tool that will let you do various searches and queries on the
|
19
|
+
WURFL. This is a very simple, yet powerful program for finding
|
20
|
+
information about the handsets in the WURFL. See the wurflinspector
|
21
|
+
examples section for usage.
|
22
|
+
|
23
|
+
==== Usage
|
24
|
+
|
25
|
+
The command below will search through all handsets and return the ids
|
26
|
+
of handsets that match the passed Ruby boolean evaluation
|
27
|
+
*) This command will return all handsets that have more than 2 colors.
|
28
|
+
"wurflinspector.rb -d pstorehandsets.db -s '{ |hand| hand["colors"].to_i > 2 }'"
|
29
|
+
The Ruby query must go in between the single quote marks and needs to
|
30
|
+
declare the WurflHandset instance variable name.
|
31
|
+
|
32
|
+
*) This command shows you how you can cheat with the current design of
|
33
|
+
the wurflinspector and print more user friendly results. This example
|
34
|
+
assumes you have the command line programs sort and uniq, but that is
|
35
|
+
only to make the output look better. This example does the same as the
|
36
|
+
above, except that it prints out the brand name and model name of the
|
37
|
+
matching handsets instead of the WURFL id.
|
38
|
+
|
39
|
+
Note: this should all go into one command line call
|
40
|
+
"wurflinspector.rb -d pstorehandsets.db -s '{|hand| puts
|
41
|
+
"#{hand["brand_name"]} #{hand["model_name"]}" if hand["colors"].to_i >
|
42
|
+
2}' | sort | uniq"
|
43
|
+
|
44
|
+
|
45
|
+
The following individual handset query commands will tell the value of
|
46
|
+
capabilities and from where it obtained the setting.
|
47
|
+
|
48
|
+
*) A command to query the handset with the id sonyericsson_t300_ver1
|
49
|
+
for all of its' capabilities:
|
50
|
+
"wurflinspector.rb -d pstorehandsets.db -i sonyericsson_t300_ver1"
|
51
|
+
|
52
|
+
*) A command to query the handset with the id sonyericsson_t300_ver1 for
|
53
|
+
backlight capability:
|
54
|
+
"wurflinspector.rb -d pstorehandsets.db -i sonyericsson_t300_ver1 -q
|
55
|
+
backlight"
|
56
|
+
|
57
|
+
=== wurflsanitycheck.rb
|
58
|
+
|
59
|
+
Is a partial WURFL validating program. It does a few simple
|
60
|
+
checks to make sure the XML structure is parse-able by the wurflloader.
|
61
|
+
If you receive loading errors by the wurflloader, then you can run the
|
62
|
+
wurflsanitycheck program to find the lines in the XML file that might
|
63
|
+
be causing the problem.
|
64
|
+
|
65
|
+
=== wurflcomparator.rb
|
66
|
+
|
67
|
+
Is a another simple program that will find the differences from two
|
68
|
+
WURFL Ruby PStore databases. This is another way of finding changes
|
69
|
+
from the different versions of the WURFL without running a diff on the
|
70
|
+
XML files.
|
71
|
+
|
72
|
+
=== uaproftowurfl.rb
|
73
|
+
|
74
|
+
Is a program that takes UAProfiles and creates an equivalent WURFL
|
75
|
+
entry. It holds all of the mappings used to convert a UAProfile to a
|
76
|
+
WURFL entry. This program alone makes using the Ruby tools worth it.
|
77
|
+
|
78
|
+
The mappings are not fully complete and can certainly use your input
|
79
|
+
in improving them.
|
80
|
+
|
81
|
+
About the source code:
|
82
|
+
The main piece of code to read are the methods under the
|
83
|
+
"UAProfile Mappings" comment.
|
84
|
+
|
85
|
+
For now you can ignore the details above this comment.
|
86
|
+
Basically each method is the name of a UAProfifle component.
|
87
|
+
When you parse a UAProfile file it will call each UAProfile
|
88
|
+
component's method name.
|
89
|
+
|
90
|
+
So you can simply look at UAProfile component's method to see
|
91
|
+
how it maps to the WURFL.
|
92
|
+
If a component is not found as a method it will be logged to
|
93
|
+
Standard Error. For this log one can then add the method to
|
94
|
+
the UAProfToWurfl class later.
|
95
|
+
|
96
|
+
==== Usage
|
97
|
+
|
98
|
+
A simple usage is:
|
99
|
+
|
100
|
+
ruby uaproftowurfl.rb sampleprofile.xml
|
101
|
+
|
102
|
+
Example use from a bash shell with many profiles:
|
103
|
+
|
104
|
+
for i in `ls profiles`; do
|
105
|
+
ruby uaproftowurfl.rb profiles/$i >output/$i.wurfl
|
106
|
+
2> output/$i.parser.err;
|
107
|
+
done
|
108
|
+
|
109
|
+
This assumes that you have a profiles directory with all of the UAProf
|
110
|
+
file you wish to parse and a output directory to place the results and
|
111
|
+
errors.
|
112
|
+
|
113
|
+
=== uaprofwurflcomparator.rb
|
114
|
+
|
115
|
+
Is a program that compares UAProfiles against the equivalent WURFL
|
116
|
+
entries. It takes a file that contains an UAProfile URL and an
|
117
|
+
User-Agent per line, in addition to a Ruby Wurfl PStore database. It
|
118
|
+
then compares the UAProfile against the Wurfl that matches the same
|
119
|
+
User Agent. The output is a list of the differences and a WURFL
|
120
|
+
formatted entry showing the differences.
|
121
|
+
|
122
|
+
==== Usage
|
123
|
+
|
124
|
+
You pass the program a directory to save the UAProfile files taken
|
125
|
+
from the given URL, a file that holds the UAProfil URL and User-Agent
|
126
|
+
mappings, and the Ruby PStore database that holds the WURFL.
|
127
|
+
|
128
|
+
The following is a simple example of execution
|
129
|
+
uaprofwurflcomparator.rb -d ./profiles -f all-profile.2003-08.log -c -w wurfl.db
|
130
|
+
|
131
|
+
== Authors
|
132
|
+
|
133
|
+
Zev Blut (Original Author)
|
134
|
+
Paul McMahon (gem installer, refactorings)
|
135
|
+
|
136
|
+
== Copyright
|
137
|
+
|
138
|
+
Copyright (c) 2009, mobalean (http://www.mobalean.com/)
|
139
|
+
|
140
|
+
Copyright (c) 2003, Ubiquitous Business Technology (http://ubit.com)
|
141
|
+
All rights reserved.
|
142
|
+
|
143
|
+
Send enquiries to: mailto:info@mobalean.com
|
144
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rake/rdoctask'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rubygems'
|
4
|
+
|
5
|
+
task :default => ['test']
|
6
|
+
|
7
|
+
Rake::TestTask.new(:test) do |t|
|
8
|
+
t.test_files = FileList['test/*_test.rb']
|
9
|
+
t.ruby_opts = ['-rubygems'] if defined? Gem
|
10
|
+
end
|
11
|
+
|
12
|
+
begin
|
13
|
+
require 'jeweler'
|
14
|
+
Jeweler::Tasks.new do |s|
|
15
|
+
s.name = "wurfl"
|
16
|
+
s.summary = "Library and tools for manipulating the WURFL"
|
17
|
+
s.description = "Library and tools for manipulating the WURFL"
|
18
|
+
s.email = "info@mobalean.com"
|
19
|
+
s.homepage = "http://github.com/pwim/wurfl"
|
20
|
+
s.description = "TODO"
|
21
|
+
s.authors = ["Paul McMahon", "Zev Blut"]
|
22
|
+
s.rubyforge_project = 'wurfl'
|
23
|
+
end
|
24
|
+
rescue LoadError
|
25
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
26
|
+
end
|
27
|
+
|
28
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
29
|
+
rdoc.rdoc_dir = 'rdoc'
|
30
|
+
rdoc.title = 'WURFL'
|
31
|
+
rdoc.main = "README.rdoc"
|
32
|
+
rdoc.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
require 'rake/contrib/sshpublisher'
|
37
|
+
namespace :rubyforge do
|
38
|
+
|
39
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
40
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
41
|
+
|
42
|
+
namespace :release do
|
43
|
+
desc "Publish RDoc to RubyForge."
|
44
|
+
task :docs => [:rdoc] do
|
45
|
+
config = YAML.load(
|
46
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
47
|
+
)
|
48
|
+
|
49
|
+
host = "#{config['username']}@rubyforge.org"
|
50
|
+
remote_dir = "/var/www/gforge-projects/wurfl/"
|
51
|
+
local_dir = 'rdoc'
|
52
|
+
|
53
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
rescue LoadError
|
58
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
59
|
+
end
|
60
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.2
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
4
|
+
require "wurfl/uaproftowurfl"
|
5
|
+
|
6
|
+
# The code below is called if this file is executed from the command line.
|
7
|
+
|
8
|
+
def usage
|
9
|
+
puts "Usage: usaprofparser.rb uaprof_files"
|
10
|
+
puts "No files passed to parse."
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
if ARGV.size == 0
|
15
|
+
usage
|
16
|
+
end
|
17
|
+
|
18
|
+
uaprof = Wurfl::UAProfToWURLF.new
|
19
|
+
|
20
|
+
# Parse all the files and merge them into one UAProf.
|
21
|
+
# Following profs take precedence of previous ones
|
22
|
+
ARGV.each do |file|
|
23
|
+
uaprof.parse_UAProf(file)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Now output the mapped WURFL to standard out
|
27
|
+
uaprof.output_WURFL
|
28
|
+
|
@@ -0,0 +1,223 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
4
|
+
|
5
|
+
require "getoptlong"
|
6
|
+
require "net/http"
|
7
|
+
|
8
|
+
require "wurfl/uaproftowurfl"
|
9
|
+
require "wurfl/handset"
|
10
|
+
require "wurfl/utils"
|
11
|
+
include Wurfl::Utils
|
12
|
+
|
13
|
+
# An addition to the UAProf to Wurfl to generate a WurflHandset from the UAProf.
|
14
|
+
class Wurfl::UAProfToWURLF
|
15
|
+
def make_wurfl_handset
|
16
|
+
hand = Wurfl::Handset.new("UAProf",@wurfl["user_agent"])
|
17
|
+
@wurflgroups.each do |group|
|
18
|
+
@wurfl[group].sort.each do |key,value|
|
19
|
+
hand[key] = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
return hand
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def parse_mapping_file(file)
|
28
|
+
if !File.exist?(file)
|
29
|
+
$stderr.puts "Mapping File does not exist. File passed was #{file}."
|
30
|
+
return Array.new
|
31
|
+
end
|
32
|
+
mappings = Array.new
|
33
|
+
f = File.new(file)
|
34
|
+
f.each do |line|
|
35
|
+
if m = /^"(.*)" "(.*)"$/.match(line.strip)
|
36
|
+
uaprof = m[1]
|
37
|
+
useragent = m[2]
|
38
|
+
mappings<< [uaprof,useragent]
|
39
|
+
else
|
40
|
+
$stderr.puts "Irregular format for line: #{line}" if line.strip != ""
|
41
|
+
end
|
42
|
+
end
|
43
|
+
f.close
|
44
|
+
|
45
|
+
return mappings
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_uaprofile(uaprof,profiledir,check=false)
|
49
|
+
file = strip_uaprof(uaprof)
|
50
|
+
if File.exists?("#{profiledir}/#{file}") && check
|
51
|
+
return file
|
52
|
+
end
|
53
|
+
|
54
|
+
get_and_save_uaprof_file(uaprof,profiledir)
|
55
|
+
return file
|
56
|
+
end
|
57
|
+
|
58
|
+
def strip_uaprof(uaprof)
|
59
|
+
uaprof_file = nil
|
60
|
+
if m = /([^\/]*)$/.match(uaprof)
|
61
|
+
uaprof_file = m[1]
|
62
|
+
else
|
63
|
+
$stderr.puts "Cannot find the base UAProf file in URI: #{uaprof}"
|
64
|
+
end
|
65
|
+
return uaprof_file
|
66
|
+
end
|
67
|
+
|
68
|
+
def load_pstore(pstorefile)
|
69
|
+
hands = Hash.new
|
70
|
+
begin
|
71
|
+
handsid, = load_wurfl_pstore(pstorefile)
|
72
|
+
handsid.each { |id,val| hands[val.user_agent] = val }
|
73
|
+
rescue => err
|
74
|
+
$stderr.puts "Error: Cannot load PStore file. #{pstorefile}"
|
75
|
+
$stderr.puts err.message
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
return hands
|
79
|
+
end
|
80
|
+
|
81
|
+
def get_and_save_uaprof_file(uaprof_url,savedirectory,limit=0)
|
82
|
+
base,path,port = parse_url(uaprof_url)
|
83
|
+
|
84
|
+
raise "Too many redirects from original url" if limit > 3
|
85
|
+
raise "Unparseable URL: #{url}" if base.nil?
|
86
|
+
|
87
|
+
port = 80 if port.nil?
|
88
|
+
http = Net::HTTP.new(base,port)
|
89
|
+
begin
|
90
|
+
resp, data = http.get(path)
|
91
|
+
if resp.code == "301"
|
92
|
+
# get location and call self again
|
93
|
+
http.finish
|
94
|
+
limit += 1
|
95
|
+
get_and_save_uaprof_file(resp['location'],savedirectory,limit)
|
96
|
+
return
|
97
|
+
elsif resp.code != "200"
|
98
|
+
raise "Unexpected HTTP Response code:#{resp.code} for #{uaprof_url}"
|
99
|
+
end
|
100
|
+
rescue => err
|
101
|
+
raise
|
102
|
+
end
|
103
|
+
|
104
|
+
f = File.new("#{savedirectory}/#{strip_uaprof(path)}","w")
|
105
|
+
f.write(data)
|
106
|
+
f.close
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
def parse_url(url)
|
111
|
+
m = /(http:\/\/)?(.*?)(:(\d*))?\/(.*)/i.match(url.strip)
|
112
|
+
|
113
|
+
return nil if m.nil?
|
114
|
+
return m[2],"/#{m[5]}",m[4]
|
115
|
+
end
|
116
|
+
|
117
|
+
def usage
|
118
|
+
puts "Usage: uaprofwurflcomparator.rb -d profiledirectory -f mappingfile [-w wurfldb] [-c] [-h | --help]"
|
119
|
+
puts "Examples:"
|
120
|
+
puts "uaprofwurflcomparator.rb -d ./profiles -f all-profile.2003-08.log -c -w wurfl.db"
|
121
|
+
exit 1
|
122
|
+
end
|
123
|
+
|
124
|
+
def help
|
125
|
+
puts "-d --directory : The directory to store the UA Profiles found in the log file."
|
126
|
+
puts "-f --file : The log file that has a UAProfile to User-Agent mapping per line."
|
127
|
+
puts "-c --check : A flag that will make sure to check if the profile is already in the directory or not. If it is not then it will download it."
|
128
|
+
puts "-w --wurfldb : A Ruby PStore Database of the WURFL, that is used to compare against the UAProfiles."
|
129
|
+
puts "-h --help : This message."
|
130
|
+
exit 1
|
131
|
+
end
|
132
|
+
|
133
|
+
profiledirectory = mappingfile = pstorefile = nil
|
134
|
+
existancecheck = false
|
135
|
+
begin
|
136
|
+
opt = GetoptLong.new(
|
137
|
+
["-d","--directory", GetoptLong::REQUIRED_ARGUMENT],
|
138
|
+
["-f","--file", GetoptLong::REQUIRED_ARGUMENT],
|
139
|
+
["-c","--check", GetoptLong::NO_ARGUMENT],
|
140
|
+
["-h","--help", GetoptLong::NO_ARGUMENT],
|
141
|
+
["-w","--wurfldb", GetoptLong::REQUIRED_ARGUMENT]
|
142
|
+
)
|
143
|
+
|
144
|
+
opt.each { |arg,val|
|
145
|
+
case arg
|
146
|
+
when "-d"
|
147
|
+
profiledirectory = val.strip
|
148
|
+
when "-f"
|
149
|
+
mappingfile = val.strip
|
150
|
+
when "-c"
|
151
|
+
existancecheck = true
|
152
|
+
when "-h"
|
153
|
+
help
|
154
|
+
when "-w"
|
155
|
+
pstorefile = val.strip
|
156
|
+
else
|
157
|
+
usage
|
158
|
+
end
|
159
|
+
}
|
160
|
+
usage if mappingfile.nil? || profiledirectory.nil?
|
161
|
+
rescue => err
|
162
|
+
usage
|
163
|
+
end
|
164
|
+
|
165
|
+
profiles = Hash.new
|
166
|
+
duplicates = Hash.new
|
167
|
+
mappings = parse_mapping_file(mappingfile)
|
168
|
+
mappings.each do |uaprof,useragent|
|
169
|
+
begin
|
170
|
+
prof_file = get_uaprofile(uaprof,profiledirectory,existancecheck)
|
171
|
+
uaprof_mapper = UAProfToWURLF.new
|
172
|
+
if profiles.key?(useragent)
|
173
|
+
duplicates[useragent] = Array.new if !duplicates.key?(useragent)
|
174
|
+
duplicates[useragent]<<uaprof
|
175
|
+
next
|
176
|
+
end
|
177
|
+
uaprof_mapper.parse_UAProf("#{profiledirectory}/#{prof_file}")
|
178
|
+
profiles[useragent] = uaprof_mapper
|
179
|
+
rescue => err
|
180
|
+
$stderr.puts "Error: File #{prof_file}; User-Agent:#{useragent}"
|
181
|
+
$stderr.puts "Error:#{err.message}"
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
duplicates.each do |key,profs|
|
186
|
+
$stderr.puts "Duplicates exist for #{key}"
|
187
|
+
profs.each {|prof| $stderr.puts "-- #{prof}" }
|
188
|
+
end
|
189
|
+
|
190
|
+
exit 0 if !pstorefile
|
191
|
+
|
192
|
+
wurflhandsets = load_pstore(pstorefile)
|
193
|
+
|
194
|
+
puts "Comparing WURFL Handsets"
|
195
|
+
profiles.each do |key,val|
|
196
|
+
puts "",""
|
197
|
+
|
198
|
+
if !wurflhandsets.key?(key)
|
199
|
+
puts "UAProf has a new Handset: #{key}"
|
200
|
+
puts "--------------------------------"
|
201
|
+
val.output_WURFL
|
202
|
+
puts "--------------------------------"
|
203
|
+
else
|
204
|
+
uahand = val.make_wurfl_handset
|
205
|
+
res = uahand.compare(wurflhandsets[key])
|
206
|
+
if res.size > 0
|
207
|
+
puts "#{key} : For UAProf and WURFL differ"
|
208
|
+
res.each do |dkey,dval,did|
|
209
|
+
next if did == "generic"
|
210
|
+
#Key UAPROF Value WURFL Value WURFL source id
|
211
|
+
puts " Key:#{dkey}; UVAL:#{uahand[dkey]}; WVAL:#{dval}; WSRCID:#{did}"
|
212
|
+
end
|
213
|
+
#val["user_agent"] = key
|
214
|
+
puts ""
|
215
|
+
puts "WURFL Changes are:"
|
216
|
+
puts ""
|
217
|
+
val.output_WURFL(res.map {|entry| entry[0]})
|
218
|
+
else
|
219
|
+
puts "#{key} : For UAProf and WURFL match"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|