jarvisbot_songfinder 1.0.0 → 1.1.2

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +9 -1
  3. data/Gemfile +3 -1
  4. data/Gemfile.lock +15 -13
  5. data/README.md +1 -1
  6. data/Rakefile +3 -1
  7. data/bin/console +5 -1
  8. data/changelog.md +22 -0
  9. data/fixtures/vcr_cassettes/query_customconfig.yml +107 -0
  10. data/fixtures/vcr_cassettes/query_customconfig_short_track.yml +107 -0
  11. data/fixtures/vcr_cassettes/query_text.yml +120 -16
  12. data/fixtures/vcr_cassettes/query_track_delegation.yml +122 -18
  13. data/fixtures/vcr_cassettes/query_youtube_url.yml +8 -8
  14. data/fixtures/vcr_cassettes/search_query_auxiliary_provider.yml +43 -43
  15. data/fixtures/vcr_cassettes/search_query_not_found.yml +9 -9
  16. data/fixtures/vcr_cassettes/search_query_preferred_and_auxiliary.yml +122 -18
  17. data/fixtures/vcr_cassettes/search_query_preferred_provider.yml +122 -18
  18. data/fixtures/vcr_cassettes/spotify_invalid_region_restricted.yml +57 -5
  19. data/fixtures/vcr_cassettes/spotify_invalid_search.yml +5 -5
  20. data/fixtures/vcr_cassettes/spotify_invalid_too_long.yml +57 -5
  21. data/fixtures/vcr_cassettes/spotify_invalid_url_relinked.yml +107 -0
  22. data/fixtures/vcr_cassettes/spotify_valid.yml +56 -4
  23. data/fixtures/vcr_cassettes/spotify_valid_clean_or_unknown.yml +56 -4
  24. data/fixtures/vcr_cassettes/spotify_valid_explicit.yml +57 -5
  25. data/fixtures/vcr_cassettes/spotify_valid_search.yml +61 -9
  26. data/fixtures/vcr_cassettes/url_query_known_provider.yml +14 -14
  27. data/fixtures/vcr_cassettes/youtube_invalid.yml +4 -4
  28. data/fixtures/vcr_cassettes/youtube_invalid_region_restricted.yml +8 -8
  29. data/fixtures/vcr_cassettes/youtube_invalid_search.yml +4 -4
  30. data/fixtures/vcr_cassettes/youtube_invalid_too_long.yml +130 -8
  31. data/fixtures/vcr_cassettes/youtube_invalid_wrong_category.yml +15 -15
  32. data/fixtures/vcr_cassettes/youtube_valid.yml +214 -214
  33. data/fixtures/vcr_cassettes/youtube_valid_search.yml +22 -22
  34. data/jarvisbot_songfinder.gemspec +6 -5
  35. data/lib/jarvisbot_songfinder.rb +3 -0
  36. data/lib/jarvisbot_songfinder/configuration.rb +7 -2
  37. data/lib/jarvisbot_songfinder/helpers/query.rb +23 -15
  38. data/lib/jarvisbot_songfinder/helpers/reply_message.rb +37 -26
  39. data/lib/jarvisbot_songfinder/helpers/search_query.rb +11 -5
  40. data/lib/jarvisbot_songfinder/helpers/url_query.rb +13 -8
  41. data/lib/jarvisbot_songfinder/providers/bandrequest.rb +5 -1
  42. data/lib/jarvisbot_songfinder/providers/provider.rb +25 -6
  43. data/lib/jarvisbot_songfinder/providers/spotify_api.rb +28 -35
  44. data/lib/jarvisbot_songfinder/providers/unknown_provider.rb +4 -0
  45. data/lib/jarvisbot_songfinder/providers/unknown_search_provider.rb +5 -1
  46. data/lib/jarvisbot_songfinder/providers/youtube_api.rb +37 -64
  47. data/lib/jarvisbot_songfinder/version.rb +3 -1
  48. metadata +28 -28
  49. data/fixtures/vcr_cassettes/spotify_vcr_test.yml +0 -55
  50. data/fixtures/vcr_cassettes/youtube_invalid_regionrestricted.yml +0 -147
  51. data/fixtures/vcr_cassettes/youtube_invalid_wrongcategory.yml +0 -254
@@ -1,22 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
4
+ # Responsible for handling URL based requests
5
+ # UrlQuery.new("https://www.youtube.com/watch?v=QSBco8kVuZM").track.length
6
+ # # => 172
2
7
  class UrlQuery
3
- def initialize(url)
8
+ def initialize(url, config: JarvisbotSongfinder.configuration)
9
+ @config = config
4
10
  @url = url
5
11
  @provider = select_provider
6
12
  end
7
-
13
+
8
14
  def track
9
15
  @provider
10
16
  end
11
-
17
+
12
18
  private
13
-
19
+
14
20
  def select_provider
15
- # TODO: redo with .find instead of .select
16
- provider = Provider.available_providers.find do |p|
21
+ provider = Provider.available_providers.find do |p|
17
22
  p::URL_REGEX.match @url
18
23
  end
19
- provider.nil? ? UnknownProvider.new : provider.new(@url)
24
+ provider.nil? ? UnknownProvider.new : provider.new(@url, config: @config)
20
25
  end
21
26
  end
22
- end
27
+ end
@@ -1,4 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
4
+ # Pseudo-provider for internal use, pretty much a remnant of the past
5
+ # i'm too lazy to extract into my rails app
2
6
  class Bandrequest < Provider
3
7
  def initialize(band)
4
8
  super()
@@ -33,4 +37,4 @@ module JarvisbotSongfinder
33
37
  true
34
38
  end
35
39
  end
36
- end
40
+ end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
4
+ # Abstract class for concrete providers to inherit from (Template Method Pattern)
2
5
  class Provider
3
6
  @available_providers ||= []
4
7
  class << self
@@ -6,7 +9,8 @@ module JarvisbotSongfinder
6
9
  end
7
10
 
8
11
  attr_reader :errors
9
- def initialize
12
+ def initialize(config: JarvisbotSongfinder.configuration)
13
+ @config = config
10
14
  @errors = []
11
15
  end
12
16
 
@@ -27,8 +31,9 @@ module JarvisbotSongfinder
27
31
  end
28
32
 
29
33
  def valid?
30
- return false if @errors.any?
31
- available_in_region? && not_too_long? && in_music_category?
34
+ return false if @errors.any?
35
+
36
+ available_in_region? && length_valid? && in_music_category?
32
37
  end
33
38
 
34
39
  def url
@@ -38,7 +43,7 @@ module JarvisbotSongfinder
38
43
  def explicit?
39
44
  raise NotImplementedError
40
45
  end
41
-
46
+
42
47
  private
43
48
 
44
49
  def add_error(error)
@@ -49,8 +54,22 @@ module JarvisbotSongfinder
49
54
  raise NotImplementedError
50
55
  end
51
56
 
57
+ def length_valid?
58
+ not_too_long? && not_too_short?
59
+ end
60
+
52
61
  def not_too_long?
53
- length < 600
62
+ unless length < @config.length_max
63
+ add_error(JarvisbotSongfinder::ReplyMessage::Request.too_long)
64
+ end
65
+ length < @config.length_max
66
+ end
67
+
68
+ def not_too_short?
69
+ unless length > @config.length_min
70
+ add_error(JarvisbotSongfinder::ReplyMessage::Request.too_short)
71
+ end
72
+ length > @config.length_min
54
73
  end
55
74
 
56
75
  def in_music_category?
@@ -61,4 +80,4 @@ module JarvisbotSongfinder
61
80
  raise NotImplementedError
62
81
  end
63
82
  end
64
- end
83
+ end
@@ -1,34 +1,38 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
2
4
  class SpotifyAPI < Provider
3
5
  Provider.available_providers << self
4
- ID_REGEX = /\Ahttps?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/
5
- URL_REGEX = /spotify\.com/
6
+ ID_REGEX = %r{\Ahttps?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})}.freeze
7
+ URL_REGEX = %r{spotify\.com/}.freeze
6
8
 
7
- def initialize(url)
9
+ def initialize(url, config: JarvisbotSongfinder.configuration)
8
10
  super()
11
+ @config = config
9
12
  @track_id = get_track_id(url)
10
13
  check_id_validity
11
14
  valid? unless @errors.any?
12
15
  end
13
16
 
14
- def self.from_search(query)
15
- results = RSpotify::Track.search(query)
17
+ def self.from_search(query, config: JarvisbotSongfinder.configuration)
18
+ @config = config
19
+ results = RSpotify::Track.search(query, market: @config.region)
16
20
  if results.any?
17
21
  link = "https://open.spotify.com/track/#{results.first.id}"
18
- return self.new(link)
22
+ return new(link)
19
23
  else
20
24
  return nil
21
25
  end
22
26
  end
23
-
27
+
24
28
  def length
25
29
  @track.duration_ms / 1000
26
30
  end
27
-
31
+
28
32
  def title
29
33
  @track.name
30
34
  end
31
-
35
+
32
36
  def artist
33
37
  @track.artists.first.name
34
38
  end
@@ -44,50 +48,39 @@ module JarvisbotSongfinder
44
48
  def explicit?
45
49
  @track.explicit
46
50
  end
47
-
48
- private
51
+
52
+ private
49
53
 
50
54
  # :nocov:
51
55
  def get_track_id(url)
52
56
  if !ID_REGEX.match(url)
53
57
  add_error ReplyMessage::Request.invalid_video_id
54
- return nil
58
+ nil
55
59
  else
56
60
  ID_REGEX.match(url)[1]
57
61
  end
58
62
  end
59
-
63
+
60
64
  def check_id_validity
61
- begin
62
- @track = RSpotify::Track.find(@track_id)
63
- rescue RestClient::BadRequest => e
64
- add_error ReplyMessage::Request.invalid_video_id
65
- end
65
+ @track = RSpotify::Track.find(@track_id, market: @config.region)
66
+ rescue RestClient::BadRequest
67
+ add_error ReplyMessage::Request.invalid_video_id
66
68
  end
67
69
  # :nocov:
68
-
69
- def in_music_category?
70
+
71
+ def in_music_category?
70
72
  true
71
73
  end
72
-
73
- def not_too_long?
74
- if length < 600
75
- return true
76
- else
77
- add_error ReplyMessage::Request.too_long
78
- return false
79
- end
80
- end
81
-
74
+
82
75
  def available_in_region?
83
76
  return true if @track.available_markets.empty?
84
-
85
- if @track.available_markets.include? JarvisbotSongfinder.configuration.region
77
+
78
+ if @track.available_markets.include? @config.region
86
79
  return true
87
80
  else
88
- add_error ReplyMessage::Request.region_restricted
81
+ add_error ReplyMessage::Request.region_restricted(@config.region)
89
82
  return false
90
83
  end
91
84
  end
92
- end
93
- end
85
+ end
86
+ end
@@ -1,4 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
4
+ # NullObject for handling cases where none of the providers matched request
5
+ # with their URL_REGEX
2
6
  class UnknownProvider
3
7
  attr_reader :errors
4
8
 
@@ -1,4 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
4
+ # NullObject for handling cases where searching any other provider did not
5
+ # found anything
2
6
  class UnknownSearchProvider
3
7
  attr_reader :errors
4
8
 
@@ -10,4 +14,4 @@ module JarvisbotSongfinder
10
14
  false
11
15
  end
12
16
  end
13
- end
17
+ end
@@ -1,32 +1,36 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
2
4
  class YoutubeAPI < Provider
3
5
  Provider.available_providers << self
4
- ID_REGEX = /\A((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu\.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?/
5
- URL_REGEX = /youtube\.com|youtu\.be/
6
-
7
- def initialize(url)
6
+ ID_REGEX = /\A((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu\.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?/.freeze
7
+ URL_REGEX = /youtube\.com|youtu\.be/.freeze
8
+
9
+ def initialize(url, config: JarvisbotSongfinder.configuration)
8
10
  super()
11
+ @config = config
9
12
  @track_id = get_track_id(url)
10
13
  @track = Yt::Video.new(id: @track_id) # unless @track_id.nil?
11
14
  check_id_validity
12
15
  valid? unless @errors.any?
13
16
  end
14
17
 
15
- def self.from_search(query)
18
+ def self.from_search(query, config: JarvisbotSongfinder.configuration)
19
+ @config = config
16
20
  videos = Yt::Collections::Videos.new
17
- params = {q: query, order: "relevance", video_category_id: 10}
21
+ params = { q: query, order: "relevance", video_category_id: 10 }
18
22
  if track_id = videos.where(params)&.first&.id
19
23
  link = "https://www.youtube.com/watch?v=#{track_id}"
20
- return self.new(link)
24
+ return new(link)
21
25
  else
22
26
  return nil
23
27
  end
24
28
  end
25
-
29
+
26
30
  def title
27
31
  @track.title
28
32
  end
29
-
33
+
30
34
  def length
31
35
  @track.duration
32
36
  end
@@ -47,91 +51,60 @@ module JarvisbotSongfinder
47
51
  # no way to know
48
52
  false
49
53
  end
50
-
54
+
51
55
  private
52
56
 
53
57
  # :nocov:
54
58
  def get_track_id(url)
55
59
  if !ID_REGEX.match(url)
56
60
  add_error ReplyMessage::Request.invalid_video_id
57
- return nil
61
+ nil
58
62
  else
59
63
  ID_REGEX.match(url)[5]
60
64
  end
61
65
  end
62
-
66
+
63
67
  def check_id_validity
64
- begin
65
- @track.empty?
66
- rescue Yt::Errors::NoItems => e
67
- add_error ReplyMessage::Request.invalid_video_id
68
- end
69
- end
70
-
71
- def not_too_long?
72
- if @track.duration < 600
73
- return true
74
- else
75
- add_error ReplyMessage::Request.too_long
76
- return false
77
- end
68
+ @track.empty?
69
+ rescue Yt::Errors::NoItems => e
70
+ add_error ReplyMessage::Request.invalid_video_id
78
71
  end
79
-
72
+
73
+
80
74
  def in_music_category?
81
75
  if @track.category_id == "10"
82
- return true
83
- else
76
+ true
77
+ else
84
78
  add_error ReplyMessage::Request.invalid_category
85
- return false
79
+ false
86
80
  end
87
81
  end
88
-
82
+
89
83
  def available_in_region?
90
- # TODO: refactor this into proper methods, this can be a guard clause
91
- if listed?
92
- if allowed_list_exists?
93
- if in_allowed_list?
94
- return true
95
- else
96
- add_error ReplyMessage::Request.region_restricted
97
- return false
98
- end
99
- else
100
- if in_blocked_list?
101
- add_error ReplyMessage::Request.region_restricted
102
- return false
103
- else
104
- return true
105
- end
106
- end
107
- else
108
- return true
109
- end
84
+ return true if !listed? || in_allowed_list? || !in_blocked_list?
85
+ add_error ReplyMessage::Request.region_restricted(@region)
86
+ return false
110
87
  end
111
-
88
+
112
89
  def listed?
113
- !!@track.content_detail.data&.dig('regionRestriction')
114
- end
115
-
116
- def allowed_list_exists?
117
- !!@track.content_detail.data&.dig('regionRestriction', 'allowed')
90
+ @track.content_detail.data&.dig('regionRestriction')
118
91
  end
119
-
92
+
120
93
  def in_allowed_list?
121
94
  if allowed_list = @track.content_detail.data&.dig('regionRestriction', 'allowed')
122
- allowed_list.include?(JarvisbotSongfinder.configuration.region)
95
+ allowed_list.include?(@config.region)
123
96
  else
124
- return false
97
+ false
125
98
  end
126
99
  end
127
-
100
+
128
101
  def in_blocked_list?
129
102
  if blocked_list = @track.content_detail.data&.dig('regionRestriction', 'blocked')
130
- blocked_list.include?(JarvisbotSongfinder.configuration.region)
103
+ blocked_list.include?(@config.region)
131
104
  else
132
- return false
105
+ false
133
106
  end
134
107
  end
135
108
  end
136
109
  # :nocov:
137
- end
110
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module JarvisbotSongfinder
2
- VERSION = "1.0.0"
4
+ VERSION = "1.1.2"
3
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jarvisbot_songfinder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-01 00:00:00.000000000 Z
11
+ date: 2019-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,20 +80,6 @@ dependencies:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0.16'
69
- - !ruby/object:Gem::Dependency
70
- name: pry
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: vcr
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -123,33 +123,33 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0.16'
125
125
  - !ruby/object:Gem::Dependency
126
- name: yt
126
+ name: rspotify
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 0.29.1
131
+ version: 2.4.0
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 0.29.1
138
+ version: 2.4.0
139
139
  - !ruby/object:Gem::Dependency
140
- name: rspotify
140
+ name: yt
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - "~>"
144
144
  - !ruby/object:Gem::Version
145
- version: 2.4.0
145
+ version: 0.29.1
146
146
  type: :runtime
147
147
  prerelease: false
148
148
  version_requirements: !ruby/object:Gem::Requirement
149
149
  requirements:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
- version: 2.4.0
152
+ version: 0.29.1
153
153
  description: Gem jarvissongbot uses to take user input and transform it into queryable
154
154
  music track found on enabled providers (youtube, spotify), validating it afterwards
155
155
  email:
@@ -168,6 +168,9 @@ files:
168
168
  - Rakefile
169
169
  - bin/console
170
170
  - bin/setup
171
+ - changelog.md
172
+ - fixtures/vcr_cassettes/query_customconfig.yml
173
+ - fixtures/vcr_cassettes/query_customconfig_short_track.yml
171
174
  - fixtures/vcr_cassettes/query_text.yml
172
175
  - fixtures/vcr_cassettes/query_track_delegation.yml
173
176
  - fixtures/vcr_cassettes/query_youtube_url.yml
@@ -178,19 +181,17 @@ files:
178
181
  - fixtures/vcr_cassettes/spotify_invalid_region_restricted.yml
179
182
  - fixtures/vcr_cassettes/spotify_invalid_search.yml
180
183
  - fixtures/vcr_cassettes/spotify_invalid_too_long.yml
184
+ - fixtures/vcr_cassettes/spotify_invalid_url_relinked.yml
181
185
  - fixtures/vcr_cassettes/spotify_valid.yml
182
186
  - fixtures/vcr_cassettes/spotify_valid_clean_or_unknown.yml
183
187
  - fixtures/vcr_cassettes/spotify_valid_explicit.yml
184
188
  - fixtures/vcr_cassettes/spotify_valid_search.yml
185
- - fixtures/vcr_cassettes/spotify_vcr_test.yml
186
189
  - fixtures/vcr_cassettes/url_query_known_provider.yml
187
190
  - fixtures/vcr_cassettes/youtube_invalid.yml
188
191
  - fixtures/vcr_cassettes/youtube_invalid_region_restricted.yml
189
- - fixtures/vcr_cassettes/youtube_invalid_regionrestricted.yml
190
192
  - fixtures/vcr_cassettes/youtube_invalid_search.yml
191
193
  - fixtures/vcr_cassettes/youtube_invalid_too_long.yml
192
194
  - fixtures/vcr_cassettes/youtube_invalid_wrong_category.yml
193
- - fixtures/vcr_cassettes/youtube_invalid_wrongcategory.yml
194
195
  - fixtures/vcr_cassettes/youtube_valid.yml
195
196
  - fixtures/vcr_cassettes/youtube_valid_search.yml
196
197
  - jarvisbot_songfinder.gemspec
@@ -213,7 +214,7 @@ licenses:
213
214
  metadata:
214
215
  homepage_uri: https://gitlab.com/DoubleJarvis/jarvisbot_songfinder
215
216
  source_code_uri: https://gitlab.com/DoubleJarvis/jarvisbot_songfinder
216
- changelog_uri: https://gitlab.com/DoubleJarvis/jarvisbot_songfinder/changelog.md
217
+ changelog_uri: https://gitlab.com/DoubleJarvis/jarvisbot_songfinder/blob/master/changelog.md
217
218
  post_install_message:
218
219
  rdoc_options: []
219
220
  require_paths:
@@ -229,8 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
229
230
  - !ruby/object:Gem::Version
230
231
  version: '0'
231
232
  requirements: []
232
- rubyforge_project:
233
- rubygems_version: 2.7.3
233
+ rubygems_version: 3.0.4
234
234
  signing_key:
235
235
  specification_version: 4
236
236
  summary: Take user input and return music track