wurfl 1.0.2 → 1.1.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.
- data/.gitignore +1 -0
- data/README.rdoc +31 -22
- data/VERSION +1 -1
- data/bin/wurfltools.rb +21 -0
- data/lib/wurfl/command.rb +4 -0
- data/lib/wurfl/command/comparator.rb +86 -0
- data/lib/wurfl/command/inspector.rb +142 -0
- data/lib/wurfl/command/loader.rb +129 -0
- data/lib/wurfl/command/sanitycheck.rb +40 -0
- data/lib/wurfl/command/uaproftowurfl.rb +28 -0
- data/lib/wurfl/command/uaprofwurflcomparator.rb +224 -0
- data/wurfl.gemspec +12 -9
- metadata +12 -15
- data/bin/uaproftowurfl.rb +0 -28
- data/bin/uaprofwurflcomparator.rb +0 -223
- data/bin/wurflcomparator.rb +0 -86
- data/bin/wurflinspector.rb +0 -141
- data/bin/wurflloader.rb +0 -127
- data/bin/wurflsanitycheck.rb +0 -39
@@ -0,0 +1,40 @@
|
|
1
|
+
require "wurfl/command"
|
2
|
+
|
3
|
+
# A simple command line tool to make sure that a wurfl file properly parses.
|
4
|
+
# Used to make sure changes to Wurfl/Patch files are OK.
|
5
|
+
class Wurfl::Command::Sanitycheck < Wurfl::Command
|
6
|
+
def execute
|
7
|
+
if ARGV.size != 1
|
8
|
+
puts "Must have the path of the wurfl file to check"
|
9
|
+
exit 1
|
10
|
+
end
|
11
|
+
lines = File.open(ARGV[0],"r").readlines
|
12
|
+
|
13
|
+
curdev = nil
|
14
|
+
c = 0
|
15
|
+
|
16
|
+
lines.each do |line|
|
17
|
+
line = line.strip
|
18
|
+
if line =~ /^(<d)evice.*[^\/]>$/
|
19
|
+
curdev = line
|
20
|
+
elsif line =~ /^(<d)evice.*\/>$/
|
21
|
+
if curdev
|
22
|
+
puts "#{c}:A device was not closed and we got a new device! #{curdev}"
|
23
|
+
end
|
24
|
+
curdev = nil
|
25
|
+
elsif line =~ /^(<\/d)evice>$/
|
26
|
+
if curdev.nil?
|
27
|
+
puts "#{c}:A closing device with no opening! #{curdev}"
|
28
|
+
end
|
29
|
+
curdev=nil
|
30
|
+
end
|
31
|
+
c += 1
|
32
|
+
end
|
33
|
+
|
34
|
+
if curdev
|
35
|
+
puts "The curent device was not closed #{curdev}"
|
36
|
+
end
|
37
|
+
|
38
|
+
puts "Done"
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "wurfl/command"
|
2
|
+
require "wurfl/uaproftowurfl"
|
3
|
+
|
4
|
+
class Wurfl::Command::Uaproftowurfl
|
5
|
+
def execute
|
6
|
+
if ARGV.size == 0
|
7
|
+
usage
|
8
|
+
end
|
9
|
+
|
10
|
+
uaprof = Wurfl::UAProfToWURLF.new
|
11
|
+
|
12
|
+
# Parse all the files and merge them into one UAProf.
|
13
|
+
# Following profs take precedence of previous ones
|
14
|
+
ARGV.each do |file|
|
15
|
+
uaprof.parse_UAProf(file)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Now output the mapped WURFL to standard out
|
19
|
+
uaprof.output_WURFL
|
20
|
+
end
|
21
|
+
|
22
|
+
def usage
|
23
|
+
puts "Usage: wurfltools.rb uaproftowurfl uaprof_files"
|
24
|
+
puts "No files passed to parse."
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,224 @@
|
|
1
|
+
require "wurfl/command"
|
2
|
+
require "getoptlong"
|
3
|
+
require "net/http"
|
4
|
+
|
5
|
+
require "wurfl/uaproftowurfl"
|
6
|
+
require "wurfl/handset"
|
7
|
+
require "wurfl/utils"
|
8
|
+
include Wurfl::Utils
|
9
|
+
|
10
|
+
# An addition to the UAProf to Wurfl to generate a WurflHandset from the UAProf.
|
11
|
+
class Wurfl::UAProfToWURLF
|
12
|
+
def make_wurfl_handset
|
13
|
+
hand = Wurfl::Handset.new("UAProf",@wurfl["user_agent"])
|
14
|
+
@wurflgroups.each do |group|
|
15
|
+
@wurfl[group].sort.each do |key,value|
|
16
|
+
hand[key] = value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
return hand
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
class Wurfl::Command::Uaprofwurflcomparator
|
25
|
+
def parse_mapping_file(file)
|
26
|
+
if !File.exist?(file)
|
27
|
+
$stderr.puts "Mapping File does not exist. File passed was #{file}."
|
28
|
+
return Array.new
|
29
|
+
end
|
30
|
+
mappings = Array.new
|
31
|
+
f = File.new(file)
|
32
|
+
f.each do |line|
|
33
|
+
if m = /^"(.*)" "(.*)"$/.match(line.strip)
|
34
|
+
uaprof = m[1]
|
35
|
+
useragent = m[2]
|
36
|
+
mappings<< [uaprof,useragent]
|
37
|
+
else
|
38
|
+
$stderr.puts "Irregular format for line: #{line}" if line.strip != ""
|
39
|
+
end
|
40
|
+
end
|
41
|
+
f.close
|
42
|
+
|
43
|
+
return mappings
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_uaprofile(uaprof,profiledir,check=false)
|
47
|
+
file = strip_uaprof(uaprof)
|
48
|
+
if File.exists?("#{profiledir}/#{file}") && check
|
49
|
+
return file
|
50
|
+
end
|
51
|
+
|
52
|
+
get_and_save_uaprof_file(uaprof,profiledir)
|
53
|
+
return file
|
54
|
+
end
|
55
|
+
|
56
|
+
def strip_uaprof(uaprof)
|
57
|
+
uaprof_file = nil
|
58
|
+
if m = /([^\/]*)$/.match(uaprof)
|
59
|
+
uaprof_file = m[1]
|
60
|
+
else
|
61
|
+
$stderr.puts "Cannot find the base UAProf file in URI: #{uaprof}"
|
62
|
+
end
|
63
|
+
return uaprof_file
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_pstore(pstorefile)
|
67
|
+
hands = Hash.new
|
68
|
+
begin
|
69
|
+
handsid, = load_wurfl_pstore(pstorefile)
|
70
|
+
handsid.each { |id,val| hands[val.user_agent] = val }
|
71
|
+
rescue => err
|
72
|
+
$stderr.puts "Error: Cannot load PStore file. #{pstorefile}"
|
73
|
+
$stderr.puts err.message
|
74
|
+
exit 1
|
75
|
+
end
|
76
|
+
return hands
|
77
|
+
end
|
78
|
+
|
79
|
+
def get_and_save_uaprof_file(uaprof_url,savedirectory,limit=0)
|
80
|
+
base,path,port = parse_url(uaprof_url)
|
81
|
+
|
82
|
+
raise "Too many redirects from original url" if limit > 3
|
83
|
+
raise "Unparseable URL: #{url}" if base.nil?
|
84
|
+
|
85
|
+
port = 80 if port.nil?
|
86
|
+
http = Net::HTTP.new(base,port)
|
87
|
+
begin
|
88
|
+
resp, data = http.get(path)
|
89
|
+
if resp.code == "301"
|
90
|
+
# get location and call self again
|
91
|
+
http.finish
|
92
|
+
limit += 1
|
93
|
+
get_and_save_uaprof_file(resp['location'],savedirectory,limit)
|
94
|
+
return
|
95
|
+
elsif resp.code != "200"
|
96
|
+
raise "Unexpected HTTP Response code:#{resp.code} for #{uaprof_url}"
|
97
|
+
end
|
98
|
+
rescue => err
|
99
|
+
raise
|
100
|
+
end
|
101
|
+
|
102
|
+
f = File.new("#{savedirectory}/#{strip_uaprof(path)}","w")
|
103
|
+
f.write(data)
|
104
|
+
f.close
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
def parse_url(url)
|
109
|
+
m = /(http:\/\/)?(.*?)(:(\d*))?\/(.*)/i.match(url.strip)
|
110
|
+
|
111
|
+
return nil if m.nil?
|
112
|
+
return m[2],"/#{m[5]}",m[4]
|
113
|
+
end
|
114
|
+
|
115
|
+
def usage
|
116
|
+
puts "Usage: wurfltools.rb uaprofwurflcomparator -d profiledirectory -f mappingfile [-w wurfldb] [-c] [-h | --help]"
|
117
|
+
puts "Examples:"
|
118
|
+
puts "wurfltools.rb uaprofwurflcomparator -d ./profiles -f all-profile.2003-08.log -c -w wurfl.db"
|
119
|
+
exit 1
|
120
|
+
end
|
121
|
+
|
122
|
+
def help
|
123
|
+
puts "-d --directory : The directory to store the UA Profiles found in the log file."
|
124
|
+
puts "-f --file : The log file that has a UAProfile to User-Agent mapping per line."
|
125
|
+
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."
|
126
|
+
puts "-w --wurfldb : A Ruby PStore Database of the WURFL, that is used to compare against the UAProfiles."
|
127
|
+
puts "-h --help : This message."
|
128
|
+
exit 1
|
129
|
+
end
|
130
|
+
|
131
|
+
def execute
|
132
|
+
profiledirectory = mappingfile = pstorefile = nil
|
133
|
+
existancecheck = false
|
134
|
+
begin
|
135
|
+
opt = GetoptLong.new(
|
136
|
+
["-d","--directory", GetoptLong::REQUIRED_ARGUMENT],
|
137
|
+
["-f","--file", GetoptLong::REQUIRED_ARGUMENT],
|
138
|
+
["-c","--check", GetoptLong::NO_ARGUMENT],
|
139
|
+
["-h","--help", GetoptLong::NO_ARGUMENT],
|
140
|
+
["-w","--wurfldb", GetoptLong::REQUIRED_ARGUMENT]
|
141
|
+
)
|
142
|
+
|
143
|
+
opt.each { |arg,val|
|
144
|
+
case arg
|
145
|
+
when "-d"
|
146
|
+
profiledirectory = val.strip
|
147
|
+
when "-f"
|
148
|
+
mappingfile = val.strip
|
149
|
+
when "-c"
|
150
|
+
existancecheck = true
|
151
|
+
when "-h"
|
152
|
+
help
|
153
|
+
when "-w"
|
154
|
+
pstorefile = val.strip
|
155
|
+
else
|
156
|
+
usage
|
157
|
+
end
|
158
|
+
}
|
159
|
+
usage if mappingfile.nil? || profiledirectory.nil?
|
160
|
+
rescue => err
|
161
|
+
usage
|
162
|
+
end
|
163
|
+
|
164
|
+
profiles = Hash.new
|
165
|
+
duplicates = Hash.new
|
166
|
+
mappings = parse_mapping_file(mappingfile)
|
167
|
+
mappings.each do |uaprof,useragent|
|
168
|
+
begin
|
169
|
+
prof_file = get_uaprofile(uaprof,profiledirectory,existancecheck)
|
170
|
+
uaprof_mapper = UAProfToWURLF.new
|
171
|
+
if profiles.key?(useragent)
|
172
|
+
duplicates[useragent] = Array.new if !duplicates.key?(useragent)
|
173
|
+
duplicates[useragent]<<uaprof
|
174
|
+
next
|
175
|
+
end
|
176
|
+
uaprof_mapper.parse_UAProf("#{profiledirectory}/#{prof_file}")
|
177
|
+
profiles[useragent] = uaprof_mapper
|
178
|
+
rescue => err
|
179
|
+
$stderr.puts "Error: File #{prof_file}; User-Agent:#{useragent}"
|
180
|
+
$stderr.puts "Error:#{err.message}"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
duplicates.each do |key,profs|
|
185
|
+
$stderr.puts "Duplicates exist for #{key}"
|
186
|
+
profs.each {|prof| $stderr.puts "-- #{prof}" }
|
187
|
+
end
|
188
|
+
|
189
|
+
exit 0 if !pstorefile
|
190
|
+
|
191
|
+
wurflhandsets = load_pstore(pstorefile)
|
192
|
+
|
193
|
+
puts "Comparing WURFL Handsets"
|
194
|
+
profiles.each do |key,val|
|
195
|
+
puts "",""
|
196
|
+
|
197
|
+
if !wurflhandsets.key?(key)
|
198
|
+
puts "UAProf has a new Handset: #{key}"
|
199
|
+
puts "--------------------------------"
|
200
|
+
val.output_WURFL
|
201
|
+
puts "--------------------------------"
|
202
|
+
else
|
203
|
+
uahand = val.make_wurfl_handset
|
204
|
+
res = uahand.compare(wurflhandsets[key])
|
205
|
+
if res.size > 0
|
206
|
+
puts "#{key} : For UAProf and WURFL differ"
|
207
|
+
res.each do |dkey,dval,did|
|
208
|
+
next if did == "generic"
|
209
|
+
#Key UAPROF Value WURFL Value WURFL source id
|
210
|
+
puts " Key:#{dkey}; UVAL:#{uahand[dkey]}; WVAL:#{dval}; WSRCID:#{did}"
|
211
|
+
end
|
212
|
+
#val["user_agent"] = key
|
213
|
+
puts ""
|
214
|
+
puts "WURFL Changes are:"
|
215
|
+
puts ""
|
216
|
+
val.output_WURFL(res.map {|entry| entry[0]})
|
217
|
+
else
|
218
|
+
puts "#{key} : For UAProf and WURFL match"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
data/wurfl.gemspec
CHANGED
@@ -2,14 +2,15 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{wurfl}
|
5
|
-
s.version = "1.0
|
5
|
+
s.version = "1.1.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Paul McMahon", "Zev Blut"]
|
9
|
-
s.date = %q{2009-06-
|
9
|
+
s.date = %q{2009-06-09}
|
10
|
+
s.default_executable = %q{wurfltools.rb}
|
10
11
|
s.description = %q{TODO}
|
11
12
|
s.email = %q{info@mobalean.com}
|
12
|
-
s.executables = ["
|
13
|
+
s.executables = ["wurfltools.rb"]
|
13
14
|
s.extra_rdoc_files = [
|
14
15
|
"LICENSE",
|
15
16
|
"README.rdoc"
|
@@ -20,12 +21,14 @@ Gem::Specification.new do |s|
|
|
20
21
|
"README.rdoc",
|
21
22
|
"Rakefile",
|
22
23
|
"VERSION",
|
23
|
-
"bin/
|
24
|
-
"
|
25
|
-
"
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
24
|
+
"bin/wurfltools.rb",
|
25
|
+
"lib/wurfl/command.rb",
|
26
|
+
"lib/wurfl/command/comparator.rb",
|
27
|
+
"lib/wurfl/command/inspector.rb",
|
28
|
+
"lib/wurfl/command/loader.rb",
|
29
|
+
"lib/wurfl/command/sanitycheck.rb",
|
30
|
+
"lib/wurfl/command/uaproftowurfl.rb",
|
31
|
+
"lib/wurfl/command/uaprofwurflcomparator.rb",
|
29
32
|
"lib/wurfl/handset.rb",
|
30
33
|
"lib/wurfl/loader.rb",
|
31
34
|
"lib/wurfl/uaproftowurfl.rb",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wurfl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul McMahon
|
@@ -10,19 +10,14 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-06-
|
14
|
-
default_executable:
|
13
|
+
date: 2009-06-09 00:00:00 +09:00
|
14
|
+
default_executable: wurfltools.rb
|
15
15
|
dependencies: []
|
16
16
|
|
17
17
|
description: TODO
|
18
18
|
email: info@mobalean.com
|
19
19
|
executables:
|
20
|
-
-
|
21
|
-
- wurflsanitycheck.rb
|
22
|
-
- wurflinspector.rb
|
23
|
-
- wurflloader.rb
|
24
|
-
- uaprofwurflcomparator.rb
|
25
|
-
- wurflcomparator.rb
|
20
|
+
- wurfltools.rb
|
26
21
|
extensions: []
|
27
22
|
|
28
23
|
extra_rdoc_files:
|
@@ -34,12 +29,14 @@ files:
|
|
34
29
|
- README.rdoc
|
35
30
|
- Rakefile
|
36
31
|
- VERSION
|
37
|
-
- bin/
|
38
|
-
-
|
39
|
-
-
|
40
|
-
-
|
41
|
-
-
|
42
|
-
-
|
32
|
+
- bin/wurfltools.rb
|
33
|
+
- lib/wurfl/command.rb
|
34
|
+
- lib/wurfl/command/comparator.rb
|
35
|
+
- lib/wurfl/command/inspector.rb
|
36
|
+
- lib/wurfl/command/loader.rb
|
37
|
+
- lib/wurfl/command/sanitycheck.rb
|
38
|
+
- lib/wurfl/command/uaproftowurfl.rb
|
39
|
+
- lib/wurfl/command/uaprofwurflcomparator.rb
|
43
40
|
- lib/wurfl/handset.rb
|
44
41
|
- lib/wurfl/loader.rb
|
45
42
|
- lib/wurfl/uaproftowurfl.rb
|
data/bin/uaproftowurfl.rb
DELETED
@@ -1,28 +0,0 @@
|
|
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
|
-
|
@@ -1,223 +0,0 @@
|
|
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
|
-
|