X-Git-Url: http://git.kaliko.me/?a=blobdiff_plain;f=musicpd.py;h=0fe3b671deff665e3ff73c6394ac7d363e9eb693;hb=21c2a1843902d21f559af15cdd3eb8a9f35a8b86;hp=6bb050990c900c6585bcb3c61ade7aa89eb3d0a2;hpb=ffbd90666dc18d72ca0c30ff8b34a629878de6f4;p=python-musicpd.git diff --git a/musicpd.py b/musicpd.py index 6bb0509..0fe3b67 100644 --- a/musicpd.py +++ b/musicpd.py @@ -15,6 +15,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with python-musicpd. If not, see . +# pylint: disable=C0111 + import socket @@ -22,7 +24,7 @@ HELLO_PREFIX = "OK MPD " ERROR_PREFIX = "ACK " SUCCESS = "OK" NEXT = "list_OK" -VERSION = '0.3.1b' +VERSION = '0.4.2' class MPDError(Exception): @@ -46,15 +48,40 @@ class PendingCommandError(MPDError): class IteratingError(MPDError): pass +class Range: + + def __init__(self, tpl): + self.tpl = tpl + self._check() + + def __str__(self): + if len(self.tpl) == 1: + return '{0}:'.format(self.tpl[0]) + return '{0[0]}:{0[1]}'.format(self.tpl) -class _NotConnected(object): + def __repr__(self): + return 'Range({0})'.format(self.tpl) + + def _check(self): + if not isinstance(self.tpl, tuple): + raise CommandError('Wrong type, provide a tuple') + if len(self.tpl) not in [1, 2]: + raise CommandError('length not in [1, 2]') + for index in self.tpl: + try: + index = int(index) + except (TypeError, ValueError): + raise CommandError('Not a tuple of int') + + +class _NotConnected: def __getattr__(self, attr): return self._dummy def _dummy(*args): raise ConnectionError("Not connected") -class MPDClient(object): +class MPDClient: def __init__(self): self.iterate = False self._reset() @@ -63,7 +90,7 @@ class MPDClient(object): "clearerror": self._fetch_nothing, "currentsong": self._fetch_object, "idle": self._fetch_list, - "noidle": None, + #"noidle": None, "status": self._fetch_object, "stats": self._fetch_object, # Playback Option Commands @@ -131,6 +158,7 @@ class MPDClient(object): "searchaddpl": self._fetch_nothing, "update": self._fetch_item, "rescan": self._fetch_item, + "readcomments": self._fetch_object, # Sticker Commands "sticker get": self._fetch_item, "sticker set": self._fetch_nothing, @@ -145,6 +173,7 @@ class MPDClient(object): # Audio Output Commands "disableoutput": self._fetch_nothing, "enableoutput": self._fetch_nothing, + "toggleoutput": self._fetch_nothing, "outputs": self._fetch_outputs, # Reflection Commands "commands": self._fetch_list, @@ -161,6 +190,8 @@ class MPDClient(object): } def __getattr__(self, attr): + if attr == 'send_noidle': # have send_noidle to cancel idle as well as noidle + return self.noidle() if attr.startswith("send_"): command = attr.replace("send_", "", 1) wrapper = self._send @@ -228,10 +259,15 @@ class MPDClient(object): self._wfile.write("%s\n" % line) self._wfile.flush() - def _write_command(self, command, args=[]): + def _write_command(self, command, args=None): + if args is None: + args = [] parts = [command] for arg in args: - parts.append('"%s"' % escape(str(arg))) + if isinstance(arg, tuple): + parts.append('{0!s}'.format(Range(arg))) + else: + parts.append('"%s"' % escape(str(arg))) self._write_line(" ".join(parts)) def _read_line(self): @@ -278,11 +314,13 @@ class MPDClient(object): yield value def _read_playlist(self): - for key, value in self._read_pairs(":"): + for _, value in self._read_pairs(":"): yield value - def _read_objects(self, delimiters=[]): + def _read_objects(self, delimiters=None): obj = {} + if delimiters is None: + delimiters = [] for key, value in self._read_pairs(): key = key.lower() if obj: @@ -380,6 +418,7 @@ class MPDClient(object): self.mpd_version = line[len(HELLO_PREFIX):].strip() def _reset(self): + # pylint: disable=w0201 self.mpd_version = None self._iterating = False self._pending = [] @@ -405,7 +444,7 @@ class MPDClient(object): for res in socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM, socket.IPPROTO_TCP, flags): - af, socktype, proto, canonname, sa = res + af, socktype, proto, _, sa = res sock = None try: sock = socket.socket(af, socktype, proto) @@ -420,6 +459,14 @@ class MPDClient(object): else: raise ConnectionError("getaddrinfo returns an empty list") + def noidle(self): + # noidle's special case + if not self._pending or self._pending[0] != 'idle': + raise CommandError('cannot send noidle if send_idle was not called') + del self._pending[0] + self._write_command("noidle") + return self._fetch_list() + def connect(self, host, port): if self._sock is not None: raise ConnectionError("Already connected")