diff --git a/gui/slick/views/errorlogs.mako b/gui/slick/views/errorlogs.mako index a3ff82f76259370f5a72a05b0544367eec5de429..47e52a636cf2d74bdc2cc41bc84c29a33adb0692 100644 --- a/gui/slick/views/errorlogs.mako +++ b/gui/slick/views/errorlogs.mako @@ -20,10 +20,10 @@ pre { <% if logLevel == sickbeard.logger.WARNING: errors = classes.WarningViewer.errors - title = 'Logs & Errors [WARNING]' + title = 'WARNING logs' else: errors = classes.ErrorViewer.errors - title = 'Logs & Errors [ERROR]' + title = 'ERROR logs' %> <h1 class="header">${title}</h1> <div class="align-left"><pre> diff --git a/sickbeard/notifiers/plex.py b/sickbeard/notifiers/plex.py index 35f8aeaa14a73cd67da3fe48555805bbf0344634..0c9d8f452b064b2dfe32bc9c37f288380559f42b 100644 --- a/sickbeard/notifiers/plex.py +++ b/sickbeard/notifiers/plex.py @@ -66,7 +66,7 @@ class PLEXNotifier: enc_command = urllib.urlencode(command) logger.log(u'PLEX: Encoded API command: ' + enc_command, logger.DEBUG) - url = u'http://%s/xbmcCmds/xbmcHttp/?%s' % (host, enc_command) + url = u'https://%s/xbmcCmds/xbmcHttp/?%s' % (host, enc_command) try: req = urllib2.Request(url) # if we have a password, use authentication @@ -219,7 +219,7 @@ class PLEXNotifier: hosts_failed = [] for cur_host in host_list: - url = 'http://%s/library/sections%s' % (cur_host, token_arg) + url = 'https://%s/library/sections%s' % (cur_host, token_arg) try: xml_tree = etree.parse(urllib.urlopen(url)) media_container = xml_tree.getroot() @@ -261,7 +261,7 @@ class PLEXNotifier: host_list = [] for section_key, cur_host in hosts_try.iteritems(): - url = 'http://%s/library/sections/%s/refresh%s' % (cur_host, section_key, token_arg) + url = 'https://%s/library/sections/%s/refresh%s' % (cur_host, section_key, token_arg) try: force and urllib.urlopen(url) host_list.append(cur_host) diff --git a/sickbeard/providers/nextgen.py b/sickbeard/providers/nextgen.py index 4c3236a340b7ed38ed5a13d50e0961dd76ccdd96..2ef9116c72d190888d05deb40cef135cbd700991 100644 --- a/sickbeard/providers/nextgen.py +++ b/sickbeard/providers/nextgen.py @@ -48,12 +48,9 @@ class NextGenProvider(generic.TorrentProvider): self.cache = NextGenCache(self) - self.urls = {'base_url': 'https://nxgn.org/', - 'search': 'https://nxgn.org/browse.php?search=%s&cat=0&incldead=0&modes=%s', - 'login_page': 'https://nxgn.org/login.php', - 'detail': 'https://nxgn.org/details.php?id=%s', - 'download': 'https://nxgn.org/download.php?id=%s', - 'takelogin': 'https://nxgn.org/takelogin.php?csrf=', + self.urls = {'base_url': 'https://nxtgn.info/', + 'search': 'https://nxtgn.info/browse.php?search=%s&cat=0&incldead=0&modes=%s', + 'login_page': 'https://nxtgn.info/login.php', } self.url = self.urls['base_url'] @@ -66,6 +63,7 @@ class NextGenProvider(generic.TorrentProvider): self.minseed = 0 self.minleech = 0 + self.freeleech = True def isEnabled(self): return self.enabled @@ -157,44 +155,42 @@ class NextGenProvider(generic.TorrentProvider): #Xirg STANDARD TORRENTS #Continue only if one Release is found - if len(entries) > 0: - - for result in entries: - - try: - torrentName = \ - ((result.find('div', attrs={'id': 'torrent-udgivelse2-users'})).find('a'))['title'] - torrentId = ( - ((result.find('div', attrs={'id': 'torrent-download'})).find('a'))['href']).replace( - 'download.php?id=', '') - title = str(torrentName) - download_url = (self.urls['download'] % torrentId).encode('utf8') - torrent_details_url = (self.urls['detail'] % torrentId).encode('utf8') - seeders = int(result.find('div', attrs = {'id' : 'torrent-seeders'}).a.text) - leechers = int(result.find('div', attrs = {'id' : 'torrent-leechers'}).a.text) - #FIXME - size = -1 - except (AttributeError, TypeError): - continue - - if not all([title, download_url]): - continue - - #Filter unseeded torrent - if seeders < self.minseed or leechers < self.minleech: - if mode != 'RSS': - logger.log(u"Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format(title, seeders, leechers), logger.DEBUG) - continue - - item = title, download_url, size, seeders, leechers + if not entries: + logger.log(u"Data returned from provider does not contain any torrents", logger.DEBUG) + continue + + for result in entries: + + try: + title = result.find('div', attrs={'id': 'torrent-udgivelse2-users'}).a['title'] + + dl = result.find('div', attrs={'id': 'torrent-download'}).a + download_url = self.urls['base_url'] + (dl['href'], dl['id'])['id' in dl] + + seeders = int(result.find('div', attrs={'id' : 'torrent-seeders'}).text) + leechers = int(result.find('div', attrs={'id' : 'torrent-leechers'}).text) + size = self._convertSize(result.find('div', attrs={'id' : 'torrent-size'}).text) + freeleech = result.find('div', attrs={'id': 'browse-mode-F2L'}) is not None + except (AttributeError, TypeError, KeyError): + continue + + if self.freeleech and not freeleech: + continue + + if not all([title, download_url]): + continue + + #Filter unseeded torrent + if seeders < self.minseed or leechers < self.minleech: if mode != 'RSS': - logger.log(u"Found result: %s " % title, logger.DEBUG) + logger.log(u"Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format(title, seeders, leechers), logger.DEBUG) + continue - items[mode].append(item) + item = title, download_url, size, seeders, leechers + if mode != 'RSS': + logger.log(u"Found result: %s " % title, logger.DEBUG) - else: - logger.log(u"Data returned from provider does not contain any torrents", logger.DEBUG) - continue + items[mode].append(item) except Exception, e: logger.log(u"Failed parsing provider. Traceback: %s" % traceback.format_exc(), logger.ERROR) @@ -206,6 +202,19 @@ class NextGenProvider(generic.TorrentProvider): return results + def _convertSize(self, size): + size, modifier = size[:-2], size[-2:] + size = float(size) + if modifier in 'KB': + size = size * 1024 + elif modifier in 'MB': + size = size * 1024**2 + elif modifier in 'GB': + size = size * 1024**3 + elif modifier in 'TB': + size = size * 1024**4 + return int(size) + def findPropers(self, search_date=datetime.datetime.today()): results = [] diff --git a/sickbeard/providers/tntvillage.py b/sickbeard/providers/tntvillage.py index 98ca49f663d690a34cb05147b0ad0d54eea57f1e..560255c6dda268a8f5be3b9d199f149a7a81b873 100644 --- a/sickbeard/providers/tntvillage.py +++ b/sickbeard/providers/tntvillage.py @@ -360,15 +360,6 @@ class TNTVillageProvider(generic.TorrentProvider): except (AttributeError, TypeError): continue - if not all([title, download_url]): - continue - - #Filter unseeded torrent - if seeders < self.minseed or leechers < self.minleech: - if mode != 'RSS': - logger.log(u"Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format(title, seeders, leechers), logger.DEBUG) - continue - filename_qt = self._reverseQuality(self._episodeQuality(result)) for text in self.hdtext: title1 = title @@ -397,9 +388,18 @@ class TNTVillageProvider(generic.TorrentProvider): new_title = search_show + ep_params title = new_title + if not all([title, download_url]): + continue + if self._is_season_pack(title): title = re.sub(r'([Ee][\d{1,2}\-?]+)', '', title) + #Filter unseeded torrent + if seeders < self.minseed or leechers < self.minleech: + if mode != 'RSS': + logger.log(u"Discarding torrent because it doesn't meet the minimum seeders or leechers: {0} (S:{1} L:{2})".format(title, seeders, leechers), logger.DEBUG) + continue + item = title, download_url, size, seeders, leechers if mode != 'RSS': logger.log(u"Found result: %s " % title, logger.DEBUG) diff --git a/sickbeard/providers/torrentbytes.py b/sickbeard/providers/torrentbytes.py index 2680da69bd6d548364f4cb1e072dadba6c124bb7..249562a8fe141565dcfe64f771da89f4a8dfdefb 100644 --- a/sickbeard/providers/torrentbytes.py +++ b/sickbeard/providers/torrentbytes.py @@ -99,7 +99,7 @@ class TorrentBytesProvider(generic.TorrentProvider): if mode != 'RSS': logger.log(u"Search string: %s " % search_string, logger.DEBUG) - searchURL = self.urls['search'] % (urllib.quote(search_string), self.categories) + searchURL = self.urls['search'] % (urllib.quote(search_string.encode('utf-8')), self.categories) logger.log(u"Search URL: %s" % searchURL, logger.DEBUG) data = self.getURL(searchURL) diff --git a/sickbeard/providers/torrentleech.py b/sickbeard/providers/torrentleech.py index e6b26ff9486e5abd71259236949b22805908f3a1..5eb6d24872e22cc69e7348dcff04fb0e30293f94 100644 --- a/sickbeard/providers/torrentleech.py +++ b/sickbeard/providers/torrentleech.py @@ -102,7 +102,7 @@ class TorrentLeechProvider(generic.TorrentProvider): if mode == 'RSS': searchURL = self.urls['index'] % self.categories else: - searchURL = self.urls['search'] % (urllib.quote(search_string), self.categories) + searchURL = self.urls['search'] % (urllib.quote_plus(search_string.encode('utf-8')), self.categories) logger.log(u"Search string: %s " % search_string, logger.DEBUG) data = self.getURL(searchURL) diff --git a/sickbeard/scene_exceptions.py b/sickbeard/scene_exceptions.py index f3a111eaf062e2dd9104d9cb82af2f6cac67c777..ed926d62586c00e321af61f412c2f560f10d2aac 100644 --- a/sickbeard/scene_exceptions.py +++ b/sickbeard/scene_exceptions.py @@ -197,7 +197,7 @@ def retrieve_exceptions(): if data is None: # When data is None, trouble connecting to github, or reading file failed - logger.log(u"Check scene exceptions update failed. Unable to update from: " + loc, logger.WARNING) + logger.log(u"Check scene exceptions update failed. Unable to update from: " + loc, logger.DEBUG) continue setLastRefresh(sickbeard.indexerApi(indexer).name) @@ -315,7 +315,7 @@ def _xem_exceptions_fetcher(): parsedJSON = helpers.getURL(url, session=xem_session, timeout = 90, json=True) if not parsedJSON: logger.log(u"Check scene exceptions update failed for " + sickbeard.indexerApi( - indexer).name + ", Unable to get URL: " + url, logger.ERROR) + indexer).name + ", Unable to get URL: " + url, logger.DEBUG) continue if parsedJSON['result'] == 'failure': diff --git a/sickbeard/subtitles.py b/sickbeard/subtitles.py index de96406bab879e9ac409d892f0e1dfe83cd02188..ac1ecea3fde5f3cd21bceca4251ab3e35075a8d8 100644 --- a/sickbeard/subtitles.py +++ b/sickbeard/subtitles.py @@ -135,7 +135,7 @@ def downloadSubtitles(subtitles_info): logger.log(u'%s: No subtitles found for S%02dE%02d on any provider' % (subtitles_info['show.indexerid'], subtitles_info['season'], subtitles_info['episode']), logger.DEBUG) return (existing_subtitles, None) - subliminal.save_subtitles(video, found_subtitles[video], directory=subtitles_path, single=not sickbeard.SUBTITLES_MULTI) + subliminal.save_subtitles(video, found_subtitles[video], directory=subtitles_path, single=not sickbeard.SUBTITLES_MULTI, encoding='utf-8') for video, subtitles in found_subtitles.iteritems(): for subtitle in subtitles: diff --git a/sickbeard/tv.py b/sickbeard/tv.py index 8a8d96d01ea0ef711578dc653b3f2dbed607982f..6ee0a7fb61056f92f5c09c1e89fd51bde4dc109c 100644 --- a/sickbeard/tv.py +++ b/sickbeard/tv.py @@ -264,7 +264,7 @@ class TVShow(object): episode = int(sqlResults[0]["episode"]) season = int(sqlResults[0]["season"]) logger.log( - "Found episode by absolute_number %s which is S%02dE%02d" % (absolute_number, season, episode), logger.DEBUG) + "Found episode by absolute_number %s which is S%02dE%02d" % (absolute_number, season or 0, episode or 0), logger.DEBUG) elif len(sqlResults) > 1: logger.log("Multiple entries for absolute number: " + str( absolute_number) + " in show: " + self.name + " found ", logger.ERROR) @@ -282,7 +282,7 @@ class TVShow(object): if noCreate: return None - #logger.log(str(self.indexerid) + u": An object for episode S%02dE%02d didn't exist in the cache, trying to create it" % (season, episode), logger.DEBUG) + #logger.log(str(self.indexerid) + u": An object for episode S%02dE%02d didn't exist in the cache, trying to create it" % (season or 0, episode or 0), logger.DEBUG) if file: ep = TVEpisode(self, season, episode, file) @@ -375,7 +375,7 @@ class TVShow(object): sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE showid = ? AND location != ''", [self.indexerid]) for epResult in sqlResults: - logger.log(str(self.indexerid) + u": Retrieving/creating episode S%02dE%02d" % (epResult["season"], epResult["episode"]), logger.DEBUG) + logger.log(str(self.indexerid) + u": Retrieving/creating episode S%02dE%02d" % (epResult["season"] or 0, epResult["episode"] or 0), logger.DEBUG) curEp = self.getEpisode(epResult["season"], epResult["episode"]) if not curEp: continue @@ -517,7 +517,7 @@ class TVShow(object): logger.log(u"Not curSeason in scannedEps", logger.DEBUG) scannedEps[curSeason] = {} - logger.log(u"%s: Loading episode S%02dE%02d from the DB" % (curShowid, curSeason, curEpisode), logger.DEBUG) + logger.log(u"%s: Loading episode S%02dE%02d from the DB" % (curShowid, curSeason or 0, curEpisode or 0), logger.DEBUG) try: curEp = self.getEpisode(curSeason, curEpisode) @@ -579,7 +579,7 @@ class TVShow(object): if not ep: raise EpisodeNotFoundException except EpisodeNotFoundException: - logger.log("%s: %s object for S%02dE%02d is incomplete, skipping this episode" % (self.indexerid, sickbeard.indexerApi(self.indexer).name, season, episode)) + logger.log("%s: %s object for S%02dE%02d is incomplete, skipping this episode" % (self.indexerid, sickbeard.indexerApi(self.indexer).name, season or 0, episode or 0)) continue else: try: @@ -589,7 +589,7 @@ class TVShow(object): continue with ep.lock: - logger.log("%s: Loading info from %s for episode S%02dE%02d" % (self.indexerid, sickbeard.indexerApi(self.indexer).name, season, episode),logger.DEBUG) + logger.log("%s: Loading info from %s for episode S%02dE%02d" % (self.indexerid, sickbeard.indexerApi(self.indexer).name, season or 0, episode or 0),logger.DEBUG) ep.loadFromIndexer(season, episode, tvapi=t) sql_l.append(ep.get_sql()) @@ -660,7 +660,7 @@ class TVShow(object): episode = int(curEpNum) - logger.log("%s: %s parsed to %s S%02dE%02d" % (self.indexerid, file, self.name, season, episode), logger.DEBUG) + logger.log("%s: %s parsed to %s S%02dE%02d" % (self.indexerid, file, self.name, season or 0, episode or 0), logger.DEBUG) checkQualityAgain = False same_file = False @@ -988,7 +988,7 @@ class TVShow(object): logger.DEBUG) self.nextaired = "" else: - logger.log(u"%s: Found episode S%02dE%02d" % (self.indexerid, sqlResults[0]["season"], sqlResults[0]["episode"] ) , logger.DEBUG) + logger.log(u"%s: Found episode S%02dE%02d" % (self.indexerid, sqlResults[0]["season"] or 0, sqlResults[0]["episode"] or 0) , logger.DEBUG) self.nextaired = sqlResults[0]['airdate'] return self.nextaired @@ -1107,7 +1107,7 @@ class TVShow(object): new_status = sickbeard.EP_DEFAULT_DELETED_STATUS logger.log(u"%s: Location for S%02dE%02d doesn't exist, removing it and changing our status to %s" % - (self.indexerid, season, episode, statusStrings[new_status]) ,logger.DEBUG) + (self.indexerid, season or 0, episode or 0, statusStrings[new_status]) ,logger.DEBUG) curEp.status = new_status curEp.subtitles = list() curEp.subtitles_searchcount = 0 @@ -1239,7 +1239,7 @@ class TVShow(object): def wantEpisode(self, season, episode, quality, manualSearch=False, downCurQuality=False): - logger.log(u"Checking if found episode %s S%02dE%02d is wanted at quality %s" % (self.name, season, episode, Quality.qualityStrings[quality]) , logger.DEBUG) + logger.log(u"Checking if found episode %s S%02dE%02d is wanted at quality %s" % (self.name, season or 0, episode or 0, Quality.qualityStrings[quality]) , logger.DEBUG) # if the quality isn't one we want under any circumstances then just say no anyQualities, bestQualities = Quality.splitQuality(self.quality) @@ -1442,10 +1442,10 @@ class TVEpisode(object): def downloadSubtitles(self, force=False): if not ek(os.path.isfile, self.location): logger.log(u"%s: Episode file doesn't exist, can't download subtitles for S%02dE%02d" % - (self.show.indexerid, self.season, self.episode), logger.DEBUG) + (self.show.indexerid, self.season or 0, self.episode or 0), logger.DEBUG) return - logger.log(u"%s: Downloading subtitles for S%02dE%02d" % (self.show.indexerid, self.season, self.episode), logger.DEBUG) + logger.log(u"%s: Downloading subtitles for S%02dE%02d" % (self.show.indexerid, self.season or 0, self.episode or 0), logger.DEBUG) #logging.getLogger('subliminal.api').addHandler(logging.StreamHandler()) #logging.getLogger('subliminal.api').setLevel(logging.DEBUG) @@ -1464,12 +1464,12 @@ class TVEpisode(object): if newSubtitles: subtitleList = ", ".join([subtitles.fromietf(newSub).name for newSub in newSubtitles]) logger.log(u"%s: Downloaded %s subtitles for S%02dE%02d" % - (self.show.indexerid, subtitleList, self.season, self.episode), logger.DEBUG) + (self.show.indexerid, subtitleList, self.season or 0, self.episode or 0), logger.DEBUG) notifiers.notify_subtitle_download(self.prettyName(), subtitleList) else: logger.log(u"%s: No subtitles downloaded for S%02dE%02d" % - (self.show.indexerid, self.season, self.episode), logger.DEBUG) + (self.show.indexerid, self.season or 0, self.episode or 0), logger.DEBUG) def checkForMetaFiles(self): @@ -1510,7 +1510,7 @@ class TVEpisode(object): try: self.loadFromNFO(self.location) except NoNFOException: - logger.log(u"%s: There was an error loading the NFO for episode S%02dE%02d" % (self.show.indexerid, season, episode), logger.ERROR) + logger.log(u"%s: There was an error loading the NFO for episode S%02dE%02d" % (self.show.indexerid, season or 0, episode or 0), logger.ERROR) # if we tried loading it from NFO and didn't find the NFO, try the Indexers if not self.hasnfo: @@ -1521,10 +1521,10 @@ class TVEpisode(object): # if we failed SQL *and* NFO, Indexers then fail if not result: - raise EpisodeNotFoundException("Couldn't find episode S%02dE%02d" % (season, episode)) + raise EpisodeNotFoundException("Couldn't find episode S%02dE%02d" % (season or 0, episode or 0)) def loadFromDB(self, season, episode): - logger.log(u"%s: Loading episode details from DB for episode %s S%02dE%02d" % (self.show.indexerid, self.show.name, season, episode), logger.DEBUG) + logger.log(u"%s: Loading episode details from DB for episode %s S%02dE%02d" % (self.show.indexerid, self.show.name, season or 0, episode or 0), logger.DEBUG) myDB = db.DBConnection() sqlResults = myDB.select("SELECT * FROM tv_episodes WHERE showid = ? AND season = ? AND episode = ?", @@ -1533,7 +1533,7 @@ class TVEpisode(object): if len(sqlResults) > 1: raise MultipleEpisodesInDatabaseException("Your DB has two records for the same show somehow.") elif len(sqlResults) == 0: - logger.log(u"%s: Episode S%02dE%02d not found in the database" % (self.show.indexerid, self.season, self.episode), logger.DEBUG) + logger.log(u"%s: Episode S%02dE%02d not found in the database" % (self.show.indexerid, self.season or 0, self.episode or 0), logger.DEBUG) return False else: # NAMEIT logger.log(u"AAAAA from" + str(self.season)+"x"+str(self.episode) + " -" + self.name + " to " + str(sqlResults[0]["name"])) @@ -1619,7 +1619,7 @@ class TVEpisode(object): episode = self.episode logger.log(u"%s: Loading episode details from %s for episode S%02dE%02d" % - (self.show.indexerid, sickbeard.indexerApi(self.show.indexer).name, season, episode) , logger.DEBUG) + (self.show.indexerid, sickbeard.indexerApi(self.show.indexer).name, season or 0, episode or 0) , logger.DEBUG) indexer_lang = self.show.lang @@ -1665,7 +1665,7 @@ class TVEpisode(object): return if getattr(myEp, 'episodename', None) is None: - logger.log(u"This episode %s - S%02dE%02d has no name on %s. Setting to an empty string" % (self.show.name, season, episode, sickbeard.indexerApi(self.indexer).name)) + logger.log(u"This episode %s - S%02dE%02d has no name on %s. Setting to an empty string" % (self.show.name, season or 0, episode or 0, sickbeard.indexerApi(self.indexer).name)) setattr(myEp, 'episodename', '') # if I'm incomplete on TVDB but I once was complete then just delete myself from the DB for now #if self.indexerid != -1: @@ -1673,9 +1673,9 @@ class TVEpisode(object): #return False if getattr(myEp, 'absolute_number', None) is None: - logger.log(u"This episode %s - S%02dE%02d has no absolute number on %s" %(self.show.name, season, episode, sickbeard.indexerApi(self.indexer).name), logger.DEBUG) + logger.log(u"This episode %s - S%02dE%02d has no absolute number on %s" %(self.show.name, season or 0, episode or 0, sickbeard.indexerApi(self.indexer).name), logger.DEBUG) else: - logger.log(u"%s: The absolute_number for S%02dE%02d is: %s " % (self.show.indexerid, season, episode, myEp["absolute_number"]), logger.DEBUG) + logger.log(u"%s: The absolute_number for S%02dE%02d is: %s " % (self.show.indexerid, season or 0, episode or 0, myEp["absolute_number"]), logger.DEBUG) self.absolute_number = int(myEp["absolute_number"]) self.name = getattr(myEp, 'episodename', "") @@ -1706,7 +1706,7 @@ class TVEpisode(object): try: self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2]) except (ValueError, IndexError): - logger.log(u"Malformed air date of %s retrieved from %s for (%s - S%02dE%02d)" % (firstaired, sickbeard.indexerApi(self.indexer).name, self.show.name, season, episode),logger.WARNING) + logger.log(u"Malformed air date of %s retrieved from %s for (%s - S%02dE%02d)" % (firstaired, sickbeard.indexerApi(self.indexer).name, self.show.name, season or 0, episode or 0),logger.WARNING) # if I'm incomplete on the indexer but I once was complete then just delete myself from the DB for now if self.indexerid != -1: self.deleteEpisode() @@ -1728,7 +1728,7 @@ class TVEpisode(object): if self.location: logger.log(u"%s: Setting status for S%02dE%02d based on status %s and location %s" % - (self.show.indexerid, season, episode, statusStrings[self.status], self.location), logger.DEBUG) + (self.show.indexerid, season or 0, episode or 0, statusStrings[self.status], self.location), logger.DEBUG) if not ek(os.path.isfile, self.location): if self.airdate >= datetime.date.today() or self.airdate == datetime.date.fromordinal(1): @@ -1798,7 +1798,7 @@ class TVEpisode(object): epDetails.findtext('episode') is None or int( epDetails.findtext('episode')) != self.episode: logger.log(u"%s: NFO has an <episodedetails> block for a different episode - wanted S%02dE%02d but got S%02dE%02d" % - (self.show.indexerid, self.season, self.episode, epDetails.findtext('season'), epDetails.findtext('episode') ), logger.DEBUG) + (self.show.indexerid, self.season or 0, self.episode or 0, epDetails.findtext('season') or 0, epDetails.findtext('episode') or 0 ), logger.DEBUG) continue if epDetails.findtext('title') is None or epDetails.findtext('aired') is None: @@ -1844,7 +1844,7 @@ class TVEpisode(object): def __str__(self): toReturn = "" - toReturn += "%s - S%02dE%02d - %s " % (self.show.name, self.season, self.episode, self.name ) + "\n" + toReturn += "%s - S%02dE%02d - %s " % (self.show.name, self.season or 0, self.episode or 0, self.name ) + "\n" toReturn += "location: " + str(self.location) + "\n" toReturn += "description: " + str(self.description) + "\n" toReturn += "subtitles: " + str(",".join(self.subtitles)) + "\n" @@ -1888,7 +1888,7 @@ class TVEpisode(object): def deleteEpisode(self): - logger.log(u"Deleting %s S%02dE%02d from the DB" % (self.show.name, self.season, self.episode), logger.DEBUG) + logger.log(u"Deleting %s S%02dE%02d from the DB" % (self.show.name, self.season or 0, self.episode or 0), logger.DEBUG) # remove myself from the show dictionary if self.show.getEpisode(self.season, self.episode, noCreate=True) == self: