def _make_url(self, result): if not result: return '', '' filename = '' urls = [result.url] if result.url.startswith('magnet'): torrent_hash = self.hash_from_magnet(result.url) if not torrent_hash: return urls, filename try: torrent_name = re.findall('dn=([^&]+)', result.url)[0] except Exception: torrent_name = 'NO_DOWNLOAD_NAME' urls = [ x.format(torrent_hash=torrent_hash, torrent_name=torrent_name) for x in self.bt_cache_urls ] filename = ek( join, self._get_storage_dir(), sanitize_filename(result.name) + '.' + self.provider_type) return urls, filename
def test_encoding(self): """ Test encoding """ root_dir = 'C:\\Temp\\TV' strings = ['Les Enfants De La T\xe9l\xe9', 'RT� One'] sickbeard.SYS_ENCODING = None try: locale.setlocale(locale.LC_ALL, "") sickbeard.SYS_ENCODING = locale.getpreferredencoding() except (locale.Error, IOError): pass # For OSes that are poorly configured I'll just randomly force UTF-8 if not sickbeard.SYS_ENCODING or sickbeard.SYS_ENCODING in ( 'ANSI_X3.4-1968', 'US-ASCII', 'ASCII'): sickbeard.SYS_ENCODING = 'UTF-8' for test in strings: try: show_dir = ek(os.path.join, root_dir, sanitize_filename(test)) self.assertTrue(isinstance(show_dir, six.text_type)) except Exception as error: # pylint: disable=broad-except ex(error)
def test_sanitize_filename(self): """ Test sanitize filename """ test_cases = { None: '', 42: '', b'': '', b'filename': 'filename', b'fi\\le/na*me': 'fi-le-na-me', b'fi:le"na<me': 'filename', b'fi>le|na?me': 'filename', b' . file\u2122name. .': 'filename', } unicode_test_cases = { '': '', 'filename': 'filename', 'fi\\le/na*me': 'fi-le-na-me', 'fi:le"na<me': 'filename', 'fi>le|na?me': 'filename', ' . file™name. .': 'filename', } for tests in test_cases, unicode_test_cases: for (filename, result) in six.iteritems(tests): self.assertEqual(sanitize_filename(filename), result)
def test_sanitize_filename(self): """ Test sanitize filename """ # noinspection PyByteLiteral # pylint: noqa test_cases = { None: "", 42: "", b"": "", b"filename": "filename", b"fi\\le/na*me": "fi-le-na-me", b'fi:le"na<me': "filename", b"fi>le|na?me": "filename", b" . file\u2122name. .": "filename", } unicode_test_cases = { "": "", "filename": "filename", "fi\\le/na*me": "fi-le-na-me", 'fi:le"na<me': "filename", "fi>le|na?me": "filename", " . file™name. .": "filename", } for tests in test_cases, unicode_test_cases: for (filename, result) in tests.items(): assert sanitize_filename(filename) == result
def addDefaultShow(indexer, indexer_id, name, status): """ Adds a new show with the default settings """ if not Show.find(sickbeard.showList, int(indexer_id)): logger.log("Adding show " + str(indexer_id)) root_dirs = sickbeard.ROOT_DIRS.split('|') try: location = root_dirs[int(root_dirs[0]) + 1] except Exception: location = None if location: showPath = ek(os.path.join, location, sanitize_filename(name)) dir_exists = helpers.makeDir(showPath) if not dir_exists: logger.log("Unable to create the folder {0} , can't add the show".format(showPath), logger.WARNING) return else: helpers.chmodAsParent(showPath) sickbeard.showQueueScheduler.action.add_show(int(indexer), int(indexer_id), showPath, default_status=status, quality=int(sickbeard.QUALITY_DEFAULT), season_folders=int(sickbeard.SEASON_FOLDERS_DEFAULT), paused=sickbeard.TRAKT_START_PAUSED, default_status_after=status) else: logger.log("There was an error creating the show, no root directory setting found", logger.WARNING) return
def test_encoding(self): """ Test encoding """ root_dir = 'C:\\Temp\\TV' strings = ['Les Enfants De La T\xe9l\xe9', 'RT� One'] sickbeard.SYS_ENCODING = None try: locale.setlocale(locale.LC_ALL, "") sickbeard.SYS_ENCODING = locale.getpreferredencoding() except (locale.Error, IOError): pass # For OSes that are poorly configured I'll just randomly force UTF-8 if not sickbeard.SYS_ENCODING or sickbeard.SYS_ENCODING in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'): sickbeard.SYS_ENCODING = 'UTF-8' for test in strings: try: show_dir = ek(os.path.join, root_dir, sanitize_filename(test)) self.assertTrue(isinstance(show_dir, six.text_type)) except Exception as error: # pylint: disable=broad-except ex(error)
def _make_url(self, result): if not result: return "", "" filename = "" result.url = result.url.replace("http://itorrents.org", "https://itorrents.org") urls = [result.url] if result.url.startswith("magnet"): torrent_hash = self.hash_from_magnet(result.url) if not torrent_hash: return urls, filename try: torrent_name = re.findall("dn=([^&]+)", result.url)[0] except Exception: torrent_name = "NO_DOWNLOAD_NAME" urls = [] for cache_url in self.bt_cache_urls: if isinstance(cache_url, tuple): urls.append(( cache_url[0].format(torrent_hash=torrent_hash, torrent_name=torrent_name), cache_url[1].format(torrent_hash=torrent_hash, torrent_name=torrent_name), )) else: urls.append( cache_url.format(torrent_hash=torrent_hash, torrent_name=torrent_name)) if "torrage.info/torrent.php" in result.url: torrent_hash = result.url.split("=")[1] urls = [( "https://t.torrage.info/download?h={torrent_hash}".format( torrent_hash=torrent_hash), "https://torrage.info/torrent.php?h={torrent_hash}".format( torrent_hash=torrent_hash), )] filename = join( self._get_storage_dir(), sanitize_filename(result.name) + "." + self.provider_type) return urls, filename
def _make_url(self, result): if not result: return '', '' filename = '' result.url = result.url.replace('http://itorrents.org', 'https://itorrents.org') urls = [result.url] if result.url.startswith('magnet'): torrent_hash = self.hash_from_magnet(result.url) if not torrent_hash: return urls, filename try: torrent_name = re.findall('dn=([^&]+)', result.url)[0] except Exception: torrent_name = 'NO_DOWNLOAD_NAME' urls = [] for cache_url in self.bt_cache_urls: if isinstance(cache_url, tuple): urls.append( (cache_url[0].format(torrent_hash=torrent_hash, torrent_name=torrent_name), cache_url[1].format(torrent_hash=torrent_hash, torrent_name=torrent_name))) else: urls.append( cache_url.format(torrent_hash=torrent_hash, torrent_name=torrent_name)) if 'torrage.info/torrent.php' in result.url: torrent_hash = result.url.split('=')[1] urls = [ ('https://t.torrage.info/download?h={torrent_hash}'.format( torrent_hash=torrent_hash), 'https://torrage.info/torrent.php?h={torrent_hash}'.format( torrent_hash=torrent_hash)) ] filename = join( self._get_storage_dir(), sanitize_filename(result.name) + '.' + self.provider_type) return urls, filename
def run(self): # pylint: disable=too-many-branches, too-many-statements, too-many-return-statements super(QueueItemAdd, self).run() if self.showDir: try: assert isinstance(self.showDir, six.text_type) except AssertionError: logger.log(traceback.format_exc(), logger.WARNING) self._finish_early() return logger.log('Starting to add show {0}'.format('by ShowDir: {0}'.format(self.showDir) if self.showDir else 'by Indexer Id: {0}'.format(self.indexer_id))) # make sure the Indexer IDs are valid try: lINDEXER_API_PARMS = sickbeard.indexerApi(self.indexer).api_params.copy() lINDEXER_API_PARMS['language'] = self.lang or sickbeard.INDEXER_DEFAULT_LANGUAGE logger.log('{0}: {1!r}'.format(sickbeard.indexerApi(self.indexer).name, lINDEXER_API_PARMS)) t = sickbeard.indexerApi(self.indexer).indexer(**lINDEXER_API_PARMS) s = t[self.indexer_id] # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the # Indexers provided series name if self.root_dir and not self.showDir: show_name = get_showname_from_indexer(self.indexer, self.indexer_id, self.lang) if not show_name: logger.log('Unable to get a show {0}, can\'t add the show'.format(self.showDir)) self._finish_early() return self.showDir = ek(os.path.join, self.root_dir, sanitize_filename(show_name)) dir_exists = makeDir(self.showDir) if not dir_exists: logger.log('Unable to create the folder {0}, can\'t add the show'.format(self.showDir)) self._finish_early() return chmodAsParent(self.showDir) # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show if getattr(s, 'seriesname', None) is None: # noinspection PyPep8 error_string = 'Show in {0} has no name on {1}, probably searched with the wrong language. Delete .nfo and add manually in the correct language.'.format( self.showDir, sickbeard.indexerApi(self.indexer).name) logger.log(error_string, logger.WARNING) ui.notifications.error('Unable to add show', error_string) self._finish_early() return # if the show has no episodes/seasons if not s: error_string = 'Show {0} is on {1} but contains no season/episode data.'.format( s[b'seriesname'], sickbeard.indexerApi(self.indexer).name) logger.log(error_string) ui.notifications.error('Unable to add show', error_string) self._finish_early() return except Exception as error: error_string = 'Unable to look up the show in {0} on {1} using ID {2}, not using the NFO. Delete .nfo and try adding manually again.'.format( self.showDir, sickbeard.indexerApi(self.indexer).name, self.indexer_id) logger.log('{0}: {1}'.format(error_string, error), logger.ERROR) ui.notifications.error( 'Unable to add show', error_string) if sickbeard.USE_TRAKT: trakt_id = sickbeard.indexerApi(self.indexer).config[b'trakt_id'] trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT) title = self.showDir.split('/')[-1] data = { 'shows': [ { 'title': title, 'ids': {} } ] } if trakt_id == 'tvdb_id': data['shows'][0]['ids']['tvdb'] = self.indexer_id else: data['shows'][0]['ids']['tvrage'] = self.indexer_id trakt_api.traktRequest('sync/watchlist/remove', data, method='POST') self._finish_early() return try: try: newShow = TVShow(self.indexer, self.indexer_id, self.lang) except MultipleShowObjectsException as error: # If we have the show in our list, but the location is wrong, lets fix it and refresh! existing_show = Show.find(sickbeard.showList, self.indexer_id) # noinspection PyProtectedMember if existing_show and not ek(os.path.isdir, existing_show._location): # pylint: disable=protected-access newShow = existing_show else: raise error newShow.loadFromIndexer() self.show = newShow # set up initial values self.show.location = self.showDir self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT self.show.subtitles_sr_metadata = self.subtitles_sr_metadata self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT self.show.season_folders = self.season_folders if self.season_folders is not None else sickbeard.SEASON_FOLDERS_DEFAULT self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT self.show.paused = self.paused if self.paused is not None else False # set up default new/missing episode status logger.log('Setting all episodes to the specified default status: {0}' .format(self.show.default_ep_status)) self.show.default_ep_status = self.default_status if self.show.anime: self.show.release_groups = BlackAndWhiteList(self.show.indexerid) if self.blacklist: self.show.release_groups.set_black_keywords(self.blacklist) if self.whitelist: self.show.release_groups.set_white_keywords(self.whitelist) # # be smart-ish about this # if self.show.genre and 'talk show' in self.show.genre.lower(): # self.show.air_by_date = 1 # if self.show.genre and 'documentary' in self.show.genre.lower(): # self.show.air_by_date = 0 # if self.show.classification and 'sports' in self.show.classification.lower(): # self.show.sports = 1 except sickbeard.indexer_exception as error: error_string = 'Unable to add {0} due to an error with {1}'.format( self.show.name if self.show else 'show', sickbeard.indexerApi(self.indexer).name) logger.log('{0}: {1}'.format(error_string, error), logger.ERROR) ui.notifications.error('Unable to add show', error_string) self._finish_early() return except MultipleShowObjectsException: error_string = 'The show in {0} is already in your show list, skipping'.format(self.showDir) logger.log(error_string, logger.WARNING) ui.notifications.error('Show skipped', error_string) self._finish_early() return except Exception as error: logger.log('Error trying to add show: {0}'.format(error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) self._finish_early() raise logger.log('Retrieving show info from IMDb', logger.DEBUG) try: self.show.loadIMDbInfo() except imdb_exceptions.IMDbError as error: logger.log(' Something wrong on IMDb api: {0}'.format(error), logger.WARNING) except Exception as error: logger.log('Error loading IMDb info: {0}'.format(error), logger.ERROR) try: self.show.saveToDB() except Exception as error: logger.log('Error saving the show to the database: {0}'.format(error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) self._finish_early() raise # add it to the show list if not Show.find(sickbeard.showList, self.indexer_id): sickbeard.showList.append(self.show) try: self.show.loadEpisodesFromIndexer() except Exception as error: logger.log( 'Error with {0}, not creating episode list: {1}'.format (sickbeard.indexerApi(self.show.indexer).name, error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) # update internal name cache name_cache.buildNameCache(self.show) try: self.show.loadEpisodesFromDir() except Exception as error: logger.log('Error searching dir for episodes: {0}'.format(error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) # if they set default ep status to WANTED then run the backlog to search for episodes # FIXME: This needs to be a backlog queue item!!! if self.show.default_ep_status == WANTED: logger.log('Launching backlog for this show since its episodes are WANTED') sickbeard.backlogSearchScheduler.action.searchBacklog([self.show]) self.show.writeMetadata() self.show.updateMetadata() self.show.populateCache() self.show.flushEpisodes() if sickbeard.USE_TRAKT: # if there are specific episodes that need to be added by trakt sickbeard.traktCheckerScheduler.action.manageNewShow(self.show) # add show to trakt.tv library if sickbeard.TRAKT_SYNC: sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary(self.show) if sickbeard.TRAKT_SYNC_WATCHLIST: logger.log('update watchlist') notifiers.trakt_notifier.update_watchlist(show_obj=self.show) # Load XEM data to DB for show scene_numbering.xem_refresh(self.show.indexerid, self.show.indexer, force=True) # check if show has XEM mapping so we can determine if searches should go by scene numbering or indexer numbering. if not self.scene and scene_numbering.get_xem_numbering_for_show(self.show.indexerid, self.show.indexer): self.show.scene = 1 # After initial add, set to default_status_after. self.show.default_ep_status = self.default_status_after super(QueueItemAdd, self).finish() self.finish()
def run(self): super(QueueItemAdd, self).run() if self.showDir: try: assert isinstance(self.showDir, six.text_type) except AssertionError: logger.log(traceback.format_exc(), logger.WARNING) self._finish_early() return logger.log('Starting to add show {0}'.format( 'by ShowDir: {0}'.format(self.showDir) if self. showDir else 'by Indexer Id: {0}'.format(self.indexer_id))) # make sure the Indexer IDs are valid try: s = sickchill.indexer.series_by_id(indexerid=self.indexer_id, indexer=self.indexer, language=self.lang) if not s: error_string = 'Could not find show with id:{0} on {1}, skipping'.format( self.indexer_id, sickchill.indexer.name(self.indexer)) logger.log(error_string) ui.notifications.error('Unable to add show', error_string) self._finish_early() return # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the # Indexers provided series name if self.root_dir and not self.showDir: if not s.seriesName: logger.log( 'Unable to get a show {0}, can\'t add the show'.format( self.showDir)) self._finish_early() return self.showDir = ek(os.path.join, self.root_dir, sanitize_filename(s.seriesName)) dir_exists = makeDir(self.showDir) if not dir_exists: logger.log( 'Unable to create the folder {0}, can\'t add the show'. format(self.showDir)) self._finish_early() return chmodAsParent(self.showDir) # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show if getattr(s, 'seriesName', None) is None: # noinspection PyPep8 error_string = 'Show in {0} has no name on {1}, probably searched with the wrong language. Delete .nfo and add manually in the correct language.'.format( self.showDir, sickchill.indexer.name(self.indexer)) logger.log(error_string, logger.WARNING) ui.notifications.error('Unable to add show', error_string) self._finish_early() return except Exception as error: error_string = 'Unable to look up the show in {0} on {1} using ID {2}, not using the NFO. Delete .nfo and try adding manually again.'.format( self.showDir, sickchill.indexer.name(self.indexer), self.indexer_id) logger.log('{0}: {1}'.format(error_string, error), logger.ERROR) ui.notifications.error('Unable to add show', error_string) if sickbeard.USE_TRAKT: trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT) title = self.showDir.split('/')[-1] data = { 'shows': [{ 'title': title, 'ids': { sickchill.indexer.slug(self.indexer): self.indexer_id } }] } trakt_api.traktRequest('sync/watchlist/remove', data, method='POST') self._finish_early() return try: try: newShow = TVShow(self.indexer, self.indexer_id, self.lang) except MultipleShowObjectsException as error: # If we have the show in our list, but the location is wrong, lets fix it and refresh! existing_show = Show.find(sickbeard.showList, self.indexer_id) # noinspection PyProtectedMember if existing_show and not ek(os.path.isdir, existing_show._location): newShow = existing_show else: raise error newShow.loadFromIndexer() self.show = newShow # set up initial values self.show.location = self.showDir self.show.subtitles = self.subtitles if self.subtitles is not None else sickbeard.SUBTITLES_DEFAULT self.show.subtitles_sr_metadata = self.subtitles_sr_metadata self.show.quality = self.quality if self.quality else sickbeard.QUALITY_DEFAULT self.show.season_folders = self.season_folders if self.season_folders is not None else sickbeard.SEASON_FOLDERS_DEFAULT self.show.anime = self.anime if self.anime is not None else sickbeard.ANIME_DEFAULT self.show.scene = self.scene if self.scene is not None else sickbeard.SCENE_DEFAULT self.show.paused = self.paused if self.paused is not None else False # set up default new/missing episode status logger.log( 'Setting all episodes to the specified default status: {0}'. format(self.show.default_ep_status)) self.show.default_ep_status = self.default_status if self.show.anime: self.show.release_groups = BlackAndWhiteList( self.show.indexerid) if self.blacklist: self.show.release_groups.set_black_keywords(self.blacklist) if self.whitelist: self.show.release_groups.set_white_keywords(self.whitelist) # # be smart-ish about this # if self.show.genre and 'talk show' in self.show.genre.lower(): # self.show.air_by_date = 1 # if self.show.genre and 'documentary' in self.show.genre.lower(): # self.show.air_by_date = 0 # if self.show.classification and 'sports' in self.show.classification.lower(): # self.show.sports = 1 except Exception as error: error_string = 'Unable to add {0} due to an error with {1}'.format( self.show.name if self.show else 'show', sickchill.indexer.name(self.indexer)) logger.log('{0}: {1}'.format(error_string, error), logger.ERROR) logger.log('Error trying to add show: {0}'.format(error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) ui.notifications.error('Unable to add show', error_string) self._finish_early() return except MultipleShowObjectsException: error_string = 'The show in {0} is already in your show list, skipping'.format( self.showDir) logger.log(error_string, logger.WARNING) ui.notifications.error('Show skipped', error_string) self._finish_early() return logger.log('Retrieving show info from IMDb', logger.DEBUG) try: self.show.loadIMDbInfo() except imdb_exceptions.IMDbError as error: logger.log(' Something wrong on IMDb api: {0}'.format(error), logger.WARNING) except Exception as error: logger.log('Error loading IMDb info: {0}'.format(error), logger.ERROR) try: self.show.saveToDB() except Exception as error: logger.log( 'Error saving the show to the database: {0}'.format(error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) self._finish_early() raise # add it to the show list if not Show.find(sickbeard.showList, self.indexer_id): sickbeard.showList.append(self.show) try: self.show.loadEpisodesFromIndexer() except Exception as error: logger.log( 'Error with {0}, not creating episode list: {1}'.format( self.show.idxr.name, error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) # update internal name cache name_cache.buildNameCache(self.show) try: self.show.loadEpisodesFromDir() except Exception as error: logger.log('Error searching dir for episodes: {0}'.format(error), logger.ERROR) logger.log(traceback.format_exc(), logger.DEBUG) # if they set default ep status to WANTED then run the backlog to search for episodes # FIXME: This needs to be a backlog queue item!!! if self.show.default_ep_status == WANTED: logger.log( 'Launching backlog for this show since its episodes are WANTED' ) sickbeard.backlogSearchScheduler.action.searchBacklog([self.show]) self.show.writeMetadata() self.show.updateMetadata() self.show.populateCache() self.show.flushEpisodes() if sickbeard.USE_TRAKT: # if there are specific episodes that need to be added by trakt sickbeard.traktCheckerScheduler.action.manageNewShow(self.show) # add show to trakt.tv library if sickbeard.TRAKT_SYNC: sickbeard.traktCheckerScheduler.action.addShowToTraktLibrary( self.show) if sickbeard.TRAKT_SYNC_WATCHLIST: logger.log('update watchlist') notifiers.trakt_notifier.update_watchlist(show_obj=self.show) # Load XEM data to DB for show scene_numbering.xem_refresh(self.show.indexerid, self.show.indexer, force=True) # check if show has XEM mapping so we can determine if searches should go by scene numbering or indexer numbering. if not self.scene and scene_numbering.get_xem_numbering_for_show( self.show.indexerid, self.show.indexer): self.show.scene = 1 # After initial add, set to default_status_after. self.show.default_ep_status = self.default_status_after super(QueueItemAdd, self).finish() self.finish()
def run(self): super(QueueItemAdd, self).run() logger.info( _("Starting to add show {0}").format( _("by ShowDir: {0}").format(self.showDir) if self. showDir else _("by Indexer Id: {0}").format(self.indexer_id))) # make sure the Indexer IDs are valid try: s = sickchill.indexer.series_by_id(indexerid=self.indexer_id, indexer=self.indexer, language=self.lang) if not s: error_string = _( "Could not find show with id:{0} on {1}, skipping").format( self.indexer_id, sickchill.indexer.name(self.indexer)) logger.info(error_string) ui.notifications.error(_("Unable to add show"), error_string) self._finish_early() return # Let's try to create the show Dir if it's not provided. This way we force the show dir to build build using the # Indexers provided series name if self.root_dir and not self.showDir: if not s.seriesName: logger.info( _("Unable to get a show {0}, can't add the show"). format(self.showDir)) self._finish_early() return show_dir = s.seriesName if settings.ADD_SHOWS_WITH_YEAR and s.firstAired: try: year = "({0})".format( dateutil.parser.parse(s.firstAired).year) if year not in show_dir: show_dir = "{0} {1}".format(s.seriesName, year) except (TypeError, ValueError): logger.info( _("Could not append the show year folder for the show: {0}" ).format(show_dir)) self.showDir = os.path.join(self.root_dir, sanitize_filename(show_dir)) if settings.ADD_SHOWS_WO_DIR: logger.info( _("Skipping initial creation of {0} due to config.ini setting" ).format(self.showDir)) else: dir_exists = makeDir(self.showDir) if not dir_exists: logger.info( _("Unable to create the folder {0}, can't add the show" ).format(self.showDir)) self._finish_early() return chmodAsParent(self.showDir) # this usually only happens if they have an NFO in their show dir which gave us a Indexer ID that has no proper english version of the show if getattr(s, "seriesName", None) is None: # noinspection PyPep8 error_string = _( "Show in {0} has no name on {1}, probably searched with the wrong language. Delete .nfo and add manually in the correct language." ).format(self.showDir, sickchill.indexer.name(self.indexer)) logger.warning(error_string) ui.notifications.error(_("Unable to add show"), error_string) self._finish_early() return except Exception as error: error_string = "Unable to look up the show in {0} on {1} using ID {2}, not using the NFO. Delete .nfo and try adding manually again.".format( self.showDir, sickchill.indexer.name(self.indexer), self.indexer_id) logger.exception("{0}: {1}".format(error_string, error)) ui.notifications.error(_("Unable to add show"), error_string) if settings.USE_TRAKT: trakt_api = TraktAPI(settings.SSL_VERIFY, settings.TRAKT_TIMEOUT) title = self.showDir.split("/")[-1] data = { "shows": [{ "title": title, "ids": { sickchill.indexer.slug(self.indexer): self.indexer_id } }] } trakt_api.traktRequest("sync/watchlist/remove", data, method="POST") self._finish_early() return try: try: newShow = TVShow(self.indexer, self.indexer_id, self.lang) except MultipleShowObjectsException as error: # If we have the show in our list, but the location is wrong, lets fix it and refresh! existing_show = Show.find(settings.showList, self.indexer_id) # noinspection PyProtectedMember if existing_show and not os.path.isdir( existing_show._location): newShow = existing_show else: raise error newShow.loadFromIndexer() self.show = newShow # set up initial values self.show.location = self.showDir self.show.subtitles = self.subtitles if self.subtitles is not None else settings.SUBTITLES_DEFAULT self.show.subtitles_sr_metadata = self.subtitles_sr_metadata self.show.quality = self.quality if self.quality else settings.QUALITY_DEFAULT self.show.season_folders = self.season_folders if self.season_folders is not None else settings.SEASON_FOLDERS_DEFAULT self.show.anime = self.anime if self.anime is not None else settings.ANIME_DEFAULT self.show.scene = self.scene if self.scene is not None else settings.SCENE_DEFAULT self.show.paused = self.paused if self.paused is not None else False # set up default new/missing episode status logger.info( _("Setting all episodes to the specified default status: {0}"). format(self.show.default_ep_status)) self.show.default_ep_status = self.default_status if self.show.anime: self.show.release_groups = BlackAndWhiteList( self.show.indexerid) if self.blacklist: self.show.release_groups.set_black_keywords(self.blacklist) if self.whitelist: self.show.release_groups.set_white_keywords(self.whitelist) # # be smart-ish about this # if self.show.genre and 'talk show' in self.show.genre.lower(): # self.show.air_by_date = 1 # if self.show.genre and 'documentary' in self.show.genre.lower(): # self.show.air_by_date = 0 # if self.show.classification and 'sports' in self.show.classification.lower(): # self.show.sports = 1 except Exception as error: error_string = "Unable to add {0} due to an error with {1}".format( self.show.name if self.show else "show", sickchill.indexer.name(self.indexer)) logger.exception("{0}: {1}".format(error_string, error)) logger.exception("Error trying to add show: {0}".format(error)) logger.debug(traceback.format_exc()) ui.notifications.error(_("Unable to add show"), error_string) self._finish_early() return except MultipleShowObjectsException: error_string = _( "The show in {0} is already in your show list, skipping" ).format(self.showDir) logger.warning(error_string) ui.notifications.error(_("Show skipped"), error_string) self._finish_early() return self.show.load_imdb_imfo() try: self.show.saveToDB() except Exception as error: logger.exception( "Error saving the show to the database: {0}".format(error)) logger.debug(traceback.format_exc()) self._finish_early() raise # add it to the show list if not Show.find(settings.showList, self.indexer_id): settings.showList.append(self.show) try: self.show.loadEpisodesFromIndexer() except Exception as error: logger.exception( "Error with {0}, not creating episode list: {1}".format( self.show.idxr.name, error)) logger.debug(traceback.format_exc()) # update internal name cache name_cache.build_name_cache(self.show) try: self.show.loadEpisodesFromDir() except Exception as error: logger.exception( "Error searching dir for episodes: {0}".format(error)) logger.debug(traceback.format_exc()) # if they set default ep status to WANTED then run the backlog to search for episodes # FIXME: This needs to be a backlog queue item!!! if self.show.default_ep_status == WANTED: logger.info( "Launching backlog for this show since its episodes are WANTED" ) settings.backlogSearchScheduler.action.searchBacklog([self.show]) self.show.writeMetadata() self.show.updateMetadata() self.show.populateCache() self.show.flushEpisodes() if settings.USE_TRAKT: # if there are specific episodes that need to be added by trakt settings.traktCheckerScheduler.action.manageNewShow(self.show) # add show to trakt.tv library if settings.TRAKT_SYNC: settings.traktCheckerScheduler.action.addShowToTraktLibrary( self.show) if settings.TRAKT_SYNC_WATCHLIST: logger.info("update watchlist") notifiers.trakt_notifier.update_watchlist(show_obj=self.show) # Load XEM data to DB for show scene_numbering.xem_refresh(self.show.indexerid, self.show.indexer, force=True) # check if show has XEM mapping so we can determine if searches should go by scene numbering or indexer numbering. if not self.scene and scene_numbering.get_xem_numbering_for_show( self.show.indexerid, self.show.indexer): self.show.scene = 1 # After initial add, set to default_status_after. self.show.default_ep_status = self.default_status_after super(QueueItemAdd, self).finish() self.finish()