rack-locale_chooser 0.0.7

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
+ pkg/*
2
+ *.gem
3
+ .bundle
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in rack-locale_chooser.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,32 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-locale_chooser (0.0.4)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.1.2)
10
+ i18n (0.4.2)
11
+ rack (1.1.0)
12
+ rack-test (0.5.4)
13
+ rack (>= 1.0)
14
+ rspec (2.0.1)
15
+ rspec-core (~> 2.0.1)
16
+ rspec-expectations (~> 2.0.1)
17
+ rspec-mocks (~> 2.0.1)
18
+ rspec-core (2.0.1)
19
+ rspec-expectations (2.0.1)
20
+ diff-lcs (>= 1.1.2)
21
+ rspec-mocks (2.0.1)
22
+ rspec-core (~> 2.0.1)
23
+ rspec-expectations (~> 2.0.1)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ i18n
30
+ rack-locale_chooser!
31
+ rack-test
32
+ rspec (~> 2.0.0.beta.22)
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rack'
3
+
4
+ module Rack
5
+ module LocaleChooser
6
+ autoload :Chooser, 'rack-locale_chooser/chooser'
7
+
8
+ def self.new(app, options = {})
9
+ Chooser.new(app, options)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,94 @@
1
+ require 'net/geoip'
2
+
3
+ module Rack::LocaleChooser
4
+ class Chooser
5
+ def initialize(app, options = {})
6
+ @app, @options = app, {
7
+ :default_domain => 'example.com',
8
+ :geodb_path => '/usr/local/Cellar/geoip/1.4.6/share/GeoIP/GeoLiteCity.dat'
9
+ }.merge(options)
10
+ @geodb = Net::GeoIP.new(@options[:geodb_path])
11
+ end
12
+
13
+ def call(env)
14
+ @env = env
15
+ @request = Rack::Request.new(@env)
16
+
17
+ @original_url = @request.url
18
+
19
+ set_session_options
20
+
21
+ set_locale
22
+
23
+ @app.call(env) if @request.post? || @request.put? || @request.delete?
24
+
25
+ if @original_url != localized_url then
26
+ [301, {'Location' => localized_url}, '']
27
+ else
28
+ status, headers, body = @app.call(env)
29
+ response = Rack::Response.new(body, status, headers)
30
+ response.set_cookie('locale', {
31
+ :value => I18n.locale,
32
+ :path => '/',
33
+ :domain => @env["rack.session.options"][:domain]})
34
+ response.finish
35
+ end
36
+ end
37
+
38
+ # check http://codetunes.com/2009/04/17/dynamic-cookie-domains-with-racks-middleware/
39
+ def set_session_options
40
+ @env['rack.session.options'] = {} unless @env['rack.session.options']
41
+ @env['rack.session.options'][:domain] = @options[:default_domain]
42
+ end
43
+
44
+ def geo_record
45
+ @geo_record ||= begin
46
+ @geodb[@env["REMOTE_ADDR"]]
47
+ rescue Net::GeoIP::RecordNotFoundError
48
+ return nil
49
+ end
50
+ end
51
+
52
+ def url_locale
53
+ hosts = @options[:host_mappings].invert
54
+ hosts["http://#{@request.host}"] if hosts.has_key?("http://#{@request.host}")
55
+ end
56
+
57
+ def cookie_locale
58
+ @request.cookies['locale']
59
+ end
60
+
61
+ def geo_locale
62
+ @options[:country_mappings][geo_record.country_code] if @options[:country_mappings] and geo_record
63
+ end
64
+
65
+ def browser_locale
66
+ # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4
67
+ if lang = @env['HTTP_ACCEPT_LANGUAGE']
68
+ lang = lang.split(",").map { |l|
69
+ l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
70
+ l.split(';q=')
71
+ }.first
72
+ browser_locale = lang.first.split("-").first
73
+ else
74
+ browser_locale = I18n.default_locale
75
+ end
76
+ @options[:host_mappings].has_key?(browser_locale.to_sym) ? browser_locale : I18n.default_locale
77
+ end
78
+
79
+ def locale
80
+ url_locale || cookie_locale || geo_locale || browser_locale
81
+ end
82
+
83
+ def set_locale
84
+ I18n.locale = @env['rack.locale'] = locale.to_sym
85
+ @env['rack.city'] = geo_record.city if geo_record
86
+ end
87
+
88
+ def localized_url
89
+ current_host = @request.url.gsub(/http\:\/\/(\D*)[\/]|http\:\/\/(\D*)/).first().gsub(/:$|\/$/, '')
90
+ return @request.url.gsub(current_host, @options[:host_mappings][locale.to_sym]) if @options[:host_mappings][locale.to_sym]
91
+ @original_url
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ module LocaleChooser
3
+ VERSION = "0.0.7"
4
+ end
5
+ end
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "rack-locale_chooser/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "rack-locale_chooser"
7
+ s.version = Rack::LocaleChooser::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Jefferson Jean Martins Girão"]
10
+ s.email = ["contato@jefferson.eti.br"]
11
+ s.homepage = "https://github.com/jeffersongirao/rack-locale_chooser"
12
+ s.summary = %q{Rack Based Locale Selector}
13
+ s.description = %q{Rack Based Locale Selector}
14
+
15
+ s.rubyforge_project = "rack-locale_chooser"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_development_dependency "rspec", "~> 2.0.0.beta.22"
23
+ s.add_development_dependency "rack-test"
24
+ s.add_development_dependency "i18n"
25
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Rack::LocaleChooser do
4
+ def app
5
+ app = Rack::Builder.new {
6
+ use Rack::LocaleChooser::Chooser, :host_mappings => { :en => 'http://us.example.com',
7
+ :es => 'http://es.example.com' },
8
+ :country_mappings => { 'VE' => :es }
9
+ run BasicRackApp.new
10
+ }
11
+ end
12
+
13
+ context "request to root domain host" do
14
+ before do
15
+ I18n.default_locale = :en
16
+ end
17
+
18
+ it "should be redirected following cookie's value" do
19
+ get 'http://example.com/', {}, 'HTTP_COOKIE' => 'locale=es'
20
+ last_response.status.should == 301
21
+ last_response.headers['Location'].should == 'http://es.example.com/'
22
+ end
23
+
24
+ it "should be redirected folling geolocation" do
25
+ get 'http://example.com', {}
26
+ end
27
+
28
+ it "should be redirected following HTTP_ACCEPT_LANGUAGE headers" do
29
+ get 'http://example.com/', {}, 'HTTP_ACCEPT_LANGUAGE' => 'es'
30
+ last_response.status.should == 301
31
+ last_response.headers['Location'].should == 'http://es.example.com/'
32
+ I18n.locale.should == :es
33
+ end
34
+
35
+ it "should map locale to explicit domain mappings" do
36
+ get 'http://example.com/', {}, 'HTTP_ACCEPT_LANGUAGE' => 'en'
37
+ last_response.status.should == 301
38
+ last_response.headers['Location'].should == 'http://us.example.com/'
39
+ I18n.locale.should == :en
40
+ end
41
+
42
+
43
+ it "should map locale to explicit location mappings by country level" do
44
+ get 'http://example.com/', {}, 'REMOTE_ADDR' => '200.1.1.2' # Cacacas VE
45
+ last_response.status.should == 301
46
+ last_response.headers['Location'].should == 'http://es.example.com/'
47
+ end
48
+
49
+
50
+ it "fall back to default if accept language headers not on mappings" do
51
+ get 'http://example.com/', {}, 'HTTP_ACCEPT_LANGUAGE' => 'ru'
52
+ last_response.status.should == 301
53
+ last_response.headers['Location'].should == 'http://us.example.com/'
54
+ I18n.locale.should == :en
55
+ end
56
+
57
+ it "don't change anything if url is called directly" do
58
+ get 'http://es.example.com/'
59
+ last_response.status.should == 200
60
+ I18n.locale.should == :es
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'rack/test'
3
+ require 'rack-locale_chooser/chooser'
4
+ require 'i18n'
5
+
6
+ RSpec.configure do |config|
7
+ config.include Rack::Test::Methods
8
+ end
9
+
10
+ class BasicRackApp
11
+ def call(env)
12
+ [200, {'Content-Type' => 'text/plain'}, 'Hello World']
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-locale_chooser
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 7
10
+ version: 0.0.7
11
+ platform: ruby
12
+ authors:
13
+ - "Jefferson Jean Martins Gir\xC3\xA3o"
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-03 00:00:00 -03:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 62196431
30
+ segments:
31
+ - 2
32
+ - 0
33
+ - 0
34
+ - beta
35
+ - 22
36
+ version: 2.0.0.beta.22
37
+ type: :development
38
+ version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: rack-test
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ hash: 3
48
+ segments:
49
+ - 0
50
+ version: "0"
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: i18n
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 3
62
+ segments:
63
+ - 0
64
+ version: "0"
65
+ type: :development
66
+ version_requirements: *id003
67
+ description: Rack Based Locale Selector
68
+ email:
69
+ - contato@jefferson.eti.br
70
+ executables: []
71
+
72
+ extensions: []
73
+
74
+ extra_rdoc_files: []
75
+
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - Gemfile.lock
80
+ - Rakefile
81
+ - lib/rack-locale_chooser.rb
82
+ - lib/rack-locale_chooser/chooser.rb
83
+ - lib/rack-locale_chooser/version.rb
84
+ - rack-locale_chooser.gemspec
85
+ - spec/rack-locale_chooser_spec.rb
86
+ - spec/spec_helper.rb
87
+ has_rdoc: true
88
+ homepage: https://github.com/jeffersongirao/rack-locale_chooser
89
+ licenses: []
90
+
91
+ post_install_message:
92
+ rdoc_options: []
93
+
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ requirements: []
115
+
116
+ rubyforge_project: rack-locale_chooser
117
+ rubygems_version: 1.3.7
118
+ signing_key:
119
+ specification_version: 3
120
+ summary: Rack Based Locale Selector
121
+ test_files:
122
+ - spec/rack-locale_chooser_spec.rb
123
+ - spec/spec_helper.rb