open-weather-ruby-client 0.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 317dd6924aee3127f7a350a47ad0d4873db645af7d307d07a2f7f5102a058c03
4
+ data.tar.gz: cd4a8bd78a0170ada43260fd0897ba388c54ddff5f9233ea79477c292affd5e4
5
+ SHA512:
6
+ metadata.gz: df44462ca143dcd462d45ba7cb2cfc38ba1c951a705709e4b4b59d80b1b1d78057fff3cfa8aedc2d9f9c26fce1cf2b9c4a5c66178ed939055c0b4afca5083c15
7
+ data.tar.gz: 256c0bac00841ba60a5ce65e10e3b66103c8756e5c619bf93479b74660d092e22973b6e8e07eaac4cdd370be243eb6382ea7f33829fd2db9d65bbe675b61d736
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ### 0.1.0 (5/1/2020)
2
+
3
+ * Initial public release - [@dblock](https://github.com/dblock).
data/LICENSE.md ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Daniel Doubrovkine
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,231 @@
1
+ OpenWeather Ruby Client
2
+ =======================
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/open-weather-ruby-client.svg)](https://badge.fury.io/rb/open-weather-ruby-client)
5
+ [![Build Status](https://travis-ci.org/dblock/open-weather-ruby-client.svg?branch=master)](https://travis-ci.org/dblock/open-weather-ruby-client)
6
+
7
+ A Ruby client for the [OpenWeather API v3](https://openweathermap.org/api).
8
+
9
+ Unlike other clients, including [open-weather](https://github.com/coderhs/ruby_open_weather_map), provides a rich first class interface to OpenWeather models, implements more consistent error handling, and is built with thorough test coverage using actual OpenWeather data.
10
+
11
+ ## Table of Contents
12
+
13
+ - [Installation](#installation)
14
+ - [Usage](#usage)
15
+ - [Current Weather](#current-weather)
16
+ - [Current Weather for Several Cities](#current-weather-for-several-cities)
17
+ - [Cities Within a Rectangle Zone](#cities-within-a-rectangle-zone)
18
+ - [Cities Within a Circle](#cities-within-a-circle)
19
+ - [Multiple Cities by Id](#multiple-cities-by-id)
20
+ - [Configuration](#configuration)
21
+ - [Units](#units)
22
+ - [Language](#language)
23
+ - [Errors](#errors)
24
+ - [Resources](#resources)
25
+ - [Contributing](#contributing)
26
+ - [Copyright and License](#copyright-and-license)
27
+
28
+ ## Installation
29
+
30
+ Add to Gemfile.
31
+
32
+ ```
33
+ gem 'open-weather-ruby-client'
34
+ ```
35
+
36
+ Run `bundle install`.
37
+
38
+ ## Usage
39
+
40
+ Use an access token obtained from [API Keys](https://home.openweathermap.org/api_keys) on the OpenWeather website after registration.
41
+
42
+ ```ruby
43
+ client = OpenWeather::Client.new(
44
+ api_key: "1a2b3c4d5a6b7c8d9a8b7c6d5a4b3c2d1"
45
+ )
46
+ ```
47
+
48
+ ### Current Weather
49
+
50
+ Returns [current weather](https://openweathermap.org/current).
51
+
52
+ ```ruby
53
+ data = client.current_weather(city: 'London') # => OpenWeather::Models::CityWeather
54
+
55
+ data.name # => 'London'
56
+ data.main.feels_like # => 277.73
57
+ data.main.humidity # => 81
58
+ data.main.pressure # => 1005
59
+ data.main.temp # => 282.57
60
+ data.main.temp_max # => 283.15
61
+ data.main.temp_min # => 281.48
62
+ ```
63
+
64
+ Returns the current weather in metric units and Russian metadata.
65
+
66
+ ```ruby
67
+ data = client.current_weather(city: 'Moscow', units: 'metric', lang: 'ru') # => OpenWeather::Models::CityWeather
68
+
69
+ data.name # => 'Москва'
70
+ data.main.temp # => 12
71
+ ```
72
+
73
+ Returns weather by city, optional state (in the US) and optional ISO 3166 country code.
74
+
75
+ ```ruby
76
+ client.current_city('New York', 'NY', 'US')
77
+ client.current_weather(city: 'New York', state: 'NY', country: 'US')
78
+ ```
79
+
80
+ Returns weather by city ID.
81
+
82
+ ```ruby
83
+ client.current_city_id(2643743) # => weather in London
84
+ client.current_weather(id: 2643743) # => weather in London
85
+ ```
86
+
87
+ Returns weather by latitude and longitude.
88
+
89
+ ```ruby
90
+ client.current_geo(51.51, -0.13) # => weather in London
91
+ client.current_weather(lat: 51.51, lon: -0.13) # => weather in London
92
+ ```
93
+
94
+ Returns weather by zip code with an optional country code (defaults to US).
95
+
96
+ ```ruby
97
+ client.current_zip(10018, 'US') # => weather in New York, 10018
98
+ client.current_weather(zip: 10018, country: 'US') # => weather in New York, 10018
99
+ ```
100
+
101
+ See [OpenWeather::Models::CityWeather](lib/open_weather/models/data.rb) for all available properties.
102
+
103
+ ### Current Weather for Several Cities
104
+
105
+ #### Cities Within a Rectangle Zone
106
+
107
+ ```ruby
108
+ data = client.current_cities_geo_box(12, 32, 15, 37, 10) # => OpenWeather::Models::List
109
+
110
+ data.first.name # 'Birkirkara'
111
+ data.main.temp # => 16.23
112
+ ```
113
+
114
+ You can optionally name parameters.
115
+
116
+ ```ruby
117
+ client.current_cities_geo_box(lon_left: 12, lat_bottom: 32, lon_right: 15, lat_top: 37, zoom: 10) # => OpenWeather::Models::List
118
+ ```
119
+
120
+ You can use server clustering of points with `cluster: true`.
121
+
122
+ ```ruby
123
+ client.current_cities_geo_box(12, 32, 15, 37, 10, cluster: true) # => OpenWeather::Models::List
124
+ ```
125
+
126
+ #### Cities Within a Circle
127
+
128
+ ```ruby
129
+ data = client.current_cities_geo_circle(55.5, 37.5, 10) # => OpenWeather::Models::List
130
+
131
+ data.first.name # 'Shcherbinka'
132
+ data.main.temp # => 276.86
133
+ ```
134
+
135
+ You can optionally name parameters.
136
+
137
+ ```ruby
138
+ client.current_cities_geo_circle(lat: 55.5, lon: 37.5, cnt: 7) # => OpenWeather::Models::List
139
+ ```
140
+
141
+ #### Multiple Cities by Id
142
+
143
+ ```ruby
144
+ data = client.current_cities_id(524901, 703448, 2643743) # => OpenWeather::Models::List
145
+
146
+ data.first.name # 'Moscow'
147
+ data.main.temp # => 285.15
148
+ ```
149
+
150
+ ## Configuration
151
+
152
+ You can configure client options, globally.
153
+
154
+ ```ruby
155
+ OpenWeather::Client.configure do |config|
156
+ config.api_key = '1a2b3c4d5a6b7c8d9a8b7c6d5a4b3c2d1'
157
+ config.user_agent = 'OpenWeather Ruby Client/1.0'
158
+ end
159
+ ```
160
+
161
+ The following settings are supported.
162
+
163
+ setting | description
164
+ --------------------|------------
165
+ api_key | Required API key.
166
+ lang | Default language in API responses.
167
+ units | Default units in API responses.
168
+ endpoint | Defaults to `https://api.openweathermap.org/data/2.5/`.
169
+ user_agent | User-agent, defaults to _OpenWeather Ruby Client/version_.
170
+ proxy | Optional HTTP proxy.
171
+ ca_path | Optional SSL certificates path.
172
+ ca_file | Optional SSL certificates file.
173
+ logger | Optional `Logger` instance that logs HTTP requests.
174
+ timeout | Optional open/read timeout in seconds.
175
+ open_timeout | Optional connection open timeout in seconds.
176
+
177
+ ### Units
178
+
179
+ The OpenWeather API returns responses in `standard`, `metric`, and `imperial` units. You can pass `units` into API requests or configure the desired units globally.
180
+
181
+ ```ruby
182
+ data = client.weather(id: 2643743, units: 'metric')
183
+ data.name # => 'London'
184
+ data.main.temp # => 12 (degrees Celsius)
185
+ ```
186
+
187
+ ```ruby
188
+ OpenWeather.configure do |config|
189
+ config.units = 'metric'
190
+ end
191
+
192
+ data = client.weather(id: 2643743)
193
+ data.name # => 'London'
194
+ data.main.temp # => 12 (degrees Celsius)
195
+ ```
196
+
197
+ ### Language
198
+
199
+ The OpenWeather API returns responses in English and supports many other languages. You can pass `lang` into API requests or configure the desired language globally.
200
+
201
+ ```ruby
202
+ data = client.weather(id: 2643743, lang: 'ru')
203
+ data.name # => 'Лондон'
204
+ ```
205
+
206
+ ```ruby
207
+ OpenWeather.configure do |config|
208
+ config.lang = 'ru'
209
+ end
210
+
211
+ data = client.weather(id: 2643743)
212
+ data.name # => 'Лондон'
213
+ ```
214
+
215
+ ## Errors
216
+
217
+ All errors that return HTTP codes 400-600 result in either `Faraday::Error::ResourceNotFound`, `Faraday::Error::ConnectionFailed` or [OpenWeather::Errors::Fault](lib/open_weather/errors/fault.rb) exceptions.
218
+
219
+ ## Resources
220
+
221
+ * [OpenWeather API Documentation](https://openweathermap.org/api)
222
+
223
+ ## Contributing
224
+
225
+ See [CONTRIBUTING](CONTRIBUTING.md).
226
+
227
+ ## Copyright and License
228
+
229
+ Copyright (c) 2020, [Daniel Doubrovkine](https://twitter.com/dblockdotorg)
230
+
231
+ This project is licensed under the [MIT License](LICENSE.md).
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+ require 'faraday_middleware'
5
+ require 'json'
6
+ require 'logger'
7
+ require 'hashie'
8
+ require 'time'
9
+
10
+ require 'active_support/core_ext/object/to_query'
11
+ require 'active_support/core_ext/hash'
12
+ require 'active_support/concern'
13
+
14
+ require_relative 'open_weather/version'
15
+ require_relative 'open_weather/logger'
16
+
17
+ require_relative 'open_weather/errors/fault'
18
+
19
+ require_relative 'open_weather/models/model'
20
+
21
+ require_relative 'open_weather/raise_error'
22
+ require_relative 'open_weather/connection'
23
+ require_relative 'open_weather/request'
24
+ require_relative 'open_weather/config'
25
+ require_relative 'open_weather/errors'
26
+ require_relative 'open_weather/models'
27
+ require_relative 'open_weather/endpoints'
28
+ require_relative 'open_weather/client'
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ class Client
5
+ include Connection
6
+ include Request
7
+ include Endpoints::Current
8
+
9
+ attr_accessor(*Config::ATTRIBUTES)
10
+
11
+ def initialize(options = {})
12
+ OpenWeather::Config::ATTRIBUTES.each do |key|
13
+ send("#{key}=", options[key] || OpenWeather.config.send(key))
14
+ end
15
+ @logger ||= OpenWeather::Logger.logger
16
+ end
17
+
18
+ class << self
19
+ def configure
20
+ block_given? ? yield(Config) : Config
21
+ end
22
+
23
+ def config
24
+ Config
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Config
5
+ extend self
6
+
7
+ ATTRIBUTES = %i[
8
+ endpoint
9
+ api_key
10
+ proxy
11
+ user_agent
12
+ ca_path
13
+ ca_file
14
+ logger
15
+ timeout
16
+ open_timeout
17
+ lang
18
+ units
19
+ ].freeze
20
+
21
+ attr_accessor(*Config::ATTRIBUTES)
22
+
23
+ def reset
24
+ self.endpoint = 'https://api.openweathermap.org/data/2.5'
25
+ self.api_key = nil
26
+ self.user_agent = "OpenWeather Ruby Client/#{OpenWeather::VERSION}"
27
+ self.ca_path = defined?(OpenSSL) ? OpenSSL::X509::DEFAULT_CERT_DIR : nil
28
+ self.ca_file = defined?(OpenSSL) ? OpenSSL::X509::DEFAULT_CERT_FILE : nil
29
+ self.proxy = nil
30
+ self.logger = nil
31
+ self.timeout = nil
32
+ self.open_timeout = nil
33
+ self.lang = nil
34
+ self.units = nil
35
+ end
36
+ end
37
+
38
+ class << self
39
+ def configure
40
+ block_given? ? yield(Config) : Config
41
+ end
42
+
43
+ def config
44
+ Config
45
+ end
46
+ end
47
+ end
48
+
49
+ OpenWeather::Config.reset
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Connection
5
+ private
6
+
7
+ def headers
8
+ {}
9
+ end
10
+
11
+ def connection
12
+ options = {
13
+ headers: headers.merge('Accept' => 'application/json; charset=utf-8')
14
+ }
15
+
16
+ options[:headers]['User-Agent'] = user_agent if user_agent
17
+ options[:proxy] = proxy if proxy
18
+ options[:ssl] = { ca_path: ca_path, ca_file: ca_file } if ca_path || ca_file
19
+
20
+ request_options = {}
21
+ request_options[:timeout] = timeout if timeout
22
+ request_options[:open_timeout] = open_timeout if open_timeout
23
+ options[:request] = request_options if request_options.any?
24
+
25
+ ::Faraday::Connection.new(endpoint, options) do |connection|
26
+ connection.use ::Faraday::Request::Multipart
27
+ connection.use ::Faraday::Request::UrlEncoded
28
+ connection.use ::OpenWeather::Response::RaiseError
29
+ connection.use ::FaradayMiddleware::ParseJson, content_type: /\bjson$/
30
+ connection.response :logger, logger if logger
31
+ connection.adapter ::Faraday.default_adapter
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Endpoints
5
+ module Current
6
+ def current_zip(code, country = nil, options = {})
7
+ options = code.is_a?(Hash) ? options.merge(code) : options.merge(zip: code, country: country)
8
+ current_weather(options)
9
+ end
10
+
11
+ def current_geo(lat, lon = nil, options = {})
12
+ options = lat.is_a?(Hash) ? options.merge(lat) : options.merge(lat: lat, lon: lon)
13
+ current_weather(options)
14
+ end
15
+
16
+ def current_city(name, state = nil, country = nil, options = {})
17
+ options = name.is_a?(Hash) ? options.merge(name) : options.merge(city: name, state: state, country: country)
18
+ current_weather(options)
19
+ end
20
+
21
+ def current_city_id(id, options = {})
22
+ options = id.is_a?(Hash) ? options.merge(id) : options.merge(id: id)
23
+ current_weather(options)
24
+ end
25
+
26
+ def current_weather(options = {})
27
+ if options.key?(:zip) && options.key?(:country)
28
+ options = options.dup
29
+ options[:zip] = [
30
+ options.delete(:zip),
31
+ options.delete(:country)
32
+ ].compact.join(',')
33
+ elsif options.key?(:city)
34
+ options = options.dup
35
+ options[:q] = [
36
+ options.delete(:city),
37
+ options.delete(:state),
38
+ options.delete(:country)
39
+ ].compact.join(',')
40
+ end
41
+ OpenWeather::Models::CityWeather.new(get('weather', options))
42
+ end
43
+
44
+ def current_cities_geo_box(*args)
45
+ options = args[-1].is_a?(Hash) ? args.pop.dup : {}
46
+ options[:bbox] = args.join(',') if args.any?
47
+ options[:bbox] ||= [
48
+ options.delete(:lon_left),
49
+ options.delete(:lat_bottom),
50
+ options.delete(:lon_right),
51
+ options.delete(:lat_top),
52
+ options.delete(:zoom)
53
+ ].join(',')
54
+ OpenWeather::Models::List.new(get('box/city', options))
55
+ end
56
+
57
+ def current_cities_geo_circle(*args)
58
+ options = args[-1].is_a?(Hash) ? args.pop.dup : {}
59
+
60
+ if args.any?
61
+ options[:lat] = args.shift
62
+ options[:lon] = args.shift
63
+ options[:cnt] = args.shift || 1
64
+ end
65
+
66
+ OpenWeather::Models::List.new(get('find', options))
67
+ end
68
+
69
+ def current_cities_id(*args)
70
+ options = args[-1].is_a?(Hash) ? args.pop.dup : {}
71
+ options[:id] = args.join(',') if args.any?
72
+ options[:id] = options.delete(:ids) if options.key?(:ids)
73
+ options[:id] = options[:id].join(',') if options[:id].is_a?(Array)
74
+ OpenWeather::Models::List.new(get('group', options))
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'endpoints/current'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Errors
5
+ class Fault < ::Faraday::ClientError
6
+ def message
7
+ response[:body]['message'] || super
8
+ end
9
+
10
+ def headers
11
+ response[:headers]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'errors/fault'
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'logger'
4
+
5
+ module OpenWeather
6
+ class Logger < ::Logger
7
+ def self.logger
8
+ @logger ||= begin
9
+ logger = new STDOUT
10
+ logger.level = Logger::WARN
11
+ logger
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class CityWeather < Model
6
+ property 'coord', transform_with: ->(v) { OpenWeather::Models::Coord.new(v) }
7
+ property 'weather', transform_with: ->(v) { v.map { |i| OpenWeather::Models::Weather.new(i) } }
8
+ property 'base' # internal parameter
9
+ property 'main', transform_with: ->(v) { OpenWeather::Models::Main.new(v) }
10
+ property 'visibility'
11
+ property 'wind', transform_with: ->(v) { OpenWeather::Models::Wind.new(v) }
12
+ property 'clouds', transform_with: ->(v) { OpenWeather::Models::Clouds.new(v) }
13
+ property 'rain', transform_with: ->(v) { OpenWeather::Models::Rain.new(v) }
14
+ property 'snow', transform_with: ->(v) { OpenWeather::Models::Snow.new(v) }
15
+ property 'dt', transform_with: ->(v) { Time.at(v).utc } # time of data calculation, UTC
16
+ property 'sys', transform_with: ->(v) { OpenWeather::Models::Sys.new(v) }
17
+ property 'id' # city id
18
+ property 'timezone' # shift in seconds from UTC
19
+ property 'name' # city name
20
+ property 'cod' # internal parameter
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Clouds < Model
6
+ property 'all' # cloudiness, %
7
+ property 'today' # cloudiness today, %
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Coord < Model
6
+ property 'lon', from: 'Lon' # City geo location, longitude
7
+ property 'lat', from: 'Lat' # City geo location, latitude
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class List < Model
6
+ include Enumerable
7
+
8
+ property 'cod'
9
+ property 'calctime'
10
+ property 'cnt', from: 'count'
11
+ property 'list', transform_with: ->(v) { v.map { |i| OpenWeather::Models::CityWeather.new(i) } }
12
+ property 'message'
13
+
14
+ def each(&block)
15
+ list.each(&block)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Main < Model
6
+ property 'temp' # temperature in requested unit
7
+ property 'pressure' # atmospheric pressure on the sea_level or grnd_level when unavailable, hPa
8
+ property 'humidity' # humidity in %
9
+ property 'feels_like' # temperature, accounting for the human perception of weather, in requested unit
10
+ property 'temp_min' # minimal currently observed temperature
11
+ property 'temp_max' # maximal currently observed temperature
12
+ property 'sea_level' # atmospheric pressure on the sea level, hPa
13
+ property 'grnd_level' # atmospheric pressure on the ground level, hPa
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Model < Hashie::Trash
6
+ include Hashie::Extensions::IgnoreUndeclared
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Rain < Model
6
+ property '1h' # rain volume for the last 1 hour, mm
7
+ property '3h' # rain volume for the last 3 hours, mm
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Snow < Model
6
+ property '1h' # snow volume for the last 1 hour, mm
7
+ property '3h' # snow volume for the last 3 hours, mm
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Sys < Model
6
+ property 'type' # internal parameter
7
+ property 'id' # internal parameter
8
+ property 'message' # internal parameter
9
+ property 'country' # country code
10
+ property 'sunrise', transform_with: ->(v) { Time.at(v).utc } # sunrise time, UTC
11
+ property 'sunset', transform_with: ->(v) { Time.at(v).utc } # sunset time, UTC
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Weather < Model
6
+ property 'id' # weather condition id
7
+ property 'main' # group of weather parameters (Rain, Snow, Extreme, etc.)
8
+ property 'description' # weather condition within the group, in your language
9
+ property 'icon' # weather icon id
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Wind < Model
6
+ property 'speed' # wind speed in meter/sec or miles/hour
7
+ property 'deg' # wind direction in degrees (meteorological)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'models/model'
4
+ require_relative 'models/clouds'
5
+ require_relative 'models/coord'
6
+ require_relative 'models/city_weather'
7
+ require_relative 'models/main'
8
+ require_relative 'models/sys'
9
+ require_relative 'models/weather'
10
+ require_relative 'models/wind'
11
+ require_relative 'models/rain'
12
+ require_relative 'models/snow'
13
+ require_relative 'models/list'
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Response
5
+ class RaiseError < ::Faraday::Response::Middleware
6
+ def on_complete(env)
7
+ case env[:status]
8
+ when 404
9
+ raise Faraday::Error::ResourceNotFound, response_values(env)
10
+ when 407
11
+ # mimic the behavior that we get with proxy requests with HTTPS
12
+ raise Faraday::Error::ConnectionFailed, %(407 "Proxy Authentication Required ")
13
+ when (400...600).freeze
14
+ raise OpenWeather::Errors::Fault, response_values(env)
15
+ end
16
+ end
17
+
18
+ def response_values(env)
19
+ {
20
+ status: env.status,
21
+ headers: env.response_headers,
22
+ body: env.body
23
+ }
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Request
5
+ def get(path, options = {})
6
+ request(:get, path, options)
7
+ end
8
+
9
+ def post(path, options = {})
10
+ request(:post, path, options)
11
+ end
12
+
13
+ def put(path, options = {})
14
+ request(:put, path, options)
15
+ end
16
+
17
+ def delete(path, options = {})
18
+ request(:delete, path, options)
19
+ end
20
+
21
+ private
22
+
23
+ def request(method, path, options)
24
+ options = options.dup
25
+ options[:appid] ||= api_key if api_key.present?
26
+ options[:lang] ||= lang if lang.present?
27
+ options[:units] ||= units if units.present?
28
+ root = options.delete(:endpoint) || endpoint
29
+ path = [root, path].join('/')
30
+ response = connection.send(method) do |request|
31
+ case method
32
+ when :get, :delete
33
+ request.url(path, options)
34
+ when :post, :put
35
+ request.path = path
36
+ request.body = options unless options.empty?
37
+ end
38
+ request.options.merge!(options.delete(:request)) if options.key?(:request)
39
+ end
40
+ response.body
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ VERSION = '0.1.0'
5
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: open-weather-ruby-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Doubrovkine
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0.9'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0.9'
41
+ - !ruby/object:Gem::Dependency
42
+ name: faraday_middleware
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: hashie
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email: dblock@dblock.org
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - CHANGELOG.md
76
+ - LICENSE.md
77
+ - README.md
78
+ - lib/open-weather-ruby-client.rb
79
+ - lib/open_weather/client.rb
80
+ - lib/open_weather/config.rb
81
+ - lib/open_weather/connection.rb
82
+ - lib/open_weather/endpoints.rb
83
+ - lib/open_weather/endpoints/current.rb
84
+ - lib/open_weather/errors.rb
85
+ - lib/open_weather/errors/fault.rb
86
+ - lib/open_weather/logger.rb
87
+ - lib/open_weather/models.rb
88
+ - lib/open_weather/models/city_weather.rb
89
+ - lib/open_weather/models/clouds.rb
90
+ - lib/open_weather/models/coord.rb
91
+ - lib/open_weather/models/list.rb
92
+ - lib/open_weather/models/main.rb
93
+ - lib/open_weather/models/model.rb
94
+ - lib/open_weather/models/rain.rb
95
+ - lib/open_weather/models/snow.rb
96
+ - lib/open_weather/models/sys.rb
97
+ - lib/open_weather/models/weather.rb
98
+ - lib/open_weather/models/wind.rb
99
+ - lib/open_weather/raise_error.rb
100
+ - lib/open_weather/request.rb
101
+ - lib/open_weather/version.rb
102
+ homepage: http://github.com/dblock/open-weather-ruby-client
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 1.3.6
120
+ requirements: []
121
+ rubygems_version: 3.0.3
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: OpenWeather API Ruby client.
125
+ test_files: []