uagent_rack 0.0.1
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 +5 -0
- data/README.rdoc +98 -0
- data/VERSION +1 -0
- data/lib/uagent_rack.rb +20 -0
- data/rakefile +53 -0
- data/test/uagent_rack_test.rb +72 -0
- metadata +94 -0
data/README.rdoc
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
= uagent_rack
|
2
|
+
|
3
|
+
== Install
|
4
|
+
|
5
|
+
gem install uagent_rack
|
6
|
+
|
7
|
+
== Usage
|
8
|
+
|
9
|
+
Helps you to deal with user agents on top of rack. When a browser
|
10
|
+
sends a request to your web application the request has an
|
11
|
+
HTTP_USER_AGENT attribute that identifies the device an browser. For
|
12
|
+
example, the next string identifies an particular model of iPhone,
|
13
|
+
that uses an specific mobile version for Safari.
|
14
|
+
|
15
|
+
Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us)
|
16
|
+
AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11
|
17
|
+
Safari/528.16
|
18
|
+
|
19
|
+
Each mobile phone model will send you a particular user agent string,
|
20
|
+
thus is a good idea classify the devices in groups an develop a
|
21
|
+
specific interface for each group. For each group we define a key, so
|
22
|
+
the user agent parser receive the user agent string and returns that
|
23
|
+
key. For example, the answer for the string above could be :mobile or
|
24
|
+
:iphone, depending on the parser configuration. To known how to
|
25
|
+
configure the parser read the
|
26
|
+
uagent[http://http://github.com/danielhz/uagent] documentation.
|
27
|
+
|
28
|
+
This gem adds the RackParse class to the UAgent module, that extends
|
29
|
+
the Parser class. Unlike Parser, that analyzes the HTTP_USER_AGENT
|
30
|
+
variable every time, uagent_rack parse the user_agent only the first
|
31
|
+
time and store it in the session. Thus, the following requests will be
|
32
|
+
answered using the data in the session. Also, an user can change the
|
33
|
+
user agent adding a value for the parameter +user_agent+ in the URI
|
34
|
+
query.
|
35
|
+
|
36
|
+
=== Code example
|
37
|
+
|
38
|
+
require 'rubygmes'
|
39
|
+
require 'uagent_rack'
|
40
|
+
|
41
|
+
parser = UAgent::Parser.new
|
42
|
+
|
43
|
+
# We create an environment with a mobile user agent.
|
44
|
+
|
45
|
+
env1 = {
|
46
|
+
...
|
47
|
+
"HTTP_USER_AGENT" => "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_1_2 like Mac OS X; en-us) " +
|
48
|
+
"AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7D11 Safari/528.16",
|
49
|
+
...
|
50
|
+
}
|
51
|
+
|
52
|
+
parser.call(env1) # gets :mobile
|
53
|
+
|
54
|
+
# We create another that changes the user agent
|
55
|
+
|
56
|
+
env2 = {
|
57
|
+
...
|
58
|
+
"QUERY_STRING" => "user_agent=dektop",
|
59
|
+
"REQUEST_URI" => "/index?user_agent=desktop",
|
60
|
+
...
|
61
|
+
})
|
62
|
+
|
63
|
+
parser.call(env2) # gets :dektop
|
64
|
+
parser.call(env1) # gets :dektop
|
65
|
+
|
66
|
+
== Install from code
|
67
|
+
|
68
|
+
First you need uagent
|
69
|
+
|
70
|
+
$ gem install uagent
|
71
|
+
|
72
|
+
Then download the code from the repository:
|
73
|
+
|
74
|
+
$ git clone git@github.com:danielhz/uagent_rack.git
|
75
|
+
|
76
|
+
This project uses jeweler to build the gem, so you can use this commands:
|
77
|
+
|
78
|
+
$ rake build # to build the gem
|
79
|
+
$ rake install # to build and install the gem in one step
|
80
|
+
|
81
|
+
Also, if you want test the gem you can use the spec task:
|
82
|
+
|
83
|
+
$ rake spec
|
84
|
+
|
85
|
+
This project uses rcov so you can check the coverage opening the HTML
|
86
|
+
file in the coverage directory after running the spec.
|
87
|
+
|
88
|
+
== Other Stuff
|
89
|
+
|
90
|
+
Author:: Daniel Hernández, daniel@degu.cl
|
91
|
+
License:: GPL V3
|
92
|
+
|
93
|
+
== Warranty
|
94
|
+
|
95
|
+
This software is provided "as is" and without any express or implied
|
96
|
+
warranties, including, without limitation, the implied warranties of
|
97
|
+
merchantability and fitness for a particular purpose.
|
98
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/uagent_rack.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'uagent'
|
4
|
+
require 'rack'
|
5
|
+
|
6
|
+
module UAgent
|
7
|
+
|
8
|
+
class RackParser < Parser
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
req = Rack::Request.new(env)
|
12
|
+
unless req.params['user_agent'].nil?
|
13
|
+
req.session[:user_agent] = req.params['user_agent'].to_sym
|
14
|
+
end
|
15
|
+
req.session[:user_agent] || super(env)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
data/rakefile
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
|
6
|
+
desc 'Default: run rspec tests.'
|
7
|
+
task :default => :spec
|
8
|
+
|
9
|
+
desc 'Run all tests'
|
10
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
11
|
+
t.spec_files = Dir.glob('test/*_test.rb')
|
12
|
+
t.spec_opts << '--format specdoc'
|
13
|
+
t.rcov = true
|
14
|
+
end
|
15
|
+
|
16
|
+
begin
|
17
|
+
require 'jeweler'
|
18
|
+
Jeweler::Tasks.new do |gemspec|
|
19
|
+
gemspec.name = "uagent_rack"
|
20
|
+
gemspec.authors = ["Daniel Hernández"]
|
21
|
+
gemspec.email = "daniel@degu.cl"
|
22
|
+
gemspec.homepage = "http://github.com/danielhz/uagent_rack"
|
23
|
+
gemspec.summary = "Helps you to deal with user agents on top of rack"
|
24
|
+
gemspec.rubyforge_project = "uagent_rack"
|
25
|
+
gemspec.description = "Helps you to deal with user agents on top of rack"
|
26
|
+
gemspec.add_dependency('uagent', '>= 0.0.3')
|
27
|
+
gemspec.add_dependency('rack', '>= 0.9.1')
|
28
|
+
end
|
29
|
+
rescue LoadError
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'darkfish-rdoc'
|
34
|
+
DARKFISH_ENABLED = true
|
35
|
+
rescue LoadError => ex
|
36
|
+
DARKFISH_ENABLED = false
|
37
|
+
end
|
38
|
+
|
39
|
+
BASE_RDOC_OPTIONS = [
|
40
|
+
'--line-numbers', '--inline-source',
|
41
|
+
'--main' , 'README.rdoc',
|
42
|
+
'--title', 'uagent'
|
43
|
+
]
|
44
|
+
|
45
|
+
rd = Rake::RDocTask.new do |rdoc|
|
46
|
+
rdoc.rdoc_dir = 'html'
|
47
|
+
rdoc.title = "uagent_rack"
|
48
|
+
rdoc.options = BASE_RDOC_OPTIONS.dup
|
49
|
+
rdoc.options << '-SHN' << '-f' << 'darkfish' if DARKFISH_ENABLED
|
50
|
+
rdoc.options << '--charset' << 'utf-8'
|
51
|
+
rdoc.rdoc_files.include('README.rdoc')
|
52
|
+
rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc')
|
53
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Rspec tests
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'uagent_rack'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
describe 'UAgent::RackParser' do
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
@env = {
|
11
|
+
"SERVER_NAME" => "localhost",
|
12
|
+
"HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
|
13
|
+
"HTTP_HOST" => "localhost:3001",
|
14
|
+
"rack.session" => {},
|
15
|
+
"HTTP_KEEP_ALIVE" => "115",
|
16
|
+
"HTTP_USER_AGENT" => "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10",
|
17
|
+
"REQUEST_PATH" => "/index",
|
18
|
+
"rack.url_scheme"=>"http",
|
19
|
+
"rack.request.cookie_hash" => {"rack.session"=>"cab867c36b7fc7385f5716cc5c793ac7"},
|
20
|
+
"SERVER_PROTOCOL" => "HTTP/1.1",
|
21
|
+
"HTTP_ACCEPT_LANGUAGE" => "en-us,en;q=0.5",
|
22
|
+
"rack.errors" => IO.new(0),
|
23
|
+
"REMOTE_ADDR" => "127.0.0.1",
|
24
|
+
"PATH_INFO" => "/index",
|
25
|
+
"SERVER_SOFTWARE" => "Mongrel 1.1.5",
|
26
|
+
"rack.run_once" => false,
|
27
|
+
"rack.version" => [1, 1],
|
28
|
+
"SCRIPT_NAME" => "",
|
29
|
+
"rack.request.cookie_string" => "rack.session=cab867c36b7fc7385f5716cc5c793ac7",
|
30
|
+
"HTTP_COOKIE" => "rack.session=cab867c36b7fc7385f5716cc5c793ac7",
|
31
|
+
"HTTP_VERSION" => "HTTP/1.1",
|
32
|
+
"rack.multithread" => true,
|
33
|
+
"REQUEST_URI" => "/index",
|
34
|
+
"rack.multiprocess" => false,
|
35
|
+
"SERVER_PORT" => "3001",
|
36
|
+
"HTTP_ACCEPT_CHARSET" => "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
|
37
|
+
"REQUEST_METHOD" => "GET",
|
38
|
+
"rack.session.options" => {
|
39
|
+
:domain => nil,
|
40
|
+
:expire_after => 2592000,
|
41
|
+
:defer => false,
|
42
|
+
:sidbits => 128,
|
43
|
+
:secure => false,
|
44
|
+
:key => "rack.session",
|
45
|
+
:httponly => true,
|
46
|
+
:renew => false,
|
47
|
+
:id => "cab867c36b7fc7385f5716cc5c793ac7",
|
48
|
+
:path => "/",
|
49
|
+
:drop => false
|
50
|
+
},
|
51
|
+
"GATEWAY_INTERFACE" => "CGI/1.2",
|
52
|
+
"HTTP_CONNECTION" => "keep-alive",
|
53
|
+
"HTTP_ACCEPT_ENCODING" => "gzip,deflate",
|
54
|
+
"QUERY_STRING" => "",
|
55
|
+
"rack.input" => StringIO.new
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'get the user agent' do
|
60
|
+
parser = UAgent::RackParser.new()
|
61
|
+
env = @env.clone
|
62
|
+
parser.call(env).should == :desktop
|
63
|
+
env.merge!({
|
64
|
+
"QUERY_STRING" => "user_agent=mobile",
|
65
|
+
"REQUEST_URI" => "/index?user_agent=mobile",
|
66
|
+
})
|
67
|
+
parser.call(env).should == :mobile
|
68
|
+
env = @env.clone
|
69
|
+
parser.call(env).should == :mobile
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: uagent_rack
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- "Daniel Hern\xC3\xA1ndez"
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-09-25 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: uagent
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 0
|
30
|
+
- 3
|
31
|
+
version: 0.0.3
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rack
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 9
|
44
|
+
- 1
|
45
|
+
version: 0.9.1
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
description: Helps you to deal with user agents on top of rack
|
49
|
+
email: daniel@degu.cl
|
50
|
+
executables: []
|
51
|
+
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files:
|
55
|
+
- README.rdoc
|
56
|
+
files:
|
57
|
+
- .gitignore
|
58
|
+
- README.rdoc
|
59
|
+
- VERSION
|
60
|
+
- lib/uagent_rack.rb
|
61
|
+
- rakefile
|
62
|
+
- test/uagent_rack_test.rb
|
63
|
+
has_rdoc: true
|
64
|
+
homepage: http://github.com/danielhz/uagent_rack
|
65
|
+
licenses: []
|
66
|
+
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options:
|
69
|
+
- --charset=UTF-8
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
version: "0"
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project: uagent_rack
|
89
|
+
rubygems_version: 1.3.6
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Helps you to deal with user agents on top of rack
|
93
|
+
test_files:
|
94
|
+
- test/uagent_rack_test.rb
|