wurfl_store 0.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/MIT-LICENSE +20 -0
- data/README +27 -0
- data/Rakefile +51 -0
- data/init.rb +4 -0
- data/install.rb +6 -0
- data/lib/tasks/wurfl_store_tasks.rake +23 -0
- data/lib/wurfl_store.rb +30 -0
- data/lib/wurfl_store/cache_initializer.rb +47 -0
- data/lib/wurfl_store/filter.rb +12 -0
- data/lib/wurfl_store/view.rb +24 -0
- data/lib/wurfl_store/wurfl/wurfl_load.rb +121 -0
- data/lib/wurfl_store/wurfl/wurflhandset.rb +154 -0
- data/uninstall.rb +1 -0
- metadata +97 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 mobiThought
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
WurflStore : Wurfl Redis Store
|
2
|
+
============
|
3
|
+
|
4
|
+
Wurfl Redis Store
|
5
|
+
|
6
|
+
Installation
|
7
|
+
============
|
8
|
+
|
9
|
+
Install the gem from gemcutter:
|
10
|
+
|
11
|
+
sudo gem install wurfl_store
|
12
|
+
|
13
|
+
Special Thanks
|
14
|
+
==============
|
15
|
+
|
16
|
+
WurflStore was inspired and based on wurfl_store . Many thanks to the authors and contributors.
|
17
|
+
|
18
|
+
|
19
|
+
Feedback
|
20
|
+
========
|
21
|
+
|
22
|
+
Send Feedback and questions to: sbertel at mobithought.com
|
23
|
+
|
24
|
+
|
25
|
+
More will Coming Soon, Wait for MobiThought
|
26
|
+
|
27
|
+
Copyright (c) 2010 Shenouda Bertel, MobiThought, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
|
7
|
+
desc 'Default: run unit tests.'
|
8
|
+
task :default => :test
|
9
|
+
|
10
|
+
desc 'Test the wurfl_store plugin.'
|
11
|
+
Rake::TestTask.new(:test) do |t|
|
12
|
+
t.libs << 'lib'
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = true
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'Generate documentation for the wurfl_store gem.'
|
19
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
20
|
+
rdoc.rdoc_dir = 'rdoc'
|
21
|
+
rdoc.title = 'WurflStore'
|
22
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
23
|
+
rdoc.rdoc_files.include('README')
|
24
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
25
|
+
end
|
26
|
+
|
27
|
+
PKG_FILES = FileList[ '[a-zA-Z]*', 'generators/**/*', 'lib/**/*', 'test/**/*' ]
|
28
|
+
|
29
|
+
spec = Gem::Specification.new do |s|
|
30
|
+
s.name = "wurfl_store"
|
31
|
+
s.version = "0.1.0"
|
32
|
+
s.authors = ["Shenouda Bertel"]
|
33
|
+
s.description = "Wurfl Redis Store"
|
34
|
+
s.email = "sbertel@mobithought.com"
|
35
|
+
s.homepage = "http://mobithought.com/"
|
36
|
+
s.files = PKG_FILES.to_a
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubyforge_project = "wurfl_store"
|
39
|
+
s.rubygems_version = "1.3.6"
|
40
|
+
s.summary = "Wurfl Redis Store"
|
41
|
+
s.platform = Gem::Platform::RUBY
|
42
|
+
s.add_dependency('redis-store')
|
43
|
+
s.add_dependency('nokogiri')
|
44
|
+
s.has_rdoc = false
|
45
|
+
s.extra_rdoc_files = ["README"]
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'Turn this plugin into a gem.'
|
49
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
50
|
+
pkg.gem_spec = spec
|
51
|
+
end
|
data/init.rb
ADDED
data/install.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
namespace :wurfl do
|
2
|
+
desc "Download the latest wurfl.xml.gz and unpack it."
|
3
|
+
task :update do
|
4
|
+
require Pathname.new(File.dirname(__FILE__)).join('..', 'wurfl_store', 'wurfl', 'wurfl_load')
|
5
|
+
|
6
|
+
FileUtils.mkdir_p(Rails.root.join('tmp', 'wurfl'))
|
7
|
+
FileUtils.cd(Rails.root.join('tmp', 'wurfl'))
|
8
|
+
|
9
|
+
return_code = `wget -N -- http://downloads.sourceforge.net/project/wurfl/WURFL/latest/wurfl-latest.xml.gz`.to_i
|
10
|
+
raise 'Failed to download wurfl-latest.xml.gz' unless return_code == 0
|
11
|
+
|
12
|
+
return_code = `gunzip -c wurfl-latest.xml.gz > wurfl.xml`.to_i
|
13
|
+
raise 'Failed to unzip wurfl-latest.xml.gz' unless return_code == 0
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Load the latest XML file into the cache."
|
17
|
+
task :cache_update do
|
18
|
+
require Pathname.new(File.dirname(__FILE__)).join('..', 'wurfl_store', 'cache_initializer')
|
19
|
+
require Rails.root.join('config', 'environment.rb')
|
20
|
+
puts 'This can take a minute or two. Be patient.'
|
21
|
+
WurflStore::CacheInitializer.refresh_cache
|
22
|
+
end
|
23
|
+
end
|
data/lib/wurfl_store.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'wurfl_store/cache_initializer'
|
2
|
+
require 'wurfl_store/view'
|
3
|
+
require 'wurfl_store/filter'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'activesupport'
|
6
|
+
require 'redis-store'
|
7
|
+
|
8
|
+
module WurflStore
|
9
|
+
attr_accessor :cache
|
10
|
+
def self.cache
|
11
|
+
@cache
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.init
|
15
|
+
@cache = ActiveSupport::Cache.lookup_store(:redis_store)
|
16
|
+
# determine if the cache has been initialized with the wurfl
|
17
|
+
CacheInitializer.initialize_cache if WurflStore.cache.read('wurfl_initialized').nil?
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.get_handset(user_agent)
|
21
|
+
return nil if user_agent.nil?
|
22
|
+
CacheInitializer.cache_initialized?
|
23
|
+
user_agent.slice!(250..-1)
|
24
|
+
handset = @cache.read(user_agent.tr(' ', ''))
|
25
|
+
chopped_user_agent = user_agent.chop
|
26
|
+
return nil if chopped_user_agent.empty?
|
27
|
+
return self.get_handset(chopped_user_agent) if handset.nil?
|
28
|
+
return handset
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require Pathname.new(File.dirname(__FILE__)).join('wurfl', 'wurfl_load')
|
2
|
+
|
3
|
+
module WurflStore
|
4
|
+
module CacheInitializer
|
5
|
+
def self.load_wurfl
|
6
|
+
wurfl_loader = WurflLoader.new
|
7
|
+
path_to_wurfl = Rails.root.join('tmp', 'wurfl', 'wurfl.xml')
|
8
|
+
unless path_to_wurfl.exist?
|
9
|
+
puts 'Could not find wurfl.xml. Have you run rake wurfl:update yet?'
|
10
|
+
Process.exit
|
11
|
+
end
|
12
|
+
return wurfl_loader.load_wurfl(path_to_wurfl)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.cache_initialized?
|
16
|
+
return true if WurflStore.cache.read('wurfl_initialized')
|
17
|
+
initialize_cache
|
18
|
+
loop do
|
19
|
+
break if WurflStore.cache.read('wurfl_initialized')
|
20
|
+
sleep(0.1)
|
21
|
+
end
|
22
|
+
return true
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.initialize_cache
|
26
|
+
# Prevent more than one process from trying to initialize the cache.
|
27
|
+
return unless WurflStore.cache.write('wurfl_initializing', true, :unless_exist => true)
|
28
|
+
|
29
|
+
WurflStore.cache.write('wurfl_initialized', false)
|
30
|
+
# Proceed to initialize the cache.
|
31
|
+
xml_to_cache
|
32
|
+
WurflStore.cache.write('wurfl_initializing', false)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.xml_to_cache
|
36
|
+
handsets, fallbacks = load_wurfl
|
37
|
+
handsets.each_value do |handset|
|
38
|
+
WurflStore.cache.write(handset.user_agent.tr(' ', ''), handset)
|
39
|
+
end
|
40
|
+
WurflStore.cache.write('wurfl_initialized', true)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.refresh_cache
|
44
|
+
xml_to_cache
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module WurflStore
|
2
|
+
module Filter
|
3
|
+
|
4
|
+
def set_wurfl
|
5
|
+
return unless session[:handset_checked].nil?
|
6
|
+
handset = WurflStore.get_handset(request.headers['HTTP_USER_AGENT'])
|
7
|
+
session[:handset_agent] = handset.user_agent unless handset.nil?
|
8
|
+
session[:handset_checked] = true
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module WurflStore
|
2
|
+
module View
|
3
|
+
|
4
|
+
def handset
|
5
|
+
WurflStore.get_handset(session[:handset_agent])
|
6
|
+
end
|
7
|
+
|
8
|
+
def handset_capability(capability)
|
9
|
+
return nil if handset.nil?
|
10
|
+
capability = handset[capability]
|
11
|
+
return nil if capability.nil?
|
12
|
+
case capability.strip
|
13
|
+
when /^d+$/
|
14
|
+
capability = capability.to_i
|
15
|
+
when /^true$/i
|
16
|
+
capability = true
|
17
|
+
when /^false$/i
|
18
|
+
capability = false
|
19
|
+
end
|
20
|
+
return capability
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require Pathname.new(File.dirname(__FILE__)).join('wurflhandset')
|
2
|
+
require 'rubygems'
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
# Modified to use nokogiri. GREATLY increased speed.
|
6
|
+
# $Id: wurflloader.rb,v 1.1 2003/11/23 12:26:05 zevblut Exp $
|
7
|
+
# Authors: Zev Blut (zb@ubit.com)
|
8
|
+
# Copyright (c) 2003, Ubiquitous Business Technology (http://ubit.com)
|
9
|
+
# All rights reserved.
|
10
|
+
#
|
11
|
+
# Redistribution and use in source and binary forms, with or without
|
12
|
+
# modification, are permitted provided that the following conditions are
|
13
|
+
# met:
|
14
|
+
#
|
15
|
+
#
|
16
|
+
# * Redistributions of source code must retain the above copyright
|
17
|
+
# notice, this list of conditions and the following disclaimer.
|
18
|
+
#
|
19
|
+
# * Redistributions in binary form must reproduce the above
|
20
|
+
# copyright notice, this list of conditions and the following
|
21
|
+
# disclaimer in the documentation and/or other materials provided
|
22
|
+
# with the distribution.
|
23
|
+
#
|
24
|
+
# * Neither the name of the WURFL nor the names of its
|
25
|
+
# contributors may be used to endorse or promote products derived
|
26
|
+
# from this software without specific prior written permission.
|
27
|
+
#
|
28
|
+
#
|
29
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
30
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
31
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
32
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
33
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
34
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
35
|
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
36
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
37
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
38
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
39
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
40
|
+
|
41
|
+
class WurflLoader
|
42
|
+
def initialize
|
43
|
+
@handsets = Hash::new
|
44
|
+
@fallbacks = Hash::new
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_wurfl(wurflfile)
|
48
|
+
file = File.new(wurflfile)
|
49
|
+
doc = Nokogiri::XML::Document.parse file
|
50
|
+
|
51
|
+
# read counter
|
52
|
+
rcount = 0
|
53
|
+
|
54
|
+
# iterate over all of the devices in the file
|
55
|
+
doc.xpath("wurfl/devices/device").each do |element|
|
56
|
+
|
57
|
+
rcount += 1
|
58
|
+
hands = nil # the reference to the current handset
|
59
|
+
if element.attributes["id"].to_s == "generic"
|
60
|
+
# setup the generic Handset
|
61
|
+
element.attributes["user_agent"] = "generic"
|
62
|
+
if @handsets.key?("generic") then
|
63
|
+
hands = @handsets["generic"]
|
64
|
+
puts "Updating the generic handset at count #{rcount}" if @verbose
|
65
|
+
else
|
66
|
+
# the generic handset has not been created. Make it
|
67
|
+
hands = WurflHandset::new "generic","generic"
|
68
|
+
@handsets["generic"] = hands
|
69
|
+
@fallbacks["generic"] = Array::new
|
70
|
+
puts "Made the generic handset at count #{rcount}" if @verbose
|
71
|
+
end
|
72
|
+
|
73
|
+
else
|
74
|
+
# Setup an actual handset
|
75
|
+
|
76
|
+
# check if handset already exists.
|
77
|
+
wurflid = element.attributes["id"].to_s
|
78
|
+
if @handsets.key?(wurflid)
|
79
|
+
# Must have been created by someone who named it as a fallback earlier.
|
80
|
+
hands = @handsets[wurflid]
|
81
|
+
else
|
82
|
+
hands = WurflHandset::new "",""
|
83
|
+
end
|
84
|
+
hands.wurfl_id = wurflid
|
85
|
+
hands.user_agent = element.attributes["user_agent"].to_s
|
86
|
+
hands.user_agent = 'generic' if hands.user_agent.empty?
|
87
|
+
|
88
|
+
# get the fallback and copy it's values into this handset's hashtable
|
89
|
+
fallb = element.attributes["fall_back"].to_s
|
90
|
+
|
91
|
+
# for tracking of who has fallbacks
|
92
|
+
if !@fallbacks.key?(fallb)
|
93
|
+
@fallbacks[fallb] = Array::new
|
94
|
+
end
|
95
|
+
@fallbacks[fallb]<< hands.user_agent
|
96
|
+
|
97
|
+
# Now set the handset to the proper fallback reference
|
98
|
+
if !@handsets.key?(fallb)
|
99
|
+
# We have a fallback that does not exist yet, create the reference.
|
100
|
+
@handsets[fallb] = WurflHandset::new "",""
|
101
|
+
end
|
102
|
+
hands.fallback = @handsets[fallb]
|
103
|
+
end
|
104
|
+
|
105
|
+
# now copy this handset's specific capabilities into it's hashtable
|
106
|
+
element.xpath("./*/capability").each do |el2|
|
107
|
+
hands[el2.attributes["name"].to_s] = el2.attributes["value"].to_s
|
108
|
+
end
|
109
|
+
@handsets[hands.wurfl_id] = hands
|
110
|
+
|
111
|
+
# Do some error checking
|
112
|
+
if hands.wurfl_id.nil?
|
113
|
+
puts "a handset with a nil id at #{rcount}"
|
114
|
+
elsif hands.user_agent.nil?
|
115
|
+
puts "a handset with a nil agent at #{rcount}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
return @handsets, @fallbacks
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# Copyright (c) 2003, Ubiquitous Business Technology (http://ubit.com)
|
2
|
+
# All rights reserved.
|
3
|
+
#
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are
|
6
|
+
# met:
|
7
|
+
#
|
8
|
+
#
|
9
|
+
# * Redistributions of source code must retain the above copyright
|
10
|
+
# notice, this list of conditions and the following disclaimer.
|
11
|
+
#
|
12
|
+
# * Redistributions in binary form must reproduce the above
|
13
|
+
# copyright notice, this list of conditions and the following
|
14
|
+
# disclaimer in the documentation and/or other materials provided
|
15
|
+
# with the distribution.
|
16
|
+
#
|
17
|
+
# * Neither the name of the WURFL nor the names of its
|
18
|
+
# contributors may be used to endorse or promote products derived
|
19
|
+
# from this software without specific prior written permission.
|
20
|
+
#
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
23
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
24
|
+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
25
|
+
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
26
|
+
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
27
|
+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
28
|
+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
29
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
30
|
+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
31
|
+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
32
|
+
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
|
34
|
+
# $Id: wurflhandset.rb,v 1.1 2003/11/23 12:26:05 zevblut Exp $
|
35
|
+
# Authors: Zev Blut (zb@ubit.com)
|
36
|
+
|
37
|
+
=begin
|
38
|
+
A class that represents a handset based on information taken from the WURFL.
|
39
|
+
=end
|
40
|
+
class WurflHandset
|
41
|
+
|
42
|
+
extend Enumerable
|
43
|
+
|
44
|
+
attr_accessor :wurfl_id, :user_agent, :fallback
|
45
|
+
|
46
|
+
# Constructor
|
47
|
+
# Parameters:
|
48
|
+
# wurfl_id: is the WURFL ID of the handset
|
49
|
+
# useragent: is the user agent of the handset
|
50
|
+
# fallback: is the fallback handset that this handset
|
51
|
+
# uses for missing details.
|
52
|
+
def initialize (wurfl_id,useragent,fallback=nil)
|
53
|
+
# A hash to hold keys and values specific to this handset
|
54
|
+
@capabilityhash = Hash::new
|
55
|
+
@wurfl_id = wurfl_id.to_s
|
56
|
+
@user_agent = useragent.to_s
|
57
|
+
@fallback = fallback
|
58
|
+
end
|
59
|
+
|
60
|
+
# Hash accessor
|
61
|
+
# Parameters:
|
62
|
+
# key: the WURFL key whose value is desired
|
63
|
+
# Returns:
|
64
|
+
# The value of the key, nil if the handset does not have the key.
|
65
|
+
def [] (key)
|
66
|
+
# Check if the handset actually has the key
|
67
|
+
if @capabilityhash.key?(key)
|
68
|
+
return @capabilityhash[key]
|
69
|
+
else
|
70
|
+
# The handset does not so check if the fallback handset does
|
71
|
+
# Note: that this is actually a recursive call.
|
72
|
+
if @fallback != nil
|
73
|
+
return @fallback[key]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
# if it gets this far then no one has the key
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
|
80
|
+
# like the above accessor, but also to know who the value
|
81
|
+
# comes from
|
82
|
+
# Returns:
|
83
|
+
# the value and the id of the handset from which the value was obtained
|
84
|
+
def get_value_and_owner(key)
|
85
|
+
return @capabilityhash[key],@wurfl_id if @capabilityhash.key?(key)
|
86
|
+
return @fallback.get_value_and_owner(key) if @fallback != nil
|
87
|
+
return nil,nil
|
88
|
+
end
|
89
|
+
|
90
|
+
# Setter, A method to set a key and value of the handset.
|
91
|
+
def []= (key,val)
|
92
|
+
@capabilityhash[key] = val.to_s
|
93
|
+
end
|
94
|
+
|
95
|
+
# A Method to iterate over all of the keys and values that the handset has.
|
96
|
+
# Note: this will abstract the hash iterator to handle all the lower level
|
97
|
+
# calls for the fallback values.
|
98
|
+
def each
|
99
|
+
keys = self.keys
|
100
|
+
keys.each do |key|
|
101
|
+
# here is the magic that gives us the key and value of the handset
|
102
|
+
# all the way up to the fallbacks end.
|
103
|
+
# Call the pass block with the key and value passed
|
104
|
+
yield key, self[key]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# A method to get all of the keys that the handset has.
|
109
|
+
def keys
|
110
|
+
# merge the unique keys of the handset and it's fallback
|
111
|
+
return @capabilityhash.keys | @fallback.keys if @fallback != nil
|
112
|
+
# no fallback so just return the handset's keys
|
113
|
+
return @capabilityhash.keys
|
114
|
+
end
|
115
|
+
|
116
|
+
# A method to do a simple equality check against two handsets.
|
117
|
+
# Parameter:
|
118
|
+
# other: Is the another WurflHandset to check against.
|
119
|
+
# Returns:
|
120
|
+
# true if the two handsets are equal in all values.
|
121
|
+
# false if they are not exactly equal in values, id and user agent.
|
122
|
+
# Note: for a more detailed comparison, use the compare method.
|
123
|
+
def ==(other)
|
124
|
+
return false if other.nil? || other.class != WurflHandset
|
125
|
+
if (self.wurfl_id == other.wurfl_id) && (self.user_agent == other.user_agent)
|
126
|
+
other.each do |key,value|
|
127
|
+
return false if value != self[key]
|
128
|
+
end
|
129
|
+
return true
|
130
|
+
end
|
131
|
+
return false
|
132
|
+
end
|
133
|
+
|
134
|
+
# A method to compare a handset's values against another handset.
|
135
|
+
# Parameters:
|
136
|
+
# other: is the another WurflHandset to compare against
|
137
|
+
# Returns:
|
138
|
+
# An array of the different values.
|
139
|
+
# Each entry in the Array is an Array of three values.
|
140
|
+
# The first value is the key in which both handsets have different values.
|
141
|
+
# The second is the other handset's value for the key.
|
142
|
+
# The third is the handset id from where the other handset got it's value.
|
143
|
+
def compare(other)
|
144
|
+
differences = Array.new
|
145
|
+
self.keys.each do |key|
|
146
|
+
oval,oid = other.get_value_and_owner(key)
|
147
|
+
if @capabilityhash[key].to_s != oval.to_s
|
148
|
+
differences<< [key,oval,oid]
|
149
|
+
end
|
150
|
+
end
|
151
|
+
return differences
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
data/uninstall.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
# Uninstall hook code here
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wurfl_store
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Shenouda Bertel
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-31 00:00:00 +03:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: redis-store
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: nokogiri
|
34
|
+
prerelease: false
|
35
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
segments:
|
40
|
+
- 0
|
41
|
+
version: "0"
|
42
|
+
type: :runtime
|
43
|
+
version_requirements: *id002
|
44
|
+
description: Wurfl Redis Store
|
45
|
+
email: sbertel@mobithought.com
|
46
|
+
executables: []
|
47
|
+
|
48
|
+
extensions: []
|
49
|
+
|
50
|
+
extra_rdoc_files:
|
51
|
+
- README
|
52
|
+
files:
|
53
|
+
- MIT-LICENSE
|
54
|
+
- README
|
55
|
+
- install.rb
|
56
|
+
- init.rb
|
57
|
+
- Rakefile
|
58
|
+
- uninstall.rb
|
59
|
+
- lib/tasks/wurfl_store_tasks.rake
|
60
|
+
- lib/wurfl_store.rb
|
61
|
+
- lib/wurfl_store/view.rb
|
62
|
+
- lib/wurfl_store/wurfl/wurfl_load.rb
|
63
|
+
- lib/wurfl_store/wurfl/wurflhandset.rb
|
64
|
+
- lib/wurfl_store/filter.rb
|
65
|
+
- lib/wurfl_store/cache_initializer.rb
|
66
|
+
has_rdoc: true
|
67
|
+
homepage: http://mobithought.com/
|
68
|
+
licenses: []
|
69
|
+
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
requirements: []
|
90
|
+
|
91
|
+
rubyforge_project: wurfl_store
|
92
|
+
rubygems_version: 1.3.6
|
93
|
+
signing_key:
|
94
|
+
specification_version: 3
|
95
|
+
summary: Wurfl Redis Store
|
96
|
+
test_files: []
|
97
|
+
|