can take a long while, bad in that we loose some of the async requirements... as things are in a thread, do requests web synchronously, we no longer have to raise a Defered.. I'm not happy, but it'll take work to properly be a mix between the two.. [git-p4: depot-paths = "//depot/": change = 1308]main
@@ -31,7 +31,7 @@ from elementtree.ElementTree import Element, SubElement, tostring | |||||
from upnp import UPnPPublisher, errorCode | from upnp import UPnPPublisher, errorCode | ||||
from DIDLLite import DIDLElement, Container, Movie, Resource, MusicTrack | from DIDLLite import DIDLElement, Container, Movie, Resource, MusicTrack | ||||
from twisted.internet import defer | |||||
from twisted.internet import defer, threads | |||||
from twisted.python import failure | from twisted.python import failure | ||||
import debug | import debug | ||||
@@ -76,6 +76,13 @@ class doRecall(defer.Deferred): | |||||
else: | else: | ||||
self.defer.callback(ret) | self.defer.callback(ret) | ||||
@staticmethod | |||||
def wrapper(fun, *args, **kwargs): | |||||
try: | |||||
return fun(*args, **kwargs) | |||||
except defer.Deferred, x: | |||||
return doRecallgen(x, fun, *args, **kwargs) | |||||
def doRecallgen(defer, fun, *args, **kwargs): | def doRecallgen(defer, fun, *args, **kwargs): | ||||
i = doRecall(defer, fun, *args, **kwargs) | i = doRecall(defer, fun, *args, **kwargs) | ||||
return i.defer | return i.defer | ||||
@@ -186,14 +193,12 @@ class ContentDirectoryControl(UPnPPublisher, dict): | |||||
'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' % \ | 'StartingIndex=%s RequestedCount=%s SortCriteria=%s)' % \ | ||||
tuple(map(repr, args)) | tuple(map(repr, args)) | ||||
try: | |||||
ret = self.thereal_soap_Browse(*args) | |||||
except defer.Deferred, x: | |||||
ret = doRecallgen(x, self.soap_Browse, *args) | |||||
l['response'] = ret | |||||
def setresp(r): | |||||
l['response'] = r | |||||
return r | |||||
return ret | |||||
return threads.deferToThread(self.thereal_soap_Browse, | |||||
*args).addCallback(setresp) | |||||
def thereal_soap_Browse(self, *args): | def thereal_soap_Browse(self, *args): | ||||
"""Required: Incrementally browse the native heirachy of the Content | """Required: Incrementally browse the native heirachy of the Content | ||||
@@ -14,6 +14,7 @@ from twisted.internet import reactor | |||||
from twisted.python import log | from twisted.python import log | ||||
import twisted.web | import twisted.web | ||||
import urlparse | import urlparse | ||||
import urllib2 | |||||
def getPage(url, contextFactory=None, *args, **kwargs): | def getPage(url, contextFactory=None, *args, **kwargs): | ||||
"""Download a web page as a string. | """Download a web page as a string. | ||||
@@ -178,15 +179,15 @@ class PYVR(Container): | |||||
Container.__init__(self, *args, **kwargs) | Container.__init__(self, *args, **kwargs) | ||||
self.pathObjmap = {} | self.pathObjmap = {} | ||||
self.pend = None | |||||
#self.pend = None | |||||
self.lastmodified = None | self.lastmodified = None | ||||
self.newobjs = None | self.newobjs = None | ||||
self.objs = {} | self.objs = {} | ||||
self.lastcheck = 0 | self.lastcheck = 0 | ||||
def checkUpdate(self): | def checkUpdate(self): | ||||
if self.pend is not None: | |||||
raise self.pend | |||||
#if self.pend is not None: | |||||
# raise self.pend | |||||
if time.time() - self.lastcheck < 10: | if time.time() - self.lastcheck < 10: | ||||
return | return | ||||
@@ -194,45 +195,50 @@ class PYVR(Container): | |||||
# Check to see if any changes have been made | # Check to see if any changes have been made | ||||
self.runCheck() | self.runCheck() | ||||
raise self.pend | |||||
def runCheck(self): | def runCheck(self): | ||||
print 'runCheck' | |||||
self.page = getPage(self.url, method='HEAD') | |||||
self.page.deferred.addErrback(self.errCheck).addCallback( | |||||
self.doCheck) | |||||
self.pend = self.page.deferred | |||||
while True: | |||||
try: | |||||
self.page = urllib2.urlopen(self.url) | |||||
break | |||||
except urllib2.HTTPError: | |||||
time.sleep(.1) | |||||
#self.page = getPage(self.url, method='HEAD') | |||||
#self.page.deferred.addErrback(self.errCheck).addCallback( | |||||
# self.doCheck) | |||||
#self.pend = self.page.deferred | |||||
return self.doCheck(self.page) | |||||
def errCheck(self, x): | def errCheck(self, x): | ||||
print 'errCheck:', `x` | print 'errCheck:', `x` | ||||
self.runCheck() | self.runCheck() | ||||
def doCheck(self, x): | def doCheck(self, x): | ||||
print 'doCheck:', self.page.status | |||||
if self.page.status != '200': | |||||
print 'foo' | |||||
return reactor.callLater(.01, self.runCheck) | |||||
#print 'doCheck:', self.page.status | |||||
#if self.page.status != '200': | |||||
# print 'foo' | |||||
# return reactor.callLater(.01, self.runCheck) | |||||
self.lastcheck = time.time() | self.lastcheck = time.time() | ||||
slm = self.page.response_headers['last-modified'] | |||||
slm = self.page.info()['last-modified'] | |||||
if slm == self.lastmodified: | if slm == self.lastmodified: | ||||
# Page the same, don't do anything | # Page the same, don't do anything | ||||
self.pend = None | |||||
#self.pend = None | |||||
return | return | ||||
self.page = getPage(self.url) | |||||
self.page.deferred.addCallback(self.parsePage) | |||||
self.pend = self.page.deferred | |||||
return self.parsePage(self.page) | |||||
#self.page = getPage(self.url) | |||||
#self.page.deferred.addCallback(self.parsePage) | |||||
#self.pend = self.page.deferred | |||||
return self.pend | |||||
#return self.pend | |||||
def parsePage(self, page): | def parsePage(self, page): | ||||
slm = self.page.response_headers['last-modified'] | |||||
slm = self.page.info()['last-modified'] | |||||
self.lastmodified = slm | self.lastmodified = slm | ||||
del self.page | del self.page | ||||
self.pend = None | |||||
#self.pend = None | |||||
self.newobjs = recxmltoobj(page) | |||||
self.newobjs = recxmltoobj(page.read()) | |||||
self.doUpdate() | self.doUpdate() | ||||
def doUpdate(self): | def doUpdate(self): | ||||
@@ -303,13 +303,14 @@ class ShoutStation(ShoutURL): | |||||
kwargs['mimetype'] = self.station['MimeType'].encode('ascii') | kwargs['mimetype'] = self.station['MimeType'].encode('ascii') | ||||
kwargs['bitrate'] = self.station['Bitrate'] * 128 # 1024k / 8bit | kwargs['bitrate'] = self.station['Bitrate'] * 128 # 1024k / 8bit | ||||
ShoutURL.__init__(*args, **kwargs) | |||||
ShoutURL.__init__(self, *args, **kwargs) | |||||
class ShoutGenre(MusicGenre): | class ShoutGenre(MusicGenre): | ||||
def __init__(self, *args, **kwargs): | def __init__(self, *args, **kwargs): | ||||
self.genre = kwargs['genre'] | self.genre = kwargs['genre'] | ||||
del kwargs['genre'] | del kwargs['genre'] | ||||
self.feeds = ShoutcastFeedAsync(self.genre) | |||||
#self.feeds = ShoutcastFeedAsync(self.genre) | |||||
self.feeds = feeds.ShoutcastFeed(self.genre) | |||||
self.sl = None | self.sl = None | ||||
self.pathObjmap = {} | self.pathObjmap = {} | ||||
@@ -376,7 +377,8 @@ class ShoutCast(Container): | |||||
def __init__(self, *args, **kwargs): | def __init__(self, *args, **kwargs): | ||||
Container.__init__(self, *args, **kwargs) | Container.__init__(self, *args, **kwargs) | ||||
self.genres = GenreFeedAsync() | |||||
#self.genres = GenreFeedAsync() | |||||
self.genres = feeds.GenreFeed() | |||||
self.genre_list = None | self.genre_list = None | ||||
self.pathObjmap = {} | self.pathObjmap = {} | ||||
@@ -402,7 +404,7 @@ class ShoutCast(Container): | |||||
continue | continue | ||||
doupdate = True | doupdate = True | ||||
self.pathObjmap[i] = self.cd.addItem(self.id, | self.pathObjmap[i] = self.cd.addItem(self.id, | ||||
ShoutGenre, i, genre = i) | |||||
ShoutGenre, i, genre=i) | |||||
self.genre_list = nl | self.genre_list = nl | ||||