X-Git-Url: https://git.kaliko.me/?a=blobdiff_plain;f=mpd.py;h=56112a9f5db6950ed16c3318569d8be5ee976475;hb=9eea05a9c3180a856e99ceadb21c118ea050fa69;hp=32b51a17e4b324ae79dccd33287c4eae6cc11ebb;hpb=03647a81484640a4a6197774408a45973c9dbe39;p=python-musicpd.git diff --git a/mpd.py b/mpd.py index 32b51a1..56112a9 100644 --- a/mpd.py +++ b/mpd.py @@ -41,6 +41,9 @@ class CommandListError(MPDError): class PendingCommandError(MPDError): pass +class IteratingError(MPDError): + pass + class _NotConnected(object): def __getattr__(self, attr): @@ -143,6 +146,7 @@ class MPDClient(object): else: command = attr wrapper = self._execute + command = command.replace("_", " ") if command not in self._commands: raise AttributeError("'%s' object has no attribute '%s'" % (self.__class__.__name__, attr)) @@ -151,18 +155,21 @@ class MPDClient(object): def _send(self, command, args): if self._command_list is not None: raise CommandListError("Cannot use send_%s in a command list" % - command) + command.replace(" ", "_")) self._write_command(command, args) self._pending.append(command) def _fetch(self, command, args=None): if self._command_list is not None: raise CommandListError("Cannot use fetch_%s in a command list" % - command) + command.replace(" ", "_")) + if self._iterating: + raise IteratingError("Cannot use fetch_%s while iterating" % + command.replace(" ", "_")) if not self._pending: raise PendingCommandError("No pending commands to fetch") if self._pending[0] != command: - raise PendingCommandError("%s is not the currently " + raise PendingCommandError("'%s' is not the currently " "pending command" % command) del self._pending[0] retval = self._commands[command] @@ -170,13 +177,16 @@ class MPDClient(object): return retval() def _execute(self, command, args): + if self._iterating: + raise IteratingError("Cannot execute '%s' while iterating" % + command) if self._pending: - raise PendingCommandError("Cannot execute %s with " + raise PendingCommandError("Cannot execute '%s' with " "pending commands" % command) retval = self._commands[command] if self._command_list is not None: if not callable(retval): - raise CommandListError("%s not allowed in command list" % + raise CommandListError("'%s' not allowed in command list" % command) self._write_command(command, args) self._command_list.append(retval) @@ -261,15 +271,25 @@ class MPDClient(object): yield obj def _read_command_list(self): - for retval in self._command_list: - yield retval() - self._command_list = None + try: + for retval in self._command_list: + yield retval() + finally: + self._command_list = None self._fetch_nothing() + def _iterator_wrapper(self, iterator): + try: + for item in iterator: + yield item + finally: + self._iterating = False + def _wrap_iterator(self, iterator): if not self.iterate: return list(iterator) - return iterator + self._iterating = True + return self._iterator_wrapper(iterator) def _fetch_nothing(self): line = self._read_line() @@ -326,6 +346,7 @@ class MPDClient(object): def _reset(self): self.mpd_version = None + self._iterating = False self._pending = [] self._command_list = None self._sock = None @@ -345,26 +366,26 @@ class MPDClient(object): flags = socket.AI_ADDRCONFIG except AttributeError: flags = 0 - msg = "getaddrinfo returns an empty list" + err = None for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, socket.IPPROTO_TCP, flags): af, socktype, proto, canonname, sa = res + sock = None try: sock = socket.socket(af, socktype, proto) sock.connect(sa) - except socket.error, msg: - if sock: + return sock + except socket.error, err: + if sock is not None: sock.close() - sock = None - continue - break - if not sock: - raise socket.error(msg) - return sock + if err is not None: + raise err + else: + raise ConnectionError("getaddrinfo returns an empty list") def connect(self, host, port): - if self._sock: + if self._sock is not None: raise ConnectionError("Already connected") if host.startswith("/"): self._sock = self._connect_unix(host) @@ -385,13 +406,15 @@ class MPDClient(object): self._reset() def fileno(self): - if not self._sock: + if self._sock is None: raise ConnectionError("Not connected") return self._sock.fileno() def command_list_ok_begin(self): if self._command_list is not None: raise CommandListError("Already in command list") + if self._iterating: + raise IteratingError("Cannot begin command list while iterating") if self._pending: raise PendingCommandError("Cannot begin command list " "with pending commands") @@ -401,6 +424,8 @@ class MPDClient(object): def command_list_end(self): if self._command_list is None: raise CommandListError("Not in command list") + if self._iterating: + raise IteratingError("Already iterating over a command list") self._write_command("command_list_end") return self._fetch_command_list()