mpd_client 0.0.6 → 0.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.
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "mpd_client"
4
+ require 'bundler/setup'
5
+ require 'mpd_client'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "mpd_client"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  gem 'mpd_client', path: '../'
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler'
4
+ Bundler.setup :default
5
+
6
+ require 'logger'
7
+ require 'mpd_client'
8
+
9
+ client = MPD::Client.new
10
+
11
+ client = MPD::Client.new
12
+ client.log = Logger.new($stderr)
13
+
14
+ client.connect('localhost', 6600)
15
+
16
+ # Lists all changed systems:
17
+ # database, update, stored_playlist, playlist, player, mixer, output, options, sticker, subscription, message
18
+ #
19
+ subsystems = %w[player playlist]
20
+
21
+ loop do
22
+ resp = client.idle(*subsystems)
23
+ puts resp
24
+ end
25
+
26
+ client.close
27
+ client.disconnect
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  Bundler.setup :default
3
5
 
@@ -5,16 +7,16 @@ require 'pp'
5
7
  require 'logger'
6
8
  require 'mpd_client'
7
9
 
8
- MPDClient.log = Logger.new($stderr)
10
+ MPD::Client.log = Logger.new($stderr)
9
11
 
10
- client = MPDClient.new
12
+ client = MPD::Client.new
11
13
  client.connect('localhost', 6600)
12
14
 
13
15
  # delete all songs from the current playlist, except for the firts ten
14
- client.delete([10,])
16
+ client.delete([10])
15
17
 
16
18
  # move the first three songs after the fifth number in the playlist
17
19
  client.move([0, 3], 5)
18
20
 
19
21
  # print songs form 5 to 10
20
- client.playlistinfo([5, 10]).each{ |s| puts "#{s['artist']} - #{s['title']}"}
22
+ client.playlistinfo([5, 10]).each { |s| puts "#{s['artist']} - #{s['title']}" }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  Bundler.setup :default
3
5
 
@@ -5,9 +7,9 @@ require 'pp'
5
7
  require 'logger'
6
8
  require 'mpd_client'
7
9
 
8
- MPDClient.log = Logger.new($stderr)
10
+ MPD::Client.log = Logger.new($stderr)
9
11
 
10
- client = MPDClient.new
12
+ client = MPD::Client.new
11
13
  client.connect('localhost', 6600)
12
14
 
13
15
  # Get id of the first song in the playllist
@@ -16,7 +18,7 @@ pp "#{song['artist']} - #{song['title']}"
16
18
  song_id = song['id']
17
19
 
18
20
  # Specifies the portion of the song that shall be played
19
- client.rangeid(song_id, [60,70])
21
+ client.rangeid(song_id, [60, 70])
20
22
 
21
23
  # Play the playlist at song 1
22
24
  client.play(1)
@@ -1,24 +1,26 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  Bundler.setup :default
3
5
 
4
6
  require 'logger'
5
7
  require 'mpd_client'
6
8
 
7
- # MPDClient.log = Logger.new($stderr)
9
+ # MPD::Client.log = Logger.new($stderr)
8
10
 
9
- client = MPDClient.new
11
+ client = MPD::Client.new
10
12
 
11
13
  type = ARGV[0]
12
14
  what = ARGV[1]
13
15
 
14
- client = MPDClient.new
16
+ client = MPD::Client.new
15
17
  client.log = Logger.new($stderr)
16
18
 
17
19
  # Connecting to the server
18
20
  client.connect('localhost', 6600)
19
21
 
20
22
  puts "MPD version: #{client.mpd_version}"
21
- puts "mpd_client version: #{MPDClient::VERSION}"
23
+ puts "mpd_client version: #{MPD::Client::VERSION}"
22
24
 
23
25
  client.stop
24
26
  client.clear # clear the current playlist
@@ -32,7 +34,7 @@ songs = client.search(type, what)
32
34
 
33
35
  client.command_list_ok_begin # start a command list to speed up operations
34
36
  songs.each do |song|
35
- client.add(song['file']) if song.has_key?('file')
37
+ client.add(song['file']) if song.key?('file')
36
38
  end
37
39
  client.command_list_end
38
40
 
@@ -1,26 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler'
2
4
  Bundler.setup :default
3
5
 
4
6
  require 'logger'
5
7
  require 'mpd_client'
6
8
 
7
- MPDClient.log = Logger.new($stderr)
9
+ MPD::Client.log = Logger.new($stderr)
8
10
 
9
11
  # Stickers
10
12
  # http://www.musicpd.org/doc/protocol/ch03s07.html
11
13
 
12
- client = MPDClient.new
14
+ client = MPD::Client.new
13
15
 
14
16
  # Connecting to the server
15
17
  client.connect('/run/mpd/socket')
16
18
 
17
19
  puts "MPD version: #{client.mpd_version}"
18
- puts "mpd_client version: #{MPDClient::VERSION}"
20
+ puts "mpd_client version: #{MPD::Client::VERSION}"
19
21
 
20
- uri = "world/j/Jane Air/2012.Иллюзия полёта/12. Любить любовь.ogg"
22
+ uri = 'world/j/Jane Air/2012.Иллюзия полёта/12. Любить любовь.ogg'
21
23
 
22
24
  # sticker set {TYPE} {URI} {NAME} {VALUE}
23
- # Adds a sticker value to the specified object. If a sticker item with that name already exists, it is replaced.
25
+ # Adds a sticker value to the specified object.
26
+ # If a sticker item with that name already exists, it is replaced.
24
27
  #
25
28
  client.sticker_set('song', uri, 'rating', '1')
26
29
 
@@ -41,7 +44,8 @@ puts client.sticker_list('song', uri)
41
44
  puts client.sticker_find('song', '/', 'rating')
42
45
 
43
46
  # sticker delete {TYPE} {URI} [NAME]
44
- # Deletes a sticker value from the specified object. If you do not specify a sticker name, all sticker values are deleted.
47
+ # Deletes a sticker value from the specified object.
48
+ # If you do not specify a sticker name, all sticker values are deleted.
45
49
  #
46
50
  client.sticker_delete('song', uri, 'rating')
47
51
 
@@ -1,423 +1,466 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'socket'
2
- require "mpd_client/version"
3
-
4
- HELLO_PREFIX = "OK MPD "
5
- ERROR_PREFIX = "ACK "
6
- SUCCESS = "OK"
7
- NEXT = "list_OK"
8
-
9
- # MPD changelog: http://git.musicpd.org/cgit/master/mpd.git/plain/NEWS
10
- # http://www.musicpd.org/doc/protocol/command_reference.html
11
- # http://git.musicpd.org/cgit/cirrus/mpd.git/plain/doc/protocol.xml
12
- #
13
- COMMANDS = {
14
- # Status Commands
15
- "clearerror" => "fetch_nothing",
16
- "currentsong" => "fetch_object",
17
- "idle" => "fetch_list",
18
- "noidle" => "",
19
- "status" => "fetch_object",
20
- "stats" => "fetch_object",
21
- # Playback Option Commands
22
- "consume" => "fetch_nothing",
23
- "crossfade" => "fetch_nothing",
24
- "mixrampdb" => "fetch_nothing",
25
- "mixrampdelay" => "fetch_nothing",
26
- "random" => "fetch_nothing",
27
- "repeat" => "fetch_nothing",
28
- "setvol" => "fetch_nothing",
29
- "single" => "fetch_nothing",
30
- "replay_gain_mode" => "fetch_nothing",
31
- "replay_gain_status" => "fetch_item",
32
- "volume" => "fetch_nothing",
33
- # Playback Control Commands
34
- "next" => "fetch_nothing",
35
- "pause" => "fetch_nothing",
36
- "play" => "fetch_nothing",
37
- "playid" => "fetch_nothing",
38
- "previous" => "fetch_nothing",
39
- "seek" => "fetch_nothing",
40
- "seekid" => "fetch_nothing",
41
- "seekcur" => "fetch_nothing",
42
- "stop" => "fetch_nothing",
43
- # Playlist Commands
44
- "add" => "fetch_nothing",
45
- "addid" => "fetch_item",
46
- "addtagid" => "fetch_nothing",
47
- "cleartagid" => "fetch_nothing",
48
- "clear" => "fetch_nothing",
49
- "delete" => "fetch_nothing",
50
- "deleteid" => "fetch_nothing",
51
- "move" => "fetch_nothing",
52
- "moveid" => "fetch_nothing",
53
- "playlist" => "fetch_playlist",
54
- "playlistfind" => "fetch_songs",
55
- "playlistid" => "fetch_songs",
56
- "playlistinfo" => "fetch_songs",
57
- "playlistsearch" => "fetch_songs",
58
- "plchanges" => "fetch_songs",
59
- "plchangesposid" => "fetch_changes",
60
- "prio" => "fetch_nothing",
61
- "prioid" => "fetch_nothing",
62
- "rangeid" => "fetch_nothing",
63
- "shuffle" => "fetch_nothing",
64
- "swap" => "fetch_nothing",
65
- "swapid" => "fetch_nothing",
66
- # Stored Playlist Commands
67
- "listplaylist" => "fetch_list",
68
- "listplaylistinfo" => "fetch_songs",
69
- "listplaylists" => "fetch_playlists",
70
- "load" => "fetch_nothing",
71
- "playlistadd" => "fetch_nothing",
72
- "playlistclear" => "fetch_nothing",
73
- "playlistdelete" => "fetch_nothing",
74
- "playlistmove" => "fetch_nothing",
75
- "rename" => "fetch_nothing",
76
- "rm" => "fetch_nothing",
77
- "save" => "fetch_nothing",
78
- # Database Commands
79
- "count" => "fetch_object",
80
- "find" => "fetch_songs",
81
- "findadd" => "fetch_nothing",
82
- "list" => "fetch_list",
83
- "listall" => "fetch_database",
84
- "listallinfo" => "fetch_database",
85
- "listfiles" => "fetch_database",
86
- "lsinfo" => "fetch_database",
87
- "search" => "fetch_songs",
88
- "searchadd" => "fetch_nothing",
89
- "searchaddp1" => "fetch_nothing",
90
- "update" => "fetch_item",
91
- "rescan" => "fetch_item",
92
- "readcomments" => "fetch_object",
93
- # Mounts and neighbors
94
- "mount" => "fetch_nothing",
95
- "unmount" => "fetch_nothing",
96
- "listmounts" => "fetch_mounts",
97
- "listneighbors" => "fetch_neighbors",
98
- # Sticker Commands
99
- "sticker get" => "fetch_sticker",
100
- "sticker set" => "fetch_nothing",
101
- "sticker delete" => "fetch_nothing",
102
- "sticker list" => "fetch_stickers",
103
- "sticker find" => "fetch_songs",
104
- # Connection Commands
105
- "close" => "",
106
- "kill" => "",
107
- "password" => "fetch_nothing",
108
- "ping" => "fetch_nothing",
109
- # Audio Output Commands
110
- "disableoutput" => "fetch_nothing",
111
- "enableoutput" => "fetch_nothing",
112
- "outputs" => "fetch_outputs",
113
- "toggleoutput" => "fetch_nothing",
114
- # Reflection Commands
115
- "config" => "fetch_item",
116
- "commands" => "fetch_list",
117
- "notcommands" => "fetch_list",
118
- "tagtypes" => "fetch_list",
119
- "urlhandlers" => "fetch_list",
120
- "decoders" => "fetch_plugins",
121
- # Client To Client
122
- "subscribe" => "fetch_nothing",
123
- "unsubscribe" => "fetch_nothing",
124
- "channels" => "fetch_list",
125
- "readmessages" => "fetch_messages",
126
- "sendmessage" => "fetch_nothing"
127
- }
128
-
129
- # The MPDClient library is used for interactions with a MPD.
130
- #
131
- # == Example
132
- #
133
- # require 'mpd_client'
134
- # require 'logger'
135
- #
136
- # client = MPDClient.new
137
- # client.log = Logger.new($stderr)
138
- # client.connect('/var/run/mpd/socket')
139
- #
140
- class MPDClient
141
- attr_reader :mpd_version
142
-
143
- class << self
144
- # Default logger for all MPDClient instances
145
- #
146
- # MPDClient.log = Logger.new($stderr)
147
- #
148
- attr_accessor :log
149
-
150
- def add_command(name, retval)
151
- escaped_name = name.gsub(' ', '_')
152
- define_method escaped_name.to_sym do |*args|
153
- execute(name, *args, retval)
4
+ require 'mpd_client/version'
5
+
6
+ module MPD
7
+ HELLO_PREFIX = 'OK MPD '
8
+ ERROR_PREFIX = 'ACK '
9
+ SUCCESS = 'OK'
10
+ NEXT = 'list_OK'
11
+
12
+ # MPD changelog: http://git.musicpd.org/cgit/master/mpd.git/plain/NEWS
13
+ # http://www.musicpd.org/doc/protocol/command_reference.html
14
+ # http://git.musicpd.org/cgit/cirrus/mpd.git/plain/doc/protocol.xml
15
+ COMMANDS = {
16
+ # Status Commands
17
+ 'clearerror' => 'fetch_nothing',
18
+ 'currentsong' => 'fetch_object',
19
+ 'idle' => 'fetch_list',
20
+ 'noidle' => '',
21
+ 'status' => 'fetch_object',
22
+ 'stats' => 'fetch_object',
23
+ # Playback Option Commands
24
+ 'consume' => 'fetch_nothing',
25
+ 'crossfade' => 'fetch_nothing',
26
+ 'mixrampdb' => 'fetch_nothing',
27
+ 'mixrampdelay' => 'fetch_nothing',
28
+ 'random' => 'fetch_nothing',
29
+ 'repeat' => 'fetch_nothing',
30
+ 'setvol' => 'fetch_nothing',
31
+ 'single' => 'fetch_nothing',
32
+ 'replay_gain_mode' => 'fetch_nothing',
33
+ 'replay_gain_status' => 'fetch_item',
34
+ 'volume' => 'fetch_nothing',
35
+ # Playback Control Commands
36
+ 'next' => 'fetch_nothing',
37
+ 'pause' => 'fetch_nothing',
38
+ 'play' => 'fetch_nothing',
39
+ 'playid' => 'fetch_nothing',
40
+ 'previous' => 'fetch_nothing',
41
+ 'seek' => 'fetch_nothing',
42
+ 'seekid' => 'fetch_nothing',
43
+ 'seekcur' => 'fetch_nothing',
44
+ 'stop' => 'fetch_nothing',
45
+ # Playlist Commands
46
+ 'add' => 'fetch_nothing',
47
+ 'addid' => 'fetch_item',
48
+ 'addtagid' => 'fetch_nothing',
49
+ 'cleartagid' => 'fetch_nothing',
50
+ 'clear' => 'fetch_nothing',
51
+ 'delete' => 'fetch_nothing',
52
+ 'deleteid' => 'fetch_nothing',
53
+ 'move' => 'fetch_nothing',
54
+ 'moveid' => 'fetch_nothing',
55
+ 'playlist' => 'fetch_playlist',
56
+ 'playlistfind' => 'fetch_songs',
57
+ 'playlistid' => 'fetch_songs',
58
+ 'playlistinfo' => 'fetch_songs',
59
+ 'playlistsearch' => 'fetch_songs',
60
+ 'plchanges' => 'fetch_songs',
61
+ 'plchangesposid' => 'fetch_changes',
62
+ 'prio' => 'fetch_nothing',
63
+ 'prioid' => 'fetch_nothing',
64
+ 'rangeid' => 'fetch_nothing',
65
+ 'shuffle' => 'fetch_nothing',
66
+ 'swap' => 'fetch_nothing',
67
+ 'swapid' => 'fetch_nothing',
68
+ # Stored Playlist Commands
69
+ 'listplaylist' => 'fetch_list',
70
+ 'listplaylistinfo' => 'fetch_songs',
71
+ 'listplaylists' => 'fetch_playlists',
72
+ 'load' => 'fetch_nothing',
73
+ 'playlistadd' => 'fetch_nothing',
74
+ 'playlistclear' => 'fetch_nothing',
75
+ 'playlistdelete' => 'fetch_nothing',
76
+ 'playlistmove' => 'fetch_nothing',
77
+ 'rename' => 'fetch_nothing',
78
+ 'rm' => 'fetch_nothing',
79
+ 'save' => 'fetch_nothing',
80
+ # Database Commands
81
+ 'count' => 'fetch_object',
82
+ 'find' => 'fetch_songs',
83
+ 'findadd' => 'fetch_nothing',
84
+ 'list' => 'fetch_list',
85
+ 'listall' => 'fetch_database',
86
+ 'listallinfo' => 'fetch_database',
87
+ 'listfiles' => 'fetch_database',
88
+ 'lsinfo' => 'fetch_database',
89
+ 'search' => 'fetch_songs',
90
+ 'searchadd' => 'fetch_nothing',
91
+ 'searchaddp1' => 'fetch_nothing',
92
+ 'update' => 'fetch_item',
93
+ 'rescan' => 'fetch_item',
94
+ 'readcomments' => 'fetch_object',
95
+ # Mounts and neighbors
96
+ 'mount' => 'fetch_nothing',
97
+ 'unmount' => 'fetch_nothing',
98
+ 'listmounts' => 'fetch_mounts',
99
+ 'listneighbors' => 'fetch_neighbors',
100
+ # Sticker Commands
101
+ 'sticker get' => 'fetch_sticker',
102
+ 'sticker set' => 'fetch_nothing',
103
+ 'sticker delete' => 'fetch_nothing',
104
+ 'sticker list' => 'fetch_stickers',
105
+ 'sticker find' => 'fetch_songs',
106
+ # Connection Commands
107
+ 'close' => '',
108
+ 'kill' => '',
109
+ 'password' => 'fetch_nothing',
110
+ 'ping' => 'fetch_nothing',
111
+ # Audio Output Commands
112
+ 'disableoutput' => 'fetch_nothing',
113
+ 'enableoutput' => 'fetch_nothing',
114
+ 'outputs' => 'fetch_outputs',
115
+ 'toggleoutput' => 'fetch_nothing',
116
+ # Reflection Commands
117
+ 'config' => 'fetch_item',
118
+ 'commands' => 'fetch_list',
119
+ 'notcommands' => 'fetch_list',
120
+ 'tagtypes' => 'fetch_list',
121
+ 'urlhandlers' => 'fetch_list',
122
+ 'decoders' => 'fetch_plugins',
123
+ # Client To Client
124
+ 'subscribe' => 'fetch_nothing',
125
+ 'unsubscribe' => 'fetch_nothing',
126
+ 'channels' => 'fetch_list',
127
+ 'readmessages' => 'fetch_messages',
128
+ 'sendmessage' => 'fetch_nothing'
129
+ }.freeze
130
+
131
+ # The `MPD::Client` is used for interactions with a MPD server.
132
+ #
133
+ # Example:
134
+ #
135
+ # ```ruby
136
+ # require 'mpd_client'
137
+ # require 'logger'
138
+ #
139
+ # client = MPD::Client.new
140
+ # client.log = Logger.new($stderr)
141
+ # client.connect('/var/run/mpd/socket')
142
+ # ```
143
+ class Client
144
+ attr_reader :mpd_version
145
+
146
+ class << self
147
+ # Default logger for all `MPD::Client`` instances
148
+ #
149
+ # ```ruby
150
+ # MPD::Client.log = Logger.new($stderr)
151
+ # ```
152
+ attr_accessor :log
153
+
154
+ def connect(host = 'localhost', port = 6600)
155
+ client = MPD::Client.new
156
+ client.connect(host, port)
157
+
158
+ client
159
+ end
160
+
161
+ def add_command(name, retval)
162
+ escaped_name = name.tr(' ', '_')
163
+ define_method escaped_name.to_sym do |*args|
164
+ ensure_connected
165
+
166
+ execute(name, *args, retval)
167
+ end
168
+ end
169
+
170
+ def remove_command(name)
171
+ raise "Can't remove not existent '#{name}' command" unless method_defined? name.to_sym
172
+ remove_method name.to_sym
154
173
  end
155
174
  end
156
175
 
157
- def remove_command(name)
158
- raise "Can't remove not existent '#{name}' command" unless method_defined? name.to_sym
159
- remove_method name.to_sym
176
+ def initialize
177
+ @mutex = Mutex.new
178
+ reset
160
179
  end
161
- end
162
180
 
163
- def initialize
164
- @mutex = Mutex.new
165
- reset
166
- end
181
+ def connect(host = 'localhost', port = 6600)
182
+ @host = host
183
+ @port = port
167
184
 
168
- def connect(host = 'localhost', port = 6600)
169
- @host = host
170
- @port = port
171
- reconnect
172
- end
185
+ reconnect
186
+ end
187
+
188
+ def reconnect
189
+ log&.info("MPD (re)connect #{@host}, #{@port}")
190
+
191
+ @socket = if @host.start_with?('/')
192
+ UNIXSocket.new(@host)
193
+ else
194
+ TCPSocket.new(@host, @port)
195
+ end
173
196
 
174
- def reconnect
175
- log.info("MPD (re)connect #{@host}, #{@port}") if log
176
- if @host.start_with?('/')
177
- @socket = UNIXSocket.new(@host)
178
- hello
179
- else
180
- @socket = TCPSocket.new(@host, @port)
181
197
  hello
198
+ @connected = true
182
199
  end
183
- end
184
200
 
185
- def disconnect
186
- log.info("MPD disconnect") if log
187
- @socket.close
188
- reset
189
- end
201
+ def disconnect
202
+ log&.info('MPD disconnect')
203
+ @socket.close
204
+ reset
205
+ end
190
206
 
191
- # http://www.musicpd.org/doc/protocol/ch01s04.html
192
- def command_list_ok_begin
193
- raise "Already in command list" unless @command_list.nil?
194
- write_command('command_list_ok_begin')
195
- @command_list = []
196
- end
207
+ def reset
208
+ @mpd_version = nil
209
+ @command_list = nil
210
+ @socket = nil
211
+ @log = nil
212
+ @connected = false
213
+ end
214
+
215
+ def connected?
216
+ @connected
217
+ end
197
218
 
198
- def command_list_end
199
- raise "Not in command list" if @command_list.nil?
200
- write_command('command_list_end')
219
+ # http://www.musicpd.org/doc/protocol/ch01s04.html
220
+ def command_list_ok_begin
221
+ raise 'Already in command list' unless @command_list.nil?
222
+ write_command('command_list_ok_begin')
223
+ @command_list = []
224
+ end
201
225
 
202
- return fetch_command_list
203
- end
226
+ def command_list_end
227
+ raise 'Not in command list' if @command_list.nil?
228
+ write_command('command_list_end')
204
229
 
205
- # The current logger. If no logger has been set MPDClient.log is used
206
- #
207
- def log
208
- @log || MPDClient.log
209
- end
230
+ fetch_command_list
231
+ end
210
232
 
211
- # Sets the +logger+ used by this instance of MPDClient
212
- #
213
- def log= logger
214
- @log = logger
215
- end
233
+ # The current logger. If no logger has been set MPD::Client.log is used
234
+ def log
235
+ @log || MPD::Client.log
236
+ end
216
237
 
217
- private
238
+ # Sets the +logger+ used by this instance of MPD::Client
239
+ attr_writer :log
218
240
 
219
- def execute(command, *args, retval)
220
- @mutex.synchronize do
221
- if !@command_list.nil?
222
- write_command(command, *args)
223
- @command_list << retval
224
- else
241
+ private
242
+
243
+ def ensure_connected
244
+ raise 'Please connect to MPD server' unless connected?
245
+ end
246
+
247
+ def execute(command, *args, retval)
248
+ @mutex.synchronize do
225
249
  write_command(command, *args)
226
- eval retval
250
+
251
+ if !@command_list.nil?
252
+ @command_list << retval
253
+ else
254
+ eval retval
255
+ end
227
256
  end
228
257
  end
229
- end
230
258
 
231
- def write_line(line)
232
- begin
233
- @socket.puts line
234
- rescue Errno::EPIPE
235
- reconnect
236
- @socket.puts line
259
+ def write_line(line)
260
+ begin
261
+ @socket.puts line
262
+ rescue Errno::EPIPE
263
+ reconnect
264
+ @socket.puts line
265
+ end
266
+ @socket.flush
237
267
  end
238
- @socket.flush
239
- end
240
268
 
241
- def write_command(command, *args)
242
- parts = [command]
243
- args.each do |arg|
244
- if arg.kind_of?(Array)
245
- parts << (arg.size == 1 ? "\"#{arg[0].to_i}:\"" : "\"#{arg[0].to_i}:#{arg[1].to_i}\"")
246
- else
247
- parts << "\"#{escape(arg)}\""
269
+ def write_command(command, *args)
270
+ parts = [command]
271
+ args.each do |arg|
272
+ line = if arg.is_a?(Array)
273
+ arg.size == 1 ? "\"#{arg[0].to_i}:\"" : "\"#{arg[0].to_i}:#{arg[1].to_i}\""
274
+ else
275
+ "\"#{escape(arg)}\""
276
+ end
277
+
278
+ parts << line
248
279
  end
280
+ # log.debug("Calling MPD: #{command}#{args}") if log
281
+ log&.debug("Calling MPD: #{parts.join(' ')}")
282
+ write_line(parts.join(' '))
249
283
  end
250
- #log.debug("Calling MPD: #{command}#{args}") if log
251
- log.debug("Calling MPD: #{parts.join(' ')}") if log
252
- write_line(parts.join(' '))
253
- end
254
284
 
255
- def read_line
256
- line = @socket.gets.force_encoding('utf-8')
257
- raise "Connection lost while reading line" unless line.end_with?("\n")
258
- line.chomp!
259
- if line.start_with?(ERROR_PREFIX)
260
- error = line[/#{ERROR_PREFIX}(.*)/, 1].strip
261
- raise error
262
- end
285
+ def read_line
286
+ line = @socket.gets.force_encoding('utf-8')
287
+ raise 'Connection lost while reading line' unless line.end_with?("\n")
288
+ line.chomp!
289
+ if line.start_with?(ERROR_PREFIX)
290
+ error = line[/#{ERROR_PREFIX}(.*)/, 1].strip
291
+ raise error
292
+ end
263
293
 
264
- if !@command_list.nil?
265
- return if line == NEXT
266
- raise "Got unexpected '#{SUCCESS}'" if line == SUCCESS
267
- elsif line == SUCCESS
268
- return
269
- end
294
+ if !@command_list.nil?
295
+ return if line == NEXT
296
+ raise "Got unexpected '#{SUCCESS}'" if line == SUCCESS
297
+ elsif line == SUCCESS
298
+ return
299
+ end
270
300
 
271
- return line
272
- end
301
+ line
302
+ end
273
303
 
274
- def read_pair(separator)
275
- line = read_line
276
- return if line.nil?
277
- pair = line.split(separator, 2)
278
- raise "Could now parse pair: '#{line}'" if pair.size < 2
304
+ def read_pair(separator)
305
+ line = read_line
306
+ return if line.nil?
307
+ pair = line.split(separator, 2)
308
+ raise "Could now parse pair: '#{line}'" if pair.size < 2
279
309
 
280
- return pair #Array
281
- end
310
+ pair # Array
311
+ end
282
312
 
283
- def read_pairs(separator = ': ')
284
- result = []
285
- pair = read_pair(separator)
286
- while pair
287
- result << pair
313
+ def read_pairs(separator = ': ')
314
+ result = []
288
315
  pair = read_pair(separator)
289
- end
316
+ while pair
317
+ result << pair
318
+ pair = read_pair(separator)
319
+ end
290
320
 
291
- return result
292
- end
321
+ result
322
+ end
293
323
 
294
- def fetch_item
295
- pairs = read_pairs
296
- return nil if pairs.size != 1
297
- return pairs[0][1]
298
- end
324
+ def fetch_item
325
+ pairs = read_pairs
326
+ return nil if pairs.size != 1
299
327
 
300
- def fetch_nothing
301
- line = read_line
302
- raise "Got unexpected return value: #{line}" unless line.nil?
303
- end
328
+ pairs[0][1]
329
+ end
304
330
 
305
- def fetch_list
306
- result = []
307
- seen = nil
308
- read_pairs.each do |key, value|
309
- if key != seen
310
- if seen != nil
311
- raise "Expected key '#{seen}', got '#{key}'"
312
- end
313
- seen = key
314
- end
315
- result << value
331
+ def fetch_nothing
332
+ line = read_line
333
+ raise "Got unexpected value: #{line}" unless line.nil?
316
334
  end
317
335
 
318
- return result
319
- end
336
+ def fetch_list
337
+ result = []
338
+ seen = nil
320
339
 
321
- def fetch_objects(delimeters = [])
322
- result = []
323
- obj = {}
324
- read_pairs.each do |key, value|
325
- key = key.downcase
326
- if delimeters.include?(key)
327
- result << obj unless obj.empty?
328
- obj = {}
329
- elsif obj.include?(key)
330
- obj[key] << value
340
+ read_pairs.each do |key, value|
341
+ if key != seen
342
+ raise "Expected key '#{seen}', got '#{key}'" unless seen.nil?
343
+ seen = key
344
+ end
345
+
346
+ result << value
331
347
  end
332
- obj[key] = value
333
- end
334
348
 
335
- result << obj unless obj.empty?
349
+ result
350
+ end
336
351
 
337
- return result
338
- end
352
+ def fetch_objects(delimeters = [])
353
+ result = []
354
+ obj = {}
355
+ read_pairs.each do |key, value|
356
+ key = key.downcase
357
+ if delimeters.include?(key)
358
+ result << obj unless obj.empty?
359
+ obj = {}
360
+ elsif obj.include?(key)
361
+ obj[key] << value
362
+ end
363
+ obj[key] = value
364
+ end
339
365
 
340
- def fetch_object
341
- objs = fetch_objects
342
- return objs ? objs[0] : {}
343
- end
366
+ result << obj unless obj.empty?
344
367
 
345
- def fetch_changes; fetch_objects(['cpos']); end
368
+ result
369
+ end
346
370
 
347
- def fetch_songs; fetch_objects(['file']); end
371
+ def fetch_object
372
+ objs = fetch_objects
348
373
 
349
- def fetch_mounts; fetch_objects(['mount']); end
374
+ objs ? objs[0] : {}
375
+ end
350
376
 
351
- def fetch_neighbors; fetch_objects(['neighbor']); end
377
+ def fetch_changes
378
+ fetch_objects(['cpos'])
379
+ end
352
380
 
353
- def fetch_messages; fetch_objects('channel'); end
381
+ def fetch_songs
382
+ fetch_objects(['file'])
383
+ end
354
384
 
355
- def fetch_outputs; fetch_objects(['outputid']); end
385
+ def fetch_mounts
386
+ fetch_objects(['mount'])
387
+ end
356
388
 
357
- def fetch_plugins; fetch_objects(['plugin']); end
389
+ def fetch_neighbors
390
+ fetch_objects(['neighbor'])
391
+ end
358
392
 
359
- def fetch_database; fetch_objects(['file', 'directory', 'playlist']); end
393
+ def fetch_messages
394
+ fetch_objects('channel')
395
+ end
360
396
 
361
- def fetch_playlists; fetch_objects(['playlist']); end
397
+ def fetch_outputs
398
+ fetch_objects(['outputid'])
399
+ end
362
400
 
363
- def fetch_playlist
364
- result = []
365
- read_pairs(':').each do |key, value|
366
- result << value
401
+ def fetch_plugins
402
+ fetch_objects(['plugin'])
367
403
  end
368
404
 
369
- return result
370
- end
405
+ def fetch_database
406
+ fetch_objects(%w[file directory playlist])
407
+ end
371
408
 
372
- def fetch_stickers
373
- result = []
374
- read_pairs.each do |key, sticker|
375
- value = sticker.split('=', 2)
376
- raise "Could now parse sticker: #{sticker}" if value.size < 2
377
- result << Hash[*value]
409
+ def fetch_playlists
410
+ fetch_objects(['playlist'])
378
411
  end
379
412
 
380
- return result
381
- end
413
+ def fetch_playlist
414
+ result = []
415
+ read_pairs(':').each do |_key, value|
416
+ result << value
417
+ end
382
418
 
383
- def fetch_sticker; fetch_stickers[0]; end
419
+ result
420
+ end
384
421
 
385
- def fetch_command_list
386
- result = []
387
- begin
388
- @command_list.each do |retval|
389
- result << (eval retval)
422
+ def fetch_stickers
423
+ result = []
424
+ read_pairs.each do |_key, sticker|
425
+ value = sticker.split('=', 2)
426
+ raise "Could now parse sticker: #{sticker}" if value.size < 2
427
+ result << Hash[*value]
390
428
  end
391
- ensure
392
- @command_list = nil
429
+
430
+ result
393
431
  end
394
432
 
395
- return result
396
- end
433
+ def fetch_sticker
434
+ fetch_stickers[0]
435
+ end
397
436
 
437
+ def fetch_command_list
438
+ result = []
439
+ begin
440
+ @command_list.each do |retval|
441
+ result << (eval retval)
442
+ end
443
+ ensure
444
+ @command_list = nil
445
+ end
398
446
 
399
- def hello
400
- line = @socket.gets
401
- raise "Connection lost while reading MPD hello" unless line.end_with?("\n")
402
- line.chomp!
403
- raise "Got invalid MPD hello: #{line}" unless line.start_with?(HELLO_PREFIX)
404
- @mpd_version = line[/#{HELLO_PREFIX}(.*)/, 1]
405
- end
447
+ result
448
+ end
406
449
 
407
- def reset
408
- @mpd_version = nil
409
- @command_list = nil
410
- @socket = nil
411
- @log = nil
412
- end
450
+ def hello
451
+ line = @socket.gets
452
+ raise 'Connection lost while reading MPD hello' unless line.end_with?("\n")
453
+ line.chomp!
454
+ raise "Got invalid MPD hello: #{line}" unless line.start_with?(HELLO_PREFIX)
455
+ @mpd_version = line[/#{HELLO_PREFIX}(.*)/, 1]
456
+ end
413
457
 
414
- def escape(text)
415
- text.to_s.gsub("\\", "\\\\").gsub('"', '\\"')
458
+ def escape(text)
459
+ text.to_s.gsub('\\', '\\\\').gsub('"', '\\"')
460
+ end
416
461
  end
417
-
418
462
  end
419
463
 
420
- COMMANDS.each_pair do |name, callback|
421
- MPDClient.add_command(name, callback)
464
+ MPD::COMMANDS.each_pair do |name, callback|
465
+ MPD::Client.add_command(name, callback)
422
466
  end
423
-