rack-locale_chooser 0.0.7

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