from __future__ import print_function import itertools from twisted.internet import defer from twisted.internet import protocol from twisted.internet import reactor from twisted.internet import task from twisted.protocols import basic from responsedict import ResponseDict import os import sys def get_client(host='', port=6600): '''returns a deferred''' if host is '': host = os.getenv('MPD_HOST', 'localhost') #print("Using default config: %(host)s:%(port)s" % dict(host=host, port=port), file=sys.stderr) ccreator = protocol.ClientCreator(reactor, MPDProtocol) return ccreator.connectTCP(host, port) class MPDProtocol(basic.LineReceiver): delimiter = '\x0a' def __init__(self, *a, **kw): #basic.LineReceiver.__init__(self, *a, **kw) self.commands = [] self.notifications = [] self.serverinfo=None #self.lineReceived = self.noidlereceive self.listeners = {} self._idle = False def fallback(self, data): print(data.as_list()) def check_servername(self, line): if self.serverinfo is None and line.startswith('OK'): self.serverinfo = line.split() return True set_servname = check_servername def lineReceived(self, line): if self.check_servername(line): pass else: #print('line received:', repr(line)) if line.strip() == 'OK': self.reset_idle() method, deferred, data = self.commands.pop(0) d = reactor.callLater(0, deferred.callback, (method, data)) for listener in self.listeners.get(method,[]): listener.notify(self, line) else: self.commands[0][2].add_line(line.rstrip()) def add_listener(self, listener, command): self.listeners.setdefault(command, []).append(listener) return listener def reset_idle(self): self._idle = False def idle(self, subsystems=None, listener=None): if subsystems is None:subsystems = [] result = self.sendCommand('idle', *subsystems) self._idle = True if listener is not None: self.add_listener(listener, 'idle') return result def sendCommand(self, command, *args): result = None if self._idle and command not in {'idle', 'noidle'}: if self.commands[0][0] == 'idle': self.commands.pop(0) self.sendCommand('noidle') if args: command = ' '.join(itertools.chain([command], args)) self.transport.write('%s\n' % command) self.commands.append((command, defer.Deferred(), ResponseDict())) result = self.commands[-1][1] return result import pprint import traceback, inspect @defer.inlineCallbacks def run(mpdClient): #NOTE: remember, idleHandler not used! method, result = yield mpdClient.idle(['playlist']) print(method, result) method, result = yield mpdClient.sendCommand('playlistinfo') print(result.as_list()) import time time.sleep(1) run(mpdClient) def fail(*a, **kw): print(*a, **kw) if __name__ == '__main__': get_client().addCallbacks(run,fail) reactor.run()