@@ -5,6 +5,12 @@
__version__ = '$Change$'
# $Id$
# The handling of defers and state in this module is not very good. It
# needs some work to ensure that error cases are properly handled. What
# do we do if we get no URLs for a PLS? Do we delete ourselves just to be
# readded (when we get PLS refeshing working)? Do we set a content-length
# to zero till we get one?
import ConfigParser
import StringIO
import os.path
@@ -188,7 +194,12 @@ class ShoutProxy(resource.Resource):
protocol.ClientCreator(reactor, ShoutTransfer, request,
self.startNextConnection).connectTCP(host, port)
def triggerdefered(self, fun):
map(fun, self.afterurls)
self.afterurls = None
def gotPLS(self, page):
self.fetchingurls = False
try:
pls = ConfigParser.SafeConfigParser()
pls.readfp(StringIO.StringIO(page))
@@ -203,19 +214,23 @@ class ShoutProxy(resource.Resource):
self.urlpos = random.randrange(len(self.urls))
except:
self.dump_exc()
self.urls = None
self.triggerdefered(lambda x: x.errback(1))
return
self.afterurls.callback(1)
self.afterurls = None
self.triggerdefered(lambda x: x.callback(1))
def errPLS(self, failure):
self.request.write(failure.render(self.request))
self.request.finish()
self.request = None
self.fetchingurls = False
self.triggerdefered(lambda x: x.errback(1))
def processRequest(self, ign, request):
self.startNextConnection(request)
def errRequest(self, ign, request):
request.write(failure.render(self.request))
request.finish()
def render(self, request):
request.setHeader('content-type', self.mt)
@@ -236,15 +251,20 @@ class ShoutProxy(resource.Resource):
# shouldn't getPage do proper escaping for me?
getPage(self.shoutpls.encode('ascii')) \
.addCallbacks(self.gotPLS, self.errPLS)
self.afterurls = defer.Deferred()
self.afterurls = [ defer.Deferred() ]
else:
self.afterurls.append(defer.Deferred())
# Always add the callback if we don't have urls
self.afterurls.addCallback(self.processRequest, request)
self.afterurls[-1].addCallbacks(self.processRequest,
errback=self.errRequest, callbackArgs=(request, ),
errbackArgs=(request, ))
else:
self.startNextConnection(request)
# and make sure the connection doesn't get closed
return server.NOT_DONE_YET
synchronized = [ 'render', 'gotPLS', 'startNextConnection' ]
synchronized = [ 'gotPLS', 'render', 'startNextConnection',
'triggerdefered', ]
threadable.synchronize(ShoutProxy)
class ShoutStation(AudioItem):