open-weather-ruby-client 0.2.0 → 0.3.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
  SHA256:
3
- metadata.gz: 1d3916328b6401b21690d359dab0aa1f893282b9456f7d9960fcb8a3024fc625
4
- data.tar.gz: 66657fdd5b0cbad2889b5467cdf9e009b4b8e32cd997c0d86c7ddbf19b14e644
3
+ metadata.gz: 3b61381c999fcbbcefa63521936ee96cc28eb7648a9b2b13cc9d01a608d8b12f
4
+ data.tar.gz: aaa00190d52e86a471f2dca1e52c5c4f5fbf67cdfdf5639fe9302d793d1326e2
5
5
  SHA512:
6
- metadata.gz: 75c4b1f7baafa1a3a61d5b8ba3223a8ac3eeabc2a6a1ccec506e8f718608088b1289487e562a3061d74ba517c09de8bcd4150e3cbad381e893fb9db1b71976ee
7
- data.tar.gz: 6e769293fc354dd3af19780e4cba5a92a0730d2ded3db7976f44d25e8518b49b58bd62bfd7e033ab2ca2d7194db01df03e91a834a67b55824443f45465a9b59e
6
+ metadata.gz: 890ef7edc806545a9b83f99a87133d7ff83900593f17e5aadcf76f7389cfa7c6a3249d0f4911d6d257d493a00dd572880f8848ee68a6ba0cd5ffd9561c53c75f
7
+ data.tar.gz: 3094f7b9d058070590db2ddfabc99d9f799f00b3b185fb9efd93b348d9abd8f124ec8d2f0552f7430850bf08dc7cb698e802c648a32aa9dbaf333b343c0521b4
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ### 0.3.0 (2023/03/25)
2
+
3
+ * [#30](https://github.com/dblock/open-weather-ruby-client/pull/30): Added support for Ruby 3.2 - [@petergoldstein](https://github.com/petergoldstein).
4
+ * [#27](https://github.com/dblock/open-weather-ruby-client/pull/27): Removed default values for Faraday’s SSL settings ca_file and ca_path - [@sunny](https://github.com/sunny).
5
+ * [#21](https://github.com/dblock/open-weather-ruby-client/pull/21), [#20](https://github.com/dblock/open-weather-ruby-client/pull/20), [#19](https://github.com/dblock/open-weather-ruby-client/pull/19), [#18](https://github.com/dblock/open-weather-ruby-client/pull/18): Added support for Stations API - [@wasabigeek](https://github.com/wasabigeek).
6
+ * [#22](https://github.com/dblock/open-weather-ruby-client/pull/23): Removed API version from `Config#endpoint` - [@dblock](https://github.com/dblock).
7
+
1
8
  ### 0.2.0 (2020/05/17)
2
9
 
3
10
  * [#14](https://github.com/dblock/open-weather-ruby-client/pull/14): Added support for One Call API - [@dblock](https://github.com/dblock).
data/README.md CHANGED
@@ -2,9 +2,9 @@ OpenWeather Ruby Client
2
2
  =======================
3
3
 
4
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)
5
+ [![Tests Status](https://github.com/dblock/open-weather-ruby-client/actions/workflows/test.yml/badge.svg)](https://github.com/dblock/open-weather-ruby-client/actions)
6
6
 
7
- A Ruby client for the [OpenWeather API v2.5](https://openweathermap.org/api).
7
+ A Ruby client for the [OpenWeather API v2.5 and v3.0](https://openweathermap.org/api).
8
8
 
9
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
 
@@ -20,6 +20,14 @@ Unlike other clients, including [open-weather](https://github.com/coderhs/ruby_o
20
20
  - [One Call](#one-call)
21
21
  - [Current and Forecast Weather](#current-and-forecast-weather)
22
22
  - [Historical Weather](#historical-weather)
23
+ - [Stations](#stations)
24
+ - [Register a Station](#register-a-station)
25
+ - [List Stations](#list-stations)
26
+ - [Get Station](#get-station)
27
+ - [Update Station](#update-station)
28
+ - [Delete Station](#delete-station)
29
+ - [Create Measurements](#create-measurements)
30
+ - [Get Measurements](#get-measurements)
23
31
  - [Configuration](#configuration)
24
32
  - [Units](#units)
25
33
  - [Converting Temperature](#converting-temperature)
@@ -193,6 +201,96 @@ data.current # => OpenWeather::Models::OneCall::CurrentWeather
193
201
  data.hourly # => Array[OpenWeather::Models::OneCall::HourlyWeather]
194
202
  ```
195
203
 
204
+ ### Stations
205
+
206
+ The [Stations API](https://openweathermap.org/stations) lets your manage personal weather stations and measurements.
207
+
208
+ #### Register a Station
209
+
210
+ To register a station, you can call the client method:
211
+ ```ruby
212
+ data = client.register_station(external_id: 'SF_TEST001', ...) # => OpenWeather::Models::Station
213
+ data.id # => '5ed2118acca8ce0001f1aeg1'
214
+ data.external_id # => 'SF_TEST001'
215
+ ```
216
+ Alternatively, call `register!` on an instance of `Station`:
217
+ ```ruby
218
+ model = OpenWeather::Models::Station.new(external_id: 'SF_TEST001', ...)
219
+ model.register!
220
+ model.id # => '5ed2118acca8ce0001f1aeg1'
221
+ ```
222
+
223
+ #### List Stations
224
+
225
+ To list all stations, call the client method:
226
+ ```ruby
227
+ client.list_stations # => Array[OpenWeather::Models::Station]
228
+ ```
229
+
230
+ #### Get Station
231
+
232
+ To get a station, call the client method:
233
+ ```ruby
234
+ client.get_station('5ed2118acca8ce0001f1aeg1') # => OpenWeather::Models::Station
235
+ ```
236
+
237
+ #### Update Station
238
+
239
+ To update a station, call the client method:
240
+ ```ruby
241
+ client.update_station('5ed2118acca8ce0001f1aeg1', external_id: 'SF_TEST002') # => OpenWeather::Models::Station
242
+ ```
243
+ Alternatively, call `update!` on an instance of `Station`:
244
+ ```ruby
245
+ model = OpenWeather::Models::Station.new(external_id: 'SF_TEST001', ...)
246
+ model.register!
247
+ model.update!(external_id: 'SF_TEST002')
248
+ model.external_id # => 'SF_TEST002'
249
+ ```
250
+
251
+ #### Delete Station
252
+
253
+ To delete a station, call the client method:
254
+ ```ruby
255
+ data = client.delete_station('5ed2118acca8ce0001f1aeg1') # => nil
256
+ ```
257
+
258
+ #### Create Measurements
259
+
260
+ To create measurements, call the client method:
261
+ ```ruby
262
+ client.create_measurements([
263
+ {
264
+ "station_id": -1,
265
+ "dt": 1479817340,
266
+ "temperature": 18.7,
267
+ "wind_speed": 1.2,
268
+ "wind_gust": 3.4,
269
+ "pressure": 1021,
270
+ "humidity": 87,
271
+ "rain_1h": 2,
272
+ "clouds": [
273
+ {
274
+ "condition": 'NSC'
275
+ }
276
+ ]
277
+ }
278
+ ]) # => nil
279
+ ```
280
+
281
+ #### Get Measurements
282
+
283
+ To get measurements, call the client method with the required parameters:
284
+ ```ruby
285
+ client.get_measurements(
286
+ station_id: '5ed21a12cca8ce0001f1aef1',
287
+ type: 'd',
288
+ limit: 100,
289
+ from: 1469817340,
290
+ to: 1591620047
291
+ ) # => Array[OpenWeather::Models::Stations::Measurement]
292
+ ```
293
+
196
294
  ## Configuration
197
295
 
198
296
  You can configure client options, globally.
@@ -211,7 +309,7 @@ setting | description
211
309
  api_key | Required API key.
212
310
  lang | Default language in API responses.
213
311
  units | Default units in API responses.
214
- endpoint | Defaults to `https://api.openweathermap.org/data/2.5/`.
312
+ endpoint | Defaults to `https://api.openweathermap.org/data`.
215
313
  user_agent | User-agent, defaults to _OpenWeather Ruby Client/version_.
216
314
  proxy | Optional HTTP proxy.
217
315
  ca_path | Optional SSL certificates path.
@@ -6,6 +6,7 @@ module OpenWeather
6
6
  include Request
7
7
  include Endpoints::Current
8
8
  include Endpoints::OneCall
9
+ include Endpoints::Stations
9
10
 
10
11
  attr_accessor(*Config::ATTRIBUTES)
11
12
 
@@ -21,11 +21,11 @@ module OpenWeather
21
21
  attr_accessor(*Config::ATTRIBUTES)
22
22
 
23
23
  def reset
24
- self.endpoint = 'https://api.openweathermap.org/data/2.5'
24
+ self.endpoint = 'https://api.openweathermap.org/data'
25
25
  self.api_key = nil
26
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
27
+ self.ca_path = nil
28
+ self.ca_file = nil
29
29
  self.proxy = nil
30
30
  self.logger = nil
31
31
  self.timeout = nil
@@ -11,7 +11,10 @@ module OpenWeather
11
11
  def connection
12
12
  @connection ||= begin
13
13
  options = {
14
- headers: headers.merge('Accept' => 'application/json; charset=utf-8')
14
+ headers: headers.merge(
15
+ 'Accept' => 'application/json; charset=utf-8',
16
+ 'Content-Type' => 'application/json'
17
+ )
15
18
  }
16
19
 
17
20
  options[:headers]['User-Agent'] = user_agent if user_agent
@@ -38,7 +38,7 @@ module OpenWeather
38
38
  options.delete(:country)
39
39
  ].compact.join(',')
40
40
  end
41
- OpenWeather::Models::City::Weather.new(get('weather', options), options)
41
+ OpenWeather::Models::City::Weather.new(get('2.5/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), options)
54
+ OpenWeather::Models::List.new(get('2.5/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), options)
66
+ OpenWeather::Models::List.new(get('2.5/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), options)
74
+ OpenWeather::Models::List.new(get('2.5/group', options), options)
75
75
  end
76
76
  end
77
77
  end
@@ -7,7 +7,7 @@ module OpenWeather
7
7
  options = lat.is_a?(Hash) ? options.merge(lat) : options.merge(lat: lat, lon: lon)
8
8
  options[:exclude] = options[:exclude].join(',') if options[:exclude].is_a?(Array)
9
9
  options[:dt] = options[:dt].to_i if options[:dt].is_a?(Time)
10
- path = options.key?(:dt) ? 'onecall/timemachine' : 'onecall'
10
+ path = options.key?(:dt) ? '2.5/onecall/timemachine' : '2.5/onecall'
11
11
  OpenWeather::Models::OneCall::Weather.new(get(path, options), options)
12
12
  end
13
13
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Endpoints
5
+ module Stations
6
+ def register_station(options = {})
7
+ OpenWeather::Models::Station.new(post('3.0/stations', options))
8
+ end
9
+
10
+ def list_stations
11
+ get('3.0/stations').map { |data| OpenWeather::Models::Station.new(data) }
12
+ end
13
+
14
+ def get_station(id)
15
+ validate_id(id)
16
+
17
+ OpenWeather::Models::Station.new(get("3.0/stations/#{id}"))
18
+ end
19
+
20
+ def update_station(id, options = {})
21
+ validate_id(id)
22
+
23
+ OpenWeather::Models::Station.new(put("3.0/stations/#{id}", options))
24
+ end
25
+
26
+ def delete_station(id)
27
+ validate_id(id)
28
+
29
+ delete("3.0/stations/#{id}")
30
+ nil
31
+ end
32
+
33
+ def create_measurements(measurements, options = {})
34
+ post('3.0/measurements', options.merge(body: measurements))
35
+ nil
36
+ end
37
+
38
+ def get_measurements(options)
39
+ required_keys = %i[station_id type limit from to]
40
+ missing_keys = required_keys - options.keys
41
+ raise ArgumentError, "Missing params: #{missing_keys.join(', ')}" if missing_keys.any?
42
+
43
+ get('3.0/measurements', options).map { |m| OpenWeather::Models::Stations::Measurement.new(m) }
44
+ end
45
+
46
+ private
47
+
48
+ def validate_id(id)
49
+ raise ArgumentError, 'Invalid ID' unless id&.is_a?(String)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -2,3 +2,4 @@
2
2
 
3
3
  require_relative 'endpoints/current'
4
4
  require_relative 'endpoints/one_call'
5
+ require_relative 'endpoints/stations'
@@ -10,7 +10,8 @@ module OpenWeather
10
10
  attr_reader :options
11
11
 
12
12
  def initialize(args = nil, options = {})
13
- super args
13
+ transformed_args = args.respond_to?(:transform_keys) ? args.transform_keys(&:to_s) : args
14
+ super transformed_args
14
15
  @options = { units: OpenWeather.config.units }.merge(options || {})
15
16
  end
16
17
 
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ class Station < Model
6
+ property 'id', from: 'ID' # internal identifier for the station
7
+ property 'external_id' # external identifier for the station
8
+ property 'name' # name of the station
9
+ property 'latitude' # geographical coordinates of the location (latitude)
10
+ property 'longitude' # geographical coordinates of the location (longitude)
11
+ property 'altitude' # height of station above sea level
12
+ property 'created_at' # timestamp when station was created
13
+ property 'updated_at' # timestamp when station was updated
14
+ property 'rank' # rank of station
15
+
16
+ def register!
17
+ data = OpenWeather::Client.new.register_station(to_h)
18
+ update_attributes!(data)
19
+
20
+ self
21
+ end
22
+
23
+ def update!(attributes)
24
+ data = OpenWeather::Client.new.update_station(id, attributes)
25
+ update_attributes!(data)
26
+
27
+ self
28
+ end
29
+
30
+ def delete!
31
+ OpenWeather::Client.new.delete_station(id)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ module Stations
6
+ class Humidity < Model
7
+ property 'average'
8
+ property 'weight'
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ module Stations
6
+ class Measurement < Model
7
+ property 'station_id' # The internal ID of the station
8
+ property 'type' # Type of the aggregated data - minute, hour or day. Specifies the letters m, h or d respectively
9
+ property 'date' # Time of measurement
10
+ property 'temp'
11
+ property 'humidity'
12
+ property 'wind'
13
+ property 'precipitation'
14
+ property 'pressure'
15
+
16
+ def initialize(args = nil, options = {})
17
+ super args, options
18
+
19
+ self.temp = OpenWeather::Models::Stations::Temp.new(temp, options) if temp
20
+ self.humidity = OpenWeather::Models::Stations::Humidity.new(humidity, options) if humidity
21
+ self.pressure = OpenWeather::Models::Stations::Pressure.new(pressure, options) if pressure
22
+ self.precipitation = OpenWeather::Models::Stations::Precipitation.new(precipitation, options) if precipitation
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ module Stations
6
+ class Precipitation < Model
7
+ property 'rain'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ module Stations
6
+ class Pressure < Model
7
+ property 'min'
8
+ property 'max'
9
+ property 'average'
10
+ property 'weight'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenWeather
4
+ module Models
5
+ module Stations
6
+ class Temp < Model
7
+ temperature_property 'min'
8
+ temperature_property 'max'
9
+ temperature_property 'average'
10
+ property 'weight'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -13,3 +13,9 @@ require_relative 'models/snow'
13
13
  require_relative 'models/list'
14
14
  require_relative 'models/city'
15
15
  require_relative 'models/one_call'
16
+ require_relative 'models/station'
17
+ require_relative 'models/stations/measurement'
18
+ require_relative 'models/stations/temp'
19
+ require_relative 'models/stations/humidity'
20
+ require_relative 'models/stations/pressure'
21
+ require_relative 'models/stations/precipitation'
@@ -20,6 +20,14 @@ module OpenWeather
20
20
 
21
21
  private
22
22
 
23
+ #
24
+ # @param [Symbol] method - Faraday HTTP method.
25
+ # @param [String] path - URL to send.
26
+ # @param [Hash] options - :appid, :lang, :units, :endpoint, :body keys will configure the request.
27
+ # The rest will be converted to query params for GET/DELETE, or jsonified for POST/PUT.
28
+ #
29
+ # @return [Object] - the Faraday::Response#body.
30
+ #
23
31
  def request(method, path, options)
24
32
  options = options.dup
25
33
  options[:appid] ||= api_key if api_key.present?
@@ -33,7 +41,12 @@ module OpenWeather
33
41
  request.url(path, options)
34
42
  when :post, :put
35
43
  request.path = path
36
- request.body = options unless options.empty?
44
+ request.params = { appid: options.delete(:appid) }
45
+ if options.key?(:body)
46
+ request.body = options.delete(:body).to_json
47
+ elsif !options.empty?
48
+ request.body = options.to_json
49
+ end
37
50
  end
38
51
  request.options.merge!(options.delete(:request)) if options.key?(:request)
39
52
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenWeather
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-17 00:00:00.000000000 Z
11
+ date: 2023-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
- description:
69
+ description:
70
70
  email: dblock@dblock.org
71
71
  executables: []
72
72
  extensions: []
@@ -82,6 +82,7 @@ files:
82
82
  - lib/open_weather/endpoints.rb
83
83
  - lib/open_weather/endpoints/current.rb
84
84
  - lib/open_weather/endpoints/one_call.rb
85
+ - lib/open_weather/endpoints/stations.rb
85
86
  - lib/open_weather/errors.rb
86
87
  - lib/open_weather/errors/fault.rb
87
88
  - lib/open_weather/logger.rb
@@ -106,6 +107,12 @@ files:
106
107
  - lib/open_weather/models/one_call/weather.rb
107
108
  - lib/open_weather/models/rain.rb
108
109
  - lib/open_weather/models/snow.rb
110
+ - lib/open_weather/models/station.rb
111
+ - lib/open_weather/models/stations/humidity.rb
112
+ - lib/open_weather/models/stations/measurement.rb
113
+ - lib/open_weather/models/stations/precipitation.rb
114
+ - lib/open_weather/models/stations/pressure.rb
115
+ - lib/open_weather/models/stations/temp.rb
109
116
  - lib/open_weather/models/sys.rb
110
117
  - lib/open_weather/models/weather.rb
111
118
  - lib/open_weather/models/wind.rb
@@ -116,7 +123,7 @@ homepage: http://github.com/dblock/open-weather-ruby-client
116
123
  licenses:
117
124
  - MIT
118
125
  metadata: {}
119
- post_install_message:
126
+ post_install_message:
120
127
  rdoc_options: []
121
128
  require_paths:
122
129
  - lib
@@ -132,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
139
  version: 1.3.6
133
140
  requirements: []
134
141
  rubygems_version: 3.1.3
135
- signing_key:
142
+ signing_key:
136
143
  specification_version: 4
137
144
  summary: OpenWeather API Ruby client.
138
145
  test_files: []