rails_client_timezone 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/README.md +87 -0
- data/lib/geoip.rb +929 -0
- data/lib/rails_client_timezone/active_support_ext.rb +163 -0
- data/lib/rails_client_timezone/filter.rb +60 -0
- data/lib/rails_client_timezone/setting.rb +34 -0
- data/lib/rails_client_timezone/version.rb +3 -0
- data/rails_client_timezone.gemspec +30 -0
- metadata +80 -0
@@ -0,0 +1,163 @@
|
|
1
|
+
module RailsClientTimezone
|
2
|
+
# ActiveSupport class for mapping tz info identifiers to rails identifiers
|
3
|
+
class ActiveSupportExt
|
4
|
+
TIMEZONE_MAPPING = {
|
5
|
+
"Pacific/Midway"=>"International Date Line West",
|
6
|
+
"Pacific/Midway"=>"Midway Island",
|
7
|
+
"Pacific/Pago_Pago"=>"American Samoa",
|
8
|
+
"Pacific/Honolulu"=>"Hawaii",
|
9
|
+
"America/Juneau"=>"Alaska",
|
10
|
+
"America/Los_Angeles"=>"Pacific Time (US & Canada)",
|
11
|
+
"America/Tijuana"=>"Tijuana",
|
12
|
+
"America/Denver"=>"Mountain Time (US & Canada)",
|
13
|
+
"America/Phoenix"=>"Arizona",
|
14
|
+
"America/Chihuahua"=>"Chihuahua",
|
15
|
+
"America/Mazatlan"=>"Mazatlan",
|
16
|
+
"America/Chicago"=>"Central Time (US & Canada)",
|
17
|
+
"America/Regina"=>"Saskatchewan",
|
18
|
+
"America/Mexico_City"=>"Mexico City",
|
19
|
+
"America/Monterrey"=>"Monterrey",
|
20
|
+
"America/Guatemala"=>"Central America",
|
21
|
+
"America/New_York"=>"Eastern Time (US & Canada)",
|
22
|
+
"America/Indianapolis"=>"Indiana (East)",
|
23
|
+
"America/Indiana/Indianapolis"=>"Indiana (East)",
|
24
|
+
"America/Bogota"=>"Bogota",
|
25
|
+
"America/Lima"=>"Quito",
|
26
|
+
"America/Halifax"=>"Atlantic Time (Canada)",
|
27
|
+
"America/Caracas"=>"Caracas",
|
28
|
+
"America/La_Paz"=>"La Paz",
|
29
|
+
"America/Santiago"=>"Santiago",
|
30
|
+
"America/Santo_Domingo"=>"Santiago",
|
31
|
+
"America/St_Johns"=>"Newfoundland",
|
32
|
+
"America/Sao_Paulo"=>"Brasilia",
|
33
|
+
"America/Argentina/Buenos_Aires"=>"Buenos Aires",
|
34
|
+
"America/Montevideo"=>"Montevideo",
|
35
|
+
"America/Argentina/San_Juan"=>"Georgetown",
|
36
|
+
"America/Guyana"=>"Georgetown",
|
37
|
+
"America/Godthab"=>"Greenland",
|
38
|
+
"Atlantic/South_Georgia"=>"Mid-Atlantic",
|
39
|
+
"Atlantic/Azores"=>"Azores",
|
40
|
+
"Atlantic/Cape_Verde"=>"Cape Verde Is.",
|
41
|
+
"Europe/Dublin"=>"Dublin",
|
42
|
+
"Europe/London"=>"London",
|
43
|
+
"Europe/Lisbon"=>"Lisbon",
|
44
|
+
"Africa/Casablanca"=>"Casablanca",
|
45
|
+
"Africa/Monrovia"=>"Monrovia",
|
46
|
+
"Etc/UTC"=>"UTC",
|
47
|
+
"Europe/Belgrade"=>"Belgrade",
|
48
|
+
"Europe/Bratislava"=>"Bratislava",
|
49
|
+
"Europe/Budapest"=>"Budapest",
|
50
|
+
"Europe/Ljubljana"=>"Ljubljana",
|
51
|
+
"Europe/Prague"=>"Prague",
|
52
|
+
"Europe/Sarajevo"=>"Sarajevo",
|
53
|
+
"Europe/Skopje"=>"Skopje",
|
54
|
+
"Europe/Warsaw"=>"Warsaw",
|
55
|
+
"Europe/Zagreb"=>"Zagreb",
|
56
|
+
"Europe/Brussels"=>"Brussels",
|
57
|
+
"Europe/Copenhagen"=>"Copenhagen",
|
58
|
+
"Europe/Madrid"=>"Madrid",
|
59
|
+
"Europe/Paris"=>"Paris",
|
60
|
+
"Europe/Amsterdam"=>"Amsterdam",
|
61
|
+
"Europe/Berlin"=>"Bern",
|
62
|
+
"Europe/Rome"=>"Rome",
|
63
|
+
"Europe/Stockholm"=>"Stockholm",
|
64
|
+
"Europe/Vienna"=>"Vienna",
|
65
|
+
"Africa/Algiers"=>"West Central Africa",
|
66
|
+
"Europe/Bucharest"=>"Bucharest",
|
67
|
+
"Africa/Cairo"=>"Cairo",
|
68
|
+
"Africa/Kinshasa"=>"West Central Africa",
|
69
|
+
"Europe/Helsinki"=>"Helsinki",
|
70
|
+
"Europe/Kiev"=>"Kyev",
|
71
|
+
"Europe/Riga"=>"Riga",
|
72
|
+
"Europe/Sofia"=>"Sofia",
|
73
|
+
"Europe/Tallinn"=>"Tallinn",
|
74
|
+
"Europe/Vilnius"=>"Vilnius",
|
75
|
+
"Europe/Athens"=>"Athens",
|
76
|
+
"Europe/Istanbul"=>"Istanbul",
|
77
|
+
"Europe/Minsk"=>"Minsk",
|
78
|
+
"Asia/Jerusalem"=>"Jerusalem",
|
79
|
+
"Africa/Harare"=>"Harare",
|
80
|
+
"Africa/Johannesburg"=>"Pretoria",
|
81
|
+
"Europe/Kaliningrad"=>"Kaliningrad",
|
82
|
+
"Europe/Moscow"=>"Moscow",
|
83
|
+
"Europe/Volgograd"=>"Volgograd",
|
84
|
+
"Europe/Samara"=>"Samara",
|
85
|
+
"Asia/Kuwait"=>"Kuwait",
|
86
|
+
"Asia/Riyadh"=>"Riyadh",
|
87
|
+
"Africa/Nairobi"=>"Nairobi",
|
88
|
+
"Asia/Baghdad"=>"Baghdad",
|
89
|
+
"Asia/Tehran"=>"Tehran",
|
90
|
+
"Asia/Muscat"=>"Abu Dhabi",
|
91
|
+
"Asia/Muscat"=>"Muscat",
|
92
|
+
"Asia/Baku"=>"Baku",
|
93
|
+
"Asia/Tbilisi"=>"Tbilisi",
|
94
|
+
"Asia/Yerevan"=>"Yerevan",
|
95
|
+
"Asia/Kabul"=>"Kabul",
|
96
|
+
"Asia/Yekaterinburg"=>"Ekaterinburg",
|
97
|
+
"Asia/Karachi"=>"Karachi",
|
98
|
+
"Asia/Tashkent"=>"Tashkent",
|
99
|
+
"Asia/Kolkata"=>"Chennai",
|
100
|
+
"Asia/Calcutta"=>"New Delhi",
|
101
|
+
"Asia/Kathmandu"=>"Kathmandu",
|
102
|
+
"Asia/Katmandu"=>"Kathmandu",
|
103
|
+
"Asia/Dhaka"=>"Dhaka",
|
104
|
+
"Asia/Colombo"=>"Sri Jayawardenepura",
|
105
|
+
"Asia/Almaty"=>"Almaty",
|
106
|
+
"Asia/Qyzylorda"=>"Almaty",
|
107
|
+
"Asia/Novosibirsk"=>"Novosibirsk",
|
108
|
+
"Asia/Bangkok"=>"Bangkok",
|
109
|
+
"Asia/Jakarta"=>"Jakarta",
|
110
|
+
"Asia/Krasnoyarsk"=>"Krasnoyarsk",
|
111
|
+
"Asia/Shanghai"=>"Beijing",
|
112
|
+
"Asia/Chongqing"=>"Chongqing",
|
113
|
+
"Asia/Hong_Kong"=>"Hong Kong",
|
114
|
+
"Asia/Urumqi"=>"Urumqi",
|
115
|
+
"Asia/Kuala_Lumpur"=>"Kuala Lumpur",
|
116
|
+
"Asia/Rangoon"=>"Rangoon",
|
117
|
+
"Asia/Singapore"=>"Singapore",
|
118
|
+
"Asia/Taipei"=>"Taipei",
|
119
|
+
"Asia/Irkutsk"=>"Irkutsk",
|
120
|
+
"Asia/Ulaanbaatar"=>"Ulaanbaatar",
|
121
|
+
"Asia/Seoul"=>"Seoul",
|
122
|
+
"Asia/Tokyo"=>"Tokyo",
|
123
|
+
"Asia/Yakutsk"=>"Yakutsk",
|
124
|
+
"Australia/Darwin"=>"Darwin",
|
125
|
+
"Australia/Adelaide"=>"Adelaide",
|
126
|
+
"Australia/Melbourne"=>"Melbourne",
|
127
|
+
"Australia/Lord_Howe"=>"Melbourne",
|
128
|
+
"Australia/Queensland"=>"Brisbane",
|
129
|
+
"Australia/Victoria"=>"Melbourne",
|
130
|
+
"Australia/NSW"=>"Melbourne",
|
131
|
+
"Australia/Sydney"=>"Sydney",
|
132
|
+
"Australia/Brisbane"=>"Brisbane",
|
133
|
+
"Australia/Hobart"=>"Hobart",
|
134
|
+
"Australia/Currie"=>"Melbourne",
|
135
|
+
"Australia/Broken_Hill"=>"Adelaide",
|
136
|
+
"Australia/Lindeman"=>"Brisbane",
|
137
|
+
"Australia/Perth"=>"Perth",
|
138
|
+
"Australia/Eucla"=>"Perth",
|
139
|
+
"Asia/Vladivostok"=>"Vladivostok",
|
140
|
+
"Pacific/Guam"=>"Guam",
|
141
|
+
"Pacific/Port_Moresby"=>"Port Moresby",
|
142
|
+
"Asia/Magadan"=>"Magadan",
|
143
|
+
"Asia/Srednekolymsk"=>"Srednekolymsk",
|
144
|
+
"Pacific/Guadalcanal"=>"Solomon Is.",
|
145
|
+
"Pacific/Noumea"=>"New Caledonia",
|
146
|
+
"Pacific/Fiji"=>"Fiji",
|
147
|
+
"Asia/Kamchatka"=>"Kamchatka",
|
148
|
+
"Pacific/Majuro"=>"Marshall Is.",
|
149
|
+
"Pacific/Auckland"=>"Auckland",
|
150
|
+
"Pacific/Auckland"=>"Wellington",
|
151
|
+
"Pacific/Tongatapu"=>"Nuku'alofa",
|
152
|
+
"Pacific/Fakaofo"=>"Tokelau Is.",
|
153
|
+
"Pacific/Chatham"=>"Chatham Is.",
|
154
|
+
"Pacific/Pago_Pago"=>"Samoa",
|
155
|
+
"Pacific/Galapagos"=>"Samoa",
|
156
|
+
"Pacific/Apia"=>"Samoa"
|
157
|
+
}
|
158
|
+
|
159
|
+
def self.format(zone)
|
160
|
+
TIMEZONE_MAPPING[zone] || nil
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Runs the controller code in the user's time zone which is determined through the offsets passed via cookies.
|
2
|
+
module RailsClientTimezone
|
3
|
+
class Filter
|
4
|
+
|
5
|
+
def self.filter(controller, &block)
|
6
|
+
cookies = controller.send(:cookies)
|
7
|
+
|
8
|
+
current_time_zone = if Setting.mode == :browser
|
9
|
+
get_time_zone_by_browser_offset(cookies[:utc_offset_summer], cookies[:utc_offset_winter], cookies[:last_known_tz])
|
10
|
+
elsif Setting.mode == :ip
|
11
|
+
get_time_zone_by_ip(controller, cookies[:last_known_tz])
|
12
|
+
else
|
13
|
+
get_time_zone_by_smart(controller, cookies[:utc_offset_summer], cookies[:utc_offset_winter], cookies[:last_known_tz])
|
14
|
+
end
|
15
|
+
controller.response.set_cookie(:last_known_tz, {:path => "/", :value => current_time_zone.name})
|
16
|
+
|
17
|
+
Time.use_zone(current_time_zone) do
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the time zone based on parsed *utc_offset_summer* and *utc_offset_winter*
|
23
|
+
# Returns the default TimeZone if none is resolved
|
24
|
+
def self.get_time_zone_by_browser_offset(utc_offset_summer, utc_offset_winter, last_known_tz)
|
25
|
+
# ActiveSupport::TimeZone[offset] - will return the first time zone that matches the offset.
|
26
|
+
# But, we need to get the exact time zone inorder to reflect the daylight savings.
|
27
|
+
# So, we get the user's time zone exactly by matching the summer offset and winter offset both.
|
28
|
+
[ActiveSupport::TimeZone[last_known_tz.to_s], ActiveSupport::TimeZone.all].flatten.compact.detect(ifnone = Time.method(:zone_default)) do |zone|
|
29
|
+
Time.use_zone(zone.name) do
|
30
|
+
if utc_offset_summer.present? && utc_offset_winter.present?
|
31
|
+
(Time.zone.parse(Setting.mid_summer_date_str).utc_offset == utc_offset_summer.to_i && Time.zone.parse(Setting.mid_winter_date_str).utc_offset == utc_offset_winter.to_i)
|
32
|
+
else
|
33
|
+
(Time.zone.name == last_known_tz.to_s)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the time zone based on IP address
|
40
|
+
# Returns the default TimeZone if none is resolved
|
41
|
+
def self.get_time_zone_by_ip(controller, last_known_tz = nil)
|
42
|
+
return ActiveSupport::TimeZone[last_known_tz] if last_known_tz && ActiveSupport::TimeZone[last_known_tz]
|
43
|
+
begin
|
44
|
+
ip_addr = controller.request.remote_ip
|
45
|
+
geo_timezone = GeoIP.new(Setting.geoip_data_path).city(ip_addr) ? GeoIP.new(Setting.geoip_data_path).city(ip_addr).timezone : nil
|
46
|
+
timezone_name = geo_timezone && ActiveSupportExt.format(geo_timezone) ? ActiveSupportExt.format(geo_timezone) : Time.zone_default.name
|
47
|
+
rescue Exception => e
|
48
|
+
ActiveSupport::TimeZone[Time.zone_default.name]
|
49
|
+
end
|
50
|
+
ActiveSupport::TimeZone[timezone_name]
|
51
|
+
end
|
52
|
+
|
53
|
+
# Returns the time zone using both ip address and browser offset
|
54
|
+
# Returns the default TimeZone if none is resolved
|
55
|
+
def self.get_time_zone_by_smart(controller, utc_offset_summer, utc_offset_winter, last_known_tz)
|
56
|
+
last_known_tz_val = last_known_tz ? last_known_tz : get_time_zone_by_ip(controller).name
|
57
|
+
get_time_zone_by_browser_offset(utc_offset_summer, utc_offset_winter, last_known_tz_val)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module RailsClientTimezone
|
2
|
+
class Setting
|
3
|
+
class << self
|
4
|
+
attr_writer :baseline_year
|
5
|
+
attr_writer :mode
|
6
|
+
attr_writer :geoip_data_path
|
7
|
+
|
8
|
+
#Possible mode values - :ip, :browser, :smart
|
9
|
+
def mode
|
10
|
+
@mode ||= :smart
|
11
|
+
end
|
12
|
+
|
13
|
+
def geoip_data_path
|
14
|
+
@geoip_data_path ||= File.expand_path(File.join(File.dirname(__FILE__), '../..', 'data/geoip', 'GeoLiteCity.dat'))
|
15
|
+
end
|
16
|
+
|
17
|
+
def baseline_year
|
18
|
+
@baseline_year ||= 2011
|
19
|
+
end
|
20
|
+
|
21
|
+
def mid_summer_date_str
|
22
|
+
"#{year}-6-21"
|
23
|
+
end
|
24
|
+
|
25
|
+
def mid_winter_date_str
|
26
|
+
"#{year}-12-21"
|
27
|
+
end
|
28
|
+
|
29
|
+
def year
|
30
|
+
(baseline_year.to_sym == :current) ? Time.zone.now.year : baseline_year
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rails_client_timezone/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rails_client_timezone"
|
7
|
+
s.version = RailsClientTimezone::VERSION
|
8
|
+
s.authors = ["Udaya Kiran", "Yamini Devarajan"]
|
9
|
+
s.email = ["udaykiran.vit@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Rails Browser Timezone client gem}
|
12
|
+
s.description = %q{Simple code to detect browser time zone and handle it in rails app}
|
13
|
+
|
14
|
+
s.rubyforge_project = "rails_client_timezone"
|
15
|
+
|
16
|
+
s.files = %w[
|
17
|
+
Gemfile
|
18
|
+
README.md
|
19
|
+
lib/rails_client_timezone/filter.rb
|
20
|
+
lib/rails_client_timezone/version.rb
|
21
|
+
lib/rails_client_timezone/setting.rb
|
22
|
+
lib/rails_client_timezone/active_support_ext.rb
|
23
|
+
lib/geoip.rb
|
24
|
+
rails_client_timezone.gemspec
|
25
|
+
]
|
26
|
+
s.require_paths = ["lib"]
|
27
|
+
|
28
|
+
s.add_runtime_dependency "activesupport", '> 2'
|
29
|
+
s.add_runtime_dependency "geoip", '1.6.1'
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rails_client_timezone
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Udaya Kiran
|
8
|
+
- Yamini Devarajan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-01-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">"
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '2'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">"
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '2'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: geoip
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 1.6.1
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 1.6.1
|
42
|
+
description: Simple code to detect browser time zone and handle it in rails app
|
43
|
+
email:
|
44
|
+
- udaykiran.vit@gmail.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- Gemfile
|
50
|
+
- README.md
|
51
|
+
- lib/geoip.rb
|
52
|
+
- lib/rails_client_timezone/active_support_ext.rb
|
53
|
+
- lib/rails_client_timezone/filter.rb
|
54
|
+
- lib/rails_client_timezone/setting.rb
|
55
|
+
- lib/rails_client_timezone/version.rb
|
56
|
+
- rails_client_timezone.gemspec
|
57
|
+
homepage: ''
|
58
|
+
licenses: []
|
59
|
+
metadata: {}
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project: rails_client_timezone
|
76
|
+
rubygems_version: 2.4.5.1
|
77
|
+
signing_key:
|
78
|
+
specification_version: 4
|
79
|
+
summary: Rails Browser Timezone client gem
|
80
|
+
test_files: []
|