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 | ||||