wurfl_store 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+