shellify 1.1.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b457f8f07a6f855b4cbb3a2839df79780b49760ad264247b6225cb5fe7d0be3
4
- data.tar.gz: 5e96c98b637eccc3f1fc4e24808baf60db90deca6eb061810a5db7bddc2d14ce
3
+ metadata.gz: f62fa09eb7f90e2bc486320a18dc252ffb8a751a6d67e72ce3fb5a149e1965ef
4
+ data.tar.gz: b9cb6abde7095e6b5f2e358e6962897dbb797b3e90823bfb8c3422b1bacf7766
5
5
  SHA512:
6
- metadata.gz: bd69fbf66ede7b711ca6d5c24d568272f73ee2cc4303e8a4900dac5f525118e96e9c2e9f1de69e8dad4cf9268d4da103cfc07d9454e5e6c87fab7622135d7ae6
7
- data.tar.gz: f162600a265e3e6167caf78480eb9d640a1089a93c6de8deb9739b9e9ea13b639cbc617157eec14cb468cf027a5f40a083957dd651a314346f839aa53c9df162
6
+ metadata.gz: cd101fc048837d34a1db93c0c36c8ebb3270ea2779628f154309d58837f4d0666ba673b53c954d4b6ca06ee7efdf30fa214f8e561c70a391d1dfc35dba0926fc
7
+ data.tar.gz: c2fa18b6cebc2eff9ca4406576ba24efb98d77fbfd015ee9d1312b84ac98a4dd7ce0ce0d18f6dd7cf458f8ee32d92514a23734b3ec618d84bc2de83a9533ab9d
data/lib/shellify/cli.rb CHANGED
@@ -22,8 +22,8 @@ module Shellify
22
22
  command :configure do |c|
23
23
  c.description = 'Set the Spotify client_id and client_secret'
24
24
  c.action do
25
- client_id = ask("Spotify Client ID: ")
26
- client_secret = ask("Spotify Client Secret: ") { |q| q.echo = '*' }
25
+ client_id = ask('Spotify Client ID: ')
26
+ client_secret = ask('Spotify Client Secret: ') { |q| q.echo = '*' }
27
27
  @config.client_id = client_id
28
28
  @config.client_secret = client_secret
29
29
  @config.save!
@@ -58,15 +58,15 @@ module Shellify
58
58
  command :playing do |c|
59
59
  c.description = 'List information about the current song'
60
60
  c.action do
61
- return puts " Nothing playing" unless @user.player.playing?
61
+ return puts ' Nothing playing' unless @user.player.playing?
62
62
 
63
- print_current_song
63
+ print_currently_playing
64
64
  end
65
65
  end
66
66
 
67
67
  command :volume do |c|
68
68
  c.description = 'Set the volume of the current playback device'
69
- c.action do |args, options|
69
+ c.action do |args, _options|
70
70
  @user.player.volume(args[0])
71
71
  end
72
72
  end
@@ -91,52 +91,73 @@ module Shellify
91
91
  c.description = 'List your playlists'
92
92
  c.action do
93
93
  @user.playlists.each do |playlist|
94
- puts " #{playlist.name} - #{playlist.owner.display_name}#{" - Collaborative" if playlist.collaborative}"
94
+ puts " #{playlist.name} - #{playlist.owner.display_name}#{' - Collaborative' if playlist.collaborative}"
95
95
  end
96
96
  end
97
97
  end
98
98
 
99
99
  command :add do |c|
100
- c.description = 'Add the current song to the provided playlist'
100
+ c.description = 'Add the current song or album to the provided playlist'
101
+ c.option '-a', '--album'
101
102
  c.action do |args, options|
102
- return puts " Nothing playing" unless @user.player.playing?
103
+ return puts ' Nothing playing' unless @user.player.playing?
103
104
 
104
105
  exit_with_message(local_track_message, 0) if track_is_local?(playing)
105
106
  playlist = @user.playlists.find { |p| p.name == args[0] }
106
- return puts " Playlist not found" unless playlist
107
- exit_with_message(add_to_collaborative_playlist_message, 0) if playlist.owner != @user
107
+ return puts ' Playlist not found' unless playlist
108
+
109
+ exit_with_message(add_to_collaborative_playlist_message, 0) if playlist.owner.id != @user.id
110
+
111
+ item = options.album ? playing.album.tracks : [playing]
112
+ playlist.add_tracks!(item)
113
+ end
114
+ end
108
115
 
109
- playlist.add_tracks!([playing])
116
+ command :queue do |c|
117
+ c.description = 'List the next songs in the queue'
118
+ c.action do
119
+ items = @user.player.next_up
120
+ exit_with_message(' Nothing in the queue', 0) if items.empty?
121
+ items.each.with_index(1) do |item, i|
122
+ case item.type
123
+ when 'episode'
124
+ puts " #{i.to_s.rjust(items.size.to_s.size, ' ')} - #{item.name} - #{item.show.name}"
125
+ when 'track'
126
+ puts " #{i.to_s.rjust(items.size.to_s.size, ' ')} - #{item.name} - "\
127
+ "#{item.artists.map(&:name).join(', ')}"
128
+ end
129
+ end
110
130
  end
111
131
  end
112
132
 
113
133
  command :remove do |c|
114
- c.description = 'Remove the currently playing song from the provided playlist'
134
+ c.description = 'Remove the currently playing song or album from the provided playlist'
135
+ c.option '-a', '--album'
115
136
  c.action do |args, options|
116
- return puts " Nothing playing" unless @user.player.playing?
137
+ return puts ' Nothing playing' unless @user.player.playing?
117
138
 
118
139
  exit_with_message(local_track_message, 0) if track_is_local?(playing)
119
140
  playlist = @user.playlists.find { |p| p.name == args[0] }
120
- return puts " Playlist not found" unless playlist
121
- exit_with_message(add_to_collaborative_playlist_message, 0) if playlist.owner != @user
141
+ return puts ' Playlist not found' unless playlist
142
+
143
+ exit_with_message(add_to_collaborative_playlist_message, 0) if playlist.owner.id != @user.id
122
144
 
123
- playlist.remove_tracks!([playing])
145
+ item = options.album ? playing.album.tracks : [playing]
146
+ playlist.remove_tracks!(item)
124
147
  end
125
148
  end
126
149
 
127
150
  command :play do |c|
128
151
  c.description = 'Play or Pause on the currently playing device'
129
152
  c.action do
130
- begin
131
- if @user.player.playing?
132
- @user.player.pause
133
- else
134
- @user.player.play
135
- print_current_song
136
- end
137
- rescue RestClient::NotFound
138
- @user.player.play(@user.devices.first.id)
153
+ if @user.player.playing?
154
+ @user.player.pause
155
+ else
156
+ @user.player.play
157
+ print_currently_playing
139
158
  end
159
+ rescue RestClient::NotFound
160
+ @user.player.play(@user.devices.first.id)
140
161
  end
141
162
  end
142
163
 
@@ -144,7 +165,7 @@ module Shellify
144
165
  c.description = 'Skip to the next song in the queue'
145
166
  c.action do
146
167
  @user.player.next
147
- print_current_song
168
+ print_currently_playing
148
169
  end
149
170
  end
150
171
 
@@ -152,7 +173,7 @@ module Shellify
152
173
  c.description = 'Skip the the previous song in the queue'
153
174
  c.action do
154
175
  @user.player.previous
155
- print_current_song
176
+ print_currently_playing
156
177
  end
157
178
  end
158
179
 
@@ -160,15 +181,15 @@ module Shellify
160
181
  c.description = 'Restart the currently playing song'
161
182
  c.action do
162
183
  @user.player.seek 0
163
- print_current_song
184
+ print_currently_playing
164
185
  end
165
186
  end
166
187
 
167
188
  command :seek do |c|
168
189
  c.description = 'Seek to the specified time in the current song'
169
- c.action do |args, option|
190
+ c.action do |args, _option|
170
191
  @user.player.seek(time_to_ms(args[0]))
171
- print_current_song
192
+ print_currently_playing
172
193
  end
173
194
  end
174
195
 
@@ -191,20 +212,28 @@ module Shellify
191
212
  end
192
213
 
193
214
  def add_to_collaborative_playlist_message
194
- " Shellify can't perform this action for collaborative playlists you don't own"
215
+ " Shellify can't perform this action for collaborative playlists you don't own"
195
216
  end
196
217
 
197
218
  def track_is_local?(track)
198
219
  track.uri.split(':')[1] == 'local'
199
220
  end
200
221
 
201
- def print_current_song
202
- puts ' Now Playing:'
203
- puts " #{playing.name} - #{playing.artists.first.name} - "\
204
- "#{duration_to_s(@user.player.progress)}/#{duration_to_s(playing.duration_ms)}"\
205
- "#{" - ♥" if !track_is_local?(playing) && @user.saved_tracks?([playing]).first}"\
206
- "#{" - local" if track_is_local?(playing)}"
222
+ def current_song
223
+ puts "Now Playing - #{duration_to_s(@user.player.progress)}/#{duration_to_s(playing.duration_ms)}"\
224
+ "#{' - ♥' if !track_is_local?(playing) && @user.saved_tracks?([playing]).first}"\
225
+ "#{' - local' if track_is_local?(playing)}\n"\
226
+ " #{playing.name}\n"\
227
+ " #{playing.album.name}\n"\
228
+ " #{playing.artists.map(&:name).join(', ')}"
229
+ end
207
230
 
231
+ def print_currently_playing
232
+ if playing.nil?
233
+ puts "Now Playing - Podcast - #{duration_to_s(@user.player.progress)}"
234
+ else
235
+ current_song
236
+ end
208
237
  end
209
238
 
210
239
  def exit_with_message(message, code = 1)
@@ -4,8 +4,8 @@ module Shellify
4
4
  class Config
5
5
  attr_accessor :client_id, :client_secret, :config_dir
6
6
 
7
- CONFIG_DIR = ENV['HOME'] + '/.config/shellify'
8
- CONFIG_FILE = CONFIG_DIR + '/config.json'
7
+ CONFIG_DIR = "#{ENV['HOME']}/.config/shellify"
8
+ CONFIG_FILE = "#{CONFIG_DIR}/config.json"
9
9
  SPOTIFY_AUTHORIZATION_SCOPES = %w[
10
10
  user-read-playback-state
11
11
  user-modify-playback-state
@@ -31,16 +31,16 @@ module Shellify
31
31
 
32
32
  def save!
33
33
  File.open(CONFIG_FILE, 'w') do |file|
34
- file.write(JSON.pretty_generate({client_id: @client_id, client_secret: @client_secret}))
34
+ file.write(JSON.pretty_generate({ client_id: @client_id, client_secret: @client_secret }))
35
35
  end
36
36
  end
37
37
 
38
38
  private
39
39
 
40
40
  def load_config
41
- return unless File.exists?(CONFIG_FILE)
41
+ return unless File.exist?(CONFIG_FILE)
42
42
 
43
- JSON.parse(File.read(CONFIG_FILE)).each_pair { |k,v| instance_variable_set("@#{k}", v) }
43
+ JSON.parse(File.read(CONFIG_FILE)).each_pair { |k, v| instance_variable_set("@#{k}", v) }
44
44
  end
45
45
  end
46
46
  end
@@ -25,7 +25,7 @@ module Shellify
25
25
  begin
26
26
  tokens = fetch_tokens(params['code'])
27
27
  rescue RestClient::Exception => e
28
- body = "Spotify didn't like that\n" + e.response
28
+ body = "Spotify didn't like that\n#{e.response}"
29
29
  end
30
30
 
31
31
  @client.puts headers(body.length)
@@ -41,7 +41,7 @@ module Shellify
41
41
  def headers(content_length)
42
42
  [
43
43
  'HTTP/1.1 200 Ok',
44
- "date: #{Time.now.utc.strftime("%a, %d %b %Y %H:%M:%S GMT")}",
44
+ "date: #{Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')}",
45
45
  'server: ruby',
46
46
  "Content-Length: #{content_length}",
47
47
  '',
@@ -51,7 +51,7 @@ module Shellify
51
51
 
52
52
  def fetch_tokens(code)
53
53
  headers = {
54
- 'Authorization': "Basic " + Base64.strict_encode64("#{@config.client_id}:#{@config.client_secret}"),
54
+ 'Authorization': 'Basic ' + Base64.strict_encode64("#{@config.client_id}:#{@config.client_secret}"),
55
55
  }
56
56
 
57
57
  params = {
@@ -62,7 +62,7 @@ module Shellify
62
62
  code: code,
63
63
  }
64
64
 
65
- JSON.parse(RestClient.post("https://accounts.spotify.com/api/token", params, headers))
65
+ JSON.parse(RestClient.post('https://accounts.spotify.com/api/token', params, headers))
66
66
  end
67
67
  end
68
68
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RSpotify
4
+ class Player
5
+ def next_up
6
+ url = 'me/player/queue'
7
+ response = User.oauth_get(@user.id, url)
8
+ return response if RSpotify.raw_response
9
+
10
+ response['queue'].map do |item|
11
+ type_class = RSpotify.const_get(item['type'].capitalize)
12
+ type_class.new item
13
+ end
14
+ end
15
+
16
+ def currently_playing
17
+ url = 'me/player/currently-playing'
18
+ response = User.oauth_get(@user.id, url)
19
+ return response if RSpotify.raw_response
20
+
21
+ type_class = RSpotify.const_get(response['currently_playing_type'].capitalize)
22
+ type_class.new response['item'] unless response['item'].nil?
23
+ end
24
+ end
25
+ end
data/lib/shellify/user.rb CHANGED
@@ -28,25 +28,25 @@ module Shellify
28
28
 
29
29
  def save!
30
30
  File.open(@user_file_path, 'w') do |file|
31
- file.write(JSON.pretty_generate({id: @id, token: @token, refresh_token: @refresh_token}))
31
+ file.write(JSON.pretty_generate({ id: @id, token: @token, refresh_token: @refresh_token }))
32
32
  end
33
33
  end
34
34
 
35
35
  private
36
36
 
37
37
  def load_persisted_user
38
- JSON.parse(File.read(@user_file_path)).each_pair { |k,v| instance_variable_set("@#{k}", v) }
38
+ JSON.parse(File.read(@user_file_path)).each_pair { |k, v| instance_variable_set("@#{k}", v) }
39
39
  end
40
40
 
41
41
  def access_refresh_callback
42
- Proc.new do |new_access_token, _token_lifetime|
42
+ proc do |new_access_token, _token_lifetime|
43
43
  @token = new_access_token
44
44
  save!
45
45
  end
46
46
  end
47
47
 
48
48
  def create_user_file
49
- return if File.exists?(@user_file_path)
49
+ return if File.exist?(@user_file_path)
50
50
 
51
51
  FileUtils.mkdir_p(@config_dir)
52
52
  FileUtils.touch(@user_file_path)
@@ -56,7 +56,7 @@ module Shellify
56
56
  return unless File.zero?(@user_file_path)
57
57
 
58
58
  File.open(@user_file_path, 'w') do |file|
59
- file.write(JSON.pretty_generate({id: '', token: '', refresh_token: '',}))
59
+ file.write(JSON.pretty_generate({ id: '', token: '', refresh_token: '' }))
60
60
  end
61
61
  end
62
62
  end
@@ -14,7 +14,7 @@ module Shellify
14
14
  end
15
15
 
16
16
  def time_to_ms(time)
17
- time.split(':').map { |a| a.to_i }.inject(0) { |a, b| a * 60 + b} * 1000
17
+ time.split(':').map(&:to_i).inject(0) { |a, b| a * 60 + b } * 1000
18
18
  end
19
19
 
20
20
  def generate_oauth_url
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Shellify
4
- VERSION = '1.1.2'
4
+ VERSION = '1.3.0'
5
5
  end
data/lib/shellify.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'fileutils'
4
4
  require 'json'
5
5
  require 'rspotify'
6
+ require 'shellify/rspotify_patch'
6
7
  require 'shellify/version'
7
8
 
8
9
  module Shellify
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shellify
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Derek Povah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-29 00:00:00.000000000 Z
11
+ date: 2023-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
@@ -81,6 +81,7 @@ files:
81
81
  - lib/shellify/cli.rb
82
82
  - lib/shellify/config.rb
83
83
  - lib/shellify/oauth_callback_handler.rb
84
+ - lib/shellify/rspotify_patch.rb
84
85
  - lib/shellify/user.rb
85
86
  - lib/shellify/utils.rb
86
87
  - lib/shellify/version.rb
@@ -99,14 +100,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
99
100
  requirements:
100
101
  - - ">="
101
102
  - !ruby/object:Gem::Version
102
- version: 2.4.0
103
+ version: 2.7.0
103
104
  required_rubygems_version: !ruby/object:Gem::Requirement
104
105
  requirements:
105
106
  - - ">="
106
107
  - !ruby/object:Gem::Version
107
108
  version: '0'
108
109
  requirements: []
109
- rubygems_version: 3.3.3
110
+ rubygems_version: 3.4.17
110
111
  signing_key:
111
112
  specification_version: 4
112
113
  summary: Use Spotify from the command line