git.fiddlerwoaroof.com
Raw Blame History
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()