ruby-mpd 0.1.7 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +2 -2
- data/lib/ruby-mpd.rb +59 -61
- data/lib/ruby-mpd/exceptions.rb +2 -2
- data/lib/ruby-mpd/parser.rb +33 -36
- data/lib/ruby-mpd/playlist.rb +1 -1
- data/lib/ruby-mpd/plugins/controls.rb +2 -2
- data/lib/ruby-mpd/plugins/database.rb +2 -2
- data/lib/ruby-mpd/plugins/information.rb +1 -1
- data/lib/ruby-mpd/plugins/outputs.rb +1 -1
- data/lib/ruby-mpd/plugins/playback_options.rb +1 -1
- data/lib/ruby-mpd/plugins/playlists.rb +1 -1
- data/lib/ruby-mpd/plugins/queue.rb +4 -4
- data/lib/ruby-mpd/plugins/reflection.rb +1 -1
- data/lib/ruby-mpd/plugins/stickers.rb +2 -2
- data/lib/ruby-mpd/song.rb +8 -3
- data/ruby-mpd.gemspec +1 -1
- data/test/libtests.rb +9 -9
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
ruby-mpd is a powerful object-oriented Music Player Daemon library, forked from librmpd.
|
4
4
|
librmpd is as of writing outdated by 6 years! This library tries to act as a successor,
|
5
5
|
originally using librmpd as a base, however almost all of the codebase was rewritten.
|
6
|
-
ruby-mpd supports all "modern" MPD features.
|
6
|
+
ruby-mpd supports all "modern" MPD features as well as callbacks.
|
7
7
|
|
8
8
|
== MPD Protocol
|
9
9
|
|
@@ -41,7 +41,7 @@ When you are done, disconnect by calling disconnect.
|
|
41
41
|
|
42
42
|
*Note*: The server may disconnect you at any time due to inactivity. This can
|
43
43
|
be fixed by enabling callbacks (see the Callbacks section) or by issuing a
|
44
|
-
`ping` command at certain intervals
|
44
|
+
`ping` command at certain intervals.
|
45
45
|
|
46
46
|
Once connected, you can issue commands to talk to the server.
|
47
47
|
|
data/lib/ruby-mpd.rb
CHANGED
@@ -46,16 +46,20 @@ class MPD
|
|
46
46
|
def initialize(hostname = 'localhost', port = 6600)
|
47
47
|
@hostname = hostname
|
48
48
|
@port = port
|
49
|
-
|
50
|
-
@version = nil
|
51
|
-
@tags = nil
|
49
|
+
reset_vars
|
52
50
|
|
53
|
-
@stop_cb_thread = false
|
54
51
|
@mutex = Mutex.new
|
55
|
-
@cb_thread = nil
|
56
52
|
@callbacks = {}
|
57
53
|
end
|
58
54
|
|
55
|
+
# Initialize instance variables on new object, or on disconnect.
|
56
|
+
def reset_vars
|
57
|
+
@socket = nil
|
58
|
+
@version = nil
|
59
|
+
@tags = nil
|
60
|
+
end
|
61
|
+
private :reset_vars
|
62
|
+
|
59
63
|
# This will register a block callback that will trigger whenever
|
60
64
|
# that specific event happens.
|
61
65
|
#
|
@@ -81,12 +85,51 @@ class MPD
|
|
81
85
|
# @param [Symbol] event The event that happened.
|
82
86
|
# @return [void]
|
83
87
|
def emit(event, *args)
|
84
|
-
@callbacks[event]
|
88
|
+
return unless @callbacks[event]
|
85
89
|
@callbacks[event].each do |handle|
|
86
90
|
handle.call *args
|
87
91
|
end
|
88
92
|
end
|
89
93
|
|
94
|
+
# Constructs a callback loop thread and/or resumes it.
|
95
|
+
# @return [Thread]
|
96
|
+
def callback_thread
|
97
|
+
@cb_thread ||= Thread.new(self) do |mpd|
|
98
|
+
old_status = {}
|
99
|
+
while true
|
100
|
+
status = mpd.status rescue {}
|
101
|
+
|
102
|
+
status[:connection] = mpd.connected?
|
103
|
+
|
104
|
+
status[:time] = [nil, nil] if !status[:time] # elapsed, total
|
105
|
+
status[:audio] = [nil, nil, nil] if !status[:audio] # samp, bits, chans
|
106
|
+
|
107
|
+
status.each do |key, val|
|
108
|
+
next if val == old_status[key] # skip unchanged keys
|
109
|
+
|
110
|
+
if key == :song
|
111
|
+
emit(:song, mpd.current_song)
|
112
|
+
else # convert arrays to splat arguments
|
113
|
+
val.is_a?(Array) ? emit(key, *val) : emit(key, val)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
old_status = status
|
118
|
+
sleep 0.1
|
119
|
+
|
120
|
+
if !status[:connection] && !Thread.current[:stop]
|
121
|
+
sleep 2
|
122
|
+
mpd.connect rescue nil
|
123
|
+
end
|
124
|
+
|
125
|
+
Thread.stop if Thread.current[:stop]
|
126
|
+
end
|
127
|
+
end
|
128
|
+
@cb_thread[:stop] = false
|
129
|
+
@cb_thread.run if @cb_thread.stop?
|
130
|
+
end
|
131
|
+
private :callback_thread
|
132
|
+
|
90
133
|
# Connect to the daemon.
|
91
134
|
#
|
92
135
|
# When called without any arguments, this will just connect to the server
|
@@ -104,47 +147,7 @@ class MPD
|
|
104
147
|
@socket = File.exists?(@hostname) ? UNIXSocket.new(@hostname) : TCPSocket.new(@hostname, @port)
|
105
148
|
@version = @socket.gets.chomp.gsub('OK MPD ', '') # Read the version
|
106
149
|
|
107
|
-
if callbacks
|
108
|
-
@stop_cb_thread = false
|
109
|
-
@cb_thread = Thread.new(self) { |mpd|
|
110
|
-
old_status = {}
|
111
|
-
connected = ''
|
112
|
-
while !@stop_cb_thread
|
113
|
-
status = mpd.status rescue {}
|
114
|
-
c = mpd.connected?
|
115
|
-
|
116
|
-
# @todo Move into status[:connection]?
|
117
|
-
if connected != c
|
118
|
-
connected = c
|
119
|
-
emit(:connection, connected)
|
120
|
-
end
|
121
|
-
|
122
|
-
status[:time] = [nil, nil] if !status[:time] # elapsed, total
|
123
|
-
status[:audio] = [nil, nil, nil] if !status[:audio] # samp, bits, chans
|
124
|
-
|
125
|
-
status.each do |key, val|
|
126
|
-
next if val == old_status[key] # skip unchanged keys
|
127
|
-
|
128
|
-
if key == :song
|
129
|
-
emit(:song, mpd.current_song)
|
130
|
-
else # convert arrays to splat arguments
|
131
|
-
val.is_a?(Array) ? emit(key, *val) : emit(key, val)
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
old_status = status
|
136
|
-
sleep 0.1
|
137
|
-
|
138
|
-
if !connected
|
139
|
-
sleep 2
|
140
|
-
unless @stop_cb_thread
|
141
|
-
mpd.connect rescue nil
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
}
|
146
|
-
end
|
147
|
-
|
150
|
+
callback_thread if callbacks
|
148
151
|
return true
|
149
152
|
end
|
150
153
|
|
@@ -163,13 +166,13 @@ class MPD
|
|
163
166
|
# the callback thread, thus disabling callbacks.
|
164
167
|
# @return [Boolean] True if successfully disconnected, false otherwise.
|
165
168
|
def disconnect
|
166
|
-
@
|
169
|
+
@cb_thread[:stop] = true if @cb_thread
|
167
170
|
|
168
171
|
return false if !@socket
|
169
172
|
|
170
173
|
@socket.puts 'close'
|
171
174
|
@socket.close
|
172
|
-
|
175
|
+
reset_vars
|
173
176
|
return true
|
174
177
|
end
|
175
178
|
|
@@ -202,7 +205,7 @@ class MPD
|
|
202
205
|
# @return (see #handle_server_response)
|
203
206
|
# @raise [MPDError] if the command failed.
|
204
207
|
def send_command(command, *args)
|
205
|
-
raise ConnectionError, "Not connected to the server!" if
|
208
|
+
raise ConnectionError, "Not connected to the server!" if !@socket
|
206
209
|
|
207
210
|
@mutex.synchronize do
|
208
211
|
begin
|
@@ -210,7 +213,7 @@ class MPD
|
|
210
213
|
response = handle_server_response
|
211
214
|
return parse_response(command, response)
|
212
215
|
rescue Errno::EPIPE
|
213
|
-
|
216
|
+
reset_vars # kill the socket and reset
|
214
217
|
raise ConnectionError, 'Broken pipe (got disconnected)'
|
215
218
|
end
|
216
219
|
end
|
@@ -225,21 +228,16 @@ class MPD
|
|
225
228
|
# @return [true] If "OK" is returned.
|
226
229
|
# @raise [MPDError] If an "ACK" is returned.
|
227
230
|
def handle_server_response
|
228
|
-
return if @socket.nil?
|
229
|
-
|
230
231
|
msg = ''
|
231
|
-
|
232
|
-
|
233
|
-
while reading
|
234
|
-
line = @socket.gets
|
235
|
-
case line
|
232
|
+
while true
|
233
|
+
case line = @socket.gets
|
236
234
|
when "OK\n", nil
|
237
|
-
|
235
|
+
break
|
238
236
|
when /^ACK/
|
239
237
|
error = line
|
240
|
-
|
238
|
+
break
|
241
239
|
else
|
242
|
-
msg
|
240
|
+
msg << line
|
243
241
|
end
|
244
242
|
end
|
245
243
|
|
data/lib/ruby-mpd/exceptions.rb
CHANGED
@@ -12,7 +12,7 @@ class MPD
|
|
12
12
|
class ServerArgumentError < ServerError; end
|
13
13
|
# MPD server password incorrect - ACK_ERROR_PASSWORD
|
14
14
|
class IncorrectPassword < ServerError; end
|
15
|
-
# ACK_ERROR_PERMISSION - not permitted to use the command.
|
15
|
+
# ACK_ERROR_PERMISSION - not permitted to use the command.
|
16
16
|
# (Mostly, the solution is to connect via UNIX domain socket)
|
17
17
|
class PermissionError < ServerError; end
|
18
18
|
|
@@ -30,4 +30,4 @@ class MPD
|
|
30
30
|
class NotPlaying < ServerError; end
|
31
31
|
# ACK_ERROR_EXIST - the resource already exists.
|
32
32
|
class AlreadyExists < ServerError; end
|
33
|
-
end
|
33
|
+
end
|
data/lib/ruby-mpd/parser.rb
CHANGED
@@ -40,7 +40,7 @@ class MPD
|
|
40
40
|
|
41
41
|
|
42
42
|
# Commands, where it makes sense to always explicitly return an array.
|
43
|
-
RETURN_ARRAY = [:channels, :outputs, :readmessages, :list, :listall,
|
43
|
+
RETURN_ARRAY = [:channels, :outputs, :readmessages, :list, :listall,
|
44
44
|
:listallinfo, :find, :search, :listplaylists, :listplaylist, :playlistfind,
|
45
45
|
:playlistsearch, :plchanges, :tagtypes, :commands, :notcommands, :urlhandlers,
|
46
46
|
:decoders, :listplaylistinfo]
|
@@ -57,8 +57,8 @@ class MPD
|
|
57
57
|
value.to_sym
|
58
58
|
elsif key == :playlist && !value.to_i.zero?
|
59
59
|
# doc states it's an unsigned int, meaning if we get 0,
|
60
|
-
# then it's a name string.
|
61
|
-
# @todo HAXX
|
60
|
+
# then it's a name string.
|
61
|
+
# @todo HAXX! what if playlist name is '123'?
|
62
62
|
value.to_i
|
63
63
|
elsif key == :db_update
|
64
64
|
Time.at(value.to_i)
|
@@ -71,13 +71,12 @@ class MPD
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
# Parses a single response line into
|
75
|
-
def parse_line(
|
76
|
-
return nil if
|
77
|
-
key, value =
|
74
|
+
# Parses a single response line into a key-object (value) pair.
|
75
|
+
def parse_line(line)
|
76
|
+
return nil if line.nil?
|
77
|
+
key, value = line.split(/:\s?/, 2)
|
78
78
|
key = key.downcase.to_sym
|
79
|
-
|
80
|
-
return parse_key(key, value.chomp)
|
79
|
+
return key, parse_key(key, value.chomp)
|
81
80
|
end
|
82
81
|
|
83
82
|
# This builds a hash out of lines returned from the server,
|
@@ -88,16 +87,14 @@ class MPD
|
|
88
87
|
return {} if string.nil?
|
89
88
|
|
90
89
|
string.split("\n").each_with_object({}) do |line, hash|
|
91
|
-
key,
|
92
|
-
key = key.downcase.to_sym
|
93
|
-
value ||= '' # no nil values please ("album: ")
|
90
|
+
key, object = parse_line(line)
|
94
91
|
|
95
92
|
# if val appears more than once, make an array of vals.
|
96
93
|
if hash.include? key
|
97
|
-
hash[key] =
|
98
|
-
hash[key] <<
|
94
|
+
hash[key] = Array(hash[key]) # convert to array (http://rubyquicktips.com/post/9618833891/convert-object-to-array)
|
95
|
+
hash[key] << object # add new obj to array
|
99
96
|
else # val hasn't appeared yet, map it.
|
100
|
-
hash[key] =
|
97
|
+
hash[key] = object # map obj to key
|
101
98
|
end
|
102
99
|
end
|
103
100
|
end
|
@@ -109,10 +106,15 @@ class MPD
|
|
109
106
|
return array.map {|hash| Song.new(hash) }
|
110
107
|
end
|
111
108
|
|
109
|
+
# Remove lines which we don't want.
|
110
|
+
def filter_lines(string, filter)
|
111
|
+
string.split("\n").reject {|line| line =~ /(#{filter.join('|')}):/}.join("\n")
|
112
|
+
end
|
113
|
+
|
112
114
|
# Make chunks from string.
|
113
115
|
# @return [Array<String>]
|
114
116
|
def make_chunks(string)
|
115
|
-
first_key = string.match(/\A(.+?)
|
117
|
+
first_key = string.match(/\A(.+?):\s?/)[1]
|
116
118
|
|
117
119
|
chunks = string.split(/\n(?=#{first_key})/)
|
118
120
|
chunks.inject([]) do |result, chunk|
|
@@ -121,28 +123,37 @@ class MPD
|
|
121
123
|
end
|
122
124
|
|
123
125
|
# Parses the response, determining per-command on what parsing logic
|
124
|
-
# to use (build_response vs
|
126
|
+
# to use (build_response vs build a single grouped hash).
|
125
127
|
#
|
126
128
|
# @return [Array<Hash>, Array<String>, String, Integer] Parsed response.
|
127
129
|
def parse_response(command, string)
|
128
130
|
# return explicit array if needed
|
129
|
-
return RETURN_ARRAY.include?(command) ? [] : true if string
|
130
|
-
command == :listall
|
131
|
+
return RETURN_ARRAY.include?(command) ? [] : true if string == true
|
132
|
+
if command == :listall
|
133
|
+
build_hash(string)
|
134
|
+
elsif command == :listallinfo
|
135
|
+
build_response(command, string, [:directory, :playlist])
|
136
|
+
else
|
137
|
+
build_response(command, string)
|
138
|
+
end
|
131
139
|
end
|
132
140
|
|
133
141
|
# Parses the response into appropriate objects (either a single object,
|
134
142
|
# or an array of objects or an array of hashes).
|
135
143
|
#
|
136
144
|
# @return [Array<Hash>, Array<String>, String, Integer] Parsed response.
|
137
|
-
def build_response(command, string)
|
145
|
+
def build_response(command, string, filter=nil)
|
138
146
|
return [] if string.nil? || !string.is_a?(String)
|
139
147
|
|
148
|
+
# filter lines if filter specified
|
149
|
+
string = filter_lines(string,filter) if filter
|
150
|
+
|
140
151
|
chunks = make_chunks(string)
|
141
152
|
# if there are any new lines (more than one data piece), it's a hash, else an object.
|
142
153
|
is_hash = chunks.any? {|chunk| chunk.include? "\n"}
|
143
154
|
|
144
155
|
list = chunks.inject([]) do |result, chunk|
|
145
|
-
result << (is_hash ? build_hash(chunk) : parse_line(chunk))
|
156
|
+
result << (is_hash ? build_hash(chunk) : parse_line(chunk)[1]) # parse_line(chunk)[1] is object
|
146
157
|
end
|
147
158
|
|
148
159
|
# if list has only one element and not set to explicit array, return it, else return array
|
@@ -150,19 +161,5 @@ class MPD
|
|
150
161
|
return result
|
151
162
|
end
|
152
163
|
|
153
|
-
# Parse the response into groups that have the same key (used for file lists,
|
154
|
-
# groups together files, directories and playlists).
|
155
|
-
# @return [Hash<Array>] A hash of key groups.
|
156
|
-
def build_grouped_response(string)
|
157
|
-
return [] if string.nil? || !string.is_a?(String)
|
158
|
-
|
159
|
-
string.split("\n").each_with_object({}) do |line, hash|
|
160
|
-
key, value = line.split(': ', 2)
|
161
|
-
key = key.downcase.to_sym
|
162
|
-
hash[key] ||= []
|
163
|
-
hash[key] << parse_key(key, value.chomp) # map val to key
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
164
|
end
|
168
|
-
end
|
165
|
+
end
|
data/lib/ruby-mpd/playlist.rb
CHANGED
@@ -19,7 +19,7 @@ class MPD
|
|
19
19
|
# @param [Hash] pos :id of the song where to start playing.
|
20
20
|
# @macro returnraise
|
21
21
|
def play(pos = nil)
|
22
|
-
if pos.is_a?(Hash)
|
22
|
+
if pos.is_a?(Hash)
|
23
23
|
if pos[:id]
|
24
24
|
send_command :playid, priority, pos[:id]
|
25
25
|
else
|
@@ -61,4 +61,4 @@ class MPD
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
end
|
64
|
-
end
|
64
|
+
end
|
@@ -43,7 +43,7 @@ class MPD
|
|
43
43
|
# @param [Hash] pos :id to specify the song ID to delete instead of position.
|
44
44
|
# @macro returnraise
|
45
45
|
def delete(pos)
|
46
|
-
if pos.is_a?(Hash)
|
46
|
+
if pos.is_a?(Hash)
|
47
47
|
if pos[:id]
|
48
48
|
send_command :deleteid, pos[:id]
|
49
49
|
else
|
@@ -64,7 +64,7 @@ class MPD
|
|
64
64
|
# @param [Hash] from :id to specify the song ID to move instead of position.
|
65
65
|
# @macro returnraise
|
66
66
|
def move(from, to)
|
67
|
-
if pos.is_a?(Hash)
|
67
|
+
if pos.is_a?(Hash)
|
68
68
|
if pos[:id]
|
69
69
|
send_command :moveid, pos[:id], to
|
70
70
|
else
|
@@ -110,7 +110,7 @@ class MPD
|
|
110
110
|
# @param [Range] pos A range of positions.
|
111
111
|
# @param [Hash] pos :id to specify the song ID to move instead of position.
|
112
112
|
def song_priority(priority, pos)
|
113
|
-
if pos.is_a?(Hash)
|
113
|
+
if pos.is_a?(Hash)
|
114
114
|
if pos[:id]
|
115
115
|
send_command :prioid, priority, pos[:id]
|
116
116
|
else
|
@@ -151,4 +151,4 @@ class MPD
|
|
151
151
|
|
152
152
|
end
|
153
153
|
end
|
154
|
-
end
|
154
|
+
end
|
@@ -26,7 +26,7 @@ class MPD
|
|
26
26
|
# Adds a sticker value to the specified object. If a sticker
|
27
27
|
# item with that name already exists, it is replaced.
|
28
28
|
def set_sticker(type, uri, name, value)
|
29
|
-
send_command :sticker, :set, type, uri, name
|
29
|
+
send_command :sticker, :set, type, uri, name, value
|
30
30
|
end
|
31
31
|
|
32
32
|
# Deletes a sticker value from the specified object. If you do
|
@@ -49,4 +49,4 @@ class MPD
|
|
49
49
|
end
|
50
50
|
|
51
51
|
end
|
52
|
-
end
|
52
|
+
end
|
data/lib/ruby-mpd/song.rb
CHANGED
@@ -5,11 +5,16 @@ class MPD; end
|
|
5
5
|
# If the field doesn't exist or isn't set, nil will be returned
|
6
6
|
class MPD::Song
|
7
7
|
# length in seconds
|
8
|
-
|
8
|
+
attr_reader :file, :title, :time, :artist, :album, :albumartist
|
9
9
|
|
10
10
|
def initialize(options)
|
11
|
-
@data = {} #allowed fields are @types + :file
|
11
|
+
@data = {} # allowed fields are @types + :file
|
12
12
|
@time = options.delete(:time).first #HAXX for array return
|
13
|
+
@file = options.delete(:file)
|
14
|
+
@title = options.delete(:title)
|
15
|
+
@artist = options.delete(:artist)
|
16
|
+
@album = options.delete(:album)
|
17
|
+
@albumartist = options.delete(:albumartist)
|
13
18
|
@data.merge! options
|
14
19
|
end
|
15
20
|
|
@@ -34,4 +39,4 @@ class MPD::Song
|
|
34
39
|
raise NoMethodError, "#{m}"
|
35
40
|
end
|
36
41
|
end
|
37
|
-
end
|
42
|
+
end
|
data/ruby-mpd.gemspec
CHANGED
data/test/libtests.rb
CHANGED
@@ -305,7 +305,7 @@ class MPDTester < Test::Unit::TestCase
|
|
305
305
|
@mpd.connect
|
306
306
|
|
307
307
|
dirs = @mpd.directories
|
308
|
-
|
308
|
+
|
309
309
|
assert_equal 7, dirs.size
|
310
310
|
assert_equal 'Astral_Projection', dirs[0]
|
311
311
|
assert_equal 'Astral_Projection/Dancing_Galaxy', dirs[1]
|
@@ -439,7 +439,7 @@ class MPDTester < Test::Unit::TestCase
|
|
439
439
|
pls = @mpd.playlist
|
440
440
|
|
441
441
|
assert_equal 8, pls.size
|
442
|
-
|
442
|
+
|
443
443
|
pls.each do |song|
|
444
444
|
assert_equal 'Astral Projection', song.artist
|
445
445
|
assert_equal 'Dancing Galaxy', song.album
|
@@ -581,7 +581,7 @@ class MPDTester < Test::Unit::TestCase
|
|
581
581
|
@mpd.connect
|
582
582
|
|
583
583
|
assert @mpd.ping
|
584
|
-
|
584
|
+
|
585
585
|
@mpd.disconnect
|
586
586
|
assert_raise(MPD::ServerError) {@mpd.ping}
|
587
587
|
end
|
@@ -911,7 +911,7 @@ class MPDTester < Test::Unit::TestCase
|
|
911
911
|
assert @mpd.play
|
912
912
|
|
913
913
|
sleep 2
|
914
|
-
|
914
|
+
|
915
915
|
assert @mpd.pause = true
|
916
916
|
|
917
917
|
sleep 2
|
@@ -923,7 +923,7 @@ class MPDTester < Test::Unit::TestCase
|
|
923
923
|
song = @mpd.current_song
|
924
924
|
|
925
925
|
assert_equal 'Flying Into A Star', song.title
|
926
|
-
|
926
|
+
|
927
927
|
status = @mpd.status
|
928
928
|
|
929
929
|
assert_equal '200:585', status['time']
|
@@ -940,7 +940,7 @@ class MPDTester < Test::Unit::TestCase
|
|
940
940
|
assert @mpd.play
|
941
941
|
|
942
942
|
sleep 2
|
943
|
-
|
943
|
+
|
944
944
|
assert @mpd.pause = true
|
945
945
|
|
946
946
|
sleep 2
|
@@ -952,7 +952,7 @@ class MPDTester < Test::Unit::TestCase
|
|
952
952
|
song = @mpd.current_song
|
953
953
|
|
954
954
|
assert_equal 'Flying Into A Star', song.title
|
955
|
-
|
955
|
+
|
956
956
|
status = @mpd.status
|
957
957
|
|
958
958
|
assert_equal '200:585', status['time']
|
@@ -963,7 +963,7 @@ class MPDTester < Test::Unit::TestCase
|
|
963
963
|
|
964
964
|
def test_volume
|
965
965
|
@mpd.connect
|
966
|
-
|
966
|
+
|
967
967
|
vol = @mpd.volume
|
968
968
|
|
969
969
|
@mpd.volume = 30
|
@@ -1121,7 +1121,7 @@ class MPDTester < Test::Unit::TestCase
|
|
1121
1121
|
assert_equal 1, ret
|
1122
1122
|
|
1123
1123
|
status = @mpd.status
|
1124
|
-
|
1124
|
+
|
1125
1125
|
assert_equal '1', status['updating_db']
|
1126
1126
|
|
1127
1127
|
status = @mpd.status
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-mpd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.8
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-01-
|
12
|
+
date: 2013-01-27 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: A powerful, modern and feature complete library for the Music Player
|
15
15
|
Daemon.
|