timezone 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 46a05b3cbaa15e1f491d73af323de8afaa25d1fd
4
+ data.tar.gz: f8f66464396431dbf25a5e4f2573829a1ac7fe58
5
+ SHA512:
6
+ metadata.gz: 68fd48be56823ac5a85b6f9c03c7d9a82356e056b6d3d503e5bb6f8b39a3f43d4692e1996929aab3f0eaef409963f49c25d07e9c86229a60d29dc02119564a4a
7
+ data.tar.gz: 60264e09a76c2a21c10d6cd2cf2c66551c48715dfac8a56b5b4d9568f94a1479adb2e60c185c1ed261133147a8ed343e0cd1108f475a20dd3cb3b9eba37e02fb
data/.gitignore CHANGED
@@ -5,3 +5,4 @@
5
5
  .idea/*
6
6
  Gemfile.lock
7
7
  pkg/*
8
+ .yardoc/
@@ -101,6 +101,27 @@ Finally, by default the **Zone#list** method will order the results by the timez
101
101
  c.order_list_by = :title
102
102
  end
103
103
 
104
+ ## Using Your Own HTTP Client
105
+
106
+ If you have non-standard http request needs or want to have more control over
107
+ API calls to Geonames, you can write your own very simple http client wrapper
108
+ instead of using the built-in default.
109
+
110
+ class MyHTTPClient
111
+ def initialize(protocol, host)
112
+ end
113
+
114
+ # Return a response object that responds to #body and #code
115
+ def get(url)
116
+ end
117
+ end
118
+
119
+ Timezone::Configure.begin do |c|
120
+ c.http_client = MyHTTPClient
121
+ end
122
+
123
+ For an example, see `Timezone::NetHTTPClient` which uses the standard `Net::HTTP` library to perform API calls.
124
+
104
125
  ## Build Status [![Build Status](https://secure.travis-ci.org/panthomakos/timezone.png?branch=master)](http://travis-ci.org/panthomakos/timezone)
105
126
 
106
127
  ## Code Quality [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/panthomakos/timezone)
@@ -1,22 +1,72 @@
1
+ require 'timezone/net_http_client'
2
+
1
3
  module Timezone
2
4
  # Configuration class for the Timezone gem.
3
5
  #
4
- # Timezone::Configure.begin do |c| ... end
6
+ # You'll want to sign up for a geonames username at
7
+ # {http://www.geonames.org/login Geonames}. Use the username to
8
+ # configure your application for latitude and longitude based
9
+ # timezone searches.
10
+ #
11
+ # If you aren't going to initialize timezone objects based on lat,lng
12
+ # then this configuration is not necessary.
5
13
  #
6
- # c.username = username - the geonames username you use to access the geonames timezone API.
14
+ # @example
15
+ # Timezone::Configure.begin do |c|
16
+ # c.url = 'api.geonames.org'
17
+ # c.username = 'foo-bar'
18
+ # end
7
19
  #
8
- # Signup for a geonames username at http://www.geonames.org/login. Use that username to configure
9
- # your application for latitude and longitude based timezone searches. If you aren't going to
10
- # initialize timezone objects based on latitude and longitude then this configuration is not necessary.
11
20
  class Configure
21
+ # The Geonames API URL
22
+ #
23
+ # @return [Sting]
24
+ # the Geonames API URL ('api.geonames.org')
12
25
  def self.url
13
26
  @@url ||= 'api.geonames.org'
14
27
  end
15
28
 
16
- def self.url= url
29
+ # The Geonames API URL
30
+ #
31
+ # @param [Sting] url
32
+ # the Geonames API URL
33
+ def self.url=(url)
17
34
  @@url = url
18
35
  end
19
36
 
37
+ # The Geonames API HTTP protocol
38
+ #
39
+ # @param [String] protocol
40
+ # the Geonames API HTTP procotol
41
+ def self.protocol=(protocol)
42
+ @@protocol = protocol
43
+ end
44
+
45
+ # The Geonames API HTTP protocol
46
+ #
47
+ # @return [Sting]
48
+ # the Geonames API URL ('api.geonames.org')
49
+ def self.protocol
50
+ @protocol ||= 'http'
51
+ end
52
+
53
+ # The HTTP client that handles requests to geonames
54
+ #
55
+ # @return [Object]
56
+ # the HTTP client ({Timezone::NetHTTPClient Timezone::NetHTTPClient})
57
+ def self.http_client
58
+ @@http_client ||= Timezone::NetHTTPClient
59
+ end
60
+
61
+ # The HTTP client that handles requests to geonames
62
+ #
63
+ # @param [Object] client
64
+ # the HTTP client that handles requests to geonames
65
+ #
66
+ def self.http_client=(client)
67
+ @@http_client = client
68
+ end
69
+
20
70
  def self.username
21
71
  @@username
22
72
  end
@@ -53,6 +103,5 @@ module Timezone
53
103
  def self.order_list_by=(order)
54
104
  @@order_by = order
55
105
  end
56
-
57
106
  end
58
107
  end
@@ -0,0 +1,23 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+
4
+ module Timezone
5
+ # A basic HTTP Client that handles requests to Geonames. You can create
6
+ # your own version of this class if you want to use a proxy or a
7
+ # different http library such as faraday.
8
+ #
9
+ # @example
10
+ # Timezone::Configure.begin do |c|
11
+ # c.http_client = Timezone::NetHTTPClient
12
+ # end
13
+ class NetHTTPClient
14
+ def initialize(protocol, host)
15
+ uri = URI.parse("#{protocol}://#{host}")
16
+ @http = Net::HTTP.new(uri.host, uri.port)
17
+ end
18
+
19
+ def get(url)
20
+ @http.request(Net::HTTP::Get.new(url))
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module Timezone
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require 'json'
2
2
  require 'date'
3
3
  require 'time'
4
- require 'net/http'
4
+
5
5
  require File.expand_path(File.dirname(__FILE__) + '/error')
6
6
  require File.expand_path(File.dirname(__FILE__) + '/configure')
7
7
  require File.expand_path(File.dirname(__FILE__) + '/active_support')
@@ -146,9 +146,17 @@ module Timezone
146
146
 
147
147
  def timezone_id lat, lon #:nodoc:
148
148
  begin
149
- response = Net::HTTP.get(Timezone::Configure.url, "/timezoneJSON?lat=#{lat}&lng=#{lon}&username=#{Timezone::Configure.username}")
150
- JSON.parse(response)['timezoneId']
151
- rescue Exception => e
149
+ response = http_client.get("/timezoneJSON?lat=#{lat}&lng=#{lon}&username=#{Timezone::Configure.username}")
150
+ return nil unless response.code =~ /^2\d\d$/
151
+
152
+ data = JSON.parse(response.body)
153
+
154
+ if data['status'] && data['status']['value'] == 18
155
+ raise Timezone::Error::GeoNames, "api limit reached"
156
+ end
157
+
158
+ return data['timezoneId']
159
+ rescue => e
152
160
  raise Timezone::Error::GeoNames, e.message
153
161
  end
154
162
  end
@@ -161,5 +169,11 @@ module Timezone
161
169
  end
162
170
  end
163
171
 
172
+ private
173
+
174
+ def http_client #:nodoc:
175
+ @http_client ||= Timezone::Configure.http_client.new(
176
+ Timezone::Configure.protocol, Timezone::Configure.url)
177
+ end
164
178
  end
165
179
  end
@@ -0,0 +1 @@
1
+ {"status":{"message":"the daily limit of 30000 credits for XXXXX has been exceeded. Please throttle your requests or use the commercial service.","value":18}}
@@ -0,0 +1 @@
1
+ {"time":"2013-10-29 15:30","countryName":"Australia","sunset":"2013-10-30 19:42","rawOffset":9.5,"dstOffset":9.5,"countryCode":"AU","gmtOffset":10.5,"lng":138.477041423321,"sunrise":"2013-10-30 06:17","timezoneId":"Australia/Adelaide","lat":-34.92771808058}
@@ -1,6 +1,7 @@
1
1
  require 'timezone'
2
2
  require 'timezone/zone'
3
3
  require 'test/unit'
4
+ require "mocha/setup"
4
5
  require 'timecop'
5
6
 
6
7
  class TimezoneTest < Test::Unit::TestCase
@@ -137,12 +138,48 @@ class TimezoneTest < Test::Unit::TestCase
137
138
  assert_equal local.to_i, timezone.time(utc).to_i
138
139
  end
139
140
 
141
+ class HTTPTestClient
142
+ class << self ; attr_accessor :body ; end
143
+
144
+ Response = Struct.new(:body) do
145
+ def code ; '200' ; end
146
+ end
147
+
148
+ def initialize(protocol, host)
149
+ end
150
+
151
+ def get(url)
152
+ HTTPTestClient::Response.new(self.class.body)
153
+ end
154
+ end
155
+
140
156
  def test_using_lat_lon_coordinates
141
- Timezone::Configure.begin { |c| c.username = 'timezone' }
157
+ mock_path = File.expand_path(File.join(File.dirname(__FILE__), 'mocks'))
158
+ HTTPTestClient.body = File.open(mock_path + '/lat_lon_coords.txt').read
159
+
160
+ Timezone::Configure.begin do |c|
161
+ c.http_client = HTTPTestClient
162
+ c.username = 'timezone'
163
+ end
164
+
142
165
  timezone = Timezone::Zone.new :latlon => [-34.92771808058, 138.477041423321]
143
166
  assert_equal 'Australia/Adelaide', timezone.zone
144
167
  end
145
168
 
169
+ def test_api_limit_read_lat_lon_coordinates
170
+ mock_path = File.expand_path(File.join(File.dirname(__FILE__), 'mocks'))
171
+ HTTPTestClient.body = File.open(mock_path + '/api_limit_reached.txt').read
172
+
173
+ Timezone::Configure.begin do |c|
174
+ c.http_client = HTTPTestClient
175
+ c.username = 'timezone'
176
+ end
177
+
178
+ assert_raise Timezone::Error::GeoNames, 'api limit reached' do
179
+ Timezone::Zone.new :latlon => [-34.92771808058, 138.477041423321]
180
+ end
181
+ end
182
+
146
183
  def test_australian_timezone_with_dst
147
184
  timezone = Timezone::Zone.new :zone => 'Australia/Adelaide'
148
185
  utc = Time.utc(2010, 12, 23, 19, 37, 15)
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.homepage = "http://github.com/panthomakos/timezone"
12
12
  s.summary = "timezone-#{Timezone::VERSION}"
13
13
  s.description = %q{A simple way to get accurate current and historical timezone information based on zone or latitude and longitude coordinates. This gem uses the tz database (http://www.twinsun.com/tz/tz-link.htm) for historical timezone information. It also uses the geonames API for timezone latitude and longitude lookup (http://www.geonames.org/export/web-services.html).}
14
+ s.license = 'MIT'
14
15
 
15
16
  s.rubyforge_project = "timezone"
16
17
 
@@ -24,4 +25,5 @@ Gem::Specification.new do |s|
24
25
  s.add_development_dependency('rake')
25
26
  s.add_development_dependency('minitest', '~> 4.0')
26
27
  s.add_development_dependency('timecop')
28
+ s.add_development_dependency('mocha')
27
29
  end
metadata CHANGED
@@ -1,36 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timezone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
5
- prerelease:
4
+ version: 0.3.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Pan Thomakos
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-10-21 00:00:00.000000000 Z
11
+ date: 2014-04-15 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - '>='
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: minitest
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ~>
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ~>
44
39
  - !ruby/object:Gem::Version
@@ -46,17 +41,29 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: timecop
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ! '>='
45
+ - - '>='
52
46
  - !ruby/object:Gem::Version
53
47
  version: '0'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ! '>='
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: mocha
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
60
67
  - !ruby/object:Gem::Version
61
68
  version: '0'
62
69
  description: A simple way to get accurate current and historical timezone information
@@ -550,6 +557,7 @@ files:
550
557
  - lib/timezone/active_support.rb
551
558
  - lib/timezone/configure.rb
552
559
  - lib/timezone/error.rb
560
+ - lib/timezone/net_http_client.rb
553
561
  - lib/timezone/parser.rb
554
562
  - lib/timezone/parser/data.rb
555
563
  - lib/timezone/parser/link.rb
@@ -565,6 +573,8 @@ files:
565
573
  - lib/timezone/zone.rb
566
574
  - test/data/Helsinki_rules_without_timestamps.json
567
575
  - test/data/asia
576
+ - test/mocks/api_limit_reached.txt
577
+ - test/mocks/lat_lon_coords.txt
568
578
  - test/timezone/parser/rule/on_rules_test.rb
569
579
  - test/timezone/parser/rule_test.rb
570
580
  - test/timezone/parser/zone/data_generator_test.rb
@@ -574,33 +584,35 @@ files:
574
584
  - test/timezone_test.rb
575
585
  - timezone.gemspec
576
586
  homepage: http://github.com/panthomakos/timezone
577
- licenses: []
587
+ licenses:
588
+ - MIT
589
+ metadata: {}
578
590
  post_install_message:
579
591
  rdoc_options:
580
592
  - --charset=UTF-8
581
593
  require_paths:
582
594
  - lib
583
595
  required_ruby_version: !ruby/object:Gem::Requirement
584
- none: false
585
596
  requirements:
586
- - - ! '>='
597
+ - - '>='
587
598
  - !ruby/object:Gem::Version
588
599
  version: '0'
589
600
  required_rubygems_version: !ruby/object:Gem::Requirement
590
- none: false
591
601
  requirements:
592
- - - ! '>='
602
+ - - '>='
593
603
  - !ruby/object:Gem::Version
594
604
  version: '0'
595
605
  requirements: []
596
606
  rubyforge_project: timezone
597
- rubygems_version: 1.8.23
607
+ rubygems_version: 2.0.14
598
608
  signing_key:
599
- specification_version: 3
600
- summary: timezone-0.3.1
609
+ specification_version: 4
610
+ summary: timezone-0.3.2
601
611
  test_files:
602
612
  - test/data/Helsinki_rules_without_timestamps.json
603
613
  - test/data/asia
614
+ - test/mocks/api_limit_reached.txt
615
+ - test/mocks/lat_lon_coords.txt
604
616
  - test/timezone/parser/rule/on_rules_test.rb
605
617
  - test/timezone/parser/rule_test.rb
606
618
  - test/timezone/parser/zone/data_generator_test.rb