git.fiddlerwoaroof.com
mpdprotocol.py
49616e52
 from __future__ import print_function
0fdce423
 import itertools
1ce6083a
 
49616e52
 from twisted.internet import defer
 from twisted.internet import protocol
 from twisted.internet import reactor
0fdce423
 from twisted.internet import task
49616e52
 from twisted.protocols import basic
1ce6083a
 
49616e52
 from responsedict import ResponseDict
1ce6083a
 
0fdce423
 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)
 
 
49616e52
 class MPDProtocol(basic.LineReceiver):
     delimiter = '\x0a'
1ce6083a
 
     def __init__(self, *a, **kw):
49616e52
         #basic.LineReceiver.__init__(self, *a, **kw)
         self.commands = []
0fdce423
         self.notifications = []
1ce6083a
         self.serverinfo=None
0fdce423
         #self.lineReceived = self.noidlereceive
         self.listeners = {}
         self._idle = False
49616e52
 
     def fallback(self, data):
         print(data.as_list())
 
0fdce423
     def check_servername(self, line):
49616e52
         if self.serverinfo is None and line.startswith('OK'):
             self.serverinfo = line.split()
0fdce423
             return True
     set_servname = check_servername
 
     def lineReceived(self, line):
         if self.check_servername(line): pass
1ce6083a
         else:
0fdce423
             #print('line received:', repr(line))
49616e52
             if line.strip() == 'OK':
0fdce423
                 self.reset_idle()
49616e52
                 method, deferred, data = self.commands.pop(0)
                 d = reactor.callLater(0, deferred.callback, (method, data))
0fdce423
                 for listener in self.listeners.get(method,[]):
                     listener.notify(self, line)
49616e52
             else:
                 self.commands[0][2].add_line(line.rstrip())
 
0fdce423
     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))
49616e52
         self.transport.write('%s\n' % command)
0fdce423
         self.commands.append((command, defer.Deferred(), ResponseDict()))
         result = self.commands[-1][1]
         return result
49616e52
 
0fdce423
 import pprint
 import traceback, inspect
49616e52
 
0fdce423
 @defer.inlineCallbacks
49616e52
 def run(mpdClient):
0fdce423
     #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)
49616e52
 
 def fail(*a, **kw):
     print(*a, **kw)
 
 if __name__ == '__main__':
0fdce423
     get_client().addCallbacks(run,fail)
49616e52
     reactor.run()
 
 
1ce6083a