radio5 0.1.2 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cae0f327ab80b79f9d50626a2e59161ce8b0a2b7eb62400a2d36c0ef800b47d
4
- data.tar.gz: ae74f46091926142fd98de0be436e50a21d6a7a9755ac6d1a533d7e4cee02ad3
3
+ metadata.gz: afc335b6a9726ff30f27942868b19513b02aea353144fcd8f283bc8da3fe1159
4
+ data.tar.gz: 41852476ae434f3718e68d2c60d8fc7b868425288efeae519024d766e7d06b94
5
5
  SHA512:
6
- metadata.gz: 551122e49cbabbdc97e8655f10157fd373a29022bab4242267eb6e1bd347045445a3438de9a20c0ff3837dcc9b970c027992c8d15feb3602a4338abe5f748269
7
- data.tar.gz: 46e0212e7fc3fb608aff1b163ff600b97939a768518c6fabc688ea77b3571d974303a9285ad2f89094b83646b99f8633e69c1891fa3e65e6a6b65bd1d61379e4
6
+ metadata.gz: 8be48ecc1b8681d7749775473b9b3af13aa469aa3098a2896ffbb026056b696d3135924b19d1ff4ff79c9e6e50a6c05cb9f270372874b52c2df48401d504d72e
7
+ data.tar.gz: 639fab8c48fe128066118ebcf79e72baf3aa6ef5d104540b03bbc30d51b3f77163d9cd348fa52cc6c2b23e75027cd224d77d42ba80f7efe288d067c112628781
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ 0.2.0
2
+ ----------
3
+
4
+ - Added users endpoints support
5
+ - Replaced `track[:cover]` with `track[:cover_url]` with extended format (per size) as with users
6
+
1
7
  0.1.2
2
8
  ----------
3
9
 
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Radio5
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/radio5.svg)](https://badge.fury.io/rb/radio5)
4
- [![Build](https://github.com/ocvit/radio5/workflows/Build/badge.svg)](https://github.com/ocvit/radio5/actions)
4
+ [![Test](https://github.com/ocvit/radio5/workflows/Test/badge.svg)](https://github.com/ocvit/radio5/actions)
5
5
  [![Coverage Status](https://coveralls.io/repos/github/ocvit/radio5/badge.svg?branch=main)](https://coveralls.io/github/ocvit/radio5?branch=main)
6
6
 
7
7
  Adapter for [Radiooooo](https://radiooooo.com/) private API.
@@ -47,7 +47,7 @@ client = Radio5::Client.new(
47
47
  )
48
48
  ```
49
49
 
50
- ## Usage
50
+ ## Tracks
51
51
 
52
52
  To get random track:
53
53
 
@@ -64,7 +64,12 @@ client.random_track
64
64
  # songwriter: "Bart Howard",
65
65
  # length: 133,
66
66
  # info: "It is the original recording of Fly me to the moon !",
67
- # cover_url: "https://asset.radiooooo.com/cover/USA/1950/large/<uuid>_1.jpg",
67
+ # cover_url: {
68
+ # thumb: "https://asset.radiooooo.com/cover/USA/1950/thumb/<uuid>_1.jpg",
69
+ # small: "https://asset.radiooooo.com/cover/USA/1950/small/<uuid>_1.jpg",
70
+ # medium: "https://asset.radiooooo.com/cover/USA/1950/medium/<uuid>_1.jpg",
71
+ # large: "https://asset.radiooooo.com/cover/USA/1950/large/<uuid>_1.jpg",
72
+ # },
68
73
  # audio: {
69
74
  # mpeg: {
70
75
  # url: "https://radiooooo-track.b-cdn.net/USA/1950/<uuid>.mp3?token=<token>&expires=1704717060",
@@ -120,12 +125,12 @@ client.track("655f7bb24b0d722a021a2cf2")
120
125
  # output is exactly the same as from `#random_track`, but `created_at` is now filled
121
126
  ```
122
127
 
128
+ ## Countries / decades / moods
129
+
123
130
  OK, what input parameters are available?
124
131
 
125
132
  ```ruby
126
- # list of countries + additional info:
127
- # - `exist` - "is it still around" flag
128
- # - `rank` - subjective ranking provided by the website, only 10 countries have it
133
+ # countries
129
134
  client.countries
130
135
  # => {
131
136
  # "AFG" => {name: "Afganistan", exist: true, rank: nil},
@@ -133,6 +138,10 @@ client.countries
133
138
  # "FRA" => {name: "France", exist: true, rank: 2},
134
139
  # ...
135
140
  # }
141
+ #
142
+ # NOTES:
143
+ # - `exist` - "is it still around" flag
144
+ # - `rank` - subjective ranking provided by the website, only 10 countries have it
136
145
 
137
146
  # decades
138
147
  client.decades
@@ -142,10 +151,10 @@ client.decades
142
151
  client.moods
143
152
  # => [:fast, :slow, :weird]
144
153
  #
145
- # NOTE: by default all 3 moods are used in `#random_track` and `#island_track`
154
+ # NOTE: all 3 moods are used in `#random_track` and `#island_track` by default
146
155
  ```
147
156
 
148
- It's also possible to get all valid `country`/`decade`/`moods` combinations in advance:
157
+ It's also possible to get all valid `country`/ `moods` combinations per for specific decade in advance:
149
158
 
150
159
  ```ruby
151
160
  # grouped by country
@@ -168,10 +177,13 @@ client.countries_for_decade(1960, group_by: :mood)
168
177
  # }
169
178
  ```
170
179
 
171
- How to work with the "islands" ("playlists" in the simple words):
180
+ ## Islands
181
+
182
+ Islands work as a kind of thematic collections.
183
+
184
+ To get a list of all islands:
172
185
 
173
186
  ```ruby
174
- # list all islands
175
187
  client.islands
176
188
  # => [{
177
189
  # id: "5d330a3e06fb03d8872a3316",
@@ -208,22 +220,119 @@ client.islands
208
220
  # - `play_mode` - it is somehow used in a web app
209
221
  # - `created_by` - `id` of user who created this island
210
222
  # - `updated_by` - ...and who updated it last time
223
+ ```
224
+
225
+ To get random track from selected island:
211
226
 
212
- # to get random track from selected island
227
+ ```ruby
213
228
  client.island_track(island_id: "5d330a3e06fb03d8872a3316")
214
229
 
215
230
  # it's also possible to specify moods
216
231
  client.island_track(island_id: "5d330a3e06fb03d8872a3316", moods: [:fast, :weird])
217
232
  ```
218
233
 
219
- User endpoints - WIP.
234
+ ## Users
235
+
236
+ To get information about specific user using its `id`:
237
+
238
+ ```ruby
239
+ client.user("5d3306de06fb03d8871fd138")
240
+ # => {
241
+ # id: "5d3306de06fb03d8871fd138",
242
+ # uuid: <uuid>,
243
+ # name: "Paul Charmant-Kabil",
244
+ # info: "Dreamseeker",
245
+ # country: "FRA",
246
+ # rank: 9188,
247
+ # image_url: {
248
+ # icon: "https://asset.radiooooo.com/user/1409/icon/<uuid>_3.jpg",
249
+ # thumb: "https://asset.radiooooo.com/user/1409/thumb/<uuid>_3.jpg",
250
+ # small: "https://asset.radiooooo.com/user/1409/small/<uuid>_3.jpg",
251
+ # medium: "https://asset.radiooooo.com/user/1409/medium/<uuid>_3.jpg",
252
+ # large: "https://asset.radiooooo.com/user/1409/large/<uuid>_3.jpg"
253
+ # },
254
+ # birthday: {
255
+ # time: 1981-01-31 23:01:01 UTC,
256
+ # year_normalized: 1981
257
+ # },
258
+ # created_at: 2014-09-30 18:58:32 UTC
259
+ # }
260
+ #
261
+ # NOTES:
262
+ # - `rank` - is not unique
263
+ # - `birthday`:
264
+ # - `time` - original time from API, it is always around first day of Jan or last day of
265
+ # December, with a strange hour offset around midnight, so it looks like the
266
+ # only real value here is the year
267
+ # - `year_normalized` - de-offset'ed year
268
+ ```
269
+
270
+ To get user followers or followings counts:
271
+
272
+ ```ruby
273
+ client.user_follow_counts("5d3306de06fb03d8871fd138")
274
+ # => {
275
+ # followings: 17,
276
+ # followers: 866
277
+ # }
278
+ ```
279
+
280
+ To get list of user followers:
281
+
282
+ ```ruby
283
+ # all followers will be returned by default
284
+ client.user_followers("5d3306de06fb03d8871fd138")
285
+ # => [{
286
+ # id: "5f8f175051430765bd5c1b08",
287
+ # name: "Philart",
288
+ # country: "FRA",
289
+ # rank: 25,
290
+ # image_url: {
291
+ # icon: "https://asset.radiooooo.com/user/2010/icon/<uuid>_1.jpg",
292
+ # thumb: "https://asset.radiooooo.com/user/2010/thumb/<uuid>_1.jpg",
293
+ # small: "https://asset.radiooooo.com/user/2010/small/<uuid>_1.jpg",
294
+ # medium: "https://asset.radiooooo.com/user/2010/medium/<uuid>_1.jpg",
295
+ # large: "https://asset.radiooooo.com/user/2010/large/<uuid>_1.jpg"
296
+ # },
297
+ # created_at: 2020-10-20 16:58:56.819 UTC
298
+ # }, ...]
299
+
300
+ # it's also possible to specify size/page
301
+ client.user_followers("5d3306de06fb03d8871fd138", size: 1, page: 5)
302
+ # => [{...}]
303
+ ```
304
+
305
+ To get list of user followings:
306
+
307
+ ```ruby
308
+ # all followings will be returned by default
309
+ client.user_followings("5d3306de06fb03d8871fd138")
310
+ # => [{
311
+ # id: "640ab0cebf47667afdbf9edb",
312
+ # name: "Cap Jones",
313
+ # country: "USA",
314
+ # rank: 5,
315
+ # image_url: {
316
+ # icon: "https://asset.radiooooo.com/user/2303/icon/<uuid>_1.jpg",
317
+ # thumb: "https://asset.radiooooo.com/user/2303/thumb/<uuid>_1.jpg",
318
+ # small: "https://asset.radiooooo.com/user/2303/small/<uuid>_1.jpg",
319
+ # medium: "https://asset.radiooooo.com/user/2303/medium/<uuid>_1.jpg",
320
+ # large: "https://asset.radiooooo.com/user/2303/large/<uuid>_1.jpg"
321
+ # },
322
+ # created_at: 2023-03-10 04:23:42.87 UTC
323
+ # }, ...]
324
+
325
+ # it's also possible to specify size/page
326
+ client.user_followings("5d3306de06fb03d8871fd138", size: 1, page: 5)
327
+ # => [{...}]
328
+ ```
220
329
 
221
330
  ## Auth?
222
331
 
223
- There is just a couple of features that require login and/or premium account:
332
+ There is just a couple of features that require login (free or premium account):
224
333
 
225
- - history of "listened" tracks - track becomes "listened" when you got it via `#random_track` or `#island_track` (free)
226
- - `followed` flag for `#user` - indicates whether or not you follow this user (free)
334
+ - `#track_history` - list of tracks you "listened" via `#random_track` or `#island_track` (free)
335
+ - `user[:followed]` flag - indicates whether or not you follow this user (free)
227
336
  - `#user_liked_tracks` - list of tracks which user really vibed to (free)
228
337
  - ability to use multiple countries as a filter in `#random_track` (premium)
229
338
 
@@ -236,7 +345,7 @@ Currently auth is in a WIP state.
236
345
  - [x] Countries support
237
346
  - [x] Islands support
238
347
  - [x] Tracks support
239
- - [ ] Users support
348
+ - [x] Users support
240
349
  - [ ] Auth + auth'ed endpoints
241
350
 
242
351
  ## Development
data/lib/radio5/api.rb CHANGED
@@ -5,6 +5,7 @@ module Radio5
5
5
  class Error < StandardError; end
6
6
  class TrackNotFound < Error; end
7
7
  class MatchingTrackNotFound < Error; end
8
+ class UserNotFound < Error; end
8
9
  class UnexpectedResponse < StandardError; end
9
10
 
10
11
  HOST = "radiooooo.com"
@@ -39,6 +40,8 @@ module Radio5
39
40
  raise TrackNotFound
40
41
  in error: "No track for this selection"
41
42
  raise MatchingTrackNotFound
43
+ in error: "No info for this user"
44
+ raise UserNotFound
42
45
  in error: other_error
43
46
  raise Error, other_error
44
47
  else
@@ -3,13 +3,19 @@
3
3
  module Radio5
4
4
  class Client
5
5
  module Islands
6
- include Utils
7
-
8
- # rubocop:disable Layout/HashAlignment
9
6
  def islands
10
7
  _, json = api.get("/island/all")
11
8
 
12
9
  json.map do |island|
10
+ Parser.island_info(island)
11
+ end
12
+ end
13
+
14
+ module Parser
15
+ extend Utils
16
+
17
+ # rubocop:disable Layout/HashAlignment
18
+ def self.island_info(island)
13
19
  rank_value = island[:sort]
14
20
  rank = rank_value if rank_value.is_a?(Integer)
15
21
 
@@ -30,9 +36,9 @@ module Radio5
30
36
  favourite_count: island[:favorites],
31
37
  play_count: island.fetch(:plays),
32
38
  rank: rank,
33
- icon_url: parse_asset_url(island, :icon),
34
- splash_url: parse_asset_url(island, :splash),
35
- marker_url: parse_asset_url(island, :marker),
39
+ icon_url: parse_asset_url(island[:icon]),
40
+ splash_url: parse_asset_url(island[:splash]),
41
+ marker_url: parse_asset_url(island[:marker]),
36
42
  enabled: island.fetch(:enabled),
37
43
  free: island[:free],
38
44
  on_map: island.fetch(:onmap),
@@ -44,8 +50,8 @@ module Radio5
44
50
  updated_by: updated_by
45
51
  }
46
52
  end
53
+ # rubocop:enable Layout/HashAlignment
47
54
  end
48
- # rubocop:enable Layout/HashAlignment
49
55
  end
50
56
  end
51
57
  end
@@ -69,6 +69,9 @@ module Radio5
69
69
  created_at = created_node && parse_time_string(created_node.fetch(:date))
70
70
  created_by = created_node ? created_node.fetch(:user_id) : json.fetch(:profile_id)
71
71
 
72
+ cover_node = json[:image] || json[:cover]
73
+ cover_url = parse_image_urls(cover_node, entity: :track)
74
+
72
75
  audio = {
73
76
  mpeg: track_audio(json, :mpeg),
74
77
  ogg: track_audio(json, :ogg)
@@ -85,7 +88,7 @@ module Radio5
85
88
  songwriter: normalize_string(json[:songwriter]),
86
89
  length: json.fetch(:length),
87
90
  info: normalize_string(json[:info]),
88
- cover_url: parse_asset_url(json, :image, size: "large"),
91
+ cover_url: cover_url,
89
92
  audio: audio,
90
93
  decade: json.fetch(:decade),
91
94
  mood: symbolize_mood(json.fetch(:mood)),
@@ -110,7 +113,6 @@ module Radio5
110
113
  }
111
114
  end
112
115
  end
113
- private_constant :Parser
114
116
  end
115
117
  end
116
118
  end
@@ -3,9 +3,141 @@
3
3
  module Radio5
4
4
  class Client
5
5
  module Users
6
- def user
7
- # ...
6
+ def user(id)
7
+ validate_user_id!(id)
8
+
9
+ _, json = api.get("/contributor/#{id}")
10
+
11
+ Parser.user_info(json)
12
+ rescue Api::UserNotFound
13
+ nil
14
+ end
15
+
16
+ def user_tracks(id, status: :on_air, size: MAX_PAGE_SIZE, page: 1)
17
+ validate_user_id!(id)
18
+ validate_user_track_status!(status)
19
+ validate_page_size!(size)
20
+ validate_page_number!(page)
21
+
22
+ query_params = {
23
+ status: stringify_user_track_status(status),
24
+ size: size,
25
+ page: page
26
+ }
27
+
28
+ _, json = api.get("/contributor/uploaded/#{id}", query_params: query_params)
29
+
30
+ json.map do |track|
31
+ Parser.user_track_info(track)
32
+ end
33
+ end
34
+
35
+ def user_follow_counts(id)
36
+ validate_user_id!(id)
37
+
38
+ _, json = api.get("/follow/count/#{id}")
39
+
40
+ {
41
+ followings: json.fetch(:following),
42
+ followers: json.fetch(:followers)
43
+ }
44
+ end
45
+
46
+ def user_followers(id, size: MAX_PAGE_SIZE, page: 1)
47
+ validate_user_id!(id)
48
+ validate_page_size!(size)
49
+ validate_page_number!(page)
50
+
51
+ _, json = api.get("/follow/list/follower/#{id}", query_params: {size: size, page: page})
52
+
53
+ json.map do |user|
54
+ Parser.follow_user_info(user)
55
+ end
56
+ end
57
+
58
+ def user_followings(id, size: MAX_PAGE_SIZE, page: 1)
59
+ validate_user_id!(id)
60
+ validate_page_size!(size)
61
+ validate_page_number!(page)
62
+
63
+ _, json = api.get("/follow/list/following/#{id}", query_params: {size: size, page: page})
64
+
65
+ json.map do |user|
66
+ Parser.follow_user_info(user)
67
+ end
68
+ end
69
+
70
+ def user_liked_tracks
71
+ raise NotImplementedError, "depends on auth"
72
+ end
73
+
74
+ # rubocop:disable Layout/HashAlignment
75
+ module Parser
76
+ extend Utils
77
+
78
+ def self.user_info(json)
79
+ birthday = if json[:birthday]
80
+ time = parse_time_string(json[:birthday])
81
+ year_normalized = normalize_year(time)
82
+
83
+ {
84
+ time: time,
85
+ year_normalized: year_normalized
86
+ }
87
+ end
88
+
89
+ {
90
+ id: json.fetch(:_id),
91
+ uuid: json.fetch(:uuid),
92
+ name: normalize_string(json.fetch(:pseudonym)),
93
+ info: normalize_string(json[:info]),
94
+ country: json[:country],
95
+ rank: json.fetch(:ranking),
96
+ image_url: parse_image_urls(json[:image], entity: :user),
97
+ birthday: birthday,
98
+ created_at: parse_time_string(json.fetch(:created))
99
+ }
100
+ end
101
+
102
+ def self.user_track_info(track)
103
+ cover_node = track[:image] || track[:cover]
104
+ cover_url = parse_image_urls(cover_node, entity: :track)
105
+
106
+ {
107
+ id: track.fetch(:_id),
108
+ uuid: track.fetch(:uuid),
109
+ artist: normalize_string(track.fetch(:artist)),
110
+ title: normalize_string(track.fetch(:title)),
111
+ year: normalize_string(track.fetch(:year)),
112
+ cover_url: cover_url,
113
+ decade: track.fetch(:decade),
114
+ country: track.fetch(:country),
115
+ like_count: track.fetch(:likes),
116
+ status: symbolize_user_track_status(track[:status])
117
+ }
118
+ end
119
+
120
+ # TODO: strange name tbh, change later
121
+ def self.follow_user_info(user)
122
+ {
123
+ id: user.fetch(:_id),
124
+ name: normalize_string(user.fetch(:pseudonym)),
125
+ country: user[:country],
126
+ rank: user.fetch(:ranking),
127
+ image_url: parse_image_urls(user[:image], entity: :user),
128
+ created_at: parse_time_string(user.fetch(:created))
129
+ }
130
+ end
131
+
132
+ def self.normalize_year(time)
133
+ if time.month == 12
134
+ time.year + 1
135
+ else
136
+ time.year
137
+ end
138
+ end
8
139
  end
140
+ # rubocop:enable Layout/HashAlignment
9
141
  end
10
142
  end
11
143
  end
data/lib/radio5/client.rb CHANGED
@@ -22,8 +22,8 @@ module Radio5
22
22
  @open_timeout = open_timeout
23
23
  @read_timeout = read_timeout
24
24
  @write_timeout = write_timeout
25
- @max_retries = max_retries
26
25
  @proxy_url = proxy_url
26
+ @max_retries = max_retries
27
27
  @debug_output = debug_output
28
28
  end
29
29
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Radio5
4
4
  module Regexps
5
+ include Utils
6
+
5
7
  # rubocop:disable Layout/ExtraSpacing
6
8
 
7
9
  MONGO_ID = /^[a-f\d]{24}$/.freeze
@@ -11,18 +13,28 @@ module Radio5
11
13
  COUNTRY_ISO_CODE_GENERIC = /([A-Z]{3}|KN1)/.freeze
12
14
  COUNTRY_ISO_CODE = /^#{COUNTRY_ISO_CODE_GENERIC}$/.freeze
13
15
 
14
- ASSET_URL = lambda do |sub_path, exts|
16
+ ASSET_URL = lambda do |sub_path, exts, size = nil|
15
17
  asset_host = Regexp.escape(Utils::ASSET_HOST)
16
18
  sub_path = sub_path.is_a?(Regexp) ? sub_path : Regexp.escape(sub_path)
17
19
  exts = /(#{exts.join("|")})/
20
+ size = /\/#{size}/ if size
18
21
 
19
- /#{asset_host}#{sub_path}\/#{UUID_GENERIC}(_\d+)?\.#{exts}/
22
+ /#{asset_host}#{sub_path}#{size}\/#{UUID_GENERIC}(_\d+)?\.#{exts}/
20
23
  end.freeze
21
24
 
22
25
  ISLAND_ICON_URL = ASSET_URL.call("/island/icon", ["png", "svg"]).freeze
23
26
  ISLAND_SPLASH_URL = ASSET_URL.call("/island/splash", ["png", "svg"]).freeze
24
27
  ISLAND_MARKER_URL = ASSET_URL.call("/island/marker", ["png", "svg"]).freeze
25
- TRACK_COVER_URL = ASSET_URL.call(/\/cover\/#{COUNTRY_ISO_CODE_GENERIC}\/\d{4}\/large/, ["jpg", "jpeg"]).freeze
28
+
29
+ TRACK_COVER_URL = IMAGE_SIZES[:track].each_with_object({}) do |image_size, hash|
30
+ url = ASSET_URL.call(/\/cover\/#{COUNTRY_ISO_CODE_GENERIC}\/\d{4}/, ["jpg", "jpeg", "png", "gif"], image_size.to_s)
31
+ hash[image_size] = url
32
+ end.freeze
33
+
34
+ USER_IMAGE_URL = IMAGE_SIZES[:user].each_with_object({}) do |image_size, hash|
35
+ url = ASSET_URL.call(/\/user\/\d+/, ["jpg", "jpeg", "png", "gif"], image_size.to_s)
36
+ hash[image_size] = url
37
+ end.freeze
26
38
 
27
39
  AUDIO_URL = lambda do |exts|
28
40
  exts = /(#{exts.join("|")})/
data/lib/radio5/utils.rb CHANGED
@@ -9,17 +9,32 @@ module Radio5
9
9
 
10
10
  ASSET_HOST = "https://asset.radiooooo.com"
11
11
 
12
+ IMAGE_SIZES = {
13
+ track: %i[thumb small medium large],
14
+ user: %i[icon thumb small medium large]
15
+ }.freeze
16
+
12
17
  def parse_json(json_raw)
13
18
  JSON.parse(json_raw, symbolize_names: true)
14
19
  end
15
20
 
16
- def parse_asset_url(hash, key, size: nil)
17
- node = hash[key]
18
-
21
+ def parse_image_urls(node, entity:)
19
22
  if node
20
23
  path, filename = node.fetch_values(:path, :filename)
21
- path << "#{size}/" if size
24
+ image_sizes = IMAGE_SIZES.fetch(entity)
25
+
26
+ image_sizes.each_with_object({}) do |image_size, hash|
27
+ image_size_path = "#{path}#{image_size}/"
28
+ image_url = create_asset_url(image_size_path, filename)
29
+
30
+ hash[image_size] = image_url
31
+ end
32
+ end
33
+ end
22
34
 
35
+ def parse_asset_url(node)
36
+ if node
37
+ path, filename = node.fetch_values(:path, :filename)
23
38
  create_asset_url(path, filename)
24
39
  end
25
40
  end
@@ -50,5 +65,13 @@ module Radio5
50
65
  def symbolize_mood(mood)
51
66
  MOODS_MAPPING.key(mood)
52
67
  end
68
+
69
+ def stringify_user_track_status(status)
70
+ USER_TRACK_STATUSES_MAPPING.fetch(status)
71
+ end
72
+
73
+ def symbolize_user_track_status(status)
74
+ USER_TRACK_STATUSES_MAPPING.key(status)
75
+ end
53
76
  end
54
77
  end
@@ -20,63 +20,125 @@ module Radio5
20
20
  object.is_a?(Symbol) && MOODS_MAPPING.key?(object)
21
21
  end
22
22
 
23
+ def user_track_status?(object)
24
+ object.is_a?(Symbol) && USER_TRACK_STATUSES_MAPPING.key?(object)
25
+ end
26
+
27
+ def positive_number?(object)
28
+ object.is_a?(Integer) && object.positive?
29
+ end
30
+
31
+ def validate!
32
+ yield
33
+
34
+ true
35
+ end
36
+
37
+ def validate_user_id!(object)
38
+ validate! do
39
+ unless mongo_id?(object)
40
+ raise ArgumentError, "invalid user ID: #{object.inspect}"
41
+ end
42
+ end
43
+ end
44
+
23
45
  def validate_track_id!(object)
24
- unless mongo_id?(object)
25
- raise ArgumentError, "invalid track ID: #{object.inspect}"
46
+ validate! do
47
+ unless mongo_id?(object)
48
+ raise ArgumentError, "invalid track ID: #{object.inspect}"
49
+ end
26
50
  end
27
51
  end
28
52
 
29
53
  def validate_island_id!(object)
30
- unless mongo_id?(object)
31
- raise ArgumentError, "invalid island ID: #{object.inspect}"
54
+ validate! do
55
+ unless mongo_id?(object)
56
+ raise ArgumentError, "invalid island ID: #{object.inspect}"
57
+ end
32
58
  end
33
59
  end
34
60
 
35
61
  def validate_country_iso_codes!(iso_codes)
36
- unless iso_codes.is_a?(Array)
37
- raise ArgumentError, "country ISO codes should be an array"
38
- end
39
-
40
- iso_codes.each do |iso_code|
41
- validate_country_iso_code!(iso_code)
62
+ validate! do
63
+ unless iso_codes.is_a?(Array)
64
+ raise ArgumentError, "country ISO codes should be an array: #{iso_codes.inspect}"
65
+ end
66
+
67
+ iso_codes.each do |iso_code|
68
+ validate_country_iso_code!(iso_code)
69
+ end
42
70
  end
43
71
  end
44
72
 
45
73
  def validate_country_iso_code!(object)
46
- unless country_iso_code?(object)
47
- raise ArgumentError, "invalid country ISO code: #{object.inspect}"
74
+ validate! do
75
+ unless country_iso_code?(object)
76
+ raise ArgumentError, "invalid country ISO code: #{object.inspect}"
77
+ end
48
78
  end
49
79
  end
50
80
 
51
81
  def validate_decades!(decades)
52
- unless decades.is_a?(Array)
53
- raise ArgumentError, "decades should be an array"
54
- end
55
-
56
- decades.each do |decade|
57
- validate_decade!(decade)
82
+ validate! do
83
+ unless decades.is_a?(Array)
84
+ raise ArgumentError, "decades should be an array: #{decades.inspect}"
85
+ end
86
+
87
+ decades.each do |decade|
88
+ validate_decade!(decade)
89
+ end
58
90
  end
59
91
  end
60
92
 
61
93
  def validate_decade!(object)
62
- unless decade?(object)
63
- raise ArgumentError, "invalid decade: #{object.inspect}"
94
+ validate! do
95
+ unless decade?(object)
96
+ raise ArgumentError, "invalid decade: #{object.inspect}"
97
+ end
64
98
  end
65
99
  end
66
100
 
67
101
  def validate_moods!(moods)
68
- unless moods.is_a?(Array)
69
- raise ArgumentError, "moods should be an array"
102
+ validate! do
103
+ unless moods.is_a?(Array)
104
+ raise ArgumentError, "moods should be an array: #{moods.inspect}"
105
+ end
106
+
107
+ moods.each do |mood|
108
+ validate_mood!(mood)
109
+ end
70
110
  end
111
+ end
71
112
 
72
- moods.each do |mood|
73
- validate_mood!(mood)
113
+ def validate_mood!(object)
114
+ validate! do
115
+ unless mood?(object)
116
+ raise ArgumentError, "invalid mood: #{object.inspect}"
117
+ end
74
118
  end
75
119
  end
76
120
 
77
- def validate_mood!(object)
78
- unless mood?(object)
79
- raise ArgumentError, "invalid mood: #{object.inspect}"
121
+ def validate_user_track_status!(object)
122
+ validate! do
123
+ unless user_track_status?(object)
124
+ raise ArgumentError, "invalid user track status: #{object.inspect}"
125
+ end
126
+ end
127
+ end
128
+
129
+ def validate_page_size!(object)
130
+ validate! do
131
+ unless positive_number?(object)
132
+ raise ArgumentError, "invalid page size: #{object.inspect}"
133
+ end
134
+ end
135
+ end
136
+
137
+ def validate_page_number!(object)
138
+ validate! do
139
+ unless positive_number?(object)
140
+ raise ArgumentError, "invalid page number: #{object.inspect}"
141
+ end
80
142
  end
81
143
  end
82
144
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Radio5
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/radio5.rb CHANGED
@@ -22,4 +22,18 @@ module Radio5
22
22
  }.freeze
23
23
 
24
24
  MOODS = MOODS_MAPPING.keys.freeze
25
+
26
+ USER_TRACK_STATUSES_MAPPING = {
27
+ posted: "posted",
28
+ rejected: "rejected",
29
+ on_air: "onair",
30
+ confirmation: "confirmation",
31
+ duplicate: "duplicate",
32
+ deleted: "deleted",
33
+ broken: "broken"
34
+ }.freeze
35
+
36
+ USER_TRACK_STATUSES = USER_TRACK_STATUSES_MAPPING.keys.freeze
37
+
38
+ MAX_PAGE_SIZE = 1_000_000_000
25
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radio5
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmytro Horoshko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-09 00:00:00.000000000 Z
11
+ date: 2024-01-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Adapter for Radiooooo private API.
14
14
  email: