shellify 1.1.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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