First stage of MPC support refactoring

This commit is contained in:
Tomasz Fluxid Kowalczyk 2012-02-02 23:18:10 +01:00
parent 204317762d
commit 8ed7f061bc
3 changed files with 78 additions and 84 deletions

View File

@ -17,8 +17,6 @@ if __name__ == '__main__':
else: else:
port = 8999 port = 8999
manager = client.Manager(host, port, name) manager = client.Manager(host, port, name, lambda: mpc.MPCHCPlayer(manager))
manager.start() manager.start()
player = mpc.MPCHCPlayer(manager)
reactor.run()

View File

@ -5,11 +5,15 @@ try:
except ImportError: except ImportError:
from StringIO import StringIO from StringIO import StringIO
from twisted.internet.defer import succeed
from twisted.internet.protocol import ( from twisted.internet.protocol import (
ProcessProtocol, ProcessProtocol,
Protocol, Protocol,
) )
from twisted.protocols.basic import LineReceiver from twisted.protocols.basic import LineReceiver
from twisted.web.iweb import IBodyProducer
from zope.interface import implements
class CommandProtocol(LineReceiver): class CommandProtocol(LineReceiver):
states = None states = None
@ -88,6 +92,23 @@ class LineProcessProtocol(ProcessProtocol):
self.transport.write(line+'\n') self.transport.write(line+'\n')
class BodyProducer(object):
implements(IBodyProducer)
def __init__(self, body):
self.body = body
self.length = len(body)
def startProducing(self, consumer):
consumer.write(self.body)
return succeed(None)
def pauseProducing(self):
pass
def stopProducing(self):
pass
class BodyGetter(Protocol): class BodyGetter(Protocol):
def __init__(self, length, callback): def __init__(self, length, callback):
self.length = length self.length = length
@ -103,6 +124,9 @@ class BodyGetter(Protocol):
def connectionLost(self, reason): def connectionLost(self, reason):
self.callback(self.body.getvalue()) self.callback(self.body.getvalue())
def null_response_handler(status, headers, body):
pass
def handle_response(callback): def handle_response(callback):
def defer_callback(response): def defer_callback(response):
status = response.code status = response.code

View File

@ -3,14 +3,14 @@
import re import re
from twisted.internet import reactor from twisted.internet import reactor
from twisted.internet.defer import Deferred, succeed
from twisted.web.client import Agent from twisted.web.client import Agent
from twisted.web.http_headers import Headers from twisted.web.http_headers import Headers
from zope.interface import implements from ..network_utils import (
from twisted.web.iweb import IBodyProducer BodyProducer,
handle_response,
from ..network_utils import handle_response null_response_handler,
)
#RE_MPC_STATUS = re.compile("^OnStatus\('(.+)', '(Paused|Playing)', (\d+), '\d{2}:\d{2}:\d{2}', \d+, '\d{2}:\d{2}:\d{2}', \d+, \d+, '.+'\)$") #RE_MPC_STATUS = re.compile("^OnStatus\('(.+)', '(Paused|Playing)', (\d+), '\d{2}:\d{2}:\d{2}', \d+, '\d{2}:\d{2}:\d{2}', \d+, \d+, '.+'\)$")
RE_MPC_STATUS = re.compile(r"^OnStatus\('((?:[^']*(?:\\\\)*\\')*[^']*)', '(.+?)', (\d+),") RE_MPC_STATUS = re.compile(r"^OnStatus\('((?:[^']*(?:\\\\)*\\')*[^']*)', '(.+?)', (\d+),")
@ -66,86 +66,58 @@ PLAYING_STATUSES = {
} }
class MPCHCPlayer(object): class MPCHCPlayer(object):
def __init__(self, manager): def __init__(self, manager, host = None):
self.manager = manager self.manager = manager
self.host = 'localhost:13579'
self.filename = None # To be moved to Manager
manager.player = self manager.player = self
self.agent = Agent(reactor)
def send_set_paused(self, value): def set_paused(self, value):
self.set_property('Paused', value) self.send_post_request('wm_command=%d' % (888 if value else 887))
def send_get_paused(self): def set_position(self, value):
self.get_property('Paused') value = int(value*1000)
seconds, mseconds = divmod(value, 1000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
self.send_post_request('wm_command=-1&position=%d.%d.%d.%d' % (
hours, minutes, seconds, mseconds
))
def send_set_position(self, value): self.send_post_request(body)
self.set_property('Position', '%d'%(value*1000))
def send_get_position(self): def status_response(self, status, headers, body):
self.get_property('Position')
def send_set_speed(self, value):
pass
def send_get_speed(self):
pass
def set_property(self, name, value):
requestData = {
'Paused': lambda value: 'wm_command=888&null=0' if value else 'wm_command=887&null=0',
'Position': lambda value: "wm_command=-1&position="+ '%d.%d.%d.%d' % ((int(value)/3600000), (int(value)/60000)%60, (int(value)/1000)%60, int(value)%1000)
}[name](value)
body = StringBodyProducer(requestData)
self.sendPostRequest(body)
def get_property(self, propertyName):
agent = Agent(reactor)
request = agent.request(
'GET',
'http://localhost:13579/status.html',
Headers(),
None)
def cbRequest(status, headers, body):
m = RE_MPC_STATUS.match(body) m = RE_MPC_STATUS.match(body)
if not m: if not m:
return return
fileName, playerStatus, currentTime = m.group(1), m.group(2), m.group(3) filename, paused, position = m.group(1), m.group(2), m.group(3)
playerStatus = PLAYING_STATUSES.get(playerStatus)
if playerStatus is None: paused = PLAYING_STATUSES.get(paused)
if paused is None:
return return
if(propertyName == "Paused"): if self.filename is None:
self.manager.update_player_paused(playerStatus) self.filename = filename
if(propertyName == "Position"): position = float(position)/1000
self.manager.update_player_position(float(currentTime)/1000.0) self.manager.update_player_status(paused, position)
request.addCallback(handle_response(cbRequest)) def ask_for_status(self, propertyName):
request = self.agent.request(
'GET',
'http://localhost:13579/status.html',
Headers(),
None,
)
request.addCallback(handle_response(self.status_response))
def sendPostRequest(self, body): def send_post_request(self, body):
agent = Agent(reactor) request = self.agent.request(
request = agent.request(
'POST', 'POST',
'http://localhost:13579/command.html', 'http://%s/command.html' % self.host,
Headers({'Content-Type': ['application/x-www-form-urlencoded']}), Headers({'Content-Type': ['application/x-www-form-urlencoded']}),
body) BodyProducer(body),
)
def cbRequest(ignored): request.addCallback(handle_response(null_response_handler))
return
request.addCallback(cbRequest)
class StringBodyProducer(object):
implements(IBodyProducer)
def __init__(self, body):
self.body = body
self.length = len(body)
def startProducing(self, consumer):
consumer.write(self.body)
return succeed(None)
def pauseProducing(self):
pass
def stopProducing(self):
pass