owmo 1.2.0 → 2.0.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a412e9d668b31fda079d98755fc42eda2ecb0914
4
- data.tar.gz: 74ae3e5e9d8069f5c8466f28ba47a271aa72032f
3
+ metadata.gz: 84b6f969b10f394d6c8f9c0fda1ac2dbd6929811
4
+ data.tar.gz: 0ebeca0df38b5d6104890759bdf756feccf3fd68
5
5
  SHA512:
6
- metadata.gz: a06e37fd046e4fa840ba9b2e04e8a176ceb8db775575a3c8ad3b673321f103bf161d766202f249b60a4ad1def192a80c7073b618caa97e3d2ae9b98d836d6484
7
- data.tar.gz: 7bc73c2851eb22dbfc95e7a6f2cb701774dbad74e04972fcc96b7c0bcabb2c060522c07319c68ed6f1be0ae53645aba4f19d03c6213523b25183a4df1b000978
6
+ metadata.gz: 10dcefd739e026f47f6e3b4adfbef8101fbfee1ecf1477b483a5d8b418eb3b04aa4c0591687ccc794446dc100514c7f98d1a8cda64faa57533ac99fbc1a1cc1d
7
+ data.tar.gz: 87a157f21b913e319187b28569e058cdd85401217af165ed00e031528f1d53c601c80a2c30dc6e8b8615d80235779623ba690608f5f0f0f274515800f6bb4cee
@@ -0,0 +1,7 @@
1
+ require 'owmo'
2
+
3
+ api_key = ""
4
+
5
+ OWMO::weather(api_key) do |weather|
6
+ puts weather.get :box, bbox: [12, 32, 15, 37, 10].join(',')
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'owmo'
2
+
3
+ api_key = ""
4
+
5
+ OWMO::weather(api_key) do |weather|
6
+ puts weather.get :circle, lat: 55.5, lon: 37.5, cnt: 10
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'owmo'
2
+
3
+ api_key = ""
4
+
5
+ OWMO::weather(api_key) do |weather|
6
+ puts weather.get :group, id: [4850751,4887398,2643743,4164138,5368361].join(',')
7
+ end
@@ -1,15 +1,9 @@
1
1
  require 'json'
2
2
 
3
-
4
3
  module CoreExtensions
5
4
  module Net
6
5
  module HTTPResponse
7
6
  module WeatherResponse
8
- =begin rdoc
9
- Contains the weather data. If it's JSON, then it'll be a hash, other forms (XML, HTML)
10
- will be raw format. The raw JSON is also available using the self.body.
11
- =end
12
- attr_reader :weather
13
7
 
14
8
  =begin rdoc
15
9
  Returns the weather
@@ -17,35 +11,32 @@ Returns the weather
17
11
  def weather
18
12
  parse_weather
19
13
  @weather
20
- end # weather
14
+ end
21
15
 
22
16
  =begin rdoc
23
17
  Returns the response code
24
18
  =end
25
- public
26
19
  def weather_code
27
20
  parse_weather
28
21
  return (@weather['cod'] || "200").to_i if @weather.is_a? Hash
29
22
  200
30
- end # weather_error
23
+ end
31
24
 
32
25
  =begin rdoc
33
26
  Returns the response message
34
27
  =end
35
- public
36
28
  def weather_message
37
29
  parse_weather
38
30
  return @weather['message'] if @weather.is_a? Hash
39
- ""
40
- end # weather_message
31
+ "None"
32
+ end
41
33
 
42
34
  =begin rdoc
43
35
  Returns boolean if the response contains an error or not.
44
36
  =end
45
- public
46
37
  def has_error?
47
38
  weather_code != 200
48
- end # has_error?
39
+ end
49
40
 
50
41
  =begin rdoc
51
42
  Attempts to parse the body to JSON. This is so we don't have to continually
@@ -58,9 +49,9 @@ parse the raw JSON.
58
49
  rescue
59
50
  @weather = self.body
60
51
  end if @weather.nil?
61
- end # parse_weather
52
+ end
62
53
 
63
- end # WeatherResponse
64
- end # HTTPResponse
65
- end # Net
66
- end # CoreExtensions
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/owmo.rb CHANGED
@@ -1,4 +1,3 @@
1
- require "owmo/api"
2
1
  require "owmo/version"
3
2
  require "owmo/weather"
4
3
 
@@ -18,20 +17,26 @@ Yield a weather object for querying weather data
18
17
  ==== Attributes
19
18
  * +api_key:+ - {OpenWeatherMap.org API key}[http://openweathermap.org/appid]
20
19
  ==== Examples
21
- api_key = "<My API Key>"
22
- OWMO::weather api_key do |weather|
23
- puts weather.get :current, city_name: "London,uk"
20
+ * Single request:
21
+ api_key = ''
22
+ OWMO::weather(api_key).get :current, city_name: "London,UK"
23
+ * Muliple requests:
24
+ api_key = ''
25
+ OWMO::weather(api_key) do |weather|
26
+ puts weather.get :current, city_name: "London,UK"
27
+ puts weather.get :forecast5, city_name: "London,UK"
28
+ puts weather.get :forecast16, city_name: "London,UK"
24
29
  end
25
30
  =end
26
31
  public
27
32
  def self.weather(api_key, **params)
28
- weather = Weather.new(api_key, params)
29
-
30
- if block_given?
31
- yield weather
32
- else
33
- return weather
34
- end # if
35
- end # weather
33
+ Weather.new(api_key, params) do |weather|
34
+ if block_given?
35
+ yield weather
36
+ else
37
+ return weather
38
+ end
39
+ end
40
+ end
36
41
 
37
- end # OWMO
42
+ end
data/lib/owmo/version.rb CHANGED
@@ -3,6 +3,6 @@ module OWMO
3
3
  =begin rdoc
4
4
  Gem Version
5
5
  =end
6
- VERSION = "1.2.0"
6
+ VERSION = "2.0.0"
7
7
 
8
- end # OWMO
8
+ end
data/lib/owmo/weather.rb CHANGED
@@ -1,9 +1,12 @@
1
- require 'owmo/api'
2
- require 'owmo/weather/exceptions'
3
- require 'owmo/weather/parameters'
1
+ require 'net/http'
2
+ require 'time'
3
+ require 'core_extensions/net/http_response/weather_response'
4
4
 
5
- require 'set'
6
- require 'uri'
5
+
6
+ =begin rdoc
7
+ Include some weather response info into Net::HTTPResponse
8
+ =end
9
+ Net::HTTPResponse.include CoreExtensions::Net::HTTPResponse::WeatherResponse
7
10
 
8
11
 
9
12
  module OWMO
@@ -16,20 +19,68 @@ A weather class for retrieving current and forecasted weather conditions.
16
19
  api_key = "<My API Key>"
17
20
  weather = OWMO::Weather.new api_key: api_key
18
21
  puts weather.get :current, city_name: "London,uk"
19
-
20
22
  =end
21
23
  class Weather
22
- include WeatherAPI
23
- include WeatherExceptions
24
- include WeatherParameters
25
24
 
25
+ =begin rdoc
26
+ Weather response error to handle errors received from OpenWeatherMap.orgs API
27
+ =end
28
+ class WeatherResponseError < StandardError
29
+ def initialize(response)
30
+ @response = response
31
+ super("ERROR #{@response.weather_code}: #{@response.weather_message}")
32
+ end
33
+ end
34
+
35
+ =begin rdoc
36
+ OpenWeatherMap.Org weather API key
37
+ =end
26
38
  attr_reader :api_key
27
39
 
28
- def initialize(api_key, **kwargs) #:notnew:
40
+ =begin rdoc
41
+ Access current or forecasted conditions by (required):
42
+ =end
43
+ Paths = {
44
+ current: 'weather', # Current weather data
45
+ group: 'group', # Current weather w/multiple IDs
46
+ box: 'box/city', # Current weather w/in a rectangle box
47
+ circle: 'find', # Current weather w/in a circle
48
+ forecast5: 'forecast', # 5 day / 3 hour forecast
49
+ forecast16: 'forecast/daily' # 16 day / daily forecast
50
+ }
51
+
52
+ =begin rdoc
53
+ Geocode aliases
54
+ =end
55
+ Geocode_Aliases = {
56
+ city_name: :q,
57
+ city_id: :id,
58
+ zip_code: :zip,
59
+ latitude: :lat,
60
+ longitude: :lon
61
+ }
62
+
63
+ =begin rdoc
64
+ Either yeild the class, or instanciate it.
65
+ ==== Attributes
66
+ * +api_key+ - OpenWEatherMap.Org's weather API key
67
+ * +**kwargs+ - Any additional paramters
68
+ =end
69
+ def initialize(api_key, **kwargs)
70
+ @debug = kwargs[:debug] || FALSE
71
+ log "Debug= #{@debug}"
72
+
29
73
  @api_key = api_key
74
+ log "Api Key= #{@api_key}"
30
75
 
31
- yield self if block_given?
32
- end # initialize
76
+ log "Args= #{kwargs}"
77
+
78
+ if block_given?
79
+ log "Yielding"
80
+ yield self
81
+ log "Yield complete."
82
+ end
83
+ end
33
84
 
34
85
  =begin rdoc
35
86
  A weather class for retrieving current and forecasted weather conditions.
@@ -43,54 +94,77 @@ A weather class for retrieving current and forecasted weather conditions.
43
94
  =end
44
95
  public
45
96
  def get(path, **query)
97
+ log "Starting request= #{path} -> #{query}"
98
+ start = Time.now
99
+
46
100
  # Format Geocode info
47
- query = check_geocodes query
101
+ query = alias_geocodes(query)
48
102
 
49
103
  # Add the api key
50
104
  query[:APPID] = @api_key
51
105
 
52
106
  # Create the uri
53
- raise InvalidPathSpecified.new(path) if Paths[path].nil?
54
- uri = URI "#{OWMO::URL}/#{Paths[path]}?#{URI.encode_www_form(query).gsub('%2C', ',')}"
107
+ uri = format_uri(OWMO::URL, Paths[path], query)
55
108
 
56
109
  # Get the weather data
57
- get_weather(uri)
110
+ weather = GET(uri)
111
+
112
+ elapsed_sec = (Time.now - start).round 5
113
+ log "Request completed in #{elapsed_sec} seconds."
58
114
 
59
- end # get
115
+ weather
116
+ end
60
117
 
61
118
  =begin rdoc
62
- Ensure appropriate query options are applied to the final URI
119
+ Aliases some geocode parameters to the correct ones, for example :city_name is
120
+ easier to read than :q
63
121
  =end
64
- def check_geocodes(**query)
122
+ private
123
+ def alias_geocodes(**query)
124
+ log "Query before= #{query}"
65
125
 
66
- # May never be called since query is requiredcity_name
67
- raise MissingGeocodes if query.size == 0
126
+ (query.keys & Geocode_Aliases.keys).each do |key|
127
+ query[Geocode_Aliases[key]] = query.delete(key)
128
+ end
68
129
 
69
- Geocodes.each do |name, geocodes|
130
+ log "Query after= #{query}"
131
+ query
132
+ end
70
133
 
71
- # Get the common keys
72
- intersect = geocodes[:options].flatten & query.keys
73
-
74
- # If there are common keys
75
- if intersect.size > 0 then
134
+ =begin rdoc
135
+ Formats the url with the given url, path, and query
136
+ =end
137
+ private
138
+ def format_uri(url, path, query)
139
+ uri = URI "#{url}/#{path}?#{URI.encode_www_form(query).gsub('%2C', ',')}"
140
+ log "URI= #{uri}"
141
+ uri
142
+ end
76
143
 
77
- # Remap any keys if they are not the same as the query
78
- case geocodes[:query]
79
- when Array then
80
- intersect.zip(geocodes[:query]).each do |old_key, new_key|
81
- query[new_key] = query.delete(old_key) unless new_key == old_key
82
- end # intersect
83
- else
84
- query[geocodes[:query]] = query.delete(intersect[0]) unless geocodes[:query] == intersect[0]
85
- end # case
144
+ =begin rdoc
145
+ Sends the GET request to OpenWeatherMap.org
146
+ =end
147
+ private
148
+ def GET(uri)
149
+ log "Starting GET request"
150
+ response = Net::HTTP.start(uri.hostname, uri.port) do |http|
151
+ http.request(Net::HTTP::Get.new(uri))
152
+ end
153
+ log "Request returned= #{response.weather_code}: #{response.weather_message}".gsub(/: $/, '')
86
154
 
87
- return query
88
- end # if
155
+ # Check the response
156
+ raise WeatherResponseError.new(response) if response.has_error?
89
157
 
90
- end # GEOCODES
158
+ response.weather
159
+ end
91
160
 
92
- raise MissingGeocodes
93
- end # check_geocodes
161
+ =begin rdoc
162
+ Simple log method for debugging purposes
163
+ =end
164
+ private
165
+ def log(msg)
166
+ puts "#{DateTime.now} :~> #{msg}" if @debug
167
+ end
94
168
 
95
- end # Weather
96
- end # OWMO
169
+ end
170
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: owmo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robb
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-06-20 00:00:00.000000000 Z
11
+ date: 2017-06-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -70,6 +70,9 @@ files:
70
70
  - bin/console
71
71
  - bin/setup
72
72
  - examples/current.rb
73
+ - examples/current_box.rb
74
+ - examples/current_circle.rb
75
+ - examples/current_group.rb
73
76
  - examples/forecast16.rb
74
77
  - examples/forecast5.rb
75
78
  - examples/query_all.rb
@@ -77,15 +80,10 @@ files:
77
80
  - examples/query_mode.rb
78
81
  - examples/query_units.rb
79
82
  - examples/sinatra_example.rb
80
- - lib/core_extensions/core_extensions.rb
81
83
  - lib/core_extensions/net/http_response/weather_response.rb
82
84
  - lib/owmo.rb
83
- - lib/owmo/api.rb
84
- - lib/owmo/api/exceptions.rb
85
85
  - lib/owmo/version.rb
86
86
  - lib/owmo/weather.rb
87
- - lib/owmo/weather/exceptions.rb
88
- - lib/owmo/weather/parameters.rb
89
87
  - owmo.gemspec
90
88
  homepage: https://github.com/robb-randall/owmo
91
89
  licenses:
@@ -1,4 +0,0 @@
1
- require 'core_extensions/string/uri'
2
-
3
- module CoreExtensions
4
- end # CoreExtensions
data/lib/owmo/api.rb DELETED
@@ -1,41 +0,0 @@
1
- require 'core_extensions/net/http_response/weather_response'
2
- require 'owmo/api/exceptions'
3
-
4
- require 'net/http'
5
- require 'uri'
6
-
7
-
8
- =begin rdoc
9
- Include some weather response info into Net::HTTPResponse
10
- =end
11
- Net::HTTPResponse.include CoreExtensions::Net::HTTPResponse::WeatherResponse
12
-
13
-
14
- =begin rdoc
15
- Net module Mixins
16
- =end
17
- module WeatherAPI
18
- include ApiExceptions
19
-
20
- =begin rdoc
21
- Sends the GET request to OpenWeatherMap.org, and returns the response
22
- =end
23
- private
24
- def get_weather(uri)
25
-
26
- raise "Invalid URI: Expected URI, got #{uri.class}" unless uri.is_a? URI
27
-
28
- # Send the request
29
- request = Net::HTTP::Get.new(uri)
30
-
31
- response = Net::HTTP.start(uri.hostname, uri.port) do |http|
32
- http.request(request)
33
- end # response
34
-
35
- # Check the response
36
- raise WeatherResponseError.new(response) if response.has_error?
37
-
38
- return response.weather
39
-
40
- end # get_weather
41
- end # WeatherAPI
@@ -1,14 +0,0 @@
1
-
2
- module ApiExceptions
3
-
4
- =begin rdoc
5
- Weather response error to handle errors received from OpenWeatherMap.orgs API
6
- =end
7
- class WeatherResponseError < StandardError
8
- def initialize(response)
9
- @response = response
10
- super("ERROR #{@response.weather_code}: #{@response.weather_message}")
11
- end # initialize
12
- end # WeatherResponseError
13
-
14
- end # ApiExceptions
@@ -1,20 +0,0 @@
1
-
2
- module WeatherExceptions
3
-
4
- =begin rdoc
5
- Invalid path specified
6
- =end
7
- class InvalidPathSpecified < StandardError
8
- def initialize(path=nil)
9
- @path = path
10
- super("Invalid path specified: Got: '#{@path}', expected one of: #{Paths.keys}")
11
- end # initialize
12
- end # NoGeocodeSpecified
13
-
14
- =begin rdoc
15
- Missing Geocode from query
16
- =end
17
- class MissingGeocodes < StandardError
18
- end # MissingGeocodes
19
-
20
- end # WeatherExceptions
@@ -1,51 +0,0 @@
1
- module WeatherParameters
2
- attr_reader :Paths, :Geocodes
3
-
4
- =begin rdoc
5
- Access current or forecasted conditions by (required):
6
- * +:current+ - {Current weather data}[http://openweathermap.org/current]
7
- * +:forecast5+ - {5 day / 3 hour forecast}[http://openweathermap.org/forecast5]
8
- * +:forecast16+ - {16 day / daily forecast}[http://openweathermap.org/forecast16]
9
- =end
10
- Paths = {
11
- group: 'group', # Current weather w/multiple IDs
12
- current: 'weather', # Current weather data
13
- forecast5: 'forecast', # 5 day / 3 hour forecast
14
- forecast16: 'forecast/daily' # 16 day / daily forecast
15
- }
16
-
17
- =begin rdoc
18
- {Geocode options (required):}[http://openweathermap.org/current#one]
19
- * +q:+ or +city_name:+ - By city name
20
- * +id:+ or +city_id:+ - By city ID
21
- * +zip:+ or +zip_code:+ - By zip code
22
- * +lat:+, +lon:+ or +latitude:+, +longitude:+ - By geographic coordinates
23
- =end
24
- Geocodes = {
25
- "City Name" => {
26
- query: :q,
27
- options: [:q, :city_name]
28
- },
29
- "City ID" => {
30
- query: :id,
31
- options: [:id, :city_id]
32
- },
33
- "Zip Code" => {
34
- query: :zip,
35
- options: [:zip, :zip_code]
36
- },
37
- "Coordinance" => {
38
- query: [:lat, :lon],
39
- options: [[:lat, :lon], [:lattitude, :longitude]]
40
- },
41
- "Cities Within a Rectangle Zone" => {
42
- query: :bbox,
43
- options: [:bbox]
44
- },
45
- "Cities Within a Circle" => {
46
- query: [:lat, :lon, :cnt],
47
- options: [[:lat, :lon, :cnt],[:lattitude, :longitude, :cnt]]
48
- }
49
- }
50
-
51
- end # WeatherParameters