open-weather-ruby-client 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +10 -1
- data/README.md +78 -9
- data/lib/open-weather-ruby-client.rb +1 -3
- data/lib/open_weather/client.rb +1 -0
- data/lib/open_weather/connection.rb +19 -17
- data/lib/open_weather/endpoints.rb +1 -0
- data/lib/open_weather/endpoints/current.rb +4 -4
- data/lib/open_weather/endpoints/one_call.rb +15 -0
- data/lib/open_weather/models.rb +3 -1
- data/lib/open_weather/models/city.rb +3 -0
- data/lib/open_weather/models/city/weather.rb +38 -0
- data/lib/open_weather/models/list.rb +7 -1
- data/lib/open_weather/models/main.rb +4 -4
- data/lib/open_weather/models/mixins.rb +4 -0
- data/lib/open_weather/models/mixins/speed.rb +45 -0
- data/lib/open_weather/models/mixins/temp.rb +64 -0
- data/lib/open_weather/models/model.rb +13 -0
- data/lib/open_weather/models/one_call.rb +9 -0
- data/lib/open_weather/models/one_call/current_weather.rb +35 -0
- data/lib/open_weather/models/one_call/daily_weather.rb +34 -0
- data/lib/open_weather/models/one_call/feels_like.rb +14 -0
- data/lib/open_weather/models/one_call/hourly_weather.rb +32 -0
- data/lib/open_weather/models/one_call/minutely_weather.rb +12 -0
- data/lib/open_weather/models/one_call/temp.rb +16 -0
- data/lib/open_weather/models/one_call/weather.rb +26 -0
- data/lib/open_weather/models/sys.rb +1 -0
- data/lib/open_weather/models/weather.rb +1 -0
- data/lib/open_weather/models/wind.rb +1 -1
- data/lib/open_weather/raise_error.rb +2 -2
- data/lib/open_weather/version.rb +1 -1
- metadata +19 -6
- data/lib/open_weather/models/city_weather.rb +0 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d3916328b6401b21690d359dab0aa1f893282b9456f7d9960fcb8a3024fc625
|
4
|
+
data.tar.gz: 66657fdd5b0cbad2889b5467cdf9e009b4b8e32cd997c0d86c7ddbf19b14e644
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75c4b1f7baafa1a3a61d5b8ba3223a8ac3eeabc2a6a1ccec506e8f718608088b1289487e562a3061d74ba517c09de8bcd4150e3cbad381e893fb9db1b71976ee
|
7
|
+
data.tar.gz: 6e769293fc354dd3af19780e4cba5a92a0730d2ded3db7976f44d25e8518b49b58bd62bfd7e033ab2ca2d7194db01df03e91a834a67b55824443f45465a9b59e
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
-
### 0.
|
1
|
+
### 0.2.0 (2020/05/17)
|
2
|
+
|
3
|
+
* [#14](https://github.com/dblock/open-weather-ruby-client/pull/14): Added support for One Call API - [@dblock](https://github.com/dblock).
|
4
|
+
* [#16](https://github.com/dblock/open-weather-ruby-client/pull/16): Added support for temperature and wind speed conversion - [@dblock](https://github.com/dblock).
|
5
|
+
* [#16](https://github.com/dblock/open-weather-ruby-client/pull/16): Added `weather#icon_url` returning a parsed `URI` - [@dblock](https://github.com/dblock).
|
6
|
+
* [#15](https://github.com/dblock/open-weather-ruby-client/pull/15): Renamed `CityWeather` to `OpenWeather::Models::City::Weather` - [@dblock](https://github.com/dblock).
|
7
|
+
* [#12](https://github.com/dblock/open-weather-ruby-client/pull/12): Cache `Faraday::Connection` for persistent adapters - [@dblock](https://github.com/dblock).
|
8
|
+
* [#13](https://github.com/dblock/open-weather-ruby-client/pull/13): Require Faraday >= 1.0 - [@dblock](https://github.com/dblock).
|
9
|
+
|
10
|
+
### 0.1.0 (2020/05/01)
|
2
11
|
|
3
12
|
* Initial public release - [@dblock](https://github.com/dblock).
|
data/README.md
CHANGED
@@ -4,9 +4,9 @@ OpenWeather Ruby Client
|
|
4
4
|
[](https://badge.fury.io/rb/open-weather-ruby-client)
|
5
5
|
[](https://travis-ci.org/dblock/open-weather-ruby-client)
|
6
6
|
|
7
|
-
A Ruby client for the [OpenWeather API
|
7
|
+
A Ruby client for the [OpenWeather API v2.5](https://openweathermap.org/api).
|
8
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,
|
9
|
+
Unlike other clients, including [open-weather](https://github.com/coderhs/ruby_open_weather_map), provides a rich first class interface to OpenWeather models, structured timestamps, built-in metrics conversion for temperature and wind speed, offers more consistent error handling, and is implemented with thorough test coverage using actual OpenWeather data.
|
10
10
|
|
11
11
|
## Table of Contents
|
12
12
|
|
@@ -17,8 +17,13 @@ Unlike other clients, including [open-weather](https://github.com/coderhs/ruby_o
|
|
17
17
|
- [Cities Within a Rectangle Zone](#cities-within-a-rectangle-zone)
|
18
18
|
- [Cities Within a Circle](#cities-within-a-circle)
|
19
19
|
- [Multiple Cities by Id](#multiple-cities-by-id)
|
20
|
+
- [One Call](#one-call)
|
21
|
+
- [Current and Forecast Weather](#current-and-forecast-weather)
|
22
|
+
- [Historical Weather](#historical-weather)
|
20
23
|
- [Configuration](#configuration)
|
21
24
|
- [Units](#units)
|
25
|
+
- [Converting Temperature](#converting-temperature)
|
26
|
+
- [Converting Wind Speed](#converting-wind-speed)
|
22
27
|
- [Language](#language)
|
23
28
|
- [Errors](#errors)
|
24
29
|
- [Resources](#resources)
|
@@ -50,21 +55,24 @@ client = OpenWeather::Client.new(
|
|
50
55
|
Returns [current weather](https://openweathermap.org/current).
|
51
56
|
|
52
57
|
```ruby
|
53
|
-
data = client.current_weather(city: 'London') # => OpenWeather::Models::
|
58
|
+
data = client.current_weather(city: 'London') # => OpenWeather::Models::City::Weather
|
54
59
|
|
55
60
|
data.name # => 'London'
|
61
|
+
data.dt # => Time
|
56
62
|
data.main.feels_like # => 277.73
|
57
63
|
data.main.humidity # => 81
|
58
64
|
data.main.pressure # => 1005
|
59
65
|
data.main.temp # => 282.57
|
60
|
-
data.main.temp_max # => 283.15
|
66
|
+
data.main.temp_max # => 283.15, degrees Kelvin
|
67
|
+
data.main.temp_max_c # => 10, degrees Celcius
|
68
|
+
data.main.temp_max_f # => 50.0, degrees Farenheit
|
61
69
|
data.main.temp_min # => 281.48
|
62
70
|
```
|
63
71
|
|
64
72
|
Returns the current weather in metric units and Russian metadata.
|
65
73
|
|
66
74
|
```ruby
|
67
|
-
data = client.current_weather(city: 'Moscow', units: 'metric', lang: 'ru') # => OpenWeather::Models::
|
75
|
+
data = client.current_weather(city: 'Moscow', units: 'metric', lang: 'ru') # => OpenWeather::Models::City::Weather
|
68
76
|
|
69
77
|
data.name # => 'Москва'
|
70
78
|
data.main.temp # => 12
|
@@ -98,10 +106,12 @@ client.current_zip(10018, 'US') # => weather in New York, 10018
|
|
98
106
|
client.current_weather(zip: 10018, country: 'US') # => weather in New York, 10018
|
99
107
|
```
|
100
108
|
|
101
|
-
See [OpenWeather::Models::
|
109
|
+
See [OpenWeather::Models::City::Weather](lib/open_weather/models/city/weather.rb) and related [OpenWeather::Models](lib/open_weather/models) for all available properties.
|
102
110
|
|
103
111
|
### Current Weather for Several Cities
|
104
112
|
|
113
|
+
Collection APIs return [OpenWeather::Models::List](lib/open_weather/models/list.rb), which includes multiple instances of [OpenWeather::Models::City::Weather](lib/open_weather/models/city/weather.rb).
|
114
|
+
|
105
115
|
#### Cities Within a Rectangle Zone
|
106
116
|
|
107
117
|
```ruby
|
@@ -147,6 +157,42 @@ data.first.name # 'Moscow'
|
|
147
157
|
data.main.temp # => 285.15
|
148
158
|
```
|
149
159
|
|
160
|
+
### One Call
|
161
|
+
|
162
|
+
[One Call API](https://openweathermap.org/api/one-call-api) provides current weather, minute forecast for 1 hour, hourly forecast for 48 hours, daily forecast for 7 days, and historical weather data for 5 previous days for any geographical coordinate.
|
163
|
+
|
164
|
+
See [OpenWeather::Models::OneCall](lib/open_weather/models/one_call) for all available models and properties.
|
165
|
+
|
166
|
+
#### Current and Forecast Weather
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
data = client.one_call(lat: 33.441792, lon: -94.037689) # => OpenWeather::Models::OneCall::Weather
|
170
|
+
data.lat # => 33.44
|
171
|
+
data.lon # => -94.04
|
172
|
+
data.timezone # => 'America/Chicago'
|
173
|
+
data.current # => OpenWeather::Models::OneCall::CurrentWeather
|
174
|
+
data.minutely # => Array[OpenWeather::Models::OneCall::MinutelyWeather]
|
175
|
+
data.hourly # => Array[OpenWeather::Models::OneCall::HourlyWeather]
|
176
|
+
data.daily # => Array[OpenWeather::Models::OneCall::DailyWeather]
|
177
|
+
```
|
178
|
+
|
179
|
+
Exclude minutely and hourly data.
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
client.one_call(lat: 33.441792, lon: -94.037689, exclude: ['minutely', 'hourly'])
|
183
|
+
```
|
184
|
+
|
185
|
+
#### Historical Weather
|
186
|
+
|
187
|
+
```ruby
|
188
|
+
data = client.one_call(lat: 33.441792, lon: -94.037689, dt: Time.now - 24 * 60 * 60) # => OpenWeather::Models::OneCall::Weather
|
189
|
+
data.lat # => 33.44
|
190
|
+
data.lon # => -94.04
|
191
|
+
data.timezone # => 'America/Chicago'
|
192
|
+
data.current # => OpenWeather::Models::OneCall::CurrentWeather
|
193
|
+
data.hourly # => Array[OpenWeather::Models::OneCall::HourlyWeather]
|
194
|
+
```
|
195
|
+
|
150
196
|
## Configuration
|
151
197
|
|
152
198
|
You can configure client options, globally.
|
@@ -181,7 +227,7 @@ The OpenWeather API returns responses in `standard`, `metric`, and `imperial` un
|
|
181
227
|
```ruby
|
182
228
|
data = client.weather(id: 2643743, units: 'metric')
|
183
229
|
data.name # => 'London'
|
184
|
-
data.main.temp # => 12
|
230
|
+
data.main.temp # => 12, degrees Celcius
|
185
231
|
```
|
186
232
|
|
187
233
|
```ruby
|
@@ -191,7 +237,30 @@ end
|
|
191
237
|
|
192
238
|
data = client.weather(id: 2643743)
|
193
239
|
data.name # => 'London'
|
194
|
-
data.main.temp # => 12
|
240
|
+
data.main.temp # => 12, degrees Celcius
|
241
|
+
```
|
242
|
+
|
243
|
+
#### Converting Temperature
|
244
|
+
|
245
|
+
APIs that return temperature support conversion between default, metric and imperial units, regardless of what units were requested. The following example requests current weather in metric units in Moscow. Use `_k` for Kelvin, `_c` for Celcius and `_f` for Farenheit.
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
data = client.current_weather(city: 'Moscow', units: 'metric') # => OpenWeather::Models::City::Weather
|
249
|
+
|
250
|
+
data.main.temp_max # => 12, degrees Celcius, metric as requested
|
251
|
+
data.main.temp_max_c # => 12, degrees Celcius
|
252
|
+
data.main.temp_max_k # => 285.15, degrees Kelvin
|
253
|
+
data.main.temp_max_f # => 53.6, degrees Farenheit
|
254
|
+
```
|
255
|
+
|
256
|
+
#### Converting Wind Speed
|
257
|
+
|
258
|
+
Use `_mps` for wind speed in meters-per-second, and `_mph` for miles-per-second.
|
259
|
+
|
260
|
+
```ruby
|
261
|
+
data.wind.speed # => 3, in meters per second, metric as requested
|
262
|
+
data.main.speed_mph # => 6.71, miles per hour
|
263
|
+
data.main.speed_mps # 3, meters per second
|
195
264
|
```
|
196
265
|
|
197
266
|
### Language
|
@@ -214,7 +283,7 @@ data.name # => 'Лондон'
|
|
214
283
|
|
215
284
|
## Errors
|
216
285
|
|
217
|
-
All errors that return HTTP codes 400-600 result in either `Faraday::
|
286
|
+
All errors that return HTTP codes 400-600 result in either `Faraday::ResourceNotFound`, `Faraday::ConnectionFailed` or [OpenWeather::Errors::Fault](lib/open_weather/errors/fault.rb) exceptions.
|
218
287
|
|
219
288
|
## Resources
|
220
289
|
|
@@ -16,13 +16,11 @@ require_relative 'open_weather/logger'
|
|
16
16
|
|
17
17
|
require_relative 'open_weather/errors/fault'
|
18
18
|
|
19
|
-
require_relative 'open_weather/models
|
20
|
-
|
19
|
+
require_relative 'open_weather/models'
|
21
20
|
require_relative 'open_weather/raise_error'
|
22
21
|
require_relative 'open_weather/connection'
|
23
22
|
require_relative 'open_weather/request'
|
24
23
|
require_relative 'open_weather/config'
|
25
24
|
require_relative 'open_weather/errors'
|
26
|
-
require_relative 'open_weather/models'
|
27
25
|
require_relative 'open_weather/endpoints'
|
28
26
|
require_relative 'open_weather/client'
|
data/lib/open_weather/client.rb
CHANGED
@@ -9,26 +9,28 @@ module OpenWeather
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def connection
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
@connection ||= begin
|
13
|
+
options = {
|
14
|
+
headers: headers.merge('Accept' => 'application/json; charset=utf-8')
|
15
|
+
}
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
options[:headers]['User-Agent'] = user_agent if user_agent
|
18
|
+
options[:proxy] = proxy if proxy
|
19
|
+
options[:ssl] = { ca_path: ca_path, ca_file: ca_file } if ca_path || ca_file
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
request_options = {}
|
22
|
+
request_options[:timeout] = timeout if timeout
|
23
|
+
request_options[:open_timeout] = open_timeout if open_timeout
|
24
|
+
options[:request] = request_options if request_options.any?
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
::Faraday::Connection.new(endpoint, options) do |connection|
|
27
|
+
connection.use ::Faraday::Request::Multipart
|
28
|
+
connection.use ::Faraday::Request::UrlEncoded
|
29
|
+
connection.use ::OpenWeather::Response::RaiseError
|
30
|
+
connection.use ::FaradayMiddleware::ParseJson, content_type: /\bjson$/
|
31
|
+
connection.response :logger, logger if logger
|
32
|
+
connection.adapter ::Faraday.default_adapter
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
@@ -38,7 +38,7 @@ module OpenWeather
|
|
38
38
|
options.delete(:country)
|
39
39
|
].compact.join(',')
|
40
40
|
end
|
41
|
-
OpenWeather::Models::
|
41
|
+
OpenWeather::Models::City::Weather.new(get('weather', options), options)
|
42
42
|
end
|
43
43
|
|
44
44
|
def current_cities_geo_box(*args)
|
@@ -51,7 +51,7 @@ module OpenWeather
|
|
51
51
|
options.delete(:lat_top),
|
52
52
|
options.delete(:zoom)
|
53
53
|
].join(',')
|
54
|
-
OpenWeather::Models::List.new(get('box/city', options))
|
54
|
+
OpenWeather::Models::List.new(get('box/city', options), options)
|
55
55
|
end
|
56
56
|
|
57
57
|
def current_cities_geo_circle(*args)
|
@@ -63,7 +63,7 @@ module OpenWeather
|
|
63
63
|
options[:cnt] = args.shift || 1
|
64
64
|
end
|
65
65
|
|
66
|
-
OpenWeather::Models::List.new(get('find', options))
|
66
|
+
OpenWeather::Models::List.new(get('find', options), options)
|
67
67
|
end
|
68
68
|
|
69
69
|
def current_cities_id(*args)
|
@@ -71,7 +71,7 @@ module OpenWeather
|
|
71
71
|
options[:id] = args.join(',') if args.any?
|
72
72
|
options[:id] = options.delete(:ids) if options.key?(:ids)
|
73
73
|
options[:id] = options[:id].join(',') if options[:id].is_a?(Array)
|
74
|
-
OpenWeather::Models::List.new(get('group', options))
|
74
|
+
OpenWeather::Models::List.new(get('group', options), options)
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Endpoints
|
5
|
+
module OneCall
|
6
|
+
def one_call(lat, lon = nil, options = {})
|
7
|
+
options = lat.is_a?(Hash) ? options.merge(lat) : options.merge(lat: lat, lon: lon)
|
8
|
+
options[:exclude] = options[:exclude].join(',') if options[:exclude].is_a?(Array)
|
9
|
+
options[:dt] = options[:dt].to_i if options[:dt].is_a?(Time)
|
10
|
+
path = options.key?(:dt) ? 'onecall/timemachine' : 'onecall'
|
11
|
+
OpenWeather::Models::OneCall::Weather.new(get(path, options), options)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/open_weather/models.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'models/mixins'
|
3
4
|
require_relative 'models/model'
|
4
5
|
require_relative 'models/clouds'
|
5
6
|
require_relative 'models/coord'
|
6
|
-
require_relative 'models/city_weather'
|
7
7
|
require_relative 'models/main'
|
8
8
|
require_relative 'models/sys'
|
9
9
|
require_relative 'models/weather'
|
@@ -11,3 +11,5 @@ require_relative 'models/wind'
|
|
11
11
|
require_relative 'models/rain'
|
12
12
|
require_relative 'models/snow'
|
13
13
|
require_relative 'models/list'
|
14
|
+
require_relative 'models/city'
|
15
|
+
require_relative 'models/one_call'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module City
|
6
|
+
class Weather < Model
|
7
|
+
property 'coord'
|
8
|
+
property 'weather'
|
9
|
+
property 'base' # internal parameter
|
10
|
+
property 'main'
|
11
|
+
property 'visibility'
|
12
|
+
property 'wind'
|
13
|
+
property 'clouds'
|
14
|
+
property 'rain'
|
15
|
+
property 'snow'
|
16
|
+
property 'dt', transform_with: ->(v) { Time.at(v).utc } # time of data calculation, UTC
|
17
|
+
property 'sys'
|
18
|
+
property 'id' # city id
|
19
|
+
property 'timezone' # shift in seconds from UTC
|
20
|
+
property 'name' # city name
|
21
|
+
property 'cod' # internal parameter
|
22
|
+
|
23
|
+
def initialize(args = nil, options = {})
|
24
|
+
super args, options
|
25
|
+
|
26
|
+
self.coord = OpenWeather::Models::Coord.new(coord, options) if coord
|
27
|
+
self.weather = weather.map { |i| OpenWeather::Models::Weather.new(i, options) } if weather
|
28
|
+
self.main = OpenWeather::Models::Main.new(main, options) if main
|
29
|
+
self.wind = OpenWeather::Models::Wind.new(wind, options) if wind
|
30
|
+
self.clouds = OpenWeather::Models::Clouds.new(clouds, options) if clouds
|
31
|
+
self.rain = OpenWeather::Models::Rain.new(rain, options) if rain
|
32
|
+
self.snow = OpenWeather::Models::Snow.new(snow, options) if snow
|
33
|
+
self.sys = OpenWeather::Models::Sys.new(sys, options) if sys
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -8,9 +8,15 @@ module OpenWeather
|
|
8
8
|
property 'cod'
|
9
9
|
property 'calctime'
|
10
10
|
property 'cnt', from: 'count'
|
11
|
-
property 'list'
|
11
|
+
property 'list'
|
12
12
|
property 'message'
|
13
13
|
|
14
|
+
def initialize(args = nil, options = {})
|
15
|
+
super args, options
|
16
|
+
|
17
|
+
self.list = list.map { |i| OpenWeather::Models::City::Weather.new(i, options) } if list
|
18
|
+
end
|
19
|
+
|
14
20
|
def each(&block)
|
15
21
|
list.each(&block)
|
16
22
|
end
|
@@ -3,12 +3,12 @@
|
|
3
3
|
module OpenWeather
|
4
4
|
module Models
|
5
5
|
class Main < Model
|
6
|
-
|
6
|
+
temperature_property 'temp' # temperature in requested unit
|
7
7
|
property 'pressure' # atmospheric pressure on the sea_level or grnd_level when unavailable, hPa
|
8
8
|
property 'humidity' # humidity in %
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
temperature_property 'feels_like' # temperature, accounting for the human perception of weather, in requested unit
|
10
|
+
temperature_property 'temp_min' # minimal currently observed temperature
|
11
|
+
temperature_property 'temp_max' # maximal currently observed temperature
|
12
12
|
property 'sea_level' # atmospheric pressure on the sea level, hPa
|
13
13
|
property 'grnd_level' # atmospheric pressure on the ground level, hPa
|
14
14
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module Mixins
|
6
|
+
module Speed
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
def speed_property(field)
|
11
|
+
property field
|
12
|
+
|
13
|
+
define_method "#{field}_mps" do
|
14
|
+
to_meters_per_sec(send(field))
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method "#{field}_mph" do
|
18
|
+
to_miles_per_hour(send(field))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def to_meters_per_sec(value)
|
26
|
+
case units
|
27
|
+
when :imperial
|
28
|
+
(value.to_f / 2.23694).round(2)
|
29
|
+
else
|
30
|
+
value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_miles_per_hour(value)
|
35
|
+
case units
|
36
|
+
when :metric
|
37
|
+
(value * 2.23694).round(2)
|
38
|
+
else
|
39
|
+
value
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module Mixins
|
6
|
+
module Temp
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
def temperature_property(field)
|
11
|
+
property field
|
12
|
+
|
13
|
+
define_method "#{field}_k" do
|
14
|
+
to_kelvin(send(field))
|
15
|
+
end
|
16
|
+
|
17
|
+
define_method "#{field}_c" do
|
18
|
+
to_celcius(send(field))
|
19
|
+
end
|
20
|
+
|
21
|
+
define_method "#{field}_f" do
|
22
|
+
to_farenheit(send(field))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def to_kelvin(value)
|
30
|
+
case units
|
31
|
+
when :metric
|
32
|
+
(value.to_f + 273.15).round(2)
|
33
|
+
when :imperial
|
34
|
+
((value.to_f - 32) * 5 / 9 + 273.15).round(2)
|
35
|
+
else
|
36
|
+
value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_celcius(value)
|
41
|
+
case units
|
42
|
+
when :metric
|
43
|
+
value
|
44
|
+
when :imperial
|
45
|
+
((value.to_f - 32) * 5 / 9).round(2)
|
46
|
+
else
|
47
|
+
(value.to_f - 273.15).round(2)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_farenheit(value)
|
52
|
+
case units
|
53
|
+
when :metric
|
54
|
+
((value.to_f * 9 / 5) + 32).round(2)
|
55
|
+
when :imperial
|
56
|
+
value
|
57
|
+
else
|
58
|
+
((value.to_f - 273.15) * 9 / 5 + 32).round(2)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -4,6 +4,19 @@ module OpenWeather
|
|
4
4
|
module Models
|
5
5
|
class Model < Hashie::Trash
|
6
6
|
include Hashie::Extensions::IgnoreUndeclared
|
7
|
+
include OpenWeather::Models::Mixins::Temp
|
8
|
+
include OpenWeather::Models::Mixins::Speed
|
9
|
+
|
10
|
+
attr_reader :options
|
11
|
+
|
12
|
+
def initialize(args = nil, options = {})
|
13
|
+
super args
|
14
|
+
@options = { units: OpenWeather.config.units }.merge(options || {})
|
15
|
+
end
|
16
|
+
|
17
|
+
def units
|
18
|
+
options && options[:units]&.to_sym
|
19
|
+
end
|
7
20
|
end
|
8
21
|
end
|
9
22
|
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'one_call/temp'
|
4
|
+
require_relative 'one_call/feels_like'
|
5
|
+
require_relative 'one_call/current_weather'
|
6
|
+
require_relative 'one_call/daily_weather'
|
7
|
+
require_relative 'one_call/hourly_weather'
|
8
|
+
require_relative 'one_call/minutely_weather'
|
9
|
+
require_relative 'one_call/weather'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module OneCall
|
6
|
+
class CurrentWeather < Model
|
7
|
+
property 'dt', transform_with: ->(v) { Time.at(v).utc } # time of the forecasted data UTC
|
8
|
+
property 'sunrise', transform_with: ->(v) { Time.at(v).utc } # sunrise time, UTC
|
9
|
+
property 'sunset', transform_with: ->(v) { Time.at(v).utc } # sunset time, UTC
|
10
|
+
temperature_property 'temp' # temperature
|
11
|
+
temperature_property 'feels_like' # temperature, accounts for the human perception of weather
|
12
|
+
property 'pressure' # atmospheric pressure on the sea level, hPa
|
13
|
+
property 'humidity' # humidity, %
|
14
|
+
temperature_property 'dew_point' # atmospheric temperature (varying according to pressure and humidity) below which water droplets begin to condense and dew can form
|
15
|
+
property 'clouds' # cloudiness, %
|
16
|
+
property 'uvi' # UV index
|
17
|
+
property 'visibility' # average visibility, meters
|
18
|
+
speed_property 'wind_speed' # wind speed
|
19
|
+
speed_property 'wind_gust' # wind gust
|
20
|
+
property 'wind_deg' # wind direction, degrees (meteorological)
|
21
|
+
property 'rain'
|
22
|
+
property 'snow'
|
23
|
+
property 'weather'
|
24
|
+
|
25
|
+
def initialize(args = nil, options = {})
|
26
|
+
super args, options
|
27
|
+
|
28
|
+
self.rain = OpenWeather::Models::Rain.new(rain, options) if rain
|
29
|
+
self.snow = OpenWeather::Models::Snow.new(snow, options) if snow
|
30
|
+
self.weather = weather.map { |i| OpenWeather::Models::Weather.new(i, options) } if weather
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module OneCall
|
6
|
+
class DailyWeather < Model
|
7
|
+
property 'dt', transform_with: ->(v) { Time.at(v).utc } # time of the forecasted data UTC
|
8
|
+
property 'sunrise', transform_with: ->(v) { Time.at(v).utc } # sunrise time, UTC
|
9
|
+
property 'sunset', transform_with: ->(v) { Time.at(v).utc } # sunset time, UTC
|
10
|
+
property 'temp'
|
11
|
+
property 'feels_like'
|
12
|
+
property 'pressure' # atmospheric pressure on the sea level, hPa
|
13
|
+
property 'humidity' # humidity, %
|
14
|
+
temperature_property 'dew_point' # atmospheric temperature (varying according to pressure and humidity) below which water droplets begin to condense and dew can form
|
15
|
+
speed_property 'wind_speed' # wind speed
|
16
|
+
speed_property 'wind_gust' # wind gust
|
17
|
+
property 'wind_deg' # wind direction, degrees (meteorological)
|
18
|
+
property 'clouds' # cloudiness, %
|
19
|
+
property 'uvi' # UV index
|
20
|
+
property 'rain' # precipitation volume, mm
|
21
|
+
property 'snow' # snow volume, mm
|
22
|
+
property 'weather'
|
23
|
+
|
24
|
+
def initialize(args = nil, options = {})
|
25
|
+
super args, options
|
26
|
+
|
27
|
+
self.temp = OpenWeather::Models::OneCall::Temp.new(temp, options) if temp
|
28
|
+
self.feels_like = OpenWeather::Models::OneCall::FeelsLike.new(feels_like, options) if feels_like
|
29
|
+
self.weather = weather.map { |i| OpenWeather::Models::Weather.new(i, options) } if weather
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module OneCall
|
6
|
+
class FeelsLike < Model
|
7
|
+
temperature_property 'morn'
|
8
|
+
temperature_property 'day'
|
9
|
+
temperature_property 'eve'
|
10
|
+
temperature_property 'night'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module OneCall
|
6
|
+
class HourlyWeather < Model
|
7
|
+
property 'dt', transform_with: ->(v) { Time.at(v).utc } # Time of the forecasted data UTC
|
8
|
+
temperature_property 'temp'
|
9
|
+
temperature_property 'feels_like'
|
10
|
+
property 'pressure' # atmospheric pressure on the sea level, hPa
|
11
|
+
property 'humidity' # humidity, %
|
12
|
+
temperature_property 'dew_point' # atmospheric temperature (varying according to pressure and humidity) below which water droplets begin to condense and dew can form
|
13
|
+
property 'clouds' # cloudiness, %
|
14
|
+
property 'visibility' # average visibility, meters
|
15
|
+
speed_property 'wind_speed' # wind speed.
|
16
|
+
speed_property 'wind_gust' # wind gust.
|
17
|
+
property 'wind_deg' # wind direction, degrees (meteorological)
|
18
|
+
property 'rain'
|
19
|
+
property 'snow'
|
20
|
+
property 'weather'
|
21
|
+
|
22
|
+
def initialize(args = nil, options = {})
|
23
|
+
super args, options
|
24
|
+
|
25
|
+
self.rain = OpenWeather::Models::Rain.new(rain, options) if rain
|
26
|
+
self.snow = OpenWeather::Models::Snow.new(snow, options) if snow
|
27
|
+
self.weather = weather.map { |i| OpenWeather::Models::Weather.new(i, options) } if weather
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module OneCall
|
6
|
+
class MinutelyWeather < Model
|
7
|
+
property 'dt', transform_with: ->(v) { Time.at(v).utc } # time of the forecasted data UTC
|
8
|
+
property 'precipitation'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module OneCall
|
6
|
+
class Temp < Model
|
7
|
+
temperature_property 'morn'
|
8
|
+
temperature_property 'day'
|
9
|
+
temperature_property 'eve'
|
10
|
+
temperature_property 'night'
|
11
|
+
temperature_property 'min'
|
12
|
+
temperature_property 'max'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module OpenWeather
|
4
|
+
module Models
|
5
|
+
module OneCall
|
6
|
+
class Weather < Model
|
7
|
+
property 'lat' # geographical coordinates of the location (latitude)
|
8
|
+
property 'lon' # geographical coordinates of the location (longitude)
|
9
|
+
property 'timezone' # timezone name for the requested location
|
10
|
+
property 'current' # current weather
|
11
|
+
property 'minutely' # minute forecast weather
|
12
|
+
property 'hourly' # hourly forecast weather
|
13
|
+
property 'daily' # daily forecast weather
|
14
|
+
|
15
|
+
def initialize(args = nil, options = {})
|
16
|
+
super args, options
|
17
|
+
|
18
|
+
self.current = OpenWeather::Models::OneCall::CurrentWeather.new(current, options) if current
|
19
|
+
self.minutely = minutely.map { |i| OpenWeather::Models::OneCall::MinutelyWeather.new(i, options) } if minutely
|
20
|
+
self.hourly = hourly.map { |i| OpenWeather::Models::OneCall::HourlyWeather.new(i, options) } if hourly
|
21
|
+
self.daily = daily.map { |i| OpenWeather::Models::OneCall::DailyWeather.new(i, options) } if daily
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -6,6 +6,7 @@ module OpenWeather
|
|
6
6
|
property 'id' # weather condition id
|
7
7
|
property 'main' # group of weather parameters (Rain, Snow, Extreme, etc.)
|
8
8
|
property 'description' # weather condition within the group, in your language
|
9
|
+
property 'icon_uri', from: 'icon', transform_with: ->(v) { URI.parse("http://openweathermap.org/img/wn/#{v}@2x.png") }
|
9
10
|
property 'icon' # weather icon id
|
10
11
|
end
|
11
12
|
end
|
@@ -6,10 +6,10 @@ module OpenWeather
|
|
6
6
|
def on_complete(env)
|
7
7
|
case env[:status]
|
8
8
|
when 404
|
9
|
-
raise Faraday::
|
9
|
+
raise Faraday::ResourceNotFound, response_values(env)
|
10
10
|
when 407
|
11
11
|
# mimic the behavior that we get with proxy requests with HTTPS
|
12
|
-
raise Faraday::
|
12
|
+
raise Faraday::ConnectionFailed, %(407 "Proxy Authentication Required ")
|
13
13
|
when (400...600).freeze
|
14
14
|
raise OpenWeather::Errors::Fault, response_values(env)
|
15
15
|
end
|
data/lib/open_weather/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: open-weather-ruby-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Doubrovkine
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 1.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 1.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: faraday_middleware
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -81,16 +81,29 @@ files:
|
|
81
81
|
- lib/open_weather/connection.rb
|
82
82
|
- lib/open_weather/endpoints.rb
|
83
83
|
- lib/open_weather/endpoints/current.rb
|
84
|
+
- lib/open_weather/endpoints/one_call.rb
|
84
85
|
- lib/open_weather/errors.rb
|
85
86
|
- lib/open_weather/errors/fault.rb
|
86
87
|
- lib/open_weather/logger.rb
|
87
88
|
- lib/open_weather/models.rb
|
88
|
-
- lib/open_weather/models/
|
89
|
+
- lib/open_weather/models/city.rb
|
90
|
+
- lib/open_weather/models/city/weather.rb
|
89
91
|
- lib/open_weather/models/clouds.rb
|
90
92
|
- lib/open_weather/models/coord.rb
|
91
93
|
- lib/open_weather/models/list.rb
|
92
94
|
- lib/open_weather/models/main.rb
|
95
|
+
- lib/open_weather/models/mixins.rb
|
96
|
+
- lib/open_weather/models/mixins/speed.rb
|
97
|
+
- lib/open_weather/models/mixins/temp.rb
|
93
98
|
- lib/open_weather/models/model.rb
|
99
|
+
- lib/open_weather/models/one_call.rb
|
100
|
+
- lib/open_weather/models/one_call/current_weather.rb
|
101
|
+
- lib/open_weather/models/one_call/daily_weather.rb
|
102
|
+
- lib/open_weather/models/one_call/feels_like.rb
|
103
|
+
- lib/open_weather/models/one_call/hourly_weather.rb
|
104
|
+
- lib/open_weather/models/one_call/minutely_weather.rb
|
105
|
+
- lib/open_weather/models/one_call/temp.rb
|
106
|
+
- lib/open_weather/models/one_call/weather.rb
|
94
107
|
- lib/open_weather/models/rain.rb
|
95
108
|
- lib/open_weather/models/snow.rb
|
96
109
|
- lib/open_weather/models/sys.rb
|
@@ -118,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
131
|
- !ruby/object:Gem::Version
|
119
132
|
version: 1.3.6
|
120
133
|
requirements: []
|
121
|
-
rubygems_version: 3.
|
134
|
+
rubygems_version: 3.1.3
|
122
135
|
signing_key:
|
123
136
|
specification_version: 4
|
124
137
|
summary: OpenWeather API Ruby client.
|
@@ -1,23 +0,0 @@
|
|
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
|