def loadFromNFO(self, location): if not os.path.isdir(self.show._location): sickrage.LOGGER.info( str( self.show.indexerid) + ": The show dir is missing, not bothering to try loading the episode NFO") return sickrage.LOGGER.debug( str( self.show.indexerid) + ": Loading episode details from the NFO file associated with " + location) self.location = location if self.location != "": if self.status == UNKNOWN: if isMediaFile(self.location): sickrage.LOGGER.debug("7 Status changes from " + str(self.status) + " to " + str( Quality.statusFromName(self.location, anime=self.show.is_anime))) self.status = Quality.statusFromName(self.location, anime=self.show.is_anime) nfoFile = replaceExtension(self.location, "nfo") sickrage.LOGGER.debug(str(self.show.indexerid) + ": Using NFO name " + nfoFile) if os.path.isfile(nfoFile): try: showXML = ElementTree(file=nfoFile) except (SyntaxError, ValueError) as e: sickrage.LOGGER.error("Error loading the NFO, backing up the NFO and skipping for now: {}".format(e)) try: os.rename(nfoFile, nfoFile + ".old") except Exception as e: sickrage.LOGGER.error( "Failed to rename your episode's NFO file - you need to delete it or fix it: {}".format( e)) raise NoNFOException("Error in NFO format") for epDetails in showXML.iter('episodedetails'): if epDetails.findtext('season') is None or int(epDetails.findtext('season')) != self.season or \ epDetails.findtext('episode') is None or int( epDetails.findtext('episode')) != self.episode: sickrage.LOGGER.debug( "%s: NFO has an <episodedetails> block for a different episode - wanted S%02dE%02d but got S%02dE%02d" % ( self.show.indexerid, self.season or 0, self.episode or 0, epDetails.findtext('season') or 0, epDetails.findtext('episode') or 0)) continue if epDetails.findtext('title') is None or epDetails.findtext('aired') is None: raise NoNFOException("Error in NFO format (missing episode title or airdate)") self.name = epDetails.findtext('title') self.episode = int(epDetails.findtext('episode')) self.season = int(epDetails.findtext('season')) xem_refresh(self.show.indexerid, self.show.indexer) self.scene_absolute_number = get_scene_absolute_numbering( self.show.indexerid, self.show.indexer, self.absolute_number ) self.scene_season, self.scene_episode = get_scene_numbering( self.show.indexerid, self.show.indexer, self.season, self.episode ) self.description = epDetails.findtext('plot') if self.description is None: self.description = "" if epDetails.findtext('aired'): rawAirdate = [int(x) for x in epDetails.findtext('aired').split("-")] self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2]) else: self.airdate = datetime.date.fromordinal(1) self.hasnfo = True else: self.hasnfo = False if os.path.isfile(replaceExtension(nfoFile, "tbn")): self.hastbn = True else: self.hastbn = False
def loadFromIndexer(self, season=None, episode=None, cache=True, tvapi=None, cachedSeason=None): if season is None: season = self.season if episode is None: episode = self.episode sickrage.LOGGER.debug("%s: Loading episode details from %s for episode S%02dE%02d" % (self.show.indexerid, sickrage.INDEXER_API(self.show.indexer).name, season or 0, episode or 0)) indexer_lang = self.show.lang try: if cachedSeason is None: if tvapi is None: lINDEXER_API_PARMS = sickrage.INDEXER_API(self.indexer).api_params.copy() if not cache: lINDEXER_API_PARMS[b'cache'] = False if indexer_lang: lINDEXER_API_PARMS[b'language'] = indexer_lang if self.show.dvdorder != 0: lINDEXER_API_PARMS[b'dvdorder'] = True t = sickrage.INDEXER_API(self.indexer).indexer(**lINDEXER_API_PARMS) else: t = tvapi myEp = t[self.show.indexerid][season][episode] else: myEp = cachedSeason[episode] except (indexer_error, IOError) as e: sickrage.LOGGER.debug("" + sickrage.INDEXER_API(self.indexer).name + " threw up an error: {}".format(e)) # if the episode is already valid just log it, if not throw it up if self.name: sickrage.LOGGER.debug("" + sickrage.INDEXER_API( self.indexer).name + " timed out but we have enough info from other sources, allowing the error") return else: sickrage.LOGGER.error("" + sickrage.INDEXER_API(self.indexer).name + " timed out, unable to create the episode") return False except (indexer_episodenotfound, indexer_seasonnotfound): sickrage.LOGGER.debug("Unable to find the episode on " + sickrage.INDEXER_API( self.indexer).name + "... has it been removed? Should I delete from db?") # if I'm no longer on the Indexers but I once was then delete myself from the DB if self.indexerid != -1: self.deleteEpisode() return if getattr(myEp, 'episodename', None) is None: sickrage.LOGGER.info("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, sickrage.INDEXER_API(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: # self.deleteEpisode() # return False if getattr(myEp, 'absolute_number', None) is None: sickrage.LOGGER.debug("This episode %s - S%02dE%02d has no absolute number on %s" % ( self.show.name, season or 0, episode or 0, sickrage.INDEXER_API(self.indexer).name)) else: sickrage.LOGGER.debug("%s: The absolute_number for S%02dE%02d is: %s " % ( self.show.indexerid, season or 0, episode or 0, myEp[b"absolute_number"])) self.absolute_number = int(myEp[b"absolute_number"]) self.name = getattr(myEp, 'episodename', "") self.season = season self.episode = episode xem_refresh(self.show.indexerid, self.show.indexer) self.scene_absolute_number = get_scene_absolute_numbering( self.show.indexerid, self.show.indexer, self.absolute_number ) self.scene_season, self.scene_episode = get_scene_numbering( self.show.indexerid, self.show.indexer, self.season, self.episode ) self.description = getattr(myEp, 'overview', "") firstaired = getattr(myEp, 'firstaired', None) if not firstaired or firstaired == "0000-00-00": firstaired = str(datetime.date.fromordinal(1)) rawAirdate = [int(x) for x in firstaired.split("-")] try: self.airdate = datetime.date(rawAirdate[0], rawAirdate[1], rawAirdate[2]) except (ValueError, IndexError): sickrage.LOGGER.warning("Malformed air date of %s retrieved from %s for (%s - S%02dE%02d)" % ( firstaired, sickrage.INDEXER_API(self.indexer).name, self.show.name, season or 0, episode or 0)) # 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() return False # early conversion to int so that episode doesn't get marked dirty self.indexerid = getattr(myEp, 'id', None) if self.indexerid is None: sickrage.LOGGER.error("Failed to retrieve ID from " + sickrage.INDEXER_API(self.indexer).name) if self.indexerid != -1: self.deleteEpisode() return False # don't update show status if show dir is missing, unless it's missing on purpose if not os.path.isdir( self.show._location) and not sickrage.CREATE_MISSING_SHOW_DIRS and not sickrage.ADD_SHOWS_WO_DIR: sickrage.LOGGER.info( "The show dir %s is missing, not bothering to change the episode statuses since it'd probably be invalid" % self.show._location) return if self.location: sickrage.LOGGER.debug("%s: Setting status for S%02dE%02d based on status %s and location %s" % (self.show.indexerid, season or 0, episode or 0, statusStrings[self.status], self.location)) if not os.path.isfile(self.location): if self.airdate >= datetime.date.today() or self.airdate == datetime.date.fromordinal(1): sickrage.LOGGER.debug("Episode airs in the future or has no airdate, marking it %s" % statusStrings[ UNAIRED]) self.status = UNAIRED elif self.status in [UNAIRED, UNKNOWN]: # Only do UNAIRED/UNKNOWN, it could already be snatched/ignored/skipped, or downloaded/archived to disconnected media sickrage.LOGGER.debug( "Episode has already aired, marking it %s" % statusStrings[self.show.default_ep_status]) self.status = self.show.default_ep_status if self.season > 0 else SKIPPED # auto-skip specials else: sickrage.LOGGER.debug( "Not touching status [ %s ] It could be skipped/ignored/snatched/archived" % statusStrings[ self.status]) # if we have a media file then it's downloaded elif isMediaFile(self.location): # leave propers alone, you have to either post-process them or manually change them back if self.status not in Quality.SNATCHED_PROPER + Quality.DOWNLOADED + Quality.SNATCHED + Quality.ARCHIVED: sickrage.LOGGER.debug( "5 Status changes from " + str(self.status) + " to " + str( Quality.statusFromName(self.location))) self.status = Quality.statusFromName(self.location, anime=self.show.is_anime) # shouldn't get here probably else: sickrage.LOGGER.debug("6 Status changes from " + str(self.status) + " to " + str(UNKNOWN)) self.status = UNKNOWN