wurfl_client 0.4.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 ADDED
@@ -0,0 +1,3 @@
1
+ run
2
+ pkg
3
+ rdoc
data/README ADDED
@@ -0,0 +1,98 @@
1
+ = WURFL Client
2
+
3
+ WURFL Client is a library to do WURFL (http://wurfl.sourceforge.net/) mobile device detection for web applications.
4
+ Included are tools to keep the WURFL file up to date automatically and to prepare a customized lookup tables, which
5
+ allow a fast device detection.
6
+
7
+ == Mode of Operation
8
+ The complete WURFL file is as big as ~16MB. A single device detection against it in Ruby took me 12 seconds, which is
9
+ inaceptable even for the first request of any client.
10
+
11
+ There are three optimizations to make the detection work faster:
12
+ 1.) The WURFL file is customized to remove unused capabilities, reducing it's size considerably.
13
+ 2.) Client devices are roughly detected by type (e.g. iPhone like, Nokia devices, etc.)
14
+ 3.) The WURFL Client works with previously prepared lookup tables for the roughly detected device types
15
+ in a Ruby PStore data structure, so Ruby doesn't have to parse XML files on each request.
16
+
17
+ The lookup tables are prepared during the WURFL update task, which takes quite some time. But this allows for a
18
+ very fast and for our appliances also accurate recognition.
19
+
20
+ The WURFL Client can then be implemented f.i. as a thin Rack service, see Examples.
21
+
22
+
23
+ == Requirements
24
+
25
+ Ruby 1.9: (.ord!) -> http://gist.github.com/251465
26
+ wurfl gem (http://github.com/pwim/wurfl): Handset, UserAgentMatcher, WURFL Loader
27
+
28
+ == Installation
29
+
30
+ sudo gem install wurfl_client
31
+
32
+ == Setup
33
+
34
+ To setup the environment, you have to execute following steps:
35
+ 1.) download and extract the latest WURFL file
36
+ * curl -L -o wurfl-latest.xml.gz
37
+ * gunzip wurfl-latest.xml.gz
38
+
39
+ 2.) minimize the WURFL XML file. You can adapt wurfl_minimize.yml to your needs, see http://wurfl.sourceforge.net/help_doc.php for a list of available capabilities)
40
+ * wurfl_minimize.rb
41
+
42
+ 3.) prepare the lookup tables (builds them into ./lookup directory by default). This will take some time!
43
+ * lookup_prepare.rb
44
+
45
+ Now, you are ready for device detection. If you make an automated script to do this update regularly, you must not forget to clear the lookup directory first.
46
+ The preparation script doesn't overwrite files. For minimal effect on your running webservice, you should use another lookup directory there and copy the
47
+ new data after the update is complete.
48
+
49
+ Here is an example automatic update script:
50
+ * #!/bin/sh
51
+ * curl -L -o wurfl-latest.xml.gz
52
+ * gunzip wurfl-latest.xml.gz
53
+ * wurfl_minimize.rb
54
+ * rm lookup/*
55
+ * lookup_prepare.rb
56
+ * cp lookup/* /path/to/production/lookup
57
+
58
+ == Examples
59
+
60
+ TODO: simple detection example
61
+ TODO: rack application
62
+
63
+ == Authors
64
+
65
+ * Guido Pinkas (Original Author)
66
+
67
+ == Thanks
68
+
69
+ Thanks to S. Kamerman from TERA-WURFL (http://www.tera-wurfl.com/) for his WURFL Customizer (http://www.tera-wurfl.com/wiki/index.php/WURFL_Customizer).
70
+ I only had to port the functionality to ruby.
71
+
72
+ == Contribution
73
+
74
+ Contribution is welcome. Please use the github tools (fork, pull request, etc) here on http://github.com/bluecat76/wurfl_client.
75
+
76
+ == License
77
+
78
+ The MIT License
79
+
80
+ Copyright (c) 2010 Binder Trittenwein Kommunikation GmbH (http://www.bindertrittenwein.com/)
81
+
82
+ Permission is hereby granted, free of charge, to any person obtaining a copy
83
+ of this software and associated documentation files (the "Software"), to deal
84
+ in the Software without restriction, including without limitation the rights
85
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
86
+ copies of the Software, and to permit persons to whom the Software is
87
+ furnished to do so, subject to the following conditions:
88
+
89
+ The above copyright notice and this permission notice shall be included in
90
+ all copies or substantial portions of the Software.
91
+
92
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
93
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
94
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
95
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
96
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
97
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
98
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'rake/rdoctask'
2
+ require 'rake/testtask'
3
+ require 'shoulda/tasks'
4
+
5
+ task :default => ['test']
6
+
7
+ Rake::TestTask.new(:test) do |t|
8
+ t.test_files = FileList['test/*_test.rb']
9
+ end
10
+
11
+ begin
12
+ require 'jeweler'
13
+ Jeweler::Tasks.new do |gemspec|
14
+ gemspec.name = "wurfl_client"
15
+ gemspec.summary = "Fast WURFL mobile device detection"
16
+ gemspec.description = "WURFL Client is a library to do WURFL (http://wurfl.sourceforge.net/) mobile device detection for web applications. Included are tools to keep the WURFL file up to date automatically and to prepare a customized lookup tables, which allow a fast device detection."
17
+ gemspec.email = "guido.pinkas@bindertrittenwein.com"
18
+ gemspec.homepage = "http://github.com/bluecat76/wurfl_client"
19
+ gemspec.authors = ["Guido Pinkas"]
20
+ gemspec.add_dependency 'wurfl'
21
+ end
22
+ Jeweler::GemcutterTasks.new
23
+ rescue LoadError
24
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
25
+ end
26
+
27
+ Rake::RDocTask.new(:rdoc) do |rdoc|
28
+ rdoc.rdoc_dir = 'rdoc'
29
+ rdoc.title = 'WURFL Client'
30
+ rdoc.main = "README"
31
+ rdoc.rdoc_files.include("README", "lib/**/*.rb")
32
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.4.0
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # use this program to generate lookup tables from the input WURFL XML file
4
+
5
+ require "wurfl_client/lookup_preparer"
6
+ require "yaml"
7
+
8
+ def load_configuration(file_path)
9
+ begin
10
+ config = YAML::load_file(file_path)
11
+ rescue
12
+ nil
13
+ end
14
+ end
15
+
16
+ preparer = WurflClient::LookupPreparer.new load_configuration('prepare_lookup.yml')
17
+ preparer.prepareLookupTables
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env ruby
2
+ require "xml"
3
+ require "yaml"
4
+
5
+ # use this program to minimize the WURFL XML file, so it contains only capabilities you need.
6
+ # This can reduce the lookup store size considerably!
7
+
8
+ default_config = {
9
+ 'input_file' => 'wurfl-test.xml',
10
+ 'output_file' => 'wurfl-default.xml',
11
+ 'capabilities' => ['brand_name', 'model_name', 'max_image_width', 'max_image_height', 'wta_voice_call']
12
+ }
13
+
14
+ def load_configuration(file_path)
15
+ begin
16
+ config = YAML::load_file(file_path)
17
+ rescue
18
+ nil
19
+ end
20
+ end
21
+
22
+ def minimize_wurfl(configuration)
23
+ # open input file
24
+ doc = XML::Document.file(configuration['input_file'])
25
+
26
+ # prepare output file
27
+ out = XML::Document.new()
28
+ out.root = XML::Node.new('wurfl')
29
+ out.root << XML::Node.new('devices')
30
+ devices_node = out.root.first
31
+
32
+ # go through devices list
33
+ doc.find("///devices/device").each do |element|
34
+ wurfl_id = element.attributes["id"]
35
+ user_agent = element.attributes["user_agent"]
36
+
37
+ # copy node to output
38
+ new_node = XML::Node.new('device')
39
+ element.each_attr do |attr|
40
+ new_node.attributes[attr.name] = attr.value
41
+ end
42
+
43
+ element.each do |group|
44
+ new_group = XML::Node.new('group')
45
+ # check capabilities
46
+ group.each do |cap|
47
+ if configuration['capabilities'].include? cap.attributes["name"]
48
+ # add capability
49
+ new_cap = XML::Node.new('capability')
50
+ cap.each_attr { |cap_attr| new_cap.attributes[cap_attr.name] = cap_attr.value }
51
+ new_group << new_cap
52
+ end
53
+ end
54
+ # copy group if not empty
55
+ if new_group.children?
56
+ new_node << new_group
57
+ end
58
+ end
59
+
60
+ # add node to output document
61
+ devices_node << new_node
62
+ end
63
+
64
+ # save ouput file
65
+ out.save(configuration['output_file'], :indent => true, :encoding => XML::Encoding::UTF_8)
66
+ end
67
+
68
+ config = load_configuration('wurfl_minimize.yml') || default_config
69
+ minimize_wurfl(config)
@@ -0,0 +1,31 @@
1
+ module WurflClient
2
+
3
+ # DeviceProfile stores "device context" information (desktop or mobile)
4
+ # and the "lookup prefix" used to find the correct lookup file
5
+ class DeviceProfile
6
+ attr_reader :context
7
+ attr_reader :lookup_prefix
8
+
9
+ def initialize(context, lookup_prefix)
10
+ @context = context # like "desktop, mobile, iphone, etc"
11
+ @lookup_prefix = lookup_prefix
12
+ end
13
+
14
+ def self.mobile(lookup_prefix)
15
+ DeviceProfile.new(:mobile, lookup_prefix)
16
+ end
17
+
18
+ def self.desktop
19
+ DeviceProfile.new(:desktop, nil)
20
+ end
21
+
22
+ def mobile?
23
+ @context != :desktop
24
+ end
25
+
26
+ def desktop?
27
+ @context == :desktop
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,27 @@
1
+ require "wurfl_client/device_profile"
2
+ require "wurfl/handset"
3
+ require "pstore"
4
+
5
+ module WurflClient
6
+
7
+ # This class is used to generate paths to the lookup files
8
+ class LookupHelper
9
+ def self.encodeFilename(str)
10
+ str.gsub(/[^a-zA-Z0-9_\.\-]/n) {|s| sprintf('%%%02x', s[0].ord) }
11
+ end
12
+
13
+ def initialize(lookup_base_path)
14
+ @lookup_base_path = lookup_base_path
15
+ end
16
+
17
+ def getStoreFilePath(lookup_prefix)
18
+ File.join(@lookup_base_path, LookupHelper.encodeFilename(lookup_prefix) + '.pstore')
19
+ end
20
+
21
+ def loadLookupTable(profile)
22
+ store_filename = getStoreFilePath(profile.lookup_prefix)
23
+ PStore.new(store_filename).transaction {|ps| ps["handsets"]}
24
+ end
25
+ end
26
+
27
+ end
@@ -0,0 +1,54 @@
1
+ require "wurfl/loader"
2
+ require "wurfl_client/lookup_helper.rb"
3
+ require "wurfl_client/ua_device_detector.rb"
4
+ require "pstore"
5
+
6
+ module WurflClient
7
+
8
+ # This class is used to prepare lookup tables for fast device recognition.
9
+ # The information is collected from the given WURFL XML file
10
+ class LookupPreparer
11
+
12
+ def initialize(set_config)
13
+ config = set_config || {}
14
+ @wurfl_path = config['wurfl_path'] || 'wurfl-custom.xml'
15
+ @lookup_base_path = config['lookup_base_path'] || 'lookup/'
16
+
17
+ @helper = LookupHelper.new(@lookup_base_path)
18
+ end
19
+
20
+ def prepareLookupTables
21
+ @handsets = Wurfl::Loader.new.load_wurfl(@wurfl_path)
22
+ @handsets.each do |wurfl_id, handset|
23
+ target = UserAgentDeviceDetector.detect(handset.user_agent)
24
+ if target.lookup_prefix && !(target.lookup_prefix =~ /DO_NOT_MATCH/)
25
+ saveLookupTable target
26
+ else
27
+ puts "IGNORING UA: #{handset.user_agent}"
28
+ end
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def saveLookupTable(profile)
35
+ store_filename = @helper.getStoreFilePath(profile.lookup_prefix)
36
+ return if File.exists?(store_filename)
37
+
38
+ puts "building store: #{store_filename}"
39
+
40
+ # load similar user agent strings
41
+ lookup_table = {}
42
+ @handsets.each do |wurfl_id, handset|
43
+ target = UserAgentDeviceDetector.detect(handset.user_agent)
44
+ if target.lookup_prefix==profile.lookup_prefix
45
+ lookup_table[wurfl_id] ||= handset
46
+ end
47
+ end
48
+
49
+ # save as pstore
50
+ PStore.new(store_filename).transaction {|ps| ps["handsets"] = lookup_table}
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,65 @@
1
+ require "wurfl_client/device_profile"
2
+
3
+ module WurflClient
4
+
5
+ # This class is used to determine a rough device profile from the given UserAgent string
6
+ class UserAgentDeviceDetector
7
+
8
+ def self.detect(ua_string)
9
+ detectIphone(ua_string) || detectOtherMozilla(ua_string) || detectGeneric(ua_string) || DeviceProfile.new(:desktop)
10
+ end
11
+
12
+ private
13
+
14
+ def self.detectIphone(ua_string)
15
+ case ua_string
16
+ when /iPod/
17
+ return DeviceProfile.new('iphone', 'iphone_ipod')
18
+ when /iPhone/
19
+ os_ver = ua_string[/OS ([0-9_]+)/]
20
+ prefix = 'iphone'
21
+ prefix += "_#{os_ver[$1]}" if os_ver
22
+ return DeviceProfile.new('iphone', prefix)
23
+ end
24
+ end
25
+
26
+ def self.detectOtherMozilla(ua_string)
27
+ if ua_string =~ /^Mozilla/
28
+ case ua_string
29
+ when /Nokia/
30
+ os_ver = ua_string[/Nokia([a-zA-Z0-9\-\.]+)/]
31
+ prefix = 'mozilla_nokia'
32
+ prefix += "_#{os_ver[$1]}" if os_ver
33
+ return DeviceProfile.mobile(prefix)
34
+ when /Windows CE/
35
+ os_ver = ua_string[/Windows CE; ([a-zA-Z0-9 \.]+)/]
36
+ prefix = 'mozilla_wince'
37
+ prefix += "_#{os_ver[$1]}" if os_ver
38
+ return DeviceProfile.mobile(prefix)
39
+ when /Symbian ?OS/
40
+ return DeviceProfile.mobile('mozilla_symbian')
41
+ when /PalmOS/
42
+ return DeviceProfile.mobile('mozilla_palm')
43
+ when /Motorola/
44
+ return DeviceProfile.mobile('mozilla_motorola')
45
+ when /MIDP-[0-9\.]/
46
+ prefix = 'mozilla_' + ua_string[/MIDP-[0-9\.]+/]
47
+ return DeviceProfile.mobile(prefix)
48
+ when /phone/i
49
+ return DeviceProfile.mobile('mozilla_phone')
50
+ when /mobile/i
51
+ return DeviceProfile.mobile('mozilla_mobile')
52
+ else # other mozilla is considered desktop
53
+ return DeviceProfile.desktop
54
+ end
55
+ end
56
+ end
57
+
58
+ def self.detectGeneric(ua_string)
59
+ # TODO: detect desktop vs. mobile here!
60
+ return DeviceProfile.mobile(ua_string[/^[0-9a-zA-z_\.\-]+/])
61
+ end
62
+
63
+ end
64
+
65
+ end
@@ -0,0 +1,30 @@
1
+ require "wurfl_client/ua_device_detector"
2
+ require "wurfl_client/lookup_helper"
3
+ require "wurfl/user_agent_matcher"
4
+
5
+ module WurflClient
6
+ @@lookup_base_path = 'lookup/'
7
+
8
+ # change the path to the previously generated lookup files
9
+ def self.setLookupBasePath(lookup_base_path)
10
+ @@lookup_base_path = lookup_base_path
11
+ end
12
+
13
+ # main function to detect devices
14
+ def self.detectMobileDevice(user_agent)
15
+ profile = UserAgentDeviceDetector.detect(user_agent)
16
+ if profile.mobile?
17
+ # load prepared handset list
18
+ lookup = LookupHelper.new(@@lookup_base_path)
19
+ handsets = lookup.loadLookupTable(profile)
20
+
21
+ if handsets
22
+ # TODO: load complete table as fallback!
23
+ uam = Wurfl::UserAgentMatcher.new(handsets)
24
+
25
+ # return first matching entry
26
+ uam.match_handsets(user_agent).flatten.first
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'test/unit'
3
+ require 'wurfl_client/device_profile'
4
+
5
+ class DeviceProfileTest < Test::Unit::TestCase
6
+ def setup
7
+ @mobile_prefix = 'test_mobile'
8
+ end
9
+
10
+ def test_create_mobile
11
+ dp = WurflClient::DeviceProfile.mobile(@mobile_prefix)
12
+ assert_equal dp.mobile?, true
13
+ assert_equal dp.desktop?, false
14
+ assert_equal dp.lookup_prefix, @mobile_prefix
15
+ end
16
+
17
+ def test_create_desktop
18
+ dp = WurflClient::DeviceProfile.desktop
19
+ assert_equal dp.desktop?, true
20
+ assert_equal dp.mobile?, false
21
+ assert_equal dp.lookup_prefix, nil
22
+ end
23
+
24
+ def test_initialite
25
+ dp = WurflClient::DeviceProfile.new(:mobile, @mobile_prefix)
26
+ assert_equal dp.mobile?, true
27
+ assert_equal dp.desktop?, false
28
+ assert_equal dp.lookup_prefix, @mobile_prefix
29
+ end
30
+ end
@@ -0,0 +1,28 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'test/unit'
3
+ require 'wurfl_client/lookup_helper'
4
+
5
+ class LookupHelperTest < Test::Unit::TestCase
6
+ def setup
7
+ end
8
+
9
+ def test_encode_filename
10
+ s = WurflClient::LookupHelper.encodeFilename("br#l'@*ig$^/?!--and+zurg")
11
+ assert_match /[a-z0-9\_\-\.]+/i, s
12
+ s = WurflClient::LookupHelper.encodeFilename("simpletest09-10.20")
13
+ assert_equal "simpletest09-10.20", s
14
+ end
15
+
16
+ def test_get_path
17
+ lh = WurflClient::LookupHelper.new("path/")
18
+ assert_match /^path\/.*test.*$/, lh.getStoreFilePath("test")
19
+ end
20
+
21
+ def test_load_table
22
+ lh = WurflClient::LookupHelper.new(File.join(File.dirname(__FILE__), 'data'))
23
+ p = WurflClient::DeviceProfile.mobile("iphone")
24
+ handsets = lh.loadLookupTable(p)
25
+ assert_instance_of Hash, handsets
26
+ assert_instance_of Wurfl::Handset, handsets.first[1]
27
+ end
28
+ end
@@ -0,0 +1,38 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'test/unit'
3
+ require 'wurfl_client/ua_device_detector'
4
+
5
+ class UserAgentDeviceDetectorTest < Test::Unit::TestCase
6
+ def setup
7
+ end
8
+
9
+ def test_functionality
10
+ dp = WurflClient::UserAgentDeviceDetector.detect ""
11
+ assert_instance_of WurflClient::DeviceProfile, dp
12
+ end
13
+
14
+ def test_desktop
15
+ dp = WurflClient::UserAgentDeviceDetector.detect "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10"
16
+ assert_equal true, dp.desktop?
17
+ dp = WurflClient::UserAgentDeviceDetector.detect "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
18
+ assert_equal true, dp.desktop?
19
+ dp = WurflClient::UserAgentDeviceDetector.detect "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-us) AppleWebKit/533.18.1 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5"
20
+ assert_equal true, dp.desktop?
21
+ end
22
+
23
+ def test_mobile
24
+ dp = WurflClient::UserAgentDeviceDetector.detect "SAMSUNG-GT-S5230/S5230MMIG2 SHP/VPP/R5 Jasmine/0.8 Nextreaming SMM-MMS/1.2.0 profile/MIDP-2.1 configuration/CLDC-1.1"
25
+ assert_equal true, dp.mobile?
26
+ dp = WurflClient::UserAgentDeviceDetector.detect "BlackBerry8320/4.2.2 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/100"
27
+ assert_equal true, dp.mobile?
28
+ dp = WurflClient::UserAgentDeviceDetector.detect "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16"
29
+ assert_equal true, dp.mobile?
30
+ dp = WurflClient::UserAgentDeviceDetector.detect "Mozilla/5.0 (Linux; U; Android 1.6; de-at; T-Mobile G1 Build/DRC92) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1"
31
+ assert_equal true, dp.mobile?
32
+ dp = WurflClient::UserAgentDeviceDetector.detect "SonyEricssonK550i/R1JD Browser/NetFront/3.3 Profile/MIDP-2.0 Configuration/CLDC-1.1"
33
+ assert_equal true, dp.mobile?
34
+ dp = WurflClient::UserAgentDeviceDetector.detect "Nokia6230i/2.0 (03.80) Profile/MIDP-2.0 Configuration/CLDC-1.1"
35
+ assert_equal true, dp.mobile?
36
+ end
37
+
38
+ end
@@ -0,0 +1,16 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'test/unit'
3
+ require 'wurfl_client/wurfl_client'
4
+
5
+ class WurflClientTest < Test::Unit::TestCase
6
+ def setup
7
+ end
8
+
9
+ def test_functionality
10
+ user_agent = 'Mozilla/5.0 (iPhone; U; CPU iPhone like Mac OS X; en-us)'
11
+ WurflClient::setLookupBasePath(File.join(File.dirname(__FILE__), 'data'))
12
+ device = WurflClient::detectMobileDevice(user_agent)
13
+ assert_instance_of Wurfl::Handset, device
14
+ assert_equal 'iPhone', device['model_name']
15
+ end
16
+ end
@@ -0,0 +1,59 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{wurfl_client}
8
+ s.version = "0.4.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Guido Pinkas"]
12
+ s.date = %q{2010-09-27}
13
+ s.description = %q{WURFL Client is a library to do WURFL (http://wurfl.sourceforge.net/) mobile device detection for web applications. Included are tools to keep the WURFL file up to date automatically and to prepare a customized lookup tables, which allow a fast device detection.}
14
+ s.email = %q{guido.pinkas@bindertrittenwein.com}
15
+ s.executables = ["prepare_lookup.rb", "wurfl_minimize.rb"]
16
+ s.extra_rdoc_files = [
17
+ "README"
18
+ ]
19
+ s.files = [
20
+ ".gitignore",
21
+ "README",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "bin/prepare_lookup.rb",
25
+ "bin/wurfl_minimize.rb",
26
+ "lib/wurfl_client/device_profile.rb",
27
+ "lib/wurfl_client/lookup_helper.rb",
28
+ "lib/wurfl_client/lookup_preparer.rb",
29
+ "lib/wurfl_client/ua_device_detector.rb",
30
+ "lib/wurfl_client/wurfl_client.rb",
31
+ "test/device_profile_test.rb",
32
+ "wurfl_client.gemspec"
33
+ ]
34
+ s.homepage = %q{http://github.com/bluecat76/wurfl_client}
35
+ s.rdoc_options = ["--charset=UTF-8"]
36
+ s.require_paths = ["lib"]
37
+ s.rubygems_version = %q{1.3.7}
38
+ s.summary = %q{Fast WURFL mobile device detection}
39
+ s.test_files = [
40
+ "test/lookup_helper_test.rb",
41
+ "test/device_profile_test.rb",
42
+ "test/wurfl_client_test.rb",
43
+ "test/ua_device_detector_test.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_runtime_dependency(%q<wurfl>, [">= 0"])
52
+ else
53
+ s.add_dependency(%q<wurfl>, [">= 0"])
54
+ end
55
+ else
56
+ s.add_dependency(%q<wurfl>, [">= 0"])
57
+ end
58
+ end
59
+
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wurfl_client
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 4
8
+ - 0
9
+ version: 0.4.0
10
+ platform: ruby
11
+ authors:
12
+ - Guido Pinkas
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-09-27 00:00:00 +02:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: wurfl
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ description: WURFL Client is a library to do WURFL (http://wurfl.sourceforge.net/) mobile device detection for web applications. Included are tools to keep the WURFL file up to date automatically and to prepare a customized lookup tables, which allow a fast device detection.
34
+ email: guido.pinkas@bindertrittenwein.com
35
+ executables:
36
+ - prepare_lookup.rb
37
+ - wurfl_minimize.rb
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - README
42
+ files:
43
+ - .gitignore
44
+ - README
45
+ - Rakefile
46
+ - VERSION
47
+ - bin/prepare_lookup.rb
48
+ - bin/wurfl_minimize.rb
49
+ - lib/wurfl_client/device_profile.rb
50
+ - lib/wurfl_client/lookup_helper.rb
51
+ - lib/wurfl_client/lookup_preparer.rb
52
+ - lib/wurfl_client/ua_device_detector.rb
53
+ - lib/wurfl_client/wurfl_client.rb
54
+ - test/device_profile_test.rb
55
+ - wurfl_client.gemspec
56
+ - test/lookup_helper_test.rb
57
+ - test/wurfl_client_test.rb
58
+ - test/ua_device_detector_test.rb
59
+ has_rdoc: true
60
+ homepage: http://github.com/bluecat76/wurfl_client
61
+ licenses: []
62
+
63
+ post_install_message:
64
+ rdoc_options:
65
+ - --charset=UTF-8
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ segments:
74
+ - 0
75
+ version: "0"
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ segments:
82
+ - 0
83
+ version: "0"
84
+ requirements: []
85
+
86
+ rubyforge_project:
87
+ rubygems_version: 1.3.7
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Fast WURFL mobile device detection
91
+ test_files:
92
+ - test/lookup_helper_test.rb
93
+ - test/device_profile_test.rb
94
+ - test/wurfl_client_test.rb
95
+ - test/ua_device_detector_test.rb