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.
@@ -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
@@ -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
@@ -0,0 +1,4 @@
1
+ require 'wurfl_store'
2
+ ActionController::Base.send(:include, WurflStore::Filter)
3
+ ActionView::Base.send(:include, WurflStore::View)
4
+ WurflStore.init
@@ -0,0 +1,6 @@
1
+ # Create necessary directory for wurfl.xml/pstore if it doesn't already exist.
2
+ puts 'Creating wurfl directory at' + Rails.root.join('tmp', 'wurfl')
3
+ FileUtils.mkdir_p(Rails.root.join('tmp', 'wurfl'))
4
+
5
+ FileUtils.cd(Rails.root)
6
+ 'rake wurfl:update'
@@ -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
@@ -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
@@ -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
+