lws 10.0.0 → 11.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 +4 -4
- data/CHANGELOG.md +56 -0
- data/lib/lws/apps/digital_signage.rb +0 -4
- data/lib/lws/apps/generic.rb +15 -0
- data/lib/lws/apps/resource.rb +381 -246
- data/lib/lws/errors.rb +10 -4
- data/lib/lws/middleware/json_parser.rb +1 -1
- data/lib/lws/middleware/raise_server_error.rb +37 -0
- data/lib/lws/middleware.rb +8 -0
- data/lib/lws/version.rb +1 -1
- data/lib/lws.rb +6 -0
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9060d0e061184ea7c8048291d6966629e271070ad3a96a6623e54861cc5f817
|
4
|
+
data.tar.gz: ca0e91888477bc818ec43ab7b8b9b2b44af1444b02abcc4f0b0a08e576663517
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 364a82c69867855dda2f27187112233b844b0ec2d5533dc5023f6c68aac704f1ed93ce8bc17d01d5ca5e55500bacec3f93008ac54c871f203a474f8e8d09dd92
|
7
|
+
data.tar.gz: dcb07b606e2a2464b0be0acc7afc63f690de9c7e8d953bfa1602f290a1d93901e7a1096024c7fde6ccdfad37bb392e7fa408c8702e702473751335fd47f49971
|
data/CHANGELOG.md
CHANGED
@@ -8,6 +8,60 @@ of LWS in the major/minor part of te version.
|
|
8
8
|
|
9
9
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
10
10
|
|
11
|
+
## [11.0.0] - 2025-09-30
|
12
|
+
|
13
|
+
The biggest change in this release is the complete rework of the API of the
|
14
|
+
Resource app. Instead of using subclasses of collection and collection items,
|
15
|
+
there is now only a collection and collection item model and each has a
|
16
|
+
metadata object attached that is specific to its kind.
|
17
|
+
|
18
|
+
### Added
|
19
|
+
|
20
|
+
- Add and enable support for retrying a request 3 times
|
21
|
+
- Add `LWS::Errors::ServerError` class to indicate LWS server errors
|
22
|
+
- Add generic `Metadata` resource class (which is not a REST model)
|
23
|
+
- Add `Collection::Metadata`, `Collection::VimeoMetadata`,
|
24
|
+
`Collection::WeatherLocationMetadata` and `YouTubeMetadata` resource
|
25
|
+
subclasses
|
26
|
+
- Add `Collection::Item::Metadata`, `Collection::Item::Forecast`,
|
27
|
+
`Collection::Item::ImageMetadata`, `Collection::Item::PDFMetadata`,
|
28
|
+
`Collection::Item::PowerPointMetadata`, `Collection::Item::VideoMetadata`,
|
29
|
+
`Collection::Item::VimeoMetadata` and `Collection::Item::YouTubeMetadata`
|
30
|
+
resource subclasses
|
31
|
+
- Add metadata classes for collection and collection item resource models
|
32
|
+
|
33
|
+
### Changed
|
34
|
+
|
35
|
+
- All error classes are now subclasses of `LWS::Errors::Error`
|
36
|
+
- Raise `LWS::Errors::ServerError` when (after retrying) LWS server (still)
|
37
|
+
responds with a HTTP server error (HTTP error codes 500–599)
|
38
|
+
- Raise `LWS::Errors::ServerError` when previously a `Spyke::ConnectionError`
|
39
|
+
would have been raised
|
40
|
+
- Switch to Rubycop 1.69; update Rubocop todo-items
|
41
|
+
|
42
|
+
### Removed
|
43
|
+
|
44
|
+
- Remove the `log_object` attribute from the player log model
|
45
|
+
- Remove the `Collection::Config`, `Collection::Feed`,
|
46
|
+
`Collection::Feed::Post`, `Collection::Image`, `Collection::Post`,
|
47
|
+
`Collection::Video`, `Collection::Vimeo`, `Collection::WeatherLocation`,
|
48
|
+
`Collection::WeatherLocation::Forefcast` and
|
49
|
+
`Collection::YouTube` resource models
|
50
|
+
- Drop support for the config, feed and unknown collection kind
|
51
|
+
|
52
|
+
### Fixed
|
53
|
+
|
54
|
+
- Set correct version for dependency on `faraday-follow_redirects` gem
|
55
|
+
- Decreased minimum test coverage to 90% to work around simplecov issue
|
56
|
+
- Documentation fixes
|
57
|
+
|
58
|
+
## [10.0.1] - 2024-10-10
|
59
|
+
|
60
|
+
### Fixed
|
61
|
+
|
62
|
+
- Bring back the dependency on the `net-http-persistent` gem (in case Faraday
|
63
|
+
1.x is used)
|
64
|
+
|
11
65
|
## [10.0.0] - 2024-10-10
|
12
66
|
|
13
67
|
### Added
|
@@ -571,3 +625,5 @@ Initial release
|
|
571
625
|
[9.0.1]: https://gitlab.leftclick.network/platform/ruby-lws/compare/v9.0.0...v9.0.1
|
572
626
|
[9.0.2]: https://gitlab.leftclick.network/platform/ruby-lws/compare/v9.0.1...v9.0.2
|
573
627
|
[10.0.0]: https://gitlab.leftclick.network/platform/ruby-lws/compare/v9.0.2...v10.0.0
|
628
|
+
[10.0.1]: https://gitlab.leftclick.network/platform/ruby-lws/compare/v10.0.0...v10.0.1
|
629
|
+
[11.0.0]: https://gitlab.leftclick.network/platform/ruby-lws/compare/v10.0.1...v11.0.0
|
@@ -1302,10 +1302,6 @@ module LWS::DigitalSignage
|
|
1302
1302
|
use_api LWS::DigitalSignage.api
|
1303
1303
|
uri "players/:player_id/logs(/:id)"
|
1304
1304
|
|
1305
|
-
# @!attribute log_object
|
1306
|
-
# @return [String] the URL of the player log object
|
1307
|
-
attribute :log_object
|
1308
|
-
|
1309
1305
|
# @!attribute player
|
1310
1306
|
# @return [Player] the player the log is produced by
|
1311
1307
|
belongs_to :player, class_name: "LWS::DigitalSignage::Player"
|
data/lib/lws/apps/generic.rb
CHANGED
@@ -61,6 +61,21 @@ module LWS::Generic
|
|
61
61
|
raise LWS::Errors::ResourceNotFound, msg
|
62
62
|
end
|
63
63
|
|
64
|
+
# @private
|
65
|
+
# @!visibility private
|
66
|
+
#
|
67
|
+
# Adds handling exceptions thrown by the raise error Faraday middleware.
|
68
|
+
#
|
69
|
+
# @param [String] method the HTTP method to use for the request
|
70
|
+
# @param [String] path the endpoint path to use for the request
|
71
|
+
# @param [Hash] params the query parameters to use for the request
|
72
|
+
def self.request(method, path, params = {})
|
73
|
+
super
|
74
|
+
rescue Spyke::ConnectionError => exception
|
75
|
+
msg = "connection failed/timed out for #{method.upcase} request on URI #{path}"
|
76
|
+
raise LWS::Errors::ServerError, msg
|
77
|
+
end
|
78
|
+
|
64
79
|
# @private
|
65
80
|
# @!visibility private
|
66
81
|
#
|
data/lib/lws/apps/resource.rb
CHANGED
@@ -42,10 +42,9 @@ module LWS::Resource
|
|
42
42
|
|
43
43
|
# = The collection class
|
44
44
|
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
# for example {#feed}, {#image}, {#images}, etc.).
|
45
|
+
# A collection has a specific kind and contains a single or set of items.
|
46
|
+
# For some collection kinds, there is specific metadata (see {#metadata})
|
47
|
+
# available.
|
49
48
|
class Collection < LWS::Generic::Model
|
50
49
|
use_api LWS::Resource.api
|
51
50
|
|
@@ -94,16 +93,17 @@ module LWS::Resource
|
|
94
93
|
attribute :item_ids
|
95
94
|
|
96
95
|
# @!attribute items
|
97
|
-
# The returned cllection item (sub)class that is determined by the kind
|
98
|
-
# of this collection.
|
99
|
-
#
|
100
96
|
# @return [Array<Collection::Item>] the items that are part of the
|
101
97
|
# collection
|
102
98
|
has_many :items, class_name: "LWS::Resource::Collection::Item"
|
103
99
|
|
104
100
|
# @!attribute kind
|
105
|
-
# @
|
106
|
-
#
|
101
|
+
# @note
|
102
|
+
# This library only supports a subset of the available collection/item
|
103
|
+
# kinds.
|
104
|
+
# @return ["image", "other", "pdf", "powerpoint", "video", "vimeo",
|
105
|
+
# "weather_location", "youtube"] the name of the class/kind of the
|
106
|
+
# collection
|
107
107
|
attribute :kind
|
108
108
|
|
109
109
|
# @!attribute name
|
@@ -122,314 +122,449 @@ module LWS::Resource
|
|
122
122
|
# @!attribute uuid
|
123
123
|
# @return [String] the UUID used for unique file name generation
|
124
124
|
attribute :uuid
|
125
|
-
end
|
126
|
-
|
127
|
-
# = The collection item class
|
128
|
-
class Collection::Item < LWS::Generic::Model
|
129
|
-
use_api LWS::Resource.api
|
130
|
-
uri "collections/:collection_id/items(/:id)"
|
131
125
|
|
132
|
-
#
|
133
|
-
#
|
134
|
-
#
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
126
|
+
# Returns the metadata of the collection specific to its kind.
|
127
|
+
#
|
128
|
+
# @return [Collection::Metadata] the kind-specific metadata of the collection
|
129
|
+
def metadata
|
130
|
+
case kind
|
131
|
+
# when "feed"
|
132
|
+
# attrs =
|
133
|
+
# attributes["metadata"]
|
134
|
+
# .slice("feed_url", "refresh_interval")
|
135
|
+
# .symbolize_keys
|
136
|
+
# FeedMetadata.new(attrs)
|
137
|
+
when "vimeo"
|
138
|
+
attrs = attributes["metadata"]
|
139
|
+
.slice("video_url")
|
140
|
+
.symbolize_keys
|
141
|
+
VimeoMetadata.new(attrs)
|
142
|
+
when "weather_location"
|
143
|
+
attrs =
|
144
|
+
attributes["metadata"]
|
145
|
+
.slice("city", "country", "description", "feed_url",
|
146
|
+
"forecast_interval", "kind", "lat", "link", "long", "name",
|
147
|
+
"refresh_interval", "regio", "title", "token")
|
148
|
+
.symbolize_keys
|
149
|
+
WeatherLocationMetadata.new(attrs)
|
150
|
+
when "youtube"
|
151
|
+
attrs = attributes["metadata"]
|
152
|
+
.slice("video_url")
|
153
|
+
.symbolize_keys
|
154
|
+
YouTubeMetadata.new(attrs)
|
155
|
+
else
|
156
|
+
Metadata.new
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
149
160
|
|
150
|
-
|
151
|
-
|
152
|
-
|
161
|
+
# = The metadata class
|
162
|
+
#
|
163
|
+
# This represents some kind of metadata of a collection/item that is specific to its kind.
|
164
|
+
class Metadata < Hashie::Dash
|
153
165
|
end
|
154
166
|
|
155
|
-
# = The collection
|
156
|
-
|
157
|
-
|
158
|
-
|
167
|
+
# = The collection metadata class.
|
168
|
+
#
|
169
|
+
# This represents some kind of metadata of a collection that is specific to its kind.
|
170
|
+
class Collection::Metadata < Metadata
|
159
171
|
end
|
160
172
|
|
161
|
-
# = The collection
|
162
|
-
|
163
|
-
|
173
|
+
# = The feed collection metadata class
|
174
|
+
#
|
175
|
+
# This represents the metadata of a feed collection.
|
176
|
+
# class Collection::FeedMetadata < Collection::Metadata
|
177
|
+
# # @!attribute feed_url
|
178
|
+
# # @return [String, nil] the URL of the feed
|
179
|
+
# property :feed_url
|
180
|
+
#
|
181
|
+
# # @!attribute refresh_interval
|
182
|
+
# # @return [Integer] the interval used to refresh feed (in seconds)
|
183
|
+
# property :refresh_interval
|
184
|
+
# end
|
164
185
|
|
165
|
-
# @!attribute author
|
166
|
-
# @return [String] the author of the post
|
167
|
-
attribute :author
|
168
186
|
|
169
|
-
|
170
|
-
|
171
|
-
|
187
|
+
# = The Vimeo collection metadata class
|
188
|
+
#
|
189
|
+
# This represents the metadata of a Vimeo collection.
|
190
|
+
class Collection::VimeoMetadata < Collection::Metadata
|
191
|
+
# @!attribute video_url
|
192
|
+
# @return [String, nil] the actual URL of the Vimeo video
|
193
|
+
property :video_url
|
194
|
+
end
|
172
195
|
|
173
|
-
|
174
|
-
|
175
|
-
|
196
|
+
# = The weather location collection metadata class
|
197
|
+
#
|
198
|
+
# This represents the metadata of a weather location collection.
|
199
|
+
class Collection::WeatherLocationMetadata < Collection::Metadata
|
200
|
+
# @!attribute city
|
201
|
+
# @return [String, nil] the city of the weather location
|
202
|
+
property :city
|
176
203
|
|
177
|
-
# @!attribute
|
178
|
-
# @return [String] the
|
179
|
-
|
204
|
+
# @!attribute country
|
205
|
+
# @return [String, nil] the country of the weather location
|
206
|
+
property :country
|
180
207
|
|
181
208
|
# @!attribute description
|
182
|
-
# @return [String] the description of the
|
183
|
-
|
209
|
+
# @return [String, nil] the description of the weather location
|
210
|
+
property :description
|
184
211
|
|
185
|
-
# @!attribute
|
186
|
-
# @return [String] the
|
187
|
-
|
212
|
+
# @!attribute feed_url
|
213
|
+
# @return [String, nil] the URL of the feed of the weather location
|
214
|
+
property :feed_url
|
188
215
|
|
189
|
-
# @!attribute
|
190
|
-
# @return [
|
191
|
-
|
216
|
+
# @!attribute forecast_interval
|
217
|
+
# @return ["daily", "hourly"] whether the forecast is for a specific day
|
218
|
+
# or hour
|
219
|
+
property :forecast_interval
|
192
220
|
|
193
|
-
# @!attribute
|
194
|
-
# @return [
|
195
|
-
|
221
|
+
# @!attribute kind
|
222
|
+
# @return ["open_weather_map", "unknown"] the kind of the weather location
|
223
|
+
property :kind
|
196
224
|
|
197
|
-
# @!attribute
|
198
|
-
# @return [
|
199
|
-
|
225
|
+
# @!attribute lat
|
226
|
+
# @return [Float, nil] the latitude of the weather location
|
227
|
+
property :lat
|
200
228
|
|
201
229
|
# @!attribute link
|
202
|
-
# @return [String] the
|
203
|
-
|
230
|
+
# @return [String] the link of the weather location
|
231
|
+
property :link
|
204
232
|
|
205
|
-
# @!attribute
|
206
|
-
# @return [
|
207
|
-
|
208
|
-
attribute :order_priority
|
233
|
+
# @!attribute long
|
234
|
+
# @return [Float, nil] the longitude of the weather location
|
235
|
+
property :long
|
209
236
|
|
210
|
-
# @!attribute
|
211
|
-
#
|
212
|
-
|
237
|
+
# @!attribute name
|
238
|
+
# @return [String] the name of the forecast location
|
239
|
+
property :name
|
213
240
|
|
214
|
-
# @!attribute
|
215
|
-
#
|
216
|
-
|
241
|
+
# @!attribute refresh_interval
|
242
|
+
# @return [Integer] the interval used to refresh the weather location
|
243
|
+
# (in seconds)
|
244
|
+
property :refresh_interval
|
217
245
|
|
218
|
-
# @!attribute
|
219
|
-
# @return [String] the
|
220
|
-
|
246
|
+
# @!attribute region
|
247
|
+
# @return [String, nil] the region of the weather location
|
248
|
+
property :region
|
221
249
|
|
222
250
|
# @!attribute title
|
223
|
-
# @return [String] the title of the
|
224
|
-
|
225
|
-
end
|
226
|
-
|
227
|
-
# = The collection feed class
|
228
|
-
class Collection::Feed < Collection::Item
|
229
|
-
use_api LWS::Resource.api
|
230
|
-
uri "collections/:collection_id/feeds(/:id)"
|
231
|
-
|
232
|
-
# @!attribute feed_url
|
233
|
-
# @return [String] the URL of the feed
|
234
|
-
attribute :feed_url
|
235
|
-
|
236
|
-
# @!attribute post_ids
|
237
|
-
# @return [Collection::Post] the IDs of the posts included in the feed
|
238
|
-
attribute :post_ids
|
239
|
-
|
240
|
-
# @!attribute posts
|
241
|
-
# @return [Collection::Post] the posts included in the feed
|
242
|
-
has_many :posts,
|
243
|
-
class_name: "LWS::Resource::Collection::Feed::Post",
|
244
|
-
uri: "collections/:collection_id/feeds/:feed_id/posts(/:id)"
|
251
|
+
# @return [String] the title of the weather location
|
252
|
+
property :title
|
245
253
|
|
246
|
-
#
|
247
|
-
#
|
248
|
-
|
254
|
+
# @attribute token
|
255
|
+
# @return [String, nil] the token used to refresh the forecasts
|
256
|
+
property :token
|
249
257
|
end
|
250
258
|
|
251
|
-
# = The collection
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
# @!attribute
|
256
|
-
# @return [
|
257
|
-
|
258
|
-
belongs_to :feed,
|
259
|
-
class_name: "LWS::Resource::Collection::Feed",
|
260
|
-
uri: "collections/:collection_id/feeds(/:id)"
|
261
|
-
|
262
|
-
# @!attribute feed_id
|
263
|
-
# @return [Integer] the ID of the collection feed that the collection
|
264
|
-
# feed is a post is part of
|
265
|
-
attribute :feed_id
|
259
|
+
# = The YouTube collection metadata class
|
260
|
+
#
|
261
|
+
# This represents the metadata of a YouTube collection.
|
262
|
+
class Collection::YouTubeMetadata < Collection::Metadata
|
263
|
+
# @!attribute video_url
|
264
|
+
# @return [String, nil] the actual URL of the YouTube video
|
265
|
+
property :video_url
|
266
266
|
end
|
267
267
|
|
268
|
-
# = The collection
|
269
|
-
|
268
|
+
# = The collection item class
|
269
|
+
#
|
270
|
+
# An item has associated metadata (see {#metadata}) that is specific to the
|
271
|
+
# collection item kind.
|
272
|
+
class Collection::Item < LWS::Generic::Model
|
270
273
|
use_api LWS::Resource.api
|
271
|
-
uri "collections/:collection_id/images(/:id)"
|
272
274
|
|
273
|
-
# @!attribute
|
274
|
-
#
|
275
|
-
|
276
|
-
|
277
|
-
# @!attribute thumbnail_url
|
278
|
-
# @return [String] the URL of the thumbnail of the image
|
279
|
-
attribute :thumbnail_url
|
280
|
-
end
|
275
|
+
# @!attribute collection
|
276
|
+
# @return [Collection] the collection that the collection item is a
|
277
|
+
# part of
|
278
|
+
belongs_to :collection
|
281
279
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
280
|
+
# @!attribute collection_id
|
281
|
+
# @return [Integer] the ID of the collection that the collection item is a
|
282
|
+
# part of
|
283
|
+
attribute :collection_id
|
286
284
|
|
287
285
|
# @!attribute data_url
|
288
|
-
# @return [String] the URL of the
|
286
|
+
# @return [String, nil] the URL of the item (if it has associated data)
|
289
287
|
attribute :data_url
|
290
288
|
|
291
|
-
# @!attribute
|
292
|
-
# @
|
293
|
-
|
294
|
-
|
289
|
+
# @!attribute kind
|
290
|
+
# @note
|
291
|
+
# This library only supports a subset of the available collection/item
|
292
|
+
# kinds.
|
293
|
+
# @return ["forecast", "image", "pdf", "powerpoint", "video", "vimeo",
|
294
|
+
# "youtube"] the name of the class/kind of the collection item
|
295
|
+
attribute :kind
|
295
296
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
uri "collections/:collection_id/vimeos(/:id)"
|
297
|
+
# @!attribute name
|
298
|
+
# @return [String] the name of the collection item
|
299
|
+
attribute :name
|
300
300
|
|
301
|
-
# @!attribute
|
302
|
-
# @return [
|
303
|
-
attribute :
|
301
|
+
# @!attribute position
|
302
|
+
# @return [Integer] the position of the item within the collection
|
303
|
+
attribute :position
|
304
304
|
|
305
305
|
# @!attribute thumbnail_url
|
306
|
-
# @return [String] the URL of the thumbnail of the
|
306
|
+
# @return [String, nil] the URL of the thumbnail of the item (if it has
|
307
|
+
# associated data)
|
307
308
|
attribute :thumbnail_url
|
308
|
-
end
|
309
|
-
|
310
|
-
# = The collection YouTube class
|
311
|
-
class Collection::YouTube < Collection::Item
|
312
|
-
use_api LWS::Resource.api
|
313
|
-
uri "collections/:collection_id/youtubes(/:id)"
|
314
|
-
|
315
|
-
# @!attribute data_url
|
316
|
-
# @return [String] the URL of the youtube
|
317
|
-
attribute :data_url
|
318
309
|
|
319
|
-
#
|
320
|
-
#
|
321
|
-
|
310
|
+
# Returns the metadata of the collection item specific to its kind.
|
311
|
+
#
|
312
|
+
# @return [Collection::Item::Metadata] the kind-specific metadata of the
|
313
|
+
# collection item
|
314
|
+
def metadata
|
315
|
+
attrs = attributes["metadata"]&.symbolize_keys || {}
|
316
|
+
case kind
|
317
|
+
# when "config"
|
318
|
+
# ConfigMetadata.new(json: attributes["json"])
|
319
|
+
when "forecast"
|
320
|
+
attrs =
|
321
|
+
attributes
|
322
|
+
.slice("cloudiness", "code", "date", "observation",
|
323
|
+
"precipitation", "temperature", "uv_index", "wind")
|
324
|
+
.symbolize_keys
|
325
|
+
ForecastMetadata.new(attrs)
|
326
|
+
when "image"
|
327
|
+
ImageMetadata.new(attrs)
|
328
|
+
when "pdf"
|
329
|
+
PDFMetadata.new(attrs)
|
330
|
+
# when "post"
|
331
|
+
# attrs =
|
332
|
+
# attributes.slice("author", "category", "comments", "description",
|
333
|
+
# "guid", "handle", "link", "modification_data", "order_priority",
|
334
|
+
# "publication_date", "source_url", "summary", "title")
|
335
|
+
# PostMetadata.new(attrs)
|
336
|
+
when "powerpoint"
|
337
|
+
PowerPointMetadata.new(attrs)
|
338
|
+
when "video"
|
339
|
+
VideoMetadata.new(attrs)
|
340
|
+
when "vimeo"
|
341
|
+
VimeoMetadata.new(attrs)
|
342
|
+
when "youtube"
|
343
|
+
YouTubeMetadata.new(attrs)
|
344
|
+
else
|
345
|
+
Metadata.new
|
346
|
+
end
|
347
|
+
end
|
322
348
|
end
|
323
349
|
|
324
|
-
# = The collection
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
# @return [String] the city of the weather location
|
331
|
-
attribute :city
|
332
|
-
|
333
|
-
# @!attribute country
|
334
|
-
# @return [String] the country of the weather location
|
335
|
-
attribute :country
|
336
|
-
|
337
|
-
# @!attribute description
|
338
|
-
# @return [String] the description of the weather location
|
339
|
-
attribute :description
|
340
|
-
|
341
|
-
# @!attribute feed_url
|
342
|
-
# @return [String] the URL of the feed of the weather location
|
343
|
-
attribute :feed_url
|
344
|
-
|
345
|
-
# @!attribute forecast_ids
|
346
|
-
# @return [Forecast] the IDs of the forecasts for the weather location
|
347
|
-
attribute :forecast_ids
|
348
|
-
|
349
|
-
# @!attribute forecasts
|
350
|
-
# @return [Forecast] the forecasts for the weather location
|
351
|
-
has_many :forecasts,
|
352
|
-
class_name: "LWS::Resource::Collection::WeatherLocation::Forecast",
|
353
|
-
uri: "collections/:collection_id/weather_locations/:weather_location_id/forecasts(/:id)"
|
354
|
-
|
355
|
-
# @!attribute kind
|
356
|
-
# @return ["unknown", "yahoo"] the kind of the weather location
|
357
|
-
attribute :kind
|
358
|
-
|
359
|
-
# @!attribute lat
|
360
|
-
# @return [Float, nil] the latitude of the weather location
|
361
|
-
attribute :lat
|
362
|
-
|
363
|
-
# @!attribute link
|
364
|
-
# @return [String] the link of the weather location
|
365
|
-
attribute :link
|
366
|
-
|
367
|
-
# @!attribute long
|
368
|
-
# @return [Float, nil] the longitude of the weather location
|
369
|
-
attribute :long
|
370
|
-
|
371
|
-
# @!attribute refresh_interval
|
372
|
-
# @return [Integer] the interval used to refresh the weather location
|
373
|
-
# (in seconds)
|
374
|
-
attribute :refresh_interval
|
350
|
+
# = The collection item metadata class.
|
351
|
+
#
|
352
|
+
# This represents some kind of metadata of a collection item that is specific
|
353
|
+
# to its collection kind.
|
354
|
+
class Collection::Item::Metadata < Metadata
|
355
|
+
end
|
375
356
|
|
376
|
-
|
377
|
-
|
378
|
-
|
357
|
+
# = The config collection item metadata class.
|
358
|
+
#
|
359
|
+
# This represents the metadata of a config item, part of a config collection.
|
360
|
+
# class Collection::Item::ConfigMetadata < Metadata
|
361
|
+
# # @!attribute json
|
362
|
+
# # @return [String] the JSON data of the config
|
363
|
+
# property :json
|
364
|
+
# end
|
379
365
|
|
380
|
-
# @!attribute title
|
381
|
-
# @return [String] the title of the weather location
|
382
|
-
attribute :title
|
383
|
-
end
|
384
366
|
|
385
|
-
# = The collection
|
386
|
-
|
387
|
-
|
388
|
-
|
367
|
+
# = The forecast collection item metadata class
|
368
|
+
#
|
369
|
+
# This represents the metadata of a forecast item, part of a weather location
|
370
|
+
# collection.
|
371
|
+
class Collection::Item::ForecastMetadata < Collection::Item::Metadata
|
372
|
+
# @!attribute cloudiness
|
373
|
+
# @return [Integer] the percentage of cloud cover for the weather
|
374
|
+
# location forecast
|
375
|
+
property :cloudiness
|
389
376
|
|
390
377
|
# @!attribute code
|
391
378
|
# @return [Integer] the code for the weather location forecast
|
392
|
-
|
379
|
+
property :code
|
393
380
|
|
394
381
|
# @!attribute date
|
395
382
|
# @return [Integer] the timestamp of the date of the weather location forecast
|
396
|
-
|
383
|
+
property :date
|
397
384
|
|
398
385
|
# @!attribute description
|
399
|
-
# @return [
|
400
|
-
|
386
|
+
# @return [String] the (English) description of the weather location forecast
|
387
|
+
property :description
|
401
388
|
|
402
389
|
# @!attribute observation
|
403
390
|
# @return [Boolean] whether the weather location forecast is a
|
404
391
|
# current observation
|
405
|
-
|
392
|
+
property :observation
|
393
|
+
|
394
|
+
# @!attribute precipitation
|
395
|
+
# The precipitation hash contains the propability on precipitation (key
|
396
|
+
# "probability") between 0 and 1, and the forecasted amount of rain
|
397
|
+
# (key "rain") and/or snow (key "snow") in millimeter.
|
398
|
+
# @return [Hash{String=>Float, nil}] the precipitation information of
|
399
|
+
# the weather location forecast
|
400
|
+
property :precipitation
|
406
401
|
|
407
402
|
# @!attribute temperature
|
408
403
|
# The temperature hash contains either the current temperature (key
|
409
404
|
# "now") if the forecast is an observation or the temperature range
|
410
405
|
# (keys "low" and "high") if it is not.
|
411
|
-
#
|
406
|
+
#
|
407
|
+
# For hourly forecasts, the value of either key "min" or "max" can have
|
408
|
+
# the value +true+ based on whether the forecasted temperature for this
|
409
|
+
# hour is the expected mininum or maximum temperature for the day.
|
410
|
+
# @return [Hash{String=>Float, Boolean, nil}] the temperature information of the
|
412
411
|
# weather location forecast
|
413
|
-
|
414
|
-
|
415
|
-
# @!attribute weather_location
|
416
|
-
# @return [Collection::WeatherLocation] the collection weather location
|
417
|
-
# that the collection weather location post is a part of
|
418
|
-
belongs_to :weather_location,
|
419
|
-
class_name: "LWS::Resource::Collection::WeatherLocation",
|
420
|
-
uri: "collections/:collection_id/weather_location(/:id)"
|
412
|
+
property :temperature
|
421
413
|
|
422
|
-
# @!attribute
|
423
|
-
# @return [
|
424
|
-
|
425
|
-
attribute :weather_location_id
|
414
|
+
# @!attribute uv_index
|
415
|
+
# @return [Float] the maximum UV index of the weather location forecast
|
416
|
+
property :uv_index
|
426
417
|
|
427
418
|
# @!attribute wind
|
428
419
|
# The wind hash contains the wind chill temperature (key "chill"),
|
429
420
|
# direction in degrees (key "direction"), and wind speed (key "speed").
|
430
|
-
# @return [Hash{String=>Float}] the temperature information of the
|
421
|
+
# @return [Hash{String=>Float, nil}] the temperature information of the
|
431
422
|
# weather location forecast
|
432
|
-
|
423
|
+
property :wind
|
424
|
+
end
|
425
|
+
|
426
|
+
# = The image collection item metadata class
|
427
|
+
#
|
428
|
+
# This represents the metadata of an image item, part of an image collection.
|
429
|
+
class Collection::Item::ImageMetadata < Collection::Item::Metadata
|
430
|
+
# @!attribute byte_size
|
431
|
+
# @return [Integer] the size of the image (in bytes)
|
432
|
+
property :byte_size
|
433
|
+
|
434
|
+
# @!attribute content_type
|
435
|
+
# @return [String] the MIME content type of the image
|
436
|
+
property :content_type
|
437
|
+
|
438
|
+
# @!attribute filename
|
439
|
+
# @return [String] the filename of the image
|
440
|
+
property :filename
|
441
|
+
|
442
|
+
# @!attribute height
|
443
|
+
# @return [Integer] the height of the image (in pixels)
|
444
|
+
property :height
|
445
|
+
|
446
|
+
# @!attribute width
|
447
|
+
# @return [Integer] the width of the image (in pixels)
|
448
|
+
property :width
|
449
|
+
end
|
450
|
+
|
451
|
+
# = The PDF collection item metadata class
|
452
|
+
#
|
453
|
+
# This represents the metadata of a PDF item, part of a PDF collection.
|
454
|
+
class Collection::Item::PDFMetadata < Collection::Item::ImageMetadata
|
455
|
+
end
|
456
|
+
|
457
|
+
# = The post collection item metadata class
|
458
|
+
#
|
459
|
+
# This represents the metadata of a post item, part of a feed collection.
|
460
|
+
# class Collection::Item::PostMetadata < Collection::Item::Metadata
|
461
|
+
# # @!attribute author
|
462
|
+
# # @return [String] the author of the post
|
463
|
+
# property :author
|
464
|
+
#
|
465
|
+
# # @!attribute category
|
466
|
+
# # @return [String] the category of the post
|
467
|
+
# property :category
|
468
|
+
#
|
469
|
+
# # @!attribute comments
|
470
|
+
# # @return [String] the comments of the post
|
471
|
+
# property :comments
|
472
|
+
#
|
473
|
+
# # @!attribute description
|
474
|
+
# # @return [String] the description of the post
|
475
|
+
# property :description
|
476
|
+
#
|
477
|
+
# # @!attribute description
|
478
|
+
# # @return [Array<ImageMetadata>] the description of the post
|
479
|
+
# property :enclosures
|
480
|
+
#
|
481
|
+
# # @!attribute guid
|
482
|
+
# # @return [String] the GUID of the post
|
483
|
+
# property :guid
|
484
|
+
#
|
485
|
+
# # @!attribute handle
|
486
|
+
# # @return [String] the handle of the post
|
487
|
+
# property :handle
|
488
|
+
#
|
489
|
+
# # @!attribute link
|
490
|
+
# # @return [String] the link of the post
|
491
|
+
# property :link
|
492
|
+
#
|
493
|
+
# # @!attribute link
|
494
|
+
# # @return [String] the timestamp of the modification date of the post
|
495
|
+
# property :modification_date
|
496
|
+
#
|
497
|
+
# # @!attribute order_priority
|
498
|
+
# # @return [Integer] the order priority of the of the post (ascending;
|
499
|
+
# # 0 is lowers)
|
500
|
+
# property :order_priority
|
501
|
+
#
|
502
|
+
# # @!attribute link
|
503
|
+
# # @return [String] the timestamp of the publication date of the post
|
504
|
+
# property :publication_date
|
505
|
+
#
|
506
|
+
# # @!attribute source_url
|
507
|
+
# # @return [String] the source URL of the post
|
508
|
+
# property :source_url
|
509
|
+
#
|
510
|
+
# # @!attribute summary
|
511
|
+
# # @return [String] the summary of the post
|
512
|
+
# property :summary
|
513
|
+
#
|
514
|
+
# # @!attribute title
|
515
|
+
# # @return [String] the title of the post
|
516
|
+
# property :title
|
517
|
+
# end
|
518
|
+
|
519
|
+
|
520
|
+
class Collection::Item::VideoMetadata < Collection::Item::Metadata
|
521
|
+
# @!attribute byte_size
|
522
|
+
# @return [Integer] the size of the video (in bytes)
|
523
|
+
property :byte_size
|
524
|
+
|
525
|
+
# @!attribute content_type
|
526
|
+
# @return [String] the MIME content type of the video
|
527
|
+
property :content_type
|
528
|
+
|
529
|
+
# @!attribute display_aspect_ratio
|
530
|
+
# @return [(Integer, Integer)] the aspect ratio of the video
|
531
|
+
property :display_aspect_ratio
|
532
|
+
|
533
|
+
# @!attribute duration
|
534
|
+
# @return [Integer] the duration of the video
|
535
|
+
property :duration
|
536
|
+
|
537
|
+
# @!attribute filename
|
538
|
+
# @return [String] the filename of the video
|
539
|
+
property :filename
|
540
|
+
|
541
|
+
# @!attribute height
|
542
|
+
# @return [Float] the height of the video (in pixels)
|
543
|
+
property :height
|
544
|
+
|
545
|
+
# @!attribute width
|
546
|
+
# @return [Float] the width of the video (in pixels)
|
547
|
+
property :width
|
548
|
+
end
|
549
|
+
|
550
|
+
# = The PowerPoint collection item metadata class
|
551
|
+
#
|
552
|
+
# This represents the metadata of a PowerPoint item, part of a PowerPoint
|
553
|
+
# collection.
|
554
|
+
class Collection::Item::PowerPointMetadata < Collection::Item::VideoMetadata
|
555
|
+
end
|
556
|
+
|
557
|
+
# = The Vimeo collection item metadata class
|
558
|
+
#
|
559
|
+
# This represents the metadata of a Vimeo item, part of a Vimeo collection.
|
560
|
+
class Collection::Item::VimeoMetadata < Collection::Item::VideoMetadata
|
561
|
+
end
|
562
|
+
|
563
|
+
# = The YouTube collection item metadata class
|
564
|
+
#
|
565
|
+
# This represents the metadata of a YouTube item, part of a YouTube
|
566
|
+
# collection.
|
567
|
+
class Collection::Item::YouTubeMetadata < Collection::Item::VideoMetadata
|
433
568
|
end
|
434
569
|
|
435
570
|
# = The folder class
|
data/lib/lws/errors.rb
CHANGED
@@ -16,17 +16,23 @@ module LWS
|
|
16
16
|
#
|
17
17
|
# This module contains the exceptions that can be thrown.
|
18
18
|
module Errors
|
19
|
+
# Parent class of all LWS errors.
|
20
|
+
class Error < StandardError; end
|
21
|
+
|
19
22
|
# Exception thrown if there are issues with the LWS configuration.
|
20
|
-
class ConfigError <
|
23
|
+
class ConfigError < Error; end
|
21
24
|
|
22
25
|
# Exception thrown if an invalid response is returned by LWS.
|
23
|
-
class InvalidResponse <
|
26
|
+
class InvalidResponse < Error; end
|
24
27
|
|
25
28
|
# Exception thrown if the resource could not be found in LWS.
|
26
|
-
class ResourceNotFound <
|
29
|
+
class ResourceNotFound < Error; end
|
30
|
+
|
31
|
+
# Exception thrown if the LWS server fails.
|
32
|
+
class ServerError < Error; end
|
27
33
|
|
28
34
|
# Exception thrown if there is an issue with the stubbing setup.
|
29
|
-
class StubError <
|
35
|
+
class StubError < Error; end
|
30
36
|
end
|
31
37
|
|
32
38
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# Copyright © 2016–2021 LeftClick Web Services B.V.
|
3
|
+
#
|
4
|
+
# This software is property of LeftClick Web Services B.V. and cannot be
|
5
|
+
# redistributed and/or modified without permission. The software or any
|
6
|
+
# of its parts cannot be used for any other purposes than the LeftClick
|
7
|
+
# services and only during a valid license subscription. For more
|
8
|
+
# information, please contact LeftClick Web Services B.V. at:
|
9
|
+
# Schootense Dreef 20A, 5708 HZ Helmond, The Netherlands,
|
10
|
+
# info@leftclick.eu, +3185-4444-004.
|
11
|
+
|
12
|
+
|
13
|
+
module LWS
|
14
|
+
|
15
|
+
module Middleware
|
16
|
+
|
17
|
+
# @private
|
18
|
+
# @!visibility private
|
19
|
+
class RaiseServerError <
|
20
|
+
# Use `Faraday::Response::Middleware` if it exists (Faraday < 2.0)
|
21
|
+
defined?(Faraday::Response::Middleware) ? Faraday::Response::Middleware : Faraday::Middleware
|
22
|
+
|
23
|
+
def on_complete(env)
|
24
|
+
case env[:status]
|
25
|
+
when 500...600
|
26
|
+
raise LWS::Errors::ServerError, env[:body]
|
27
|
+
when nil
|
28
|
+
raise LWS::Errors::ServerError, "response status missing"
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
data/lib/lws/middleware.rb
CHANGED
@@ -23,6 +23,7 @@ require "lws/middleware/caching"
|
|
23
23
|
require "lws/middleware/http_logger"
|
24
24
|
require "lws/middleware/json_logger"
|
25
25
|
require "lws/middleware/json_parser"
|
26
|
+
require "lws/middleware/raise_server_error"
|
26
27
|
require "lws/middleware/request_headers"
|
27
28
|
|
28
29
|
# Set up Faraday 1.0/2.0 portability using middleware class aliases.
|
@@ -50,5 +51,12 @@ module LWS
|
|
50
51
|
# available for Faraday ≥ 2.0
|
51
52
|
Caching
|
52
53
|
end
|
54
|
+
|
55
|
+
Retry =
|
56
|
+
if defined? Faraday::Request::Retry
|
57
|
+
Faraday::Request::Retry
|
58
|
+
else
|
59
|
+
Faraday::Retry::Middleware
|
60
|
+
end
|
53
61
|
end
|
54
62
|
end
|
data/lib/lws/version.rb
CHANGED
data/lib/lws.rb
CHANGED
@@ -18,6 +18,7 @@ else
|
|
18
18
|
# For Faraday ≥ 2.0 load these middleware gems separately.
|
19
19
|
require "faraday/follow_redirects"
|
20
20
|
require "faraday/net_http_persistent"
|
21
|
+
require "faraday/retry"
|
21
22
|
end
|
22
23
|
require "hashie"
|
23
24
|
require "multi_json"
|
@@ -138,6 +139,11 @@ module LWS
|
|
138
139
|
# Response
|
139
140
|
c.use Middleware::JSONLogger, config.logger if config.json_debug
|
140
141
|
c.use Middleware::JSONParser
|
142
|
+
c.use Middleware::RaiseServerError
|
143
|
+
c.use Middleware::Retry, exceptions: Middleware::Retry::DEFAULT_EXCEPTIONS +
|
144
|
+
[Errno::EALREADY, Faraday::ConnectionFailed],
|
145
|
+
interval: 0.2,
|
146
|
+
retry_statuses: [502, 503, 504]
|
141
147
|
c.use Middleware::FollowRedirects, limit: 3
|
142
148
|
if config.http_debug
|
143
149
|
c.use Middleware::HTTPLogger, config.logger, config.http_debug_headers
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 11.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- LeftClick B.V.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-09-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -64,6 +64,26 @@ dependencies:
|
|
64
64
|
- - "<"
|
65
65
|
- !ruby/object:Gem::Version
|
66
66
|
version: '2.0'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: net-http-persistent
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '2.9'
|
74
|
+
- - "<"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '5.0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '2.9'
|
84
|
+
- - "<"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '5.0'
|
67
87
|
- !ruby/object:Gem::Dependency
|
68
88
|
name: hashie
|
69
89
|
requirement: !ruby/object:Gem::Requirement
|
@@ -182,6 +202,7 @@ files:
|
|
182
202
|
- lib/lws/middleware/http_logger.rb
|
183
203
|
- lib/lws/middleware/json_logger.rb
|
184
204
|
- lib/lws/middleware/json_parser.rb
|
205
|
+
- lib/lws/middleware/raise_server_error.rb
|
185
206
|
- lib/lws/middleware/request_headers.rb
|
186
207
|
- lib/lws/stubbing.rb
|
187
208
|
- lib/lws/version.rb
|