def setUp(self): self.downloader = Downloader.Downloader(verbosity=DEBUG) self.transferer = Transferer.Transferer(id="transferer", verbosity=DEBUG_TRANSFERER) self.configFileTransmission = "tests/downloaderTransmission.json" self.configFileSynology = "tests/downloader3.json" self.configFileNone = "tests/downloaderNone.json" self.configFileTvShowSchedule = "tests/tvShowSchedule.json" self.testTransmission = os.path.isfile(self.configFileTransmission) self.tmpdir1 = unicode(tempfile.mkdtemp()) self.tmpdir2 = unicode(tempfile.mkdtemp()) self.transfererData = { "enable": True, "source": { "path": self.tmpdir1, "protocol": "file" }, "destination": { "path": self.tmpdir2, "protocol": "file" }, "delete_after": False, "pathPattern": "{seriesname}/season {seasonnumber}" } self.ts = torrentSearch.torrentSearch( id="torrentSearch", dataFile="tests/torrentSearch2.json", verbosity=DEBUG_TORRENT_SEARCH) self.t = myTvDB.myTvDB(debug=DEBUG, cache=False)
def updateInfo(self,force=False): self.logger.debug("[TvShowSchedule] updateInfo method called") v30DaysAgo = datetime.datetime.now(tzlocal.get_localzone()) - datetime.timedelta(days=30) if force: self['info']['infoUpdate'] = v30DaysAgo # If update is forced or info is indicated and newer than 30 days ago if force or self['info'].setdefault('infoUpdate',v30DaysAgo) <= v30DaysAgo: t = myTvDB.myTvDB() if 'overview' in t[self.seriesid].data.keys() and t[self.seriesid].data['overview'] is not None: overview = t[self.seriesid].data['overview'] else: overview = "" bannerAvailable = ( self.bannerDir is not None and 'banner' in t[self.seriesid].data and t[self.seriesid].data['banner'] is not None ) episodesList = t[self.seriesid].getEpisodesList() arrList = [0] for key in range(1,99): if key in episodesList.keys(): arrList.append(episodesList[key]) else: break episodesList = arrList info={ 'seriesname':t[self.seriesid].data['seriesname'], 'overview':overview, 'infoUpdate':datetime.datetime.now(tzlocal.get_localzone()), 'banner': bannerAvailable, 'episodesList':episodesList } self.set(info=info,autoComplete=False) if bannerAvailable and not self.isBannerUpdated(): self.updateBanner(t[self.seriesid].data['banner']) if self['season'] * self['episode'] > 0: try: t[self.seriesid][self['season']][self['episode']] except: self.logger.error("[tvShowSchedule] {0} S{1:02}E{2:02} does not exist. Reset to next episode" .format(self.seriesid,self['season'],self['episode'])) self.set(season=0,episode=0,status=0,autoComplete=True) return episodeData = t[self.seriesid][self['season']][self['episode']] firstaired = episodeData['firstaired'] if isinstance(firstaired,basestring): firstaired = dateutil.parser.parse(firstaired) if firstaired is None: self.logger.error("[tvShowSchedule] No firstaired for {0}".format(unicode(firstaired))) raise Exception("No firstaired for {0}".format(unicode(firstaired))) if firstaired.tzinfo is None or firstaired.tzinfo.utcoffset(firstaired) is None: firstaired = tzlocal.get_localzone().localize(firstaired) info['firstaired'] = firstaired self.set(info=info,autoComplete=False) self.setDefault() self.logger.debug("[tvShowSchedule] TvShow has been updated. New value:\n {0}".format(unicode(self.data)))
def test_creation_from_MyTvDB_with_defaultKeywords(self): t = myTvDB.myTvDB() tvShow = tvShowSchedule.tvShowScheduleFromMyTvDB( t[123], keywords=['niouf', 'niorf'], verbosity=DEBUG_TVSHOWSCHEDULE) self.assertIsInstance(tvShow, tvShowSchedule.tvShowSchedule) self.assertEqual(tvShow['status'], 0) self.assertEqual(tvShow['keywords'], ['niouf', 'niorf'])
def _cp_dispatch(self,vpath): if len(vpath) == 1: t = myTvDB.myTvDB() try: cherrypy.request.params['result'] = json.dumps(t.livesearch(vpath.pop())) except: return self.index return self.result else: return self.index
def delete(self,tvShowID=-1): self.checkModification() try: tvShowID = int(tvShowID) t = myTvDB.myTvDB() tvShow = t[tvShowID] self.tvshowlist.delete(tvShowID) self.tvshowlist.save() return {"status":200,"error":"TvShow {0} deleted".format(tvShow['seriesname'])} except Exception as e: return self._error(400,e[0])
def _cp_dispatch(self, vpath): if len(vpath) == 1: t = myTvDB.myTvDB() try: cherrypy.request.params['result'] = json.dumps( t.livesearch(vpath.pop())) except: return self.index return self.result else: return self.index
def setUp(self): self.t = myTvDB.myTvDB(debug=DEBUG,cache=False) self.id1 = 123 self.id2 = 321 self.title1 = 'TvShow 1' self.title2 = 'TvShow 2' self.tvShow1 = self.t[self.id1] self.tvShow2 = self.t[self.id2] self.d1 = [{"seriesid":self.id1,"title":self.title1,"status":0}] self.tmpdir1 = unicode(tempfile.mkdtemp()) self.tmpdir2 = unicode(tempfile.mkdtemp()) self.tmpdirBanner = unicode(tempfile.mkdtemp())
def tvShowScheduleFromId(tvShow, bannerDir=None, keywords=None, verbosity=False): t = myTvDB.myTvDB() if not isinstance(tvShow, int): raise TypeError("Incorrect argument: {0}".format( unicode(tvShow).encode('utf8'))) return tvShowScheduleFromMyTvDB(t[int(tvShow)], bannerDir=bannerDir, keywords=keywords, verbosity=verbosity)
def _DELETE(self,tvshow=None): if tvshow is not None: try: tvShowID = int(tvshow) t = myTvDB.myTvDB() tvShow = t[tvShowID] self.tvshowlist.delete(tvShowID) self.tvshowlist.save() return {"status":200,"error":"TvShow {0} deleted".format(tvShow['seriesname'])} except Exception as e: return self._error(400,e[0]) else: return self._error(400,"Unknown TV Show")
def delete(self, tvShowID=-1): self.checkModification() try: tvShowID = int(tvShowID) t = myTvDB.myTvDB() tvShow = t[tvShowID] self.tvshowlist.delete(tvShowID) self.tvshowlist.save() return { "status": 200, "error": "TvShow {0} deleted".format(tvShow['seriesname']) } except Exception as e: return self._error(400, e[0])
def tvShowScheduleFromMyTvDBEpisode(episode,bannerDir=None, keywords=None, verbosity=False): if not isinstance(episode,myTvDB.myEpisode): raise TypeError("Incorrect argument: {0} ({1})".format(unicode(episode).encode('utf8'),type(episode))) tvShow = myTvDB.myTvDB()[int(episode.get(u'seriesid', 0))] tvShowSch = tvShowScheduleFromMyTvDB(tvShow,bannerDir=bannerDir, keywords=keywords,verbosity=verbosity) tvShowSch.set( info={ "firstaired":episode.get(u'firstaired', 0) }, season=int(episode.get(u'seasonnumber', 0)), episode=int(episode.get(u'episodenumber', 0)), status=0, autoComplete=True ) return tvShowSch
def _DELETE(self, tvshow=None): if tvshow is not None: try: tvShowID = int(tvshow) t = myTvDB.myTvDB() tvShow = t[tvShowID] self.tvshowlist.delete(tvShowID) self.tvshowlist.save() return { "status": 200, "error": "TvShow {0} deleted".format(tvShow['seriesname']) } except Exception as e: return self._error(400, e[0]) else: return self._error(400, "Unknown TV Show")
def tvShowScheduleFromMyTvDBEpisode(episode, bannerDir=None, keywords=None, verbosity=False): if not isinstance(episode, myTvDB.myEpisode): raise TypeError("Incorrect argument: {0} ({1})".format( unicode(episode).encode('utf8'), type(episode))) tvShow = myTvDB.myTvDB()[int(episode.get(u'seriesid', 0))] tvShowSch = tvShowScheduleFromMyTvDB(tvShow, bannerDir=bannerDir, keywords=keywords, verbosity=verbosity) tvShowSch.set(info={"firstaired": episode.get(u'firstaired', 0)}, season=int(episode.get(u'seasonnumber', 0)), episode=int(episode.get(u'episodenumber', 0)), status=0, autoComplete=True) return tvShowSch
def add(self, **kwargs): self.checkModification() if 'title' in kwargs.keys(): seriesname = kwargs['title'] if 'seriesid' in kwargs.keys(): serie = int(kwargs['seriesid']) else: serie = seriesname else: serie = unicode(kwargs) seriesname = serie t = myTvDB.myTvDB() try: tvShow = t[serie] except Exception as e: return self._error(400,e[0]+unicode(serie)+unicode(seriesname.lower())) if tvShow.data['seriesname'].lower() == seriesname.lower(): #cherrypy.request.params['tvShowID'] = tvShow.data['id'] return self._add(tvShow.data['id'],tvShow.data['seriesname']) return {"status":401,"error":"Unknown TvShow: '{0}'".format(seriesname)}
def setUp(self): self.downloader = Downloader.Downloader(verbosity=DEBUG) self.transferer = Transferer.Transferer(id="transferer",verbosity=DEBUG_TRANSFERER) self.configFileTransmission = "tests/downloaderTransmission.json" self.configFileSynology = "tests/downloader3.json" self.configFileNone = "tests/downloaderNone.json" self.configFileTvShowSchedule = "tests/tvShowSchedule.json" self.testTransmission = os.path.isfile(self.configFileTransmission) self.tmpdir1 = unicode(tempfile.mkdtemp()) self.tmpdir2 = unicode(tempfile.mkdtemp()) self.transfererData = { "enable":True, "source": {"path": self.tmpdir1, "protocol": "file"}, "destination": {"path": self.tmpdir2, "protocol": "file"}, "delete_after":False, "pathPattern":"{seriesname}/season {seasonnumber}" } self.ts = torrentSearch.torrentSearch(id="torrentSearch",dataFile="tests/torrentSearch2.json",verbosity=DEBUG_TORRENT_SEARCH) self.t = myTvDB.myTvDB(debug=DEBUG,cache=False)
def _POST(self, tvshow=None, **kwargs): if 'title' in kwargs.keys(): seriesname = kwargs['title'] if tvshow is not None: serie = int(tvshow) else: serie = seriesname else: serie = unicode(kwargs) seriesname = serie t = myTvDB.myTvDB() try: tvShow = t[serie] except Exception as e: return self._error( 400, e[0] + unicode(serie) + unicode(seriesname.lower())) if tvShow.data['seriesname'].lower() == seriesname.lower(): try: self.tvshowlist.add(int(serie)) self.tvshowlist.save() tvShow = self.tvshowlist.getTvShow(int(serie)) except Exception as e: return self._error(400, e[0]) return { "status": 200, "error": "TvShow {0} added".format(seriesname), "data": json.loads( json.dumps(tvShow.getValue(), default=Server.json_serial)) } return { "status": 401, "error": "Unknown TvShow: '{0}'".format(seriesname) }
def add(self, **kwargs): self.checkModification() if 'title' in kwargs.keys(): seriesname = kwargs['title'] if 'seriesid' in kwargs.keys(): serie = int(kwargs['seriesid']) else: serie = seriesname else: serie = unicode(kwargs) seriesname = serie t = myTvDB.myTvDB() try: tvShow = t[serie] except Exception as e: return self._error( 400, e[0] + unicode(serie) + unicode(seriesname.lower())) if tvShow.data['seriesname'].lower() == seriesname.lower(): #cherrypy.request.params['tvShowID'] = tvShow.data['id'] return self._add(tvShow.data['id'], tvShow.data['seriesname']) return { "status": 401, "error": "Unknown TvShow: '{0}'".format(seriesname) }
def _POST(self,tvshow=None,**kwargs): if 'title' in kwargs.keys(): seriesname = kwargs['title'] if tvshow is not None: serie = int(tvshow) else: serie = seriesname else: serie = unicode(kwargs) seriesname = serie t = myTvDB.myTvDB() try: tvShow = t[serie] except Exception as e: return self._error(400,e[0]+unicode(serie)+unicode(seriesname.lower())) if tvShow.data['seriesname'].lower() == seriesname.lower(): try: self.tvshowlist.add(int(serie)) self.tvshowlist.save() tvShow = self.tvshowlist.getTvShow(int(serie)) except Exception as e: return self._error(400,e[0]) return {"status":200,"error":"TvShow {0} added".format(seriesname),"data":json.loads(json.dumps(tvShow.getValue(),default=Server.json_serial))} return {"status":401,"error":"Unknown TvShow: '{0}'".format(seriesname)}
def _create_tvdb_api(self): if self.tvdb is None: self.tvdb = myTvDB.myTvDB()
def lastdownloads(self): t = myTvDB.myTvDB() last_downloads = self.activitylog.get_last_downloads() for dl in last_downloads: dl['seriesname'] = t[dl['seriesid']].data['seriesname'] return last_downloads
def setUp(self): wwwoman.wwwomanScenario.scenario_path = "tests/wwwoman/scenario" self.t = myTvDB.myTvDB(debug=DEBUG,cache=False)
def update(self, **kwargs): if 'tvShowID' in kwargs.keys(): tvShowID = int(kwargs['tvShowID']) nextUpdate = None status = None season = None episode = None pattern = None emails = None keywords = None if 'season' in kwargs.keys() and 'episode' in kwargs.keys(): season = int(kwargs['season']) episode = int(kwargs['episode']) t = myTvDB.myTvDB() try: t[tvShowID] except: return { "status": 400, "error": "TvShow {0} does not exist".format(unicode(tvShowID)) } try: t[tvShowID][season][episode] except: return { "status": 400, "error": "No episode S{1:02}E{2:02} for TV show {0}".format( t[tvShowID].data['seriesname'], unicode(season), unicode(episode)) } status = 0 if 'pattern' in kwargs.keys(): pattern = unicode(kwargs['pattern']) if 'emails[]' in kwargs.keys(): if isinstance(kwargs['emails[]'], basestring): emails = [kwargs['emails[]']] else: emails = kwargs['emails[]'] if 'keywords[]' in kwargs.keys(): if isinstance(kwargs['keywords[]'], basestring): keywords = [kwargs['keywords[]']] else: keywords = kwargs['keywords[]'] if any(item in ['season', 'episode', 'keywords[]', 'pattern', 'force'] for item in kwargs.keys()): nextUpdate = datetime.datetime.now(tzlocal.get_localzone()) tvShow = self.tvshowlist.getTvShow(tvShowID) if tvShow is None: raise Exception("{0} not found in {1}".format( tvShowID, list(self.tvshowlist))) fname = "" self.tvshowlist.lock.acquire() try: self.checkModification() tvShow.set(status=status, season=season, episode=episode, nextUpdate=nextUpdate, pattern=pattern, emails=emails, keywords=keywords) self.tvshowlist.save() except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] finally: self.tvshowlist.lock.release() if fname == "": return { "status": 200, "error": "TvShow {0} updated".format(tvShow['info']['seriesname']), "data": json.loads( json.dumps(tvShow.getValue(), default=Server.json_serial)) } else: return self._error( 400, "{0} - {1}:{2}".format(e[0], fname, exc_tb.tb_lineno)) else: return self._error(400, "Unknown TV Show")
def update(self, **kwargs): if 'tvShowID' in kwargs.keys(): tvShowID = int(kwargs['tvShowID']) nextUpdate=None status = None season = None episode=None pattern=None emails=None keywords=None if 'season' in kwargs.keys() and 'episode' in kwargs.keys(): season = int(kwargs['season']) episode = int(kwargs['episode']) t = myTvDB.myTvDB() try: t[tvShowID] except: return {"status":400,"error":"TvShow {0} does not exist".format(unicode(tvShowID))} try: t[tvShowID][season][episode] except: return {"status":400,"error":"No episode S{1:02}E{2:02} for TV show {0}".format(t[tvShowID].data['seriesname'],unicode(season),unicode(episode))} status = 0 if 'pattern' in kwargs.keys(): pattern = unicode(kwargs['pattern']) if 'emails[]' in kwargs.keys(): if isinstance(kwargs['emails[]'],basestring): emails = [kwargs['emails[]']] else: emails = kwargs['emails[]'] if 'keywords[]' in kwargs.keys(): if isinstance(kwargs['keywords[]'],basestring): keywords = [kwargs['keywords[]']] else: keywords = kwargs['keywords[]'] if any(item in ['season','episode','keywords[]','pattern','force'] for item in kwargs.keys()): nextUpdate = datetime.datetime.now(tzlocal.get_localzone()) tvShow = self.tvshowlist.getTvShow(tvShowID) if tvShow is None: raise Exception("{0} not found in {1}".format(tvShowID,list(self.tvshowlist))) fname = "" self.tvshowlist.lock.acquire() try: self.checkModification() tvShow.set( status=status, season=season, episode=episode, nextUpdate=nextUpdate, pattern=pattern, emails=emails, keywords=keywords ) self.tvshowlist.save() except Exception as e: exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] finally: self.tvshowlist.lock.release() if fname == "": return { "status":200, "error":"TvShow {0} updated".format( tvShow['info']['seriesname'] ), "data":json.loads( json.dumps( tvShow.getValue(), default=Server.json_serial ) ) } else: return self._error(400,"{0} - {1}:{2}".format(e[0],fname,exc_tb.tb_lineno)) else: return self._error(400,"Unknown TV Show")
def updateInfo(self, force=False): self.logger.debug("[TvShowSchedule] updateInfo method called") v30DaysAgo = datetime.datetime.now( tzlocal.get_localzone()) - datetime.timedelta(days=30) if force: self['info']['infoUpdate'] = v30DaysAgo # If update is forced or info is indicated and newer than 30 days ago if force or self['info'].setdefault('infoUpdate', v30DaysAgo) <= v30DaysAgo: t = myTvDB.myTvDB() if 'overview' in t[self.seriesid].data.keys() and t[ self.seriesid].data['overview'] is not None: overview = t[self.seriesid].data['overview'] else: overview = "" bannerAvailable = (self.bannerDir is not None and 'banner' in t[self.seriesid].data and t[self.seriesid].data['banner'] is not None) episodesList = t[self.seriesid].getEpisodesList() arrList = [0] for key in range(1, 99): if key in episodesList.keys(): arrList.append(episodesList[key]) else: break episodesList = arrList info = { 'seriesname': t[self.seriesid].data['seriesname'], 'overview': overview, 'infoUpdate': datetime.datetime.now(tzlocal.get_localzone()), 'banner': bannerAvailable, 'episodesList': episodesList } self.set(info=info, autoComplete=False) if bannerAvailable and not self.isBannerUpdated(): self.updateBanner(t[self.seriesid].data['banner']) if self['season'] * self['episode'] > 0: try: t[self.seriesid][self['season']][self['episode']] except: self.logger.error( "[tvShowSchedule] {0} S{1:02}E{2:02} does not exist. Reset to next episode" .format(self.seriesid, self['season'], self['episode'])) self.set(season=0, episode=0, status=0, autoComplete=True) return episodeData = t[self.seriesid][self['season']][self['episode']] firstaired = episodeData['firstaired'] if isinstance(firstaired, basestring): firstaired = dateutil.parser.parse(firstaired) if firstaired is None: self.logger.error( "[tvShowSchedule] No firstaired for {0}".format( unicode(firstaired))) raise Exception("No firstaired for {0}".format( unicode(firstaired))) if firstaired.tzinfo is None or firstaired.tzinfo.utcoffset( firstaired) is None: firstaired = tzlocal.get_localzone().localize(firstaired) info['firstaired'] = firstaired self.set(info=info, autoComplete=False) self.setDefault() self.logger.debug( "[tvShowSchedule] TvShow has been updated. New value:\n {0}". format(unicode(self.data)))
def update(self, downloader=None, searcher=None, transferer=None, notificator=None, activitylog=None, force=False): now = datetime.datetime.now(tzlocal.get_localzone()) try: t = myTvDB.myTvDB() except: self.logger.error("Offline mode. Update canceled") return self._setDownloader(downloader) self._setTorrentSearch(searcher, mandatory=False) self._setTransferer(transferer, mandatory=False) self._setNotificator(notificator, mandatory=False) self._setActivityLog(activitylog, mandatory=False) self.logger.debug( "Next status scheduled on {0} ({2}). It is {1} ({3})".format( unicode(self['nextUpdate']), unicode(now), type(self['nextUpdate']), type(now))) if not self.isInfoUpdated(): self.updateInfo(force=True) try: self['nextUpdate'] < now except: raise Exception(self) if force or self['nextUpdate'] < now: self.logger.debug("Former status: {0}".format(self['status'])) # Added if self['status'] == 0: # Episode identified if self['season'] * self['episode'] > 0: firstaired = tzlocal.get_localzone().localize( datetime.datetime.strptime( t[self['seriesid']][self['season']][ self['episode']]['firstaired'], '%Y-%m-%d')) # Episode already aired, do next step if firstaired < now: self.set(status=20) self.update(force=True) else: # Episode not yet aired. Let's wait for it self._setNotYetAired(t[self['seriesid']][ self['season']][self['episode']]) # No episode identified else: tvShow = t[self['seriesid']] next = tvShow.nextAired() # No next episode. TV show is achieved if next is None: self._setAchieved() else: # Next episode now identified. Let's wait for it. self._setNotYetAired(next) # Not yet aired elif self['status'] == 10: firstaired = tzlocal.get_localzone().localize( datetime.datetime.strptime( t[self['seriesid']][self['season']][self['episode']] ['firstaired'], '%Y-%m-%d')) # Episode now aired. Do next step if firstaired < now: self.set(status=20) self.update(force=True) # Episode still not aired. Let's wait until its broadcast else: self._setNotYetAired( t[self['seriesid']][self['season']][self['episode']]) # Torrent needed elif self['status'] == 20: self._setTorrentSearch(searcher) if 'providers' in self.searcher.keys() and len( self.searcher['providers']) > 0: self.logger.debug("{0} torrent provider(s) found".format( unicode(len(self.searcher['providers'])))) self.set(status=22, nextUpdate=now) else: self.logger.debug("No torrent provider found") self.set(status=21, nextUpdate=now) self.update(force=True) # Torrent required from user elif self['status'] == 21: if 'providers' in self.searcher.keys() and len( self.searcher['providers']) > 0: self.logger.debug("{0} torrent provider(s) found".format( unicode(len(self.searcher['providers'])))) self.set(status=22, nextUpdate=now) self.update(force=True) # else... just waiting nextUpdate = now + datetime.timedelta(minutes=5) self.set(nextUpdate=nextUpdate) # Torrent watch from torrent provider elif self['status'] == 22: self._setTorrentSearch(searcher) if 'providers' not in self.searcher.keys() or len( self.searcher['providers']) < 1: self.set(status=21, nextUpdate=now) if 'keywords' not in self.keys() or len(self['keywords']) < 1: # No keywords keywords = [''] else: keywords = self['keywords'] for keyword in keywords: search_pattern = "{0} S{1:02}E{2:02} {3}".format( self['pattern'], self['season'], self['episode'], keyword) tor = self.searcher.search(search_pattern) # Torrent is found. Process download self.logger.debug( "Torrent is found with pattern '{0}'. Process download" .format(search_pattern)) if tor is not None: tmpFile = self.searcher.download(tor) self.logger.debug( "Torrent downloaded at {0}.".format(tmpFile)) try: downloader_id = unicode( self.downloader.add_torrent(tmpFile)) if downloader_id != '-1': self.set(status=30, downloader_id=downloader_id, nextUpdate=now) self.update(force=True) return else: self.logger.error( "Unknown error when adding torrent") except Downloader.DownloaderConnectionError: # Connection error with downloader. Waiting for 5mins self.logger.error( "Connection error with downloader. Waiting for 5mins" ) nextUpdate = now + datetime.timedelta(minutes=5) self.set(nextUpdate=nextUpdate) return except Downloader.DownloaderCorruptedTorrent: # Torrent found seems corrupted. Waiting for 5mins self.logger.error( "Torrent found seems corrupted. Waiting for 5mins" ) nextUpdate = now + datetime.timedelta(minutes=5) self.set(nextUpdate=nextUpdate) return # If torrent not found wait for 15min. self.logger.debug("Torrent not found") nextUpdate = now + datetime.timedelta(minutes=15) self.set(nextUpdate=nextUpdate) # Download in progress elif self['status'] == 30: self.logger.debug("downloader_id is: {0}".format( self['downloader_id'])) if self['downloader_id'] is not None: # Identifing status try: self.logger.debug( "[tvShowSchedule] Downloader: {0}".format( self.downloader)) status = self.downloader.get_status( self['downloader_id']) self.logger.debug( "[tvShowSchedule] Get new status: {0}".format( status)) except: self.logger.warning( "[tvShowSchedule] Unable to retrieve status for: {0}" .format(unicode(self['downloader_id']))) status = '' if status != '': # Status identified if status == "downloading": # Still downloading. Wait for 15min nextUpdate = now + datetime.timedelta(minutes=15) self.set(nextUpdate=nextUpdate) elif status == "seeding": # Download achieved. To be transfered. self.set(status=35) self.update(force=True) elif status in ['paused', 'stopped']: # Download paused. Restarting. self.set(status=33) self.update(force=True) else: # Unhandled status nextUpdate = now + datetime.timedelta(minutes=15) self.set(nextUpdate=nextUpdate) else: # Incorrect or missing torrent. Let's watch torrent again. self.set(status=20) self.update(force=True) else: # Incorrect or missing downloader identifier. Let's watch torrent again. self.logger.error( "Unable to determine slot. Push the status to 20") self.set(status=20) self.update(force=True) # Paused elif self['status'] == 33: self.logger.debug("downloader_id is: {0}".format( self['downloader_id'])) if self['downloader_id'] is not None: self.logger.debug("Starting on {0}".format( self.downloader)) self.downloader.start_torrent(self['downloader_id']) nextUpdate = now + datetime.timedelta(minutes=15) self.set(status=30, nextUpdate=nextUpdate) else: self.logger.error( "Unable to determine slot. Push the status to 20") self.set(status=20) self.update(force=True) # To be transfered elif self['status'] == 35: self.logger.debug("downloader_id is: {0}".format( self['downloader_id'])) if self['downloader_id'] is not None: # Identifing status try: self.logger.debug("Downloader: {0}".format( self.downloader)) status = self.downloader.get_status( self['downloader_id']) self.logger.debug("Get new status: {0}".format(status)) except: status = '' if status != '': # Status identified if status == "downloading": # Still downloading. Download in progress. Wait for 15min nextUpdate = now + datetime.timedelta(minutes=15) self.set(status=30, nextUpdate=nextUpdate) elif status == "seeding": # Transfer torrent self.downloadTorrent() else: # Incorrect or missing torrent. Let's watch torrent again. self.set(status=20) self.update(force=True) else: # Incorrect or missing downloader identifier. Let's watch torrent again. self.set(status=20) self.update(force=True) # Download completed elif self['status'] == 39: notifContent = "{0} S{1:02}E{2:02} has been downloaded.\n".format( self['info']['seriesname'], self['season'], self['episode']) # Schedule next episode tvShow = t[self['seriesid']][self['season']][self['episode']] self.logger.debug( "[tvShowSchedule] Current episode: {0}".format( unicode(tvShow))) next = tvShow.next() self.logger.debug("[tvShowSchedule] Next episode: {0}".format( unicode(next))) if next is None: self._setAchieved() notifContent += "Unfortunatly, for moment, it is the last episode scheduled for this TV show :(" else: self.set(season=int(next['seasonnumber']), episode=int(next['episodenumber']), status=0) self.update(force=True) notifContent += "The next episode (S{0:02}E{1:02}) is expected on {2}".format( self['season'], self['episode'], self['info']['firstaired']) if self.notificator is not None: self.notificator.send("Download completed!", notifContent, self['emails']) # Broadcast achieved elif self['status'] == 90: tvShow = t[self['seriesid']] next = tvShow.nextAired() if next is None: self._setAchieved() else: self._setNotYetAired(next) else: # Incorrect or missing status. Put status to 0 self.set(status=0) self.update(force=True)
def update(self,downloader=None,searcher=None,transferer=None,notificator=None,activitylog=None,force=False): now = datetime.datetime.now(tzlocal.get_localzone()) try: t = myTvDB.myTvDB() except: self.logger.error("Offline mode. Update canceled") return self._setDownloader(downloader) self._setTorrentSearch(searcher,mandatory=False) self._setTransferer(transferer,mandatory=False) self._setNotificator(notificator,mandatory=False) self._setActivityLog(activitylog,mandatory=False) self.logger.debug("Next status scheduled on {0} ({2}). It is {1} ({3})".format(unicode(self['nextUpdate']),unicode(now),type(self['nextUpdate']),type(now))) if not self.isInfoUpdated(): self.updateInfo(force=True) try: self['nextUpdate'] < now except: raise Exception(self) if force or self['nextUpdate'] < now: self.logger.debug("Former status: {0}".format(self['status'])) # Added if self['status'] == 0: # Episode identified if self['season'] * self['episode'] > 0: firstaired = tzlocal.get_localzone().localize(datetime.datetime.strptime(t[self['seriesid']][self['season']][self['episode']]['firstaired'],'%Y-%m-%d')) # Episode already aired, do next step if firstaired < now: self.set(status=20) self.update(force=True) else: # Episode not yet aired. Let's wait for it self._setNotYetAired(t[self['seriesid']][self['season']][self['episode']]) # No episode identified else: tvShow = t[self['seriesid']] next = tvShow.nextAired() # No next episode. TV show is achieved if next is None: self._setAchieved() else: # Next episode now identified. Let's wait for it. self._setNotYetAired(next) # Not yet aired elif self['status'] == 10: firstaired = tzlocal.get_localzone().localize(datetime.datetime.strptime(t[self['seriesid']][self['season']][self['episode']]['firstaired'],'%Y-%m-%d')) # Episode now aired. Do next step if firstaired < now: self.set(status=20) self.update(force=True) # Episode still not aired. Let's wait until its broadcast else: self._setNotYetAired(t[self['seriesid']][self['season']][self['episode']]) # Torrent needed elif self['status'] == 20: self._setTorrentSearch(searcher) if 'providers' in self.searcher.keys() and len(self.searcher['providers'])>0: self.logger.debug( "{0} torrent provider(s) found" .format(unicode(len(self.searcher['providers'])))) self.set(status=22,nextUpdate=now) else: self.logger.debug("No torrent provider found") self.set(status=21,nextUpdate=now) self.update(force=True) # Torrent required from user elif self['status'] == 21: if 'providers' in self.searcher.keys() and len(self.searcher['providers'])>0: self.logger.debug( "{0} torrent provider(s) found" .format(unicode(len(self.searcher['providers'])))) self.set(status=22,nextUpdate=now) self.update(force=True) # else... just waiting nextUpdate = now+datetime.timedelta(minutes=5) self.set(nextUpdate=nextUpdate) # Torrent watch from torrent provider elif self['status'] == 22: self._setTorrentSearch(searcher) if 'providers' not in self.searcher.keys() or len(self.searcher['providers'])<1: self.set(status=21,nextUpdate=now) if 'keywords' not in self.keys() or len(self['keywords']) < 1: # No keywords keywords = [''] else: keywords = self['keywords'] for keyword in keywords: search_pattern = "{0} S{1:02}E{2:02} {3}".format(self['pattern'],self['season'],self['episode'],keyword) tor = self.searcher.search(search_pattern) # Torrent is found. Process download self.logger.debug("Torrent is found with pattern '{0}'. Process download".format(search_pattern)) if tor is not None: tmpFile = self.searcher.download(tor) self.logger.debug("Torrent downloaded at {0}.".format(tmpFile)) try: downloader_id=unicode(self.downloader.add_torrent(tmpFile)) if downloader_id != '-1': self.set(status=30,downloader_id=downloader_id,nextUpdate=now) self.update(force=True) return else: self.logger.error("Unknown error when adding torrent") except Downloader.DownloaderConnectionError: # Connection error with downloader. Waiting for 5mins self.logger.error("Connection error with downloader. Waiting for 5mins") nextUpdate = now+datetime.timedelta(minutes=5) self.set(nextUpdate=nextUpdate) return except Downloader.DownloaderCorruptedTorrent: # Torrent found seems corrupted. Waiting for 5mins self.logger.error("Torrent found seems corrupted. Waiting for 5mins") nextUpdate = now+datetime.timedelta(minutes=5) self.set(nextUpdate=nextUpdate) return # If torrent not found wait for 15min. self.logger.debug("Torrent not found") nextUpdate = now+datetime.timedelta(minutes=15) self.set(nextUpdate=nextUpdate) # Download in progress elif self['status'] == 30: self.logger.debug("downloader_id is: {0}".format(self['downloader_id'])) if self['downloader_id'] is not None: # Identifing status try: self.logger.debug("[tvShowSchedule] Downloader: {0}".format(self.downloader)) status = self.downloader.get_status(self['downloader_id']) self.logger.debug("[tvShowSchedule] Get new status: {0}".format(status)) except: self.logger.warning("[tvShowSchedule] Unable to retrieve status for: {0}".format(unicode(self['downloader_id']))) status = '' if status != '': # Status identified if status == "downloading": # Still downloading. Wait for 15min nextUpdate = now+datetime.timedelta(minutes=15) self.set(nextUpdate=nextUpdate) elif status == "seeding": # Download achieved. To be transfered. self.set(status=35) self.update(force=True) elif status in ['paused','stopped']: # Download paused. Restarting. self.set(status=33) self.update(force=True) else: # Unhandled status nextUpdate = now+datetime.timedelta(minutes=15) self.set(nextUpdate=nextUpdate) else: # Incorrect or missing torrent. Let's watch torrent again. self.set(status=20) self.update(force=True) else: # Incorrect or missing downloader identifier. Let's watch torrent again. self.logger.error("Unable to determine slot. Push the status to 20") self.set(status=20) self.update(force=True) # Paused elif self['status'] == 33: self.logger.debug("downloader_id is: {0}".format(self['downloader_id'])) if self['downloader_id'] is not None: self.logger.debug("Starting on {0}".format(self.downloader)) self.downloader.start_torrent(self['downloader_id']) nextUpdate = now+datetime.timedelta(minutes=15) self.set(status=30,nextUpdate=nextUpdate) else: self.logger.error("Unable to determine slot. Push the status to 20") self.set(status=20) self.update(force=True) # To be transfered elif self['status'] == 35: self.logger.debug("downloader_id is: {0}".format(self['downloader_id'])) if self['downloader_id'] is not None: # Identifing status try: self.logger.debug("Downloader: {0}".format(self.downloader)) status = self.downloader.get_status(self['downloader_id']) self.logger.debug("Get new status: {0}".format(status)) except: status = '' if status != '': # Status identified if status == "downloading": # Still downloading. Download in progress. Wait for 15min nextUpdate = now+datetime.timedelta(minutes=15) self.set(status=30,nextUpdate=nextUpdate) elif status == "seeding": # Transfer torrent self.downloadTorrent() else: # Incorrect or missing torrent. Let's watch torrent again. self.set(status=20) self.update(force=True) else: # Incorrect or missing downloader identifier. Let's watch torrent again. self.set(status=20) self.update(force=True) # Download completed elif self['status'] == 39: notifContent = "{0} S{1:02}E{2:02} has been downloaded.\n".format(self['info']['seriesname'],self['season'],self['episode']) # Schedule next episode tvShow = t[self['seriesid']][self['season']][self['episode']] self.logger.debug("[tvShowSchedule] Current episode: {0}".format(unicode(tvShow))) next = tvShow.next() self.logger.debug("[tvShowSchedule] Next episode: {0}".format(unicode(next))) if next is None: self._setAchieved() notifContent += "Unfortunatly, for moment, it is the last episode scheduled for this TV show :(" else: self.set(season=int(next['seasonnumber']),episode=int(next['episodenumber']),status=0) self.update(force=True) notifContent += "The next episode (S{0:02}E{1:02}) is expected on {2}".format(self['season'],self['episode'],self['info']['firstaired']) if self.notificator is not None: self.notificator.send("Download completed!",notifContent,self['emails']) # Broadcast achieved elif self['status'] == 90: tvShow = t[self['seriesid']] next = tvShow.nextAired() if next is None: self._setAchieved() else: self._setNotYetAired(next) else: # Incorrect or missing status. Put status to 0 self.set(status=0) self.update(force=True)
def tvShowScheduleFromId(tvShow,bannerDir=None, keywords=None, verbosity=False): t = myTvDB.myTvDB() if not isinstance(tvShow,int): raise TypeError("Incorrect argument: {0}".format(unicode(tvShow).encode('utf8'))) return tvShowScheduleFromMyTvDB(t[int(tvShow)],bannerDir=bannerDir, keywords=keywords,verbosity=verbosity)
def test_creation_from_MyTvDB(self): t = myTvDB.myTvDB() tvShow = tvShowSchedule.tvShowScheduleFromMyTvDB( t[123], verbosity=DEBUG_TVSHOWSCHEDULE) self.assertIsInstance(tvShow, tvShowSchedule.tvShowSchedule) self.assertEqual(tvShow['status'], 0)
def test_creation_from_MyTvDB(self): t = myTvDB.myTvDB() tvShow = tvShowSchedule.tvShowScheduleFromMyTvDB(t[123],verbosity=DEBUG_TVSHOWSCHEDULE) self.assertIsInstance(tvShow,tvShowSchedule.tvShowSchedule) self.assertEqual(tvShow['status'],0)
def test_creation_from_MyTvDB_with_defaultKeywords(self): t = myTvDB.myTvDB() tvShow = tvShowSchedule.tvShowScheduleFromMyTvDB(t[123],keywords=['niouf','niorf'],verbosity=DEBUG_TVSHOWSCHEDULE) self.assertIsInstance(tvShow,tvShowSchedule.tvShowSchedule) self.assertEqual(tvShow['status'],0) self.assertEqual(tvShow['keywords'],['niouf','niorf'])