Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 410 lines (357 sloc) 14.373 kB
451513f mpd.py: adding one line description at top of file
J. Alexander Treuman authored
1 # Python MPD client library
96c1cf2 adding LICENSE.txt and a copyright notice to mpd.py
J. Alexander Treuman authored
2 # Copyright (C) 2008 J. Alexander Treuman <jat@spatialrift.net>
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
9a76b6e initial commit
J. Alexander Treuman authored
17 import socket
18
19
20 HELLO_PREFIX = "OK MPD "
21 ERROR_PREFIX = "ACK "
22 SUCCESS = "OK"
e5e24e0 adding command_list support
J. Alexander Treuman authored
23 NEXT = "list_OK"
9a76b6e initial commit
J. Alexander Treuman authored
24
25
26 class MPDError(Exception):
27 pass
28
ecdbc2e mpd.py: raise ConnectionError on EOF
J. Alexander Treuman authored
29 class ConnectionError(MPDError):
30 pass
31
9a76b6e initial commit
J. Alexander Treuman authored
32 class ProtocolError(MPDError):
33 pass
34
35 class CommandError(MPDError):
36 pass
37
e5e24e0 adding command_list support
J. Alexander Treuman authored
38 class CommandListError(MPDError):
39 pass
40
5c84adf mpd.py: adding support for asynchronous commands
J. Alexander Treuman authored
41 class PendingCommandError(MPDError):
42 pass
43
9a76b6e initial commit
J. Alexander Treuman authored
44
11ad737 mpd.py: raise ConnectionError when trying to use an unconnected socket
J. Alexander Treuman authored
45 class _NotConnected(object):
46 def __getattr__(self, attr):
47 return self._dummy
48
49 def _dummy(*args):
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
50 raise ConnectionError("Not connected")
11ad737 mpd.py: raise ConnectionError when trying to use an unconnected socket
J. Alexander Treuman authored
51
9a76b6e initial commit
J. Alexander Treuman authored
52 class MPDClient(object):
53 def __init__(self):
54 self.iterate = False
55 self._reset()
56 self._commands = {
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
57 # Status Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
58 "clearerror": self._fetch_nothing,
59 "currentsong": self._fetch_object,
60 "idle": self._fetch_list,
2e4bfd2 adding idle and noidle commands
J. Alexander Treuman authored
61 "noidle": None,
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
62 "status": self._fetch_object,
63 "stats": self._fetch_object,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
64 # Playback Option Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
65 "consume": self._fetch_nothing,
66 "crossfade": self._fetch_nothing,
67 "random": self._fetch_nothing,
68 "repeat": self._fetch_nothing,
69 "setvol": self._fetch_nothing,
70 "single": self._fetch_nothing,
71 "volume": self._fetch_nothing,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
72 # Playback Control Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
73 "next": self._fetch_nothing,
74 "pause": self._fetch_nothing,
75 "play": self._fetch_nothing,
76 "playid": self._fetch_nothing,
77 "previous": self._fetch_nothing,
78 "seek": self._fetch_nothing,
79 "seekid": self._fetch_nothing,
80 "stop": self._fetch_nothing,
9a76b6e initial commit
J. Alexander Treuman authored
81 # Playlist Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
82 "add": self._fetch_nothing,
83 "addid": self._fetch_item,
84 "clear": self._fetch_nothing,
85 "delete": self._fetch_nothing,
86 "deleteid": self._fetch_nothing,
87 "move": self._fetch_nothing,
88 "moveid": self._fetch_nothing,
89 "playlist": self._fetch_playlist,
90 "playlistfind": self._fetch_songs,
91 "playlistid": self._fetch_songs,
92 "playlistinfo": self._fetch_songs,
93 "playlistsearch": self._fetch_songs,
94 "plchanges": self._fetch_songs,
95 "plchangesposid": self._fetch_changes,
96 "shuffle": self._fetch_nothing,
97 "swap": self._fetch_nothing,
98 "swapid": self._fetch_nothing,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
99 # Stored Playlist Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
100 "listplaylist": self._fetch_list,
101 "listplaylistinfo": self._fetch_songs,
102 "listplaylists": self._fetch_playlists,
103 "load": self._fetch_nothing,
104 "playlistadd": self._fetch_nothing,
105 "playlistclear": self._fetch_nothing,
106 "playlistdelete": self._fetch_nothing,
107 "playlistmove": self._fetch_nothing,
108 "rename": self._fetch_nothing,
109 "rm": self._fetch_nothing,
110 "save": self._fetch_nothing,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
111 # Database Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
112 "count": self._fetch_object,
113 "find": self._fetch_songs,
114 "list": self._fetch_list,
115 "listall": self._fetch_database,
116 "listallinfo": self._fetch_database,
117 "lsinfo": self._fetch_database,
118 "search": self._fetch_songs,
119 "update": self._fetch_item,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
120 # Connection Commands
9a76b6e initial commit
J. Alexander Treuman authored
121 "close": None,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
122 "kill": None,
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
123 "password": self._fetch_nothing,
124 "ping": self._fetch_nothing,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
125 # Audio Output Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
126 "disableoutput": self._fetch_nothing,
127 "enableoutput": self._fetch_nothing,
128 "outputs": self._fetch_outputs,
4aca870 rearranging commands to match new protocol documentation
J. Alexander Treuman authored
129 # Reflection Commands
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
130 "commands": self._fetch_list,
131 "notcommands": self._fetch_list,
132 "tagtypes": self._fetch_list,
133 "urlhandlers": self._fetch_list,
9a76b6e initial commit
J. Alexander Treuman authored
134 }
135
136 def __getattr__(self, attr):
5c84adf mpd.py: adding support for asynchronous commands
J. Alexander Treuman authored
137 if attr.startswith("send_"):
138 command = attr.replace("send_", "", 1)
139 wrapper = self._send
140 elif attr.startswith("fetch_"):
141 command = attr.replace("fetch_", "", 1)
142 wrapper = self._fetch
143 else:
144 command = attr
145 wrapper = self._execute
146 if command not in self._commands:
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
147 raise AttributeError("'%s' object has no attribute '%s'" %
148 (self.__class__.__name__, attr))
5c84adf mpd.py: adding support for asynchronous commands
J. Alexander Treuman authored
149 return lambda *args: wrapper(command, args)
9a76b6e initial commit
J. Alexander Treuman authored
150
5c84adf mpd.py: adding support for asynchronous commands
J. Alexander Treuman authored
151 def _send(self, command, args):
152 if self._command_list is not None:
153 raise CommandListError("Cannot use send_%s in a command list" %
154 command)
155 self._write_command(command, args)
156 self._pending.append(command)
157
158 def _fetch(self, command, args=None):
159 if self._command_list is not None:
160 raise CommandListError("Cannot use fetch_%s in a command list" %
161 command)
162 if not self._pending:
163 raise PendingCommandError("No pending commands to fetch")
164 if self._pending[0] != command:
165 raise PendingCommandError("%s is not the currently "
166 "pending command" % command)
167 del self._pending[0]
168 retval = self._commands[command]
169 if callable(retval):
170 return retval()
171
172 def _execute(self, command, args):
173 if self._pending:
174 raise PendingCommandError("Cannot execute %s with "
175 "pending commands" % command)
176 retval = self._commands[command]
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
177 if self._command_list is not None and not callable(retval):
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
178 raise CommandListError("%s not allowed in command list" % command)
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
179 self._write_command(command, args)
180 if self._command_list is None:
e5e24e0 adding command_list support
J. Alexander Treuman authored
181 if callable(retval):
182 return retval()
183 return retval
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
184 self._command_list.append(retval)
9a76b6e initial commit
J. Alexander Treuman authored
185
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
186 def _write_line(self, line):
cde055b mpd.py: use a separate file object for reading and writing sockets
J. Alexander Treuman authored
187 self._wfile.write("%s\n" % line)
188 self._wfile.flush()
9a76b6e initial commit
J. Alexander Treuman authored
189
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
190 def _write_command(self, command, args=[]):
9a76b6e initial commit
J. Alexander Treuman authored
191 parts = [command]
192 for arg in args:
193 parts.append('"%s"' % escape(str(arg)))
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
194 self._write_line(" ".join(parts))
9a76b6e initial commit
J. Alexander Treuman authored
195
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
196 def _read_line(self):
cde055b mpd.py: use a separate file object for reading and writing sockets
J. Alexander Treuman authored
197 line = self._rfile.readline()
ecdbc2e mpd.py: raise ConnectionError on EOF
J. Alexander Treuman authored
198 if not line.endswith("\n"):
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
199 raise ConnectionError("Connection lost while reading line")
ecdbc2e mpd.py: raise ConnectionError on EOF
J. Alexander Treuman authored
200 line = line.rstrip("\n")
9a76b6e initial commit
J. Alexander Treuman authored
201 if line.startswith(ERROR_PREFIX):
202 error = line[len(ERROR_PREFIX):].strip()
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
203 raise CommandError(error)
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
204 if self._command_list is not None:
e5e24e0 adding command_list support
J. Alexander Treuman authored
205 if line == NEXT:
206 return
207 if line == SUCCESS:
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
208 raise ProtocolError("Got unexpected '%s'" % SUCCESS)
e5e24e0 adding command_list support
J. Alexander Treuman authored
209 elif line == SUCCESS:
9a76b6e initial commit
J. Alexander Treuman authored
210 return
211 return line
212
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
213 def _read_pair(self, separator):
214 line = self._read_line()
9a76b6e initial commit
J. Alexander Treuman authored
215 if line is None:
216 return
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
217 pair = line.split(separator, 1)
218 if len(pair) < 2:
219 raise ProtocolError("Could not parse pair: '%s'" % line)
220 return pair
221
222 def _read_pairs(self, separator=": "):
223 pair = self._read_pair(separator)
224 while pair:
225 yield pair
226 pair = self._read_pair(separator)
9a76b6e initial commit
J. Alexander Treuman authored
227 raise StopIteration
228
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
229 def _read_list(self):
9a76b6e initial commit
J. Alexander Treuman authored
230 seen = None
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
231 for key, value in self._read_pairs():
9a76b6e initial commit
J. Alexander Treuman authored
232 if key != seen:
233 if seen is not None:
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
234 raise ProtocolError("Expected key '%s', got '%s'" %
235 (seen, key))
9a76b6e initial commit
J. Alexander Treuman authored
236 seen = key
237 yield value
238 raise StopIteration
239
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
240 def _read_playlist(self):
241 for key, value in self._read_pairs(":"):
9a76b6e initial commit
J. Alexander Treuman authored
242 yield value
243 raise StopIteration
244
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
245 def _read_objects(self, delimiters=[]):
9a76b6e initial commit
J. Alexander Treuman authored
246 obj = {}
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
247 for key, value in self._read_pairs():
9a76b6e initial commit
J. Alexander Treuman authored
248 key = key.lower()
249 if obj:
250 if key in delimiters:
251 yield obj
252 obj = {}
c7cae3c mpd.py: don't use has_key()
J. Alexander Treuman authored
253 elif key in obj:
9a76b6e initial commit
J. Alexander Treuman authored
254 if not isinstance(obj[key], list):
255 obj[key] = [obj[key], value]
256 else:
257 obj[key].append(value)
258 continue
259 obj[key] = value
260 if obj:
261 yield obj
262 raise StopIteration
263
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
264 def _read_command_list(self):
265 for retval in self._command_list:
e5e24e0 adding command_list support
J. Alexander Treuman authored
266 yield retval()
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
267 self._command_list = None
268 self._fetch_nothing()
e5e24e0 adding command_list support
J. Alexander Treuman authored
269 raise StopIteration
270
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
271 def _wrap_iterator(self, iterator):
9a76b6e initial commit
J. Alexander Treuman authored
272 if not self.iterate:
273 return list(iterator)
274 return iterator
275
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
276 def _fetch_nothing(self):
277 line = self._read_line()
9a76b6e initial commit
J. Alexander Treuman authored
278 if line is not None:
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
279 raise ProtocolError("Got unexpected return value: '%s'" % line)
9a76b6e initial commit
J. Alexander Treuman authored
280
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
281 def _fetch_item(self):
282 pairs = list(self._read_pairs())
283 if len(pairs) != 1:
94fd67b mpd.py: making _getitem return None if no item is returned
J. Alexander Treuman authored
284 return
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
285 return pairs[0][1]
9a76b6e initial commit
J. Alexander Treuman authored
286
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
287 def _fetch_list(self):
288 return self._wrap_iterator(self._read_list())
9a76b6e initial commit
J. Alexander Treuman authored
289
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
290 def _fetch_playlist(self):
291 return self._wrap_iterator(self._read_playlist())
9a76b6e initial commit
J. Alexander Treuman authored
292
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
293 def _fetch_object(self):
294 objs = list(self._read_objects())
9a76b6e initial commit
J. Alexander Treuman authored
295 if not objs:
cdd3dd2 return an empty dict if no object is read
J. Alexander Treuman authored
296 return {}
9a76b6e initial commit
J. Alexander Treuman authored
297 return objs[0]
298
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
299 def _fetch_objects(self, delimiters):
300 return self._wrap_iterator(self._read_objects(delimiters))
9a76b6e initial commit
J. Alexander Treuman authored
301
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
302 def _fetch_songs(self):
303 return self._fetch_objects(["file"])
9a76b6e initial commit
J. Alexander Treuman authored
304
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
305 def _fetch_playlists(self):
306 return self._fetch_objects(["playlist"])
c465a35 adding listplaylists command
J. Alexander Treuman authored
307
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
308 def _fetch_database(self):
309 return self._fetch_objects(["file", "directory", "playlist"])
9a76b6e initial commit
J. Alexander Treuman authored
310
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
311 def _fetch_outputs(self):
312 return self._fetch_objects(["outputid"])
9a76b6e initial commit
J. Alexander Treuman authored
313
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
314 def _fetch_changes(self):
315 return self._fetch_objects(["cpos"])
9a76b6e initial commit
J. Alexander Treuman authored
316
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
317 def _fetch_command_list(self):
318 return self._wrap_iterator(self._read_command_list())
e5e24e0 adding command_list support
J. Alexander Treuman authored
319
9a76b6e initial commit
J. Alexander Treuman authored
320 def _hello(self):
cde055b mpd.py: use a separate file object for reading and writing sockets
J. Alexander Treuman authored
321 line = self._rfile.readline()
ecdbc2e mpd.py: raise ConnectionError on EOF
J. Alexander Treuman authored
322 if not line.endswith("\n"):
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
323 raise ConnectionError("Connection lost while reading MPD hello")
285bcce mpd.py: strip trailing \n from MPD's hello line for a nicer error mes…
J. Alexander Treuman authored
324 line = line.rstrip("\n")
9a76b6e initial commit
J. Alexander Treuman authored
325 if not line.startswith(HELLO_PREFIX):
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
326 raise ProtocolError("Got invalid MPD hello: '%s'" % line)
9a76b6e initial commit
J. Alexander Treuman authored
327 self.mpd_version = line[len(HELLO_PREFIX):].strip()
328
329 def _reset(self):
330 self.mpd_version = None
5c84adf mpd.py: adding support for asynchronous commands
J. Alexander Treuman authored
331 self._pending = []
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
332 self._command_list = None
11ad737 mpd.py: raise ConnectionError when trying to use an unconnected socket
J. Alexander Treuman authored
333 self._sock = None
cde055b mpd.py: use a separate file object for reading and writing sockets
J. Alexander Treuman authored
334 self._rfile = _NotConnected()
335 self._wfile = _NotConnected()
9a76b6e initial commit
J. Alexander Treuman authored
336
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
337 def _connect_unix(self, path):
52157b2 mpd.py: raise ConnectionError if unix sockets aren't supported
J. Alexander Treuman authored
338 if not hasattr(socket, "AF_UNIX"):
339 raise ConnectionError("Unix domain sockets not supported "
340 "on this platform")
8ec145e preliminary unix socket support
J. Alexander Treuman authored
341 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
342 sock.connect(path)
343 return sock
344
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
345 def _connect_tcp(self, host, port):
74eff57 mpd.py: adding a workaround for systems missing socket.AI_ADDRCONFIG
J. Alexander Treuman authored
346 try:
347 flags = socket.AI_ADDRCONFIG
348 except AttributeError:
349 flags = 0
8ec145e preliminary unix socket support
J. Alexander Treuman authored
350 msg = "getaddrinfo returns an empty list"
3bbc456 mpd.py: loop over addresses returned by getaddrinfo to connect to
J. Alexander Treuman authored
351 for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC,
352 socket.SOCK_STREAM, socket.IPPROTO_TCP,
74eff57 mpd.py: adding a workaround for systems missing socket.AI_ADDRCONFIG
J. Alexander Treuman authored
353 flags):
3bbc456 mpd.py: loop over addresses returned by getaddrinfo to connect to
J. Alexander Treuman authored
354 af, socktype, proto, canonname, sa = res
355 try:
8ec145e preliminary unix socket support
J. Alexander Treuman authored
356 sock = socket.socket(af, socktype, proto)
357 sock.connect(sa)
3bbc456 mpd.py: loop over addresses returned by getaddrinfo to connect to
J. Alexander Treuman authored
358 except socket.error, msg:
8ec145e preliminary unix socket support
J. Alexander Treuman authored
359 if sock:
360 sock.close()
361 sock = None
3bbc456 mpd.py: loop over addresses returned by getaddrinfo to connect to
J. Alexander Treuman authored
362 continue
363 break
8ec145e preliminary unix socket support
J. Alexander Treuman authored
364 if not sock:
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
365 raise socket.error(msg)
8ec145e preliminary unix socket support
J. Alexander Treuman authored
366 return sock
367
368 def connect(self, host, port):
369 if self._sock:
370 raise ConnectionError("Already connected")
371 if host.startswith("/"):
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
372 self._sock = self._connect_unix(host)
8ec145e preliminary unix socket support
J. Alexander Treuman authored
373 else:
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
374 self._sock = self._connect_tcp(host, port)
cde055b mpd.py: use a separate file object for reading and writing sockets
J. Alexander Treuman authored
375 self._rfile = self._sock.makefile("rb")
376 self._wfile = self._sock.makefile("wb")
2027674 mpd.py: reset to disconnected state if _hello() fails in connect()
J. Alexander Treuman authored
377 try:
378 self._hello()
8ab0077 mpd.py: catch all exceptions raised by _hello()
J. Alexander Treuman authored
379 except:
2027674 mpd.py: reset to disconnected state if _hello() fails in connect()
J. Alexander Treuman authored
380 self.disconnect()
381 raise
9a76b6e initial commit
J. Alexander Treuman authored
382
383 def disconnect(self):
cde055b mpd.py: use a separate file object for reading and writing sockets
J. Alexander Treuman authored
384 self._rfile.close()
385 self._wfile.close()
9a76b6e initial commit
J. Alexander Treuman authored
386 self._sock.close()
387 self._reset()
388
e5e24e0 adding command_list support
J. Alexander Treuman authored
389 def command_list_ok_begin(self):
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
390 if self._command_list is not None:
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
391 raise CommandListError("Already in command list")
5c84adf mpd.py: adding support for asynchronous commands
J. Alexander Treuman authored
392 if self._pending:
393 raise PendingCommandError("Cannot begin command list "
394 "with pending commands")
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
395 self._write_command("command_list_ok_begin")
396 self._command_list = []
e5e24e0 adding command_list support
J. Alexander Treuman authored
397
398 def command_list_end(self):
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
399 if self._command_list is None:
492dab0 mpd.py: changing exception raising to comply with the Python Style Guide
J. Alexander Treuman authored
400 raise CommandListError("Not in command list")
06f8433 mpd.py: internal API cleanup
J. Alexander Treuman authored
401 self._write_command("command_list_end")
402 return self._fetch_command_list()
e5e24e0 adding command_list support
J. Alexander Treuman authored
403
9a76b6e initial commit
J. Alexander Treuman authored
404
405 def escape(text):
406 return text.replace("\\", "\\\\").replace('"', '\\"')
407
408
409 # vim: set expandtab shiftwidth=4 softtabstop=4 textwidth=79:
Something went wrong with that request. Please try again.