subcl 1.0.1 → 1.1.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 +7 -0
- data/bin/subcl +4 -124
- data/bin/subcl-api +22 -0
- data/lib/subcl.rb +14 -0
- data/lib/subcl/configs.rb +61 -0
- data/lib/subcl/notify.rb +66 -0
- data/lib/subcl/picker.rb +63 -0
- data/lib/subcl/player.rb +54 -0
- data/lib/subcl/runner.rb +154 -0
- data/lib/subcl/song.rb +14 -0
- data/lib/subcl/subcl.rb +146 -0
- data/lib/subcl/subcl_error.rb +1 -0
- data/lib/subcl/subsonic_api.rb +239 -0
- metadata +57 -22
- data/lib/Configs.rb +0 -67
- data/lib/Mpc.rb +0 -68
- data/lib/Notify.rb +0 -66
- data/lib/Picker.rb +0 -63
- data/lib/Song.rb +0 -14
- data/lib/Subcl.rb +0 -159
- data/lib/Subsonic.rb +0 -297
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cce8d7f636cf3a5898c7ce68aa2287a8dcc6673d
|
4
|
+
data.tar.gz: 1df467a85ba4ab604668844a359704200ee4c88c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: adae72dbd6ab95c0501234706cdeceeb41fece5aacabf5847dd020c060e4d9a3f8cc36010ad34f70bd6c98bbe818b813f509711f98c2d7fd5bd7258ae2064513
|
7
|
+
data.tar.gz: 8a5219d0d537d6d8450de8518d334084ddcea5be42709c8db0e4871db4bd468fb2bf22c0af3c430b1231176cbad23b46e18b75e674e2c0ec1a150278eb94da8a
|
data/bin/subcl
CHANGED
@@ -1,132 +1,12 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
require 'optparse'
|
3
|
+
require 'subcl'
|
5
4
|
|
6
5
|
#don't throw a huge stacktrace
|
7
6
|
trap("INT") {
|
8
|
-
|
9
|
-
|
7
|
+
puts "\n"
|
8
|
+
exit
|
10
9
|
}
|
11
10
|
|
12
|
-
|
11
|
+
Runner.new.run ARGV
|
13
12
|
|
14
|
-
if File.exist?('debug')
|
15
|
-
puts "DEBUGGING"
|
16
|
-
options[:debug] = true
|
17
|
-
end
|
18
|
-
|
19
|
-
#no idea how to get this variable from outside, so we'll just set it in the loop
|
20
|
-
usage = nil
|
21
|
-
OptionParser.new do |opts|
|
22
|
-
opts.banner = "Usage: subcl [options] command"
|
23
|
-
opts.separator %{
|
24
|
-
Commands
|
25
|
-
list to terminal
|
26
|
-
search[-song|-album|-artist] <pattern>
|
27
|
-
ss|sl|sr <pattern>
|
28
|
-
clear queue and immediately start playing
|
29
|
-
play[-song|-album|-artist|-playlist] <pattern>
|
30
|
-
ps|pl|pr|pp <pattern>
|
31
|
-
clear queue and immediately start playing random songs
|
32
|
-
play-random <count, default 10>
|
33
|
-
r <count, default 10>
|
34
|
-
add to end of queue
|
35
|
-
queue-last[-song|-album|-artist|-playlist] <pattern>
|
36
|
-
ls|ll|lr|lp <pattern>
|
37
|
-
add after the current song
|
38
|
-
queue-next[-song|-album|-artist|-playlist] <pattern>
|
39
|
-
ns|nl|nr|np <pattern>
|
40
|
-
albumart-url [size] - print url of albumart to terminal,
|
41
|
-
optionally with a specified image size
|
42
|
-
|
43
|
-
Options }
|
44
|
-
|
45
|
-
usage = opts
|
46
|
-
|
47
|
-
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
48
|
-
options[:verbose] = v
|
49
|
-
end
|
50
|
-
opts.on('-1', '--use-first', 'On multiple matches, use the first match instead of asking interactively') do
|
51
|
-
options[:interactive] = false
|
52
|
-
end
|
53
|
-
opts.on('-s', '--shuffle', "Shuffle playlist before queueing") do
|
54
|
-
options[:shuffle] = true
|
55
|
-
end
|
56
|
-
opts.on('-c', '--current', 'Use info currently playing song instead of commandline argument') do
|
57
|
-
options[:current] = true
|
58
|
-
end
|
59
|
-
opts.on('-h', '--help', 'Display this screen') do
|
60
|
-
puts opts
|
61
|
-
exit
|
62
|
-
end
|
63
|
-
opts.on("--version", "Print version information") do
|
64
|
-
puts Configs.new.app_version
|
65
|
-
exit
|
66
|
-
end
|
67
|
-
|
68
|
-
end.parse!
|
69
|
-
|
70
|
-
unless ARGV.size >= 1
|
71
|
-
puts usage
|
72
|
-
exit
|
73
|
-
end
|
74
|
-
|
75
|
-
unless system('tty -s')
|
76
|
-
#not running in a tty, so no use for interactivity
|
77
|
-
options[:tty] = false
|
78
|
-
options[:interactive] = false
|
79
|
-
end
|
80
|
-
|
81
|
-
subcl = Subcl.new options
|
82
|
-
|
83
|
-
arg = ARGV[1,ARGV.length-1].join(" ") #put rest of args together so no quotes are required
|
84
|
-
|
85
|
-
|
86
|
-
case ARGV[0].downcase
|
87
|
-
when /^play-song$|^ps$/
|
88
|
-
subcl.queue(arg, :song, {:play => true, :clear => true})
|
89
|
-
when /^play-artist$|^pr$/
|
90
|
-
subcl.queue(arg, :artist, {:play => true, :clear => true})
|
91
|
-
when /^play-album$|^pl$/
|
92
|
-
subcl.queue(arg, :album, {:play => true, :clear => true})
|
93
|
-
when /^play-playlist$|^pp$/
|
94
|
-
subcl.queue(arg, :playlist, {:play => true, :clear => true})
|
95
|
-
when /^play-random$|^r$/
|
96
|
-
subcl.queue(arg, :randomSong, {:play => true, :clear => true})
|
97
|
-
when /^queue-next-song$|^ns$/
|
98
|
-
subcl.queue(arg, :song, {:insert => true})
|
99
|
-
when /^queue-next-artist$|^nr$/
|
100
|
-
subcl.queue(arg, :artist, {:insert => true})
|
101
|
-
when /^queue-next-album$|^nl$/
|
102
|
-
subcl.queue(arg, :album, {:insert => true})
|
103
|
-
when /^queue-next-playlist$|^np$/
|
104
|
-
subcl.queue(arg, :playlist, {:insert => true})
|
105
|
-
when /^queue-last-song$|^ls$/
|
106
|
-
subcl.queue(arg, :song)
|
107
|
-
when /^queue-last-artist$|^lr$/
|
108
|
-
subcl.queue(arg, :artist)
|
109
|
-
when /^queue-last-album$|^ll$/
|
110
|
-
subcl.queue(arg, :album)
|
111
|
-
when /^queue-last-playlist$|^lp$/
|
112
|
-
subcl.queue(arg, :playlist)
|
113
|
-
when /^search-song$|^ss$/
|
114
|
-
subcl.searchSong(arg)
|
115
|
-
when /^search-artist$|^sr$/
|
116
|
-
subcl.searchArtist(arg)
|
117
|
-
when /^search-album$|^sl$/
|
118
|
-
subcl.searchAlbum(arg)
|
119
|
-
when "albumart-url"
|
120
|
-
arg = nil if arg.empty?
|
121
|
-
puts subcl.albumartUrl(arg)
|
122
|
-
when /^album-list$|^al$/
|
123
|
-
subcl.subsonic.albumlist
|
124
|
-
when "test-notify"
|
125
|
-
subcl.testNotify
|
126
|
-
else
|
127
|
-
if options[:tty] then
|
128
|
-
puts usage
|
129
|
-
else
|
130
|
-
subcl.notifier.notify "Unrecognized command"
|
131
|
-
end
|
132
|
-
end
|
data/bin/subcl-api
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'subcl'
|
4
|
+
|
5
|
+
if ARGV.empty?
|
6
|
+
puts "Usage: subcl-api <method> [opt1=val1 [opt2=val2]...]"
|
7
|
+
exit 1
|
8
|
+
end
|
9
|
+
|
10
|
+
api = SubsonicAPI.new(Configs.new)
|
11
|
+
method = ARGV.shift
|
12
|
+
method += ".view" unless method.end_with? ".view"
|
13
|
+
params = Hash[ARGV.collect { |arg| arg.split('=') }]
|
14
|
+
|
15
|
+
LOGGER.level = Logger::INFO
|
16
|
+
|
17
|
+
begin
|
18
|
+
puts api.query(method, params)
|
19
|
+
rescue SubclError => e
|
20
|
+
$stderr.puts e.message
|
21
|
+
end
|
22
|
+
|
data/lib/subcl.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'subcl/configs'
|
2
|
+
require 'subcl/player'
|
3
|
+
require 'subcl/notify'
|
4
|
+
require 'subcl/picker'
|
5
|
+
require 'subcl/runner'
|
6
|
+
require 'subcl/song'
|
7
|
+
require 'subcl/subcl'
|
8
|
+
require 'subcl/subcl_error'
|
9
|
+
require 'subcl/subsonic_api'
|
10
|
+
|
11
|
+
require 'logger'
|
12
|
+
|
13
|
+
LOGGER = Logger.new(STDERR)
|
14
|
+
LOGGER.level = Logger::INFO
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class Configs
|
2
|
+
|
3
|
+
attr_accessor :configs
|
4
|
+
|
5
|
+
REQUIRED_SETTINGS = %i{ server username password }
|
6
|
+
OPTIONAL_SETTINGS = %i{ max_search_results notify_method random_song_count }
|
7
|
+
|
8
|
+
def initialize(file = '~/.subcl')
|
9
|
+
@configs = {
|
10
|
+
:notifyMethod => "auto",
|
11
|
+
}
|
12
|
+
|
13
|
+
@filename = File.expand_path(file)
|
14
|
+
unless File.file?(@filename)
|
15
|
+
raise "Config file not found"
|
16
|
+
end
|
17
|
+
|
18
|
+
read_configs
|
19
|
+
end
|
20
|
+
|
21
|
+
def read_configs
|
22
|
+
settings = REQUIRED_SETTINGS + OPTIONAL_SETTINGS
|
23
|
+
open(@filename).each_line do |line|
|
24
|
+
next if line.start_with? '#'
|
25
|
+
|
26
|
+
key, value = line.split(' ')
|
27
|
+
key = key.to_sym
|
28
|
+
if settings.include? key
|
29
|
+
@configs[key] = value
|
30
|
+
else
|
31
|
+
LOGGER.warn { "Unknown setting: '#{key}'" }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
REQUIRED_SETTINGS.each do |setting|
|
36
|
+
if @configs[setting].nil?
|
37
|
+
raise "Missing setting '#{setting}'"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def [](key)
|
43
|
+
raise "Undefined setting #{key}" unless @configs.has_key? key
|
44
|
+
@configs[key]
|
45
|
+
end
|
46
|
+
|
47
|
+
def []=(key, val)
|
48
|
+
settings = REQUIRED_SETTINGS + OPTIONAL_SETTINGS
|
49
|
+
settings.each do |name|
|
50
|
+
if key == name
|
51
|
+
@configs[key] = val
|
52
|
+
return
|
53
|
+
end
|
54
|
+
end
|
55
|
+
raise "Undefined setting #{key}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_hash
|
59
|
+
@configs
|
60
|
+
end
|
61
|
+
end
|
data/lib/subcl/notify.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
class Notify
|
2
|
+
|
3
|
+
SupportedMethods = %w{notify-send growlnotify awesome-client}
|
4
|
+
Icon = File.dirname(__FILE__) + "/../../share/icon.png"
|
5
|
+
|
6
|
+
def initialize(notifyMethod)
|
7
|
+
@method = nil
|
8
|
+
|
9
|
+
case notifyMethod
|
10
|
+
when nil
|
11
|
+
#do nothing
|
12
|
+
when "none"
|
13
|
+
#do nothing
|
14
|
+
when "auto"
|
15
|
+
#auto detect notifier lib
|
16
|
+
SupportedMethods.each do |method|
|
17
|
+
@binary = get_binary(method)
|
18
|
+
unless @binary.nil?
|
19
|
+
@method = method
|
20
|
+
break
|
21
|
+
end
|
22
|
+
end
|
23
|
+
else
|
24
|
+
#use specified binary
|
25
|
+
unless SupportedMethods.include? notifyMethod
|
26
|
+
raise ArgumentError, "Notification method #{notifyMethod} is not supported"
|
27
|
+
end
|
28
|
+
@binary = get_binary(notifyMethod)
|
29
|
+
@method = notifyMethod
|
30
|
+
raise ArgumentError, "No binary found for #{notifyMethod} in PATH" if @binary.nil?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_binary(name)
|
35
|
+
binary = `which #{name}`.chomp
|
36
|
+
if $?.success?
|
37
|
+
binary
|
38
|
+
else
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def notify(message)
|
44
|
+
case @method
|
45
|
+
when nil
|
46
|
+
#great, do nothing
|
47
|
+
when "notify-send"
|
48
|
+
system("notify-send --icon #{Icon} --urgency critical Subcl '#{message}'")
|
49
|
+
when "growlnotify"
|
50
|
+
system("growlnotify --image #{Icon} --title Subcl --message '#{message}'")
|
51
|
+
when "awesome-client"
|
52
|
+
naughtyCmd = %Q{
|
53
|
+
naughty.notify({
|
54
|
+
title='subcl',
|
55
|
+
text='#{message}',
|
56
|
+
icon='#{Icon}',
|
57
|
+
timeout = 10
|
58
|
+
})
|
59
|
+
}
|
60
|
+
naughtyCmd.gsub! "\n" " "
|
61
|
+
|
62
|
+
system(%Q{echo "#{naughtyCmd}" | awesome-client})
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
data/lib/subcl/picker.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
class Picker
|
2
|
+
def initialize(ary)
|
3
|
+
@available = ary
|
4
|
+
if ary.empty? then
|
5
|
+
raise ArgumentError, "Cannot initialize Picker with an empty array!"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def pick
|
10
|
+
choices = {}
|
11
|
+
|
12
|
+
i = 1
|
13
|
+
@available.each do |elem|
|
14
|
+
choices[i] = elem
|
15
|
+
$stderr.print "[#{i}] "
|
16
|
+
yield(elem)
|
17
|
+
i = i + 1
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
begin
|
22
|
+
picks = []
|
23
|
+
valid = true
|
24
|
+
$stderr.print "Pick any: "
|
25
|
+
|
26
|
+
choice = $stdin.gets
|
27
|
+
|
28
|
+
return @available if choice.chomp == 'all'
|
29
|
+
|
30
|
+
choice.split(/[ ,]+/).each do |part|
|
31
|
+
possibleRange = part.split(/\.\.|-/)
|
32
|
+
if possibleRange.length == 2
|
33
|
+
start = possibleRange[0].to_i
|
34
|
+
stop = possibleRange[1].to_i
|
35
|
+
[start, stop].each do |num|
|
36
|
+
valid = validate(num)
|
37
|
+
end
|
38
|
+
(start..stop).each do |num|
|
39
|
+
picks << choices[num]
|
40
|
+
end
|
41
|
+
|
42
|
+
elsif validate(num = part.to_i)
|
43
|
+
picks << choices[num]
|
44
|
+
else
|
45
|
+
valid == false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end while !valid
|
49
|
+
|
50
|
+
return picks
|
51
|
+
end
|
52
|
+
|
53
|
+
def validate(pickNum)
|
54
|
+
#no -1, we start filling choices{} at 1
|
55
|
+
if pickNum > 0 and pickNum <= @available.length
|
56
|
+
true
|
57
|
+
else
|
58
|
+
$stderr.puts "Invalid pick. Try again."
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
data/lib/subcl/player.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'ruby-mpd'
|
2
|
+
require 'delegate'
|
3
|
+
|
4
|
+
class Player < SimpleDelegator
|
5
|
+
def initialize
|
6
|
+
#TODO add configs for host/port/security
|
7
|
+
@mpd = MPD.new
|
8
|
+
@mpd.connect
|
9
|
+
super(@mpd)
|
10
|
+
end
|
11
|
+
|
12
|
+
#insert: whether to add the song after the currently playing one
|
13
|
+
#instead of the end of the queue
|
14
|
+
def add(song, insert = false)
|
15
|
+
unless song[:stream_url]
|
16
|
+
raise ArgumentError, "argument has no :stream_url!"
|
17
|
+
end
|
18
|
+
LOGGER.debug { "Adding #{song['title']}: #{song[:stream_url]}. Insert: #{insert}" }
|
19
|
+
if insert then
|
20
|
+
pos = @mpd.current_song.pos + 1
|
21
|
+
@mpd.addid(song[:stream_url], pos)
|
22
|
+
else
|
23
|
+
@mpd.add(song[:stream_url])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#stops the player and clears the playlist
|
28
|
+
def clearstop
|
29
|
+
@mpd.stop
|
30
|
+
@mpd.clear
|
31
|
+
end
|
32
|
+
|
33
|
+
# if song has been playing for more than 4 seconds, rewind it to the start
|
34
|
+
# otherwise go to the previous song
|
35
|
+
def rewind
|
36
|
+
if @mpd.status[:elapsed] > 4
|
37
|
+
@mpd.seek 0
|
38
|
+
else
|
39
|
+
@mpd.previous
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# if mpd is playing, pause it. Otherwise resume playback
|
44
|
+
def toggle
|
45
|
+
@mpd.pause = @mpd.playing? ? 1 : 0
|
46
|
+
end
|
47
|
+
|
48
|
+
def pause
|
49
|
+
@mpd.pause = 1
|
50
|
+
end
|
51
|
+
|
52
|
+
#TODO: might create a wrapper for current_song that makes API calls for artist, album, etc,
|
53
|
+
# in case mpd is unable to decode the metadata
|
54
|
+
end
|
data/lib/subcl/runner.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
class Runner
|
4
|
+
def initialize(options = {})
|
5
|
+
@options = {
|
6
|
+
:tty => true,
|
7
|
+
:out_stream => STDOUT,
|
8
|
+
:err_stream => STDERR,
|
9
|
+
:mock_player => nil,
|
10
|
+
:mock_api => nil
|
11
|
+
}.merge! options
|
12
|
+
|
13
|
+
#TODO refactor this away
|
14
|
+
if File.exist?('debug')
|
15
|
+
puts "DEBUGGING"
|
16
|
+
@options[:debug] = true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse_options! args
|
21
|
+
OptionParser.new do |opts|
|
22
|
+
opts.banner = "Usage: subcl [options] command"
|
23
|
+
opts.separator %{
|
24
|
+
Queue Commands
|
25
|
+
clear queue and immediately start playing
|
26
|
+
play[-song|-album|-artist|-playlist] <pattern>
|
27
|
+
ps|pl|pr|pp <pattern>
|
28
|
+
clear queue and immediately start playing random songs
|
29
|
+
play-random <count, default 10>
|
30
|
+
r <count, default 10>
|
31
|
+
add to end of queue
|
32
|
+
queue-last[-song|-album|-artist|-playlist] <pattern>
|
33
|
+
ls|ll|lr|lp <pattern>
|
34
|
+
add after the current song
|
35
|
+
queue-next[-song|-album|-artist|-playlist] <pattern>
|
36
|
+
ns|nl|nr|np <pattern>
|
37
|
+
albumart-url [size] - print url of albumart to terminal,
|
38
|
+
optionally with a specified image size
|
39
|
+
|
40
|
+
Playback Commands
|
41
|
+
play
|
42
|
+
pause
|
43
|
+
toggle (play when pause, pause when played)
|
44
|
+
stop
|
45
|
+
next
|
46
|
+
previous
|
47
|
+
rewind (get to start of song, or previous song when at start)
|
48
|
+
|
49
|
+
Options }
|
50
|
+
|
51
|
+
@usage = opts
|
52
|
+
|
53
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
54
|
+
@options[:verbose] = v
|
55
|
+
end
|
56
|
+
opts.on('-1', '--use-first', 'On multiple matches, use the first match instead of asking interactively') do
|
57
|
+
@options[:interactive] = false
|
58
|
+
end
|
59
|
+
opts.on('-s', '--shuffle', "Shuffle playlist before queueing") do
|
60
|
+
@options[:shuffle] = true
|
61
|
+
end
|
62
|
+
opts.on('-c', '--current', 'Use info currently playing song instead of commandline argument') do
|
63
|
+
@options[:current] = true
|
64
|
+
end
|
65
|
+
opts.on('-h', '--help', 'Display this screen') do
|
66
|
+
out_stream.puts opts
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
opts.on("--version", "Print version information") do
|
70
|
+
out_stream.puts Configs.new[:app_version]
|
71
|
+
exit
|
72
|
+
end
|
73
|
+
|
74
|
+
end.parse! args
|
75
|
+
end
|
76
|
+
|
77
|
+
def run(args)
|
78
|
+
LOGGER.debug { "args = #{args}" }
|
79
|
+
|
80
|
+
parse_options!(args)
|
81
|
+
|
82
|
+
LOGGER.debug { "args = #{args}" }
|
83
|
+
|
84
|
+
unless args.size >= 1
|
85
|
+
@options[:err_stream].puts @usage
|
86
|
+
exit 3
|
87
|
+
end
|
88
|
+
|
89
|
+
unless system('tty -s')
|
90
|
+
#not running in a tty, so no use for interactivity
|
91
|
+
@options[:tty] = false
|
92
|
+
@options[:interactive] = false
|
93
|
+
end
|
94
|
+
|
95
|
+
subcl = Subcl.new @options
|
96
|
+
|
97
|
+
arg = args[1,args.length-1].join(" ") #put rest of args together so no quotes are required
|
98
|
+
|
99
|
+
command = args[0].downcase
|
100
|
+
case command
|
101
|
+
|
102
|
+
when /^play-song$|^ps$/
|
103
|
+
subcl.queue(arg, :song, {:play => true, :clear => true})
|
104
|
+
when /^play-artist$|^pr$/
|
105
|
+
subcl.queue(arg, :artist, {:play => true, :clear => true})
|
106
|
+
when /^play-album$|^pl$/
|
107
|
+
subcl.queue(arg, :album, {:play => true, :clear => true})
|
108
|
+
when /^play-playlist$|^pp$/
|
109
|
+
subcl.queue(arg, :playlist, {:play => true, :clear => true})
|
110
|
+
when /^play-random$|^r$/
|
111
|
+
subcl.queue(arg, :randomSong, {:play => true, :clear => true})
|
112
|
+
when /^queue-next-song$|^ns$/
|
113
|
+
subcl.queue(arg, :song, {:insert => true})
|
114
|
+
when /^queue-next-artist$|^nr$/
|
115
|
+
subcl.queue(arg, :artist, {:insert => true})
|
116
|
+
when /^queue-next-album$|^nl$/
|
117
|
+
subcl.queue(arg, :album, {:insert => true})
|
118
|
+
when /^queue-next-playlist$|^np$/
|
119
|
+
subcl.queue(arg, :playlist, {:insert => true})
|
120
|
+
when /^queue-last-song$|^ls$/
|
121
|
+
subcl.queue(arg, :song)
|
122
|
+
when /^queue-last-artist$|^lr$/
|
123
|
+
subcl.queue(arg, :artist)
|
124
|
+
when /^queue-last-album$|^ll$/
|
125
|
+
subcl.queue(arg, :album)
|
126
|
+
when /^queue-last-playlist$|^lp$/
|
127
|
+
subcl.queue(arg, :playlist)
|
128
|
+
when "albumart-url"
|
129
|
+
arg = nil if arg.empty?
|
130
|
+
@options[:out_stream].puts subcl.albumart_url(arg)
|
131
|
+
when /^album-list$|^al$/
|
132
|
+
subcl.albumlist
|
133
|
+
when "test-notify"
|
134
|
+
subcl.testNotify
|
135
|
+
else
|
136
|
+
begin
|
137
|
+
#pass through for player commands
|
138
|
+
subcl.send(command, [])
|
139
|
+
rescue NoMethodError
|
140
|
+
unknown(command)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def unknown(command)
|
146
|
+
if @options[:tty] then
|
147
|
+
@options[:err_stream].puts "Unknown command '#{command}'"
|
148
|
+
@options[:err_stream].puts @usage
|
149
|
+
else
|
150
|
+
subcl.notifier.notify "Unknown command '#{command}'"
|
151
|
+
end
|
152
|
+
exit 3
|
153
|
+
end
|
154
|
+
end
|