radio5 0.2.1 → 0.2.3

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: 34a7a071486c1b8ca66fd02b03fe53c05e8c4ac70b77a340e70f4e0539d2e3fd
4
- data.tar.gz: c73e668fda26b54cb15a8d118b27219891e24cccd2880e6658fab3d63e2c00d3
3
+ metadata.gz: 81e7f19d89c780e030dabd2e9cee7c7179cc2a7a1a7fd225d2c0aa855ff1ca6d
4
+ data.tar.gz: 741af73c4e6b1bbfc22a0d2c2615a0cbc20adebde5a17be64501b6c1af5b08bc
5
5
  SHA512:
6
- metadata.gz: a3f2a44eac15f31ffb700eadef35327c1990dcf90e5007fce6561b7474748cda2d99227385bf516800f63ca2e84be55e128ff2e959797f3739edcf732697c541
7
- data.tar.gz: 1bd13fbcb3b333acb179404624ae79ea1d159d290cc6e423dc04f77aa9d3e33a33226750acb1a7aade1f4ae2b95b87f4725eb411bc0677b7de28e9d0ae6a510b
6
+ metadata.gz: bbe4ce5781a3f11d02fdc0aa3e847f85f4f017d0fde919b4b4006a7f501fb8ee98154208b4f5b38e4e863d1d1a777c052c4b15fe6781e2f343cf8935d4416e22
7
+ data.tar.gz: b5fac8d486b32eddd6a3666f57455907161fa8f88887da9e2e11b0f51f56f2c192d42b9cb1edce2a956934888e4c6856d0826dcc05f55257215489dce97a56da
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ 0.2.3
2
+ ----------
3
+
4
+ - Fixed incorrect HTTP requests retries counting
5
+
6
+ 0.2.2
7
+ ----------
8
+
9
+ - Refactored constants and validations
10
+ - Refactored `Countries.countries_for_decade` method
11
+
1
12
  0.2.1
2
13
  ----------
3
14
 
data/README.md CHANGED
@@ -327,6 +327,10 @@ client.user_followings("5d3306de06fb03d8871fd138", size: 1, page: 5)
327
327
  # => [{...}]
328
328
  ```
329
329
 
330
+ ## Examples
331
+
332
+ You can find examples of usage [here](https://github.com/ocvit/radio5/blob/main/examples/).
333
+
330
334
  ## Auth?
331
335
 
332
336
  There is just a couple of features that require login (free or premium account):
data/lib/radio5/api.rb CHANGED
@@ -52,7 +52,6 @@ module Radio5
52
52
  end
53
53
  end
54
54
 
55
- # rubocop:disable Layout/HashAlignment
56
55
  def create_http
57
56
  Http.new(
58
57
  host: HOST,
@@ -65,6 +64,5 @@ module Radio5
65
64
  debug_output: client.debug_output
66
65
  )
67
66
  end
68
- # rubocop:enable Layout/HashAlignment
69
67
  end
70
68
  end
@@ -3,6 +3,8 @@
3
3
  module Radio5
4
4
  class Client
5
5
  module Countries
6
+ include Constants
7
+
6
8
  def countries
7
9
  _, json = api.get("/language/countries/en.json")
8
10
 
@@ -18,25 +20,11 @@ module Radio5
18
20
  def countries_for_decade(decade, group_by: :country)
19
21
  validate_decade!(decade)
20
22
 
21
- # optimization to avoid doing this inside `case` to save HTTP request
22
- unless [:mood, :country].include?(group_by)
23
- raise ArgumentError, "invalid `group_by` value: #{group_by.inspect}"
24
- end
25
-
26
- _, json = api.get("/country/mood", query_params: {decade: decade})
27
-
28
- grouped_by_mood = json.transform_keys do |mood_upcased|
29
- mood = mood_upcased.downcase
30
-
31
- validate_mood!(mood)
32
-
33
- mood
34
- end
35
-
36
23
  case group_by
37
24
  when :mood
38
- grouped_by_mood
25
+ Fetcher.grouped_by_mood(api, decade)
39
26
  when :country
27
+ grouped_by_mood = Fetcher.grouped_by_mood(api, decade)
40
28
  grouped_by_country = Hash.new { |hash, country| hash[country] = [] }
41
29
 
42
30
  MOODS.each_with_object(grouped_by_country) do |mood, grouped_by_country|
@@ -44,6 +32,16 @@ module Radio5
44
32
  grouped_by_country[country] << mood
45
33
  end
46
34
  end
35
+ else
36
+ raise ArgumentError, "invalid `group_by` value: #{group_by.inspect}"
37
+ end
38
+ end
39
+
40
+ module Fetcher
41
+ def self.grouped_by_mood(api, decade)
42
+ _, json = api.get("/country/mood", query_params: {decade: decade})
43
+
44
+ json.transform_keys!(&:downcase)
47
45
  end
48
46
  end
49
47
  end
@@ -14,7 +14,6 @@ module Radio5
14
14
  module Parser
15
15
  extend Utils
16
16
 
17
- # rubocop:disable Layout/HashAlignment
18
17
  def self.island_info(island)
19
18
  rank_value = island[:sort]
20
19
  rank = rank_value if rank_value.is_a?(Integer)
@@ -50,7 +49,6 @@ module Radio5
50
49
  updated_by: updated_by
51
50
  }
52
51
  end
53
- # rubocop:enable Layout/HashAlignment
54
52
  end
55
53
  end
56
54
  end
@@ -3,6 +3,8 @@
3
3
  module Radio5
4
4
  class Client
5
5
  module Tracks
6
+ include Constants
7
+
6
8
  def track(track_id)
7
9
  validate_track_id!(track_id)
8
10
 
@@ -15,10 +17,8 @@ module Radio5
15
17
 
16
18
  # TODO: technically, API accepts an array of countries, but without premium
17
19
  # account only the first one is used during filtering.
18
- # `country` should be used for now
19
- # `countries` might be added in a future after implementation of auth
20
-
21
- # rubocop:disable Layout/HashAlignment
20
+ # `country` should be used for now
21
+ # `countries` might be added in a future after implementation of auth
22
22
  def random_track(country: nil, decades: [], moods: MOODS)
23
23
  iso_codes = country ? [country] : []
24
24
 
@@ -39,9 +39,7 @@ module Radio5
39
39
  rescue Api::MatchingTrackNotFound
40
40
  nil
41
41
  end
42
- # rubocop:enable Layout/HashAlignment
43
42
 
44
- # rubocop:disable Layout/HashAlignment
45
43
  def island_track(island_id:, moods: MOODS)
46
44
  validate_island_id!(island_id)
47
45
  validate_moods!(moods)
@@ -58,12 +56,10 @@ module Radio5
58
56
  rescue Api::MatchingTrackNotFound
59
57
  nil
60
58
  end
61
- # rubocop:enable Layout/HashAlignment
62
59
 
63
60
  module Parser
64
61
  extend Utils
65
62
 
66
- # rubocop:disable Layout/HashAlignment
67
63
  def self.track_info(json)
68
64
  created_node = json[:created]
69
65
  created_at = created_node && parse_time_string(created_node.fetch(:date))
@@ -98,11 +94,10 @@ module Radio5
98
94
  created_by: created_by
99
95
  }
100
96
  end
101
- # rubocop:enable Layout/HashAlignment
102
97
 
103
98
  def self.track_audio(json, format)
104
99
  url = json.fetch(:links).fetch(format)
105
- url.gsub!(/#t=\d*,\d+/, "")
100
+ url.gsub!(/#t=\d*,\d+/, "") # remove play time limit
106
101
 
107
102
  expires_at_unix = Integer(url[/(?<=expires=)\d+/])
108
103
  expires_at = parse_unix_timestamp(expires_at_unix)
@@ -3,6 +3,8 @@
3
3
  module Radio5
4
4
  class Client
5
5
  module Users
6
+ include Constants
7
+
6
8
  def user(id)
7
9
  validate_user_id!(id)
8
10
 
@@ -51,7 +53,7 @@ module Radio5
51
53
  _, json = api.get("/follow/list/follower/#{id}", query_params: {size: size, page: page})
52
54
 
53
55
  json.map do |user|
54
- Parser.follow_user_info(user)
56
+ Parser.follower_user_info(user)
55
57
  end
56
58
  end
57
59
 
@@ -63,7 +65,7 @@ module Radio5
63
65
  _, json = api.get("/follow/list/following/#{id}", query_params: {size: size, page: page})
64
66
 
65
67
  json.map do |user|
66
- Parser.follow_user_info(user)
68
+ Parser.following_user_info(user)
67
69
  end
68
70
  end
69
71
 
@@ -71,7 +73,6 @@ module Radio5
71
73
  raise NotImplementedError, "depends on auth"
72
74
  end
73
75
 
74
- # rubocop:disable Layout/HashAlignment
75
76
  module Parser
76
77
  extend Utils
77
78
 
@@ -117,8 +118,7 @@ module Radio5
117
118
  }
118
119
  end
119
120
 
120
- # TODO: strange name tbh, change later
121
- def self.follow_user_info(user)
121
+ def self.follower_user_info(user)
122
122
  {
123
123
  id: user.fetch(:_id),
124
124
  name: normalize_string(user.fetch(:pseudonym)),
@@ -128,6 +128,9 @@ module Radio5
128
128
  created_at: parse_time_string(user.fetch(:created))
129
129
  }
130
130
  end
131
+ class << self
132
+ alias_method :following_user_info, :follower_user_info
133
+ end
131
134
 
132
135
  def self.normalize_year(time)
133
136
  if time.month == 12
@@ -137,7 +140,6 @@ module Radio5
137
140
  end
138
141
  end
139
142
  end
140
- # rubocop:enable Layout/HashAlignment
141
143
  end
142
144
  end
143
145
  end
data/lib/radio5/client.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  module Radio5
4
4
  class Client
5
5
  include Utils
6
- include Validator
6
+ include Validations
7
7
  include Users
8
8
  include Countries
9
9
  include Islands
@@ -32,11 +32,11 @@ module Radio5
32
32
  end
33
33
 
34
34
  def decades
35
- DECADES
35
+ Constants::DECADES
36
36
  end
37
37
 
38
38
  def moods
39
- MOODS
39
+ Constants::MOODS
40
40
  end
41
41
  end
42
42
  end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Radio5
4
+ module Constants
5
+ DECADES = (1900..2020).step(10).to_a.freeze
6
+
7
+ MOODS_MAPPING = {
8
+ fast: "FAST",
9
+ slow: "SLOW",
10
+ weird: "WEIRD"
11
+ }.freeze
12
+
13
+ MOODS = MOODS_MAPPING.keys.freeze
14
+
15
+ USER_TRACK_STATUSES_MAPPING = {
16
+ posted: "posted",
17
+ rejected: "rejected",
18
+ on_air: "onair",
19
+ confirmation: "confirmation",
20
+ duplicate: "duplicate",
21
+ deleted: "deleted",
22
+ broken: "broken"
23
+ }.freeze
24
+
25
+ USER_TRACK_STATUSES = USER_TRACK_STATUSES_MAPPING.keys.freeze
26
+
27
+ IMAGE_SIZES = {
28
+ track: %i[thumb small medium large],
29
+ user: %i[icon thumb small medium large]
30
+ }.freeze
31
+
32
+ ASSET_HOST = "https://asset.radiooooo.com"
33
+
34
+ MAX_PAGE_SIZE = 1_000_000_000
35
+ end
36
+ end
data/lib/radio5/http.rb CHANGED
@@ -30,7 +30,6 @@ module Radio5
30
30
 
31
31
  attr_reader :host, :port, :open_timeout, :read_timeout, :write_timeout, :proxy_url, :max_retries, :debug_output, :http_client
32
32
 
33
- # rubocop:disable Layout/ExtraSpacing
34
33
  def initialize(
35
34
  host:,
36
35
  port:,
@@ -61,7 +60,6 @@ module Radio5
61
60
  c.set_debug_output(@debug_output)
62
61
  end
63
62
  end
64
- # rubocop:enable Layout/ExtraSpacing
65
63
 
66
64
  def proxy_uri
67
65
  @proxy_uri ||= parse_proxy_uri
@@ -116,12 +114,10 @@ module Radio5
116
114
 
117
115
  def make_request(request, retries: 0)
118
116
  http_client.request(request)
119
- rescue *RETRIABLE_ERRORS => error
120
- if retries < max_retries
121
- make_request(request, retries: retries + 1)
122
- else
123
- raise error
124
- end
117
+ rescue *RETRIABLE_ERRORS
118
+ raise if retries > max_retries
119
+
120
+ make_request(request, retries: retries + 1)
125
121
  end
126
122
  end
127
123
  end
data/lib/radio5/utils.rb CHANGED
@@ -5,14 +5,9 @@ require "time"
5
5
 
6
6
  module Radio5
7
7
  module Utils
8
- module_function
9
-
10
- ASSET_HOST = "https://asset.radiooooo.com"
8
+ include Constants
11
9
 
12
- IMAGE_SIZES = {
13
- track: %i[thumb small medium large],
14
- user: %i[icon thumb small medium large]
15
- }.freeze
10
+ module_function
16
11
 
17
12
  def parse_json(json_raw)
18
13
  JSON.parse(json_raw, symbolize_names: true)
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Radio5
4
+ module Validations
5
+ module Matchers
6
+ module_function
7
+
8
+ def mongo_id?(object)
9
+ object.is_a?(String) && object.match?(Regexps::MONGO_ID)
10
+ end
11
+
12
+ def country_iso_code?(object)
13
+ object.is_a?(String) && object.match?(Regexps::COUNTRY_ISO_CODE)
14
+ end
15
+
16
+ def decade?(object)
17
+ object.is_a?(Integer) && Constants::DECADES.include?(object)
18
+ end
19
+
20
+ def mood?(object)
21
+ object.is_a?(Symbol) && Constants::MOODS.include?(object)
22
+ end
23
+
24
+ def user_track_status?(object)
25
+ object.is_a?(Symbol) && Constants::USER_TRACK_STATUSES.include?(object)
26
+ end
27
+
28
+ def positive_number?(object)
29
+ object.is_a?(Integer) && object.positive?
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Radio5
4
+ module Validations
5
+ module Regexps
6
+ include Constants
7
+
8
+ MONGO_ID = /\A[a-f\d]{24}\z/.freeze
9
+ UUID_GENERIC = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/.freeze
10
+ UUID = /\A#{UUID_GENERIC}\z/.freeze
11
+
12
+ COUNTRY_ISO_CODE_GENERIC = /([A-Z]{3}|KN1)/.freeze
13
+ COUNTRY_ISO_CODE = /\A#{COUNTRY_ISO_CODE_GENERIC}\z/.freeze
14
+
15
+ # NOTE: everything below is used within RSpec custom matchers, they might be
16
+ # migrated to regular validations matchers in future, in case there will be
17
+ # a need to validate fields in response payloads on the fly
18
+
19
+ ASSET_URL = lambda do |sub_path, exts, size = nil|
20
+ asset_host = Regexp.escape(ASSET_HOST)
21
+ sub_path = sub_path.is_a?(Regexp) ? sub_path : Regexp.escape(sub_path)
22
+ exts = /(#{exts.join("|")})/
23
+ size = /\/#{size}/ if size
24
+
25
+ /#{asset_host}#{sub_path}#{size}\/#{UUID_GENERIC}(_\d+)?\.#{exts}/.freeze
26
+ end.freeze
27
+
28
+ ISLAND_ICON_URL = ASSET_URL.call("/island/icon", %w[png svg])
29
+ ISLAND_SPLASH_URL = ASSET_URL.call("/island/splash", %w[png svg])
30
+ ISLAND_MARKER_URL = ASSET_URL.call("/island/marker", %w[png svg])
31
+
32
+ TRACK_COVER_URLS = IMAGE_SIZES[:track].each_with_object({}) do |image_size, hash|
33
+ sub_path = %r(/cover/#{COUNTRY_ISO_CODE_GENERIC}/\d{4})
34
+ exts = %w[jpg jpeg png gif]
35
+ regexp = ASSET_URL.call(sub_path, exts, image_size)
36
+
37
+ hash[image_size] = regexp
38
+ end.freeze
39
+
40
+ USER_IMAGE_URLS = IMAGE_SIZES[:user].each_with_object({}) do |image_size, hash|
41
+ sub_path = %r{/user/\d+}
42
+ exts = %w[jpg jpeg png gif]
43
+ regexp = ASSET_URL.call(sub_path, exts, image_size)
44
+
45
+ hash[image_size] = regexp
46
+ end.freeze
47
+
48
+ AUDIO_URL = lambda do |exts|
49
+ exts = /(#{exts.join("|")})/
50
+
51
+ /.+\/#{UUID_GENERIC}\.#{exts}\?token=[^&]{22}&expires=\d{10}$/.freeze
52
+ end.freeze
53
+
54
+ MPEG_URL = AUDIO_URL.call(["mp3", "m4a"]).freeze
55
+ OGG_URL = AUDIO_URL.call(["ogg"]).freeze
56
+ end
57
+ end
58
+ end
@@ -1,32 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Radio5
4
- module Validator
4
+ module Validations
5
5
  module_function
6
6
 
7
- def mongo_id?(object)
8
- object.is_a?(String) && object.match?(Regexps::MONGO_ID)
9
- end
10
-
11
- def country_iso_code?(object)
12
- object.is_a?(String) && object.match?(Regexps::COUNTRY_ISO_CODE)
13
- end
14
-
15
- def decade?(object)
16
- object.is_a?(Integer) && DECADES.include?(object)
17
- end
18
-
19
- def mood?(object)
20
- object.is_a?(Symbol) && MOODS_MAPPING.key?(object)
21
- end
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
7
+ include Matchers
8
+ extend Matchers
30
9
 
31
10
  def validate!
32
11
  yield
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Radio5
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.3"
5
5
  end
data/lib/radio5.rb CHANGED
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "radio5/version"
4
+ require_relative "radio5/constants"
4
5
  require_relative "radio5/utils"
5
6
  require_relative "radio5/http"
6
7
  require_relative "radio5/api"
7
- require_relative "radio5/regexps"
8
- require_relative "radio5/validator"
8
+ require_relative "radio5/validations/regexps"
9
+ require_relative "radio5/validations/matchers"
10
+ require_relative "radio5/validations"
9
11
  require_relative "radio5/client/users"
10
12
  require_relative "radio5/client/countries"
11
13
  require_relative "radio5/client/islands"
@@ -13,27 +15,4 @@ require_relative "radio5/client/tracks"
13
15
  require_relative "radio5/client"
14
16
 
15
17
  module Radio5
16
- DECADES = (1900..2020).step(10).to_a.freeze
17
-
18
- MOODS_MAPPING = {
19
- fast: "FAST",
20
- slow: "SLOW",
21
- weird: "WEIRD"
22
- }.freeze
23
-
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
39
18
  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.2.1
4
+ version: 0.2.3
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-02-02 00:00:00.000000000 Z
11
+ date: 2024-02-10 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Adapter for Radiooooo private API.
14
14
  email:
@@ -27,10 +27,12 @@ files:
27
27
  - lib/radio5/client/islands.rb
28
28
  - lib/radio5/client/tracks.rb
29
29
  - lib/radio5/client/users.rb
30
+ - lib/radio5/constants.rb
30
31
  - lib/radio5/http.rb
31
- - lib/radio5/regexps.rb
32
32
  - lib/radio5/utils.rb
33
- - lib/radio5/validator.rb
33
+ - lib/radio5/validations.rb
34
+ - lib/radio5/validations/matchers.rb
35
+ - lib/radio5/validations/regexps.rb
34
36
  - lib/radio5/version.rb
35
37
  homepage: https://github.com/ocvit/radio5
36
38
  licenses:
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Radio5
4
- module Regexps
5
- include Utils
6
-
7
- # rubocop:disable Layout/ExtraSpacing
8
-
9
- MONGO_ID = /^[a-f\d]{24}$/.freeze
10
- UUID_GENERIC = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/.freeze
11
- UUID = /^#{UUID_GENERIC}$/.freeze
12
-
13
- COUNTRY_ISO_CODE_GENERIC = /([A-Z]{3}|KN1)/.freeze
14
- COUNTRY_ISO_CODE = /^#{COUNTRY_ISO_CODE_GENERIC}$/.freeze
15
-
16
- ASSET_URL = lambda do |sub_path, exts, size = nil|
17
- asset_host = Regexp.escape(Utils::ASSET_HOST)
18
- sub_path = sub_path.is_a?(Regexp) ? sub_path : Regexp.escape(sub_path)
19
- exts = /(#{exts.join("|")})/
20
- size = /\/#{size}/ if size
21
-
22
- /#{asset_host}#{sub_path}#{size}\/#{UUID_GENERIC}(_\d+)?\.#{exts}/
23
- end.freeze
24
-
25
- ISLAND_ICON_URL = ASSET_URL.call("/island/icon", ["png", "svg"]).freeze
26
- ISLAND_SPLASH_URL = ASSET_URL.call("/island/splash", ["png", "svg"]).freeze
27
- ISLAND_MARKER_URL = ASSET_URL.call("/island/marker", ["png", "svg"]).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
38
-
39
- AUDIO_URL = lambda do |exts|
40
- exts = /(#{exts.join("|")})/
41
-
42
- /.+\/#{UUID_GENERIC}\.#{exts}\?token=[^&]{22}&expires=\d{10}$/
43
- end.freeze
44
-
45
- MPEG_URL = AUDIO_URL.call(["mp3", "m4a"]).freeze
46
- OGG_URL = AUDIO_URL.call(["ogg"]).freeze
47
-
48
- # rubocop:enable Layout/ExtraSpacing
49
- end
50
- end