timezone 0.6.0 → 0.99.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +99 -1
  4. data/.travis.yml +6 -3
  5. data/CHANGES.markdown +10 -0
  6. data/Gemfile +1 -1
  7. data/README.markdown +129 -89
  8. data/Rakefile +7 -4
  9. data/benchmark.rb +13 -13
  10. data/lib/timezone/active_support.rb +147 -134
  11. data/lib/timezone/configure.rb +131 -110
  12. data/lib/timezone/deprecate.rb +32 -0
  13. data/lib/timezone/error.rb +16 -5
  14. data/lib/timezone/loader.rb +19 -16
  15. data/lib/timezone/lookup/basic.rb +24 -2
  16. data/lib/timezone/lookup/geonames.rb +9 -5
  17. data/lib/timezone/lookup/google.rb +24 -15
  18. data/lib/timezone/lookup/test.rb +8 -8
  19. data/lib/timezone/lookup.rb +68 -0
  20. data/lib/timezone/net_http_client.rb +23 -9
  21. data/lib/timezone/nil_zone.rb +32 -0
  22. data/lib/timezone/parser.rb +10 -5
  23. data/lib/timezone/version.rb +2 -1
  24. data/lib/timezone/zone.rb +230 -99
  25. data/lib/timezone.rb +75 -1
  26. data/test/basic_lookup_test.rb +2 -2
  27. data/test/geonames_lookup_test.rb +13 -6
  28. data/test/google_lookup_test.rb +34 -24
  29. data/test/http_test_client.rb +7 -6
  30. data/test/test_lookup_test.rb +3 -1
  31. data/test/test_timezone.rb +59 -0
  32. data/test/timezone/lookup/test_geonames.rb +59 -0
  33. data/test/timezone/lookup/test_google.rb +94 -0
  34. data/test/timezone/lookup/test_test.rb +24 -0
  35. data/test/timezone/test_deprecate.rb +20 -0
  36. data/test/timezone/test_loader.rb +32 -0
  37. data/test/timezone/test_lookup.rb +53 -0
  38. data/test/timezone/test_nil_zone.rb +26 -0
  39. data/test/timezone/test_zone.rb +49 -0
  40. data/test/timezone_test.rb +64 -63
  41. data/timezone.gemspec +16 -15
  42. metadata +39 -38
  43. data/.rubocop_todo.yml +0 -235
@@ -1,235 +1,256 @@
1
1
  require 'timezone/net_http_client'
2
2
  require 'timezone/lookup'
3
+ require 'timezone/deprecate'
3
4
 
4
5
  module Timezone
5
- # Configuration class for the Timezone gem.
6
- #
7
- # You'll want to sign up for a geonames username at
8
- # {http://www.geonames.org/login Geonames}. Use the username to
9
- # configure your application for latitude and longitude based
10
- # timezone searches.
11
- # Alternatively, you'll want to sign up for a Google api key at
12
- # {https://code.google.com/apis/console/ Google}. Use the api key to
13
- # configure your application for latitude and longitude based
14
- # timezone searches.
15
- #
16
- # If you aren't going to initialize timezone objects based on lat,lng
17
- # then this configuration is not necessary.
18
- #
19
- # @example
20
- # Timezone::Configure.begin do |c|
21
- # c.geonames_url = 'api.geonames.org'
22
- # c.username = 'foo-bar'
23
- # c.google_api_key = 'abc123'
24
- # end
6
+ # @deprecated `Timezone::Configure` will be removed in the release
7
+ # of the `timezone gem. Use `Timezone::Lookup::config` instead.
25
8
  #
9
+ # The old way to configure this gem.
10
+ # rubocop:disable Style/ClassVars
26
11
  class Configure
27
- # The Google API key
28
- #
29
- # @return [String]
30
- # the Google API key ('abc123')
12
+ DEPRECATE = '[DEPRECATED] `Timezone::Configure` will be removed ' \
13
+ 'in the release of the `timezone gem. Use `Timezone::Lookup` ' \
14
+ 'instead.'.freeze
15
+
16
+ # @deprecated `Timezone::Configure` will be removed in the release
17
+ # of the `timezone gem. Use `Timezone::Lookup instead.
31
18
  def self.google_api_key
32
- @google_api_key ||= nil
19
+ @@google_api_key ||= nil
33
20
  end
34
21
 
35
- # Google API key
36
- #
37
- # @param [String] api_key
38
- # the Google API key
22
+ # @deprecated `Timezone::Configure` will be removed in the release
23
+ # of the `timezone gem. Use `Timezone::Lookup instead.
39
24
  def self.google_api_key=(api_key)
40
- @google_api_key = api_key
25
+ @@google_api_key = api_key
41
26
  end
42
27
 
43
- # The Google Client ID (for enterprise)
44
- #
45
- # @return [String]
46
- # the Google Client ('abc123')
28
+ # @deprecated `Timezone::Configure` will be removed in the release
29
+ # of the `timezone gem. Use `Timezone::Lookup instead.
47
30
  def self.google_client_id
48
- @google_client_id ||= nil
31
+ @@google_client_id ||= nil
49
32
  end
50
33
 
51
- # Google Client ID (for enterprise)
52
- #
53
- # @param [String] client
54
- # the Google Client
34
+ # @deprecated `Timezone::Configure` will be removed in the release
35
+ # of the `timezone gem. Use `Timezone::Lookup instead.
55
36
  def self.google_client_id=(client)
56
- @google_client_id = client
37
+ @@google_client_id = client
57
38
  end
58
39
 
59
- # Use Google API if key has been set
60
- #
61
- # @return [Boolean]
40
+ # @deprecated `Timezone::Configure` will be removed in the release
41
+ # of the `timezone gem. Use `Timezone::Lookup instead.
62
42
  def self.use_google?
63
- !!google_api_key
43
+ !google_api_key.nil?
64
44
  end
65
45
 
66
- # Sign Google API request if client given (for enterprise)
67
- #
68
- # @return [Boolean]
46
+ # @deprecated `Timezone::Configure` will be removed in the release
47
+ # of the `timezone gem. Use `Timezone::Lookup instead.
69
48
  def self.use_google_enterprise?
70
- use_google? && !!google_client_id
49
+ use_google? && !google_client_id.nil?
71
50
  end
72
51
 
52
+ # @deprecated `Timezone::Configure` will be removed in the release
53
+ # of the `timezone gem. Use `Timezone::Lookup instead.
73
54
  def self.lookup=(lookup)
74
55
  @lookup = lookup && lookup.new(self)
75
56
  end
76
57
 
58
+ # @deprecated `Timezone::Configure` will be removed in the release
59
+ # of the `timezone gem. Use `Timezone::Lookup instead.
77
60
  def self.lookup
78
61
  return @lookup if @lookup
79
62
 
80
63
  use_google? ? google_lookup : geonames_lookup
81
64
  end
82
65
 
66
+ # Responsible for mapping old configuration options to new
67
+ # configuration style for forwards-compatability with the
68
+ # updated Google lookup.
69
+ class GoogleConfigMapper
70
+ def initialize(config)
71
+ @config = config
72
+ end
73
+
74
+ def protocol; @config.protocol; end
75
+
76
+ def url; @config.url; end
77
+
78
+ def http_client; @config.http_client; end
79
+
80
+ def api_key; @config.google_api_key; end
81
+
82
+ def client_id; @config.google_client_id; end
83
+
84
+ def request_handler; nil; end
85
+ end
86
+
87
+ private_constant :GoogleConfigMapper
88
+
89
+ # @deprecated `Timezone::Configure` will be removed in the release
90
+ # of the `timezone gem. Use `Timezone::Lookup instead.
83
91
  def self.google_lookup
84
- @google_lookup ||= Timezone::Lookup::Google.new(self)
92
+ @google_lookup ||=
93
+ Timezone::Lookup::Google.new(GoogleConfigMapper.new(self))
94
+ end
95
+
96
+ # Responsible for mapping old configuration options to new
97
+ # configuration style for forwards-compatability with the
98
+ # updated Geonames lookup.
99
+ class GeonamesConfigMapper
100
+ def initialize(config)
101
+ @config = config
102
+ end
103
+
104
+ def protocol; @config.protocol; end
105
+
106
+ def url; @config.url; end
107
+
108
+ def username; @config.username; end
109
+
110
+ def http_client; @config.http_client; end
111
+
112
+ def request_handler; nil; end
85
113
  end
86
114
 
115
+ private_constant :GeonamesConfigMapper
116
+
117
+ # @deprecated `Timezone::Configure` will be removed in the release
118
+ # of the `timezone gem. Use `Timezone::Lookup instead.
87
119
  def self.geonames_lookup
88
- @geonames_lookup ||= Timezone::Lookup::Geonames.new(self)
120
+ @geonames_lookup ||=
121
+ Timezone::Lookup::Geonames.new(GeonamesConfigMapper.new(self))
89
122
  end
90
123
 
91
- # The Geonames API URL
92
- #
93
- # @return [String]
94
- # the Geonames API URL ('api.geonames.org')
124
+ # @deprecated `Timezone::Configure` will be removed in the release
125
+ # of the `timezone gem. Use `Timezone::Lookup instead.
95
126
  def self.geonames_url
96
127
  @@geonames_url ||= 'api.geonames.org'
97
128
  end
98
129
 
99
- # The Geonames API URL
100
- #
101
- # @param [String] url
102
- # the Geonames API URL
130
+ # @deprecated `Timezone::Configure` will be removed in the release
131
+ # of the `timezone gem. Use `Timezone::Lookup instead.
103
132
  def self.geonames_url=(url)
104
133
  @@geonames_url = url
105
134
  end
106
135
 
107
- class << self
108
- alias url= geonames_url=
136
+ # @deprecated `Timezone::Configure` will be removed in the release
137
+ # of the `timezone gem. Use `Timezone::Lookup instead.
138
+ def self.url=(url)
139
+ self.geonames_url = url
109
140
  end
110
141
 
111
- # The Google API URL
112
- #
113
- # @return [String]
114
- # the Google API URL ('maps.googleapis.com')
142
+ # @deprecated `Timezone::Configure` will be removed in the release
143
+ # of the `timezone gem. Use `Timezone::Lookup instead.
115
144
  def self.google_url
116
145
  @@google_url ||= 'maps.googleapis.com'
117
146
  end
118
147
 
119
- # The Google API URL
120
- #
121
- # @param [String] url
122
- # the Google API URL
148
+ # @deprecated `Timezone::Configure` will be removed in the release
149
+ # of the `timezone gem. Use `Timezone::Lookup instead.
123
150
  def self.google_url=(url)
124
151
  @@google_url = url
125
152
  end
126
153
 
127
- # Use Google URL if key has been set else use Geonames URL
128
- #
129
- # @return [String]
130
- # the Google or Geonames API URL
154
+ # @deprecated `Timezone::Configure` will be removed in the release
155
+ # of the `timezone gem. Use `Timezone::Lookup instead.
131
156
  def self.url
132
157
  use_google? ? google_url : geonames_url
133
158
  end
134
159
 
135
- # The Geonames API HTTP protocol
136
- #
137
- # @param [String] protocol
138
- # the Geonames API HTTP procotol
160
+ # @deprecated `Timezone::Configure` will be removed in the release
161
+ # of the `timezone gem. Use `Timezone::Lookup instead.
139
162
  def self.geonames_protocol=(protocol)
140
163
  @@geonames_protocol = protocol
141
164
  end
142
165
 
143
- # The Geonames API HTTP protocol
144
- #
145
- # @return [String]
146
- # the Geonames API HTTP protocol ('http')
166
+ # @deprecated `Timezone::Configure` will be removed in the release
167
+ # of the `timezone gem. Use `Timezone::Lookup instead.
147
168
  def self.geonames_protocol
148
169
  @@geonames_protocol ||= 'http'
149
170
  end
150
171
 
151
- # The Google API HTTP protocol
152
- #
153
- # @param [String] protocol
154
- # the Google API HTTP procotol
172
+ # @deprecated `Timezone::Configure` will be removed in the release
173
+ # of the `timezone gem. Use `Timezone::Lookup instead.
155
174
  def self.google_protocol=(protocol)
156
175
  @@google_protocol = protocol
157
176
  end
158
177
 
159
- # The Google API HTTP protocol
160
- #
161
- # @return [String]
162
- # the Google API HTTP protocol ('https')
178
+ # @deprecated `Timezone::Configure` will be removed in the release
179
+ # of the `timezone gem. Use `Timezone::Lookup instead.
163
180
  def self.google_protocol
164
181
  @@google_protocol ||= 'https'
165
182
  end
166
183
 
167
- # Use Google protocol if key has been set else use Geonames protocol
168
- #
169
- # @return [String]
170
- # the Google or Geonames API protocol
184
+ # @deprecated `Timezone::Configure` will be removed in the release
185
+ # of the `timezone gem. Use `Timezone::Lookup instead.
171
186
  def self.protocol
172
187
  use_google? ? google_protocol : geonames_protocol
173
188
  end
174
189
 
175
- # The HTTP client that handles requests to Geonames and Google
176
- #
177
- # @return [Object]
178
- # the HTTP client ({Timezone::NetHTTPClient Timezone::NetHTTPClient})
190
+ # @deprecated `Timezone::Configure` will be removed in the release
191
+ # of the `timezone gem. Use `Timezone::Lookup instead.
179
192
  def self.http_client
180
193
  @@http_client ||= Timezone::NetHTTPClient
181
194
  end
182
195
 
183
- # The HTTP client that handles requests to Geonames and Google
184
- #
185
- # @param [Object] client
186
- # the HTTP client that handles requests to Geonames and Google
187
- #
196
+ # @deprecated `Timezone::Configure` will be removed in the release
197
+ # of the `timezone gem. Use `Timezone::Lookup instead.
188
198
  def self.http_client=(client)
189
199
  @@http_client = client
190
200
  end
191
201
 
192
- # The Geonames API username
193
- #
194
- # @return [String]
195
- # the Geonames API username ('foo-bar')
202
+ # @deprecated `Timezone::Configure` will be removed in the release
203
+ # of the `timezone gem. Use `Timezone::Lookup instead.
196
204
  def self.username
197
205
  @@username ||= nil
198
206
  end
199
207
 
200
- # The Geonames API username
201
- #
202
- # @param [String] username
203
- # the Geonames API username
208
+ # @deprecated `Timezone::Configure` will be removed in the release
209
+ # of the `timezone gem. Use `Timezone::Lookup instead.
204
210
  def self.username=(username)
205
211
  @@username = username
206
212
  end
207
213
 
214
+ # @deprecated `Timezone::Configure` will be removed in the release
215
+ # of the `timezone gem. Use `Timezone::Lookup instead.
208
216
  def self.begin
217
+ Deprecate.call(self, :begin, DEPRECATE)
209
218
  yield self
210
219
  end
211
220
 
212
- def self.replace(what, with = Hash.new)
221
+ # @deprecated `Timezone::Configure` will be removed in the release
222
+ # of the `timezone gem. Use `Timezone::Lookup instead.
223
+ def self.replace(what, with = {})
213
224
  replacements # instantiate @@replacements
214
225
  @@replacements[what] = with[:with]
215
226
  end
216
227
 
228
+ # @deprecated `Timezone::Configure` will be removed in the release
229
+ # of the `timezone gem. Use `Timezone::Lookup instead.
217
230
  def self.replacements
218
231
  @@replacements ||= {}
219
232
  end
220
233
 
234
+ # @deprecated `Timezone::Configure` will be removed in the release
235
+ # of the `timezone gem. Use `Timezone::Lookup instead.
221
236
  def self.default_for_list
222
237
  @@default_list ||= nil
223
238
  end
224
239
 
240
+ # @deprecated `Timezone::Configure` will be removed in the release
241
+ # of the `timezone gem. Use `Timezone::Lookup instead.
225
242
  def self.default_for_list=(*list)
226
243
  @@default_list = list.flatten!
227
244
  end
228
245
 
246
+ # @deprecated `Timezone::Configure` will be removed in the release
247
+ # of the `timezone gem. Use `Timezone::Lookup instead.
229
248
  def self.order_list_by
230
249
  @@order_by ||= :utc_offset
231
250
  end
232
251
 
252
+ # @deprecated `Timezone::Configure` will be removed in the release
253
+ # of the `timezone gem. Use `Timezone::Lookup instead.
233
254
  def self.order_list_by=(order)
234
255
  @@order_by = order
235
256
  end
@@ -0,0 +1,32 @@
1
+ module Timezone
2
+ # This class provides a way to set a custom hook for deprecations.
3
+ module Deprecate
4
+ class << self
5
+ # Set the custom deprecation callback. By default this
6
+ # issues a deprecation warning.
7
+ #
8
+ # @param callback [#call] the custom callback
9
+ #
10
+ # @example Send a message to StatsD
11
+ # Timezone::Deprecate.callback = lambda do |klass, method, _|
12
+ # StatsD.increment(sanitize(klass, method))
13
+ # end
14
+ #
15
+ # @example Send a message to a custom logger
16
+ # Timezone::Deprecate.callback = lambda do |klass, method, msg|
17
+ # MyLogger.log("[#{klass} : #{method}] #{msg}")
18
+ # end
19
+ attr_writer :callback
20
+
21
+ # @!visibility private
22
+ def callback
23
+ @callback || -> (_, _, message) { warn(message) }
24
+ end
25
+
26
+ # @!visibility private
27
+ def call(klass, method, message)
28
+ callback && callback.call(klass, method, message)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,6 @@
1
1
  module Timezone
2
- # Error messages that can be raised by this gem. To catch any related error message, simply use Error::Base.
2
+ # Error messages that can be raised by this gem. To catch any
3
+ # related error message, use Error::Base.
3
4
  #
4
5
  # begin
5
6
  # ...
@@ -7,13 +8,23 @@ module Timezone
7
8
  # puts "Timezone Error: #{e.message}"
8
9
  # end
9
10
  module Error
11
+ # Top-level error. All other timezone errors subclass this one.
10
12
  class Base < StandardError; end
13
+ # Indicates an invalid timezone name.
11
14
  class InvalidZone < Base; end
15
+ # @deprecated this class will be removed in the next release of the gem.
12
16
  class NilZone < Base; end
13
- class GeoNames < Base; end
14
- class Google < Base; end
17
+ # Indicates a lookup failure.
18
+ class Lookup < Base; end
19
+ # Indicates an error during lookup using the geonames API.
20
+ class GeoNames < Lookup; end
21
+ # Indicates an error during lookup using the google API.
22
+ class Google < Lookup; end
23
+ # @deprecated this class will be removed in the next release of the gem.
15
24
  class ParseTime < Base; end
16
- class Test < Base ; end
17
- class InvalidConfig < Base ; end
25
+ # Indicates a missing stub during a test lookup.
26
+ class Test < Lookup; end
27
+ # Indicates an invalid configuration.
28
+ class InvalidConfig < Base; end
18
29
  end
19
30
  end
@@ -1,27 +1,34 @@
1
1
  require 'timezone/error'
2
2
 
3
- module Timezone
3
+ module Timezone # rubocop:disable Style/Documentation
4
+ # Responsible for loading and parsing timezone data from files.
4
5
  module Loader
5
- ZONE_FILE_PATH = File.expand_path(File.dirname(__FILE__)+'/../../data')
6
+ ZONE_FILE_PATH = File.expand_path(File.dirname(__FILE__) + '/../../data')
6
7
  SOURCE_BIT = 0
7
8
 
8
9
  class << self
9
- def load(zone)
10
+ def load(name)
11
+ raise ::Timezone::Error::InvalidZone unless valid?(name)
12
+
10
13
  @rules ||= {}
11
- @rules[zone] ||= parse_zone_data(get_zone_data(zone))
14
+ @rules[name] ||= parse_zone_data(get_zone_data(name))
12
15
  end
13
16
 
14
17
  def names
15
- @@names ||= parse_zone_names
18
+ @names ||= parse_zone_names
19
+ end
20
+
21
+ def valid?(name)
22
+ names.include?(name)
16
23
  end
17
24
 
18
25
  private
19
26
 
20
27
  def parse_zone_names
21
- files = Dir[File.join(ZONE_FILE_PATH, "**/*")].map do |file|
28
+ files = Dir[File.join(ZONE_FILE_PATH, '**/*')].map do |file|
22
29
  next if File.directory?(file)
23
30
 
24
- file.gsub("#{ZONE_FILE_PATH}/", '')
31
+ file.sub("#{ZONE_FILE_PATH}/", '')
25
32
  end
26
33
 
27
34
  files.compact
@@ -35,7 +42,7 @@ module Timezone
35
42
  source = source.to_i
36
43
  dst = dst == '1'
37
44
  offset = offset.to_i
38
- source = rules.last[SOURCE_BIT]+source if rules.last
45
+ source = rules.last[SOURCE_BIT] + source if rules.last
39
46
  rules << [source, name, dst, offset]
40
47
  end
41
48
 
@@ -43,15 +50,11 @@ module Timezone
43
50
  end
44
51
 
45
52
  # Retrieve the data from a particular time zone
46
- def get_zone_data(zone)
47
- file = File.join(ZONE_FILE_PATH, zone)
48
-
49
- if !File.exists?(file)
50
- raise Timezone::Error::InvalidZone, "'#{zone}' is not a valid zone."
51
- end
52
-
53
- File.read(file)
53
+ def get_zone_data(name)
54
+ File.read(File.join(ZONE_FILE_PATH, name))
54
55
  end
55
56
  end
56
57
  end
58
+
59
+ private_constant :Loader
57
60
  end
@@ -2,9 +2,13 @@ require 'timezone/error'
2
2
 
3
3
  module Timezone
4
4
  module Lookup
5
+ # @abstract Subclass and override {#lookup} to implement
6
+ # a custom Lookup class.
5
7
  class Basic
6
8
  attr_reader :config
7
9
 
10
+ # @param config [#protocol, #url, #request_handler] a configuration
11
+ # object
8
12
  def initialize(config)
9
13
  if config.protocol.nil?
10
14
  raise(::Timezone::Error::InvalidConfig, 'missing protocol')
@@ -17,11 +21,29 @@ module Timezone
17
21
  @config = config
18
22
  end
19
23
 
24
+ # Returns an instance of the request handler.
25
+ #
26
+ # @return [#get] an instance of a request handler
20
27
  def client
21
- @client ||= config.http_client.new(config.protocol, config.url)
28
+ # TODO: Remove http_client once on 1.0.0
29
+ @client ||=
30
+ if !config.request_handler.nil?
31
+ config.request_handler.new(config)
32
+ else
33
+ config.http_client.new(config.protocol, config.url)
34
+ end
22
35
  end
23
36
 
24
- def lookup(lat, lng)
37
+ # Returns a timezone name for a given lat, long pair.
38
+ #
39
+ # @param lat [Double] latitude coordinate
40
+ # @param long [Double] longitude coordinate
41
+ # @return [String] the timezone name
42
+ # @return [nil] if the lat, long pair does not resolve to an
43
+ # actual timezone
44
+ # @raise [Timezone::Error::Base] if an error occurred while
45
+ # while performing the lookup
46
+ def lookup(_lat, _long)
25
47
  raise NoMethodError, 'lookup is not implemented'
26
48
  end
27
49
  end
@@ -5,17 +5,21 @@ require 'uri'
5
5
 
6
6
  module Timezone
7
7
  module Lookup
8
+ # @!visibility private
8
9
  class Geonames < ::Timezone::Lookup::Basic
9
10
  def initialize(config)
10
11
  if config.username.nil?
11
- raise(::Timezone::Error::InvalidConfig, 'missing username')
12
+ raise(::Timezone::Error::InvalidConfig, 'missing username'.freeze)
12
13
  end
13
14
 
15
+ config.protocol ||= 'http'.freeze
16
+ config.url ||= 'api.geonames.org'.freeze
17
+
14
18
  super
15
19
  end
16
20
 
17
- def lookup(lat, lng)
18
- response = client.get(url(lat, lng))
21
+ def lookup(lat, long)
22
+ response = client.get(url(lat, long))
19
23
 
20
24
  return unless response.code =~ /^2\d\d$/
21
25
 
@@ -32,10 +36,10 @@ module Timezone
32
36
 
33
37
  private
34
38
 
35
- def url(lat, lng)
39
+ def url(lat, long)
36
40
  query = URI.encode_www_form(
37
41
  'lat' => lat,
38
- 'lng' => lng,
42
+ 'lng' => long,
39
43
  'username' => config.username)
40
44
  "/timezoneJSON?#{query}"
41
45
  end
@@ -8,53 +8,62 @@ require 'cgi'
8
8
 
9
9
  module Timezone
10
10
  module Lookup
11
+ # @!visibility private
11
12
  class Google < ::Timezone::Lookup::Basic
12
13
  def initialize(config)
13
- if config.google_api_key.nil?
14
- raise(::Timezone::Error::InvalidConfig, 'missing api key')
14
+ if config.api_key.nil?
15
+ raise(::Timezone::Error::InvalidConfig, 'missing api key'.freeze)
15
16
  end
17
+
18
+ config.protocol ||= 'https'.freeze
19
+ config.url ||= 'maps.googleapis.com'.freeze
20
+
16
21
  super
17
22
  end
18
23
 
19
- def lookup(lat,lng)
20
- response = client.get(url(lat,lng))
24
+ def lookup(lat, long)
25
+ response = client.get(url(lat, long))
21
26
 
22
- if response.code == '403'
23
- raise(Timezone::Error::Google, '403 Forbidden')
27
+ if response.code == '403'.freeze
28
+ raise(Timezone::Error::Google, '403 Forbidden'.freeze)
24
29
  end
25
30
 
26
31
  return unless response.code =~ /^2\d\d$/
27
32
  data = JSON.parse(response.body)
28
33
 
29
- if data['status'] != 'OK'
34
+ if data['status'.freeze] != 'OK'.freeze
30
35
  raise(Timezone::Error::Google, data['errorMessage'])
31
36
  end
32
37
 
33
- data['timeZoneId']
38
+ data['timeZoneId'.freeze]
34
39
  rescue => e
35
40
  raise(Timezone::Error::Google, e.message)
36
41
  end
37
42
 
38
43
  private
39
44
 
45
+ def use_google_enterprise?
46
+ !config.client_id.nil?
47
+ end
48
+
40
49
  def authorize(url)
41
- if config.use_google_enterprise?
42
- url += "&client=#{CGI.escape(config.google_client_id)}"
50
+ if use_google_enterprise?
51
+ url += "&client=#{CGI.escape(config.client_id)}"
43
52
 
44
53
  sha1 = OpenSSL::Digest.new('sha1')
45
- binary_key = Base64.decode64(config.google_api_key.tr('-_','+/'))
54
+ binary_key = Base64.decode64(config.api_key.tr('-_', '+/'))
46
55
  binary_signature = OpenSSL::HMAC.digest(sha1, binary_key, url)
47
- signature = Base64.encode64(binary_signature).tr('+/','-_').strip
56
+ signature = Base64.encode64(binary_signature).tr('+/', '-_').strip
48
57
 
49
58
  url + "&signature=#{signature}"
50
59
  else
51
- url + "&key=#{config.google_api_key}"
60
+ url + "&key=#{config.api_key}"
52
61
  end
53
62
  end
54
63
 
55
- def url(lat,lng)
64
+ def url(lat, long)
56
65
  query = URI.encode_www_form(
57
- 'location' => "#{lat},#{lng}",
66
+ 'location' => "#{lat},#{long}",
58
67
  'timestamp' => Time.now.to_i)
59
68
 
60
69
  authorize("/maps/api/timezone/json?#{query}")