def search(self, series):
        if TraktSearchTypes.text != self.config['search_type']:
            url = '/search/%s/%s?type=%s&extended=full&limit=100' % (self.config['search_type'], series,
                                                                     ','.join(self.config['result_types']))
        else:
            url = '/search/%s?query=%s&extended=full&limit=100' % (','.join(self.config['result_types']), series)
        filtered = []
        kwargs = {}
        if None is not self.config['sleep_retry']:
            kwargs['sleep_retry'] = self.config['sleep_retry']
        try:
            resp = TraktAPI().trakt_request(url, **kwargs)
            if len(resp):
                for d in resp:
                    if isinstance(d, dict) and 'type' in d and d['type'] in self.config['result_types']:
                        for k, v in d.iteritems():
                            d[k] = self._clean_data(v)
                        if 'show' in d and TraktResultTypes.show == d['type']:
                            d.update(d['show'])
                            del d['show']
                            d['seriesname'] = self._dict_prevent_none(d, 'title', '')
                            d['genres_list'] = d.get('genres', [])
                            d['genres'] = ', '.join(['%s' % v for v in d.get('genres', []) or [] if v])
                            d['firstaired'] = (d.get('first_aired') and
                                               re.sub(r'T.*$', '', str(d.get('first_aired'))) or d.get('year'))
                        filtered.append(d)
        except TraktException as e:
            log().debug('Could not connect to Trakt service: %s' % ex(e))

        return filtered
Exemple #2
0
    def test_notify(username, blacklist_name=None):
        """
        Sends a test notification to trakt with the given authentication info and returns a boolean
        representing success.

        api: The api string to use
        username: The username to use
        blacklist_name: slug of trakt list used to hide not interested show

        Returns: True if the request succeeded, False otherwise
        """
        try:
            trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT)
            trakt_api.validateAccount()
            if blacklist_name and blacklist_name is not None:
                trakt_lists = trakt_api.traktRequest("users/" + username +
                                                     "/lists")
                found = False
                for trakt_list in trakt_lists:
                    if trakt_list['ids']['slug'] == blacklist_name:
                        return "Test notice sent successfully to Trakt"
                if not found:
                    return "Trakt blacklist doesn't exists"
            else:
                return "Test notice sent successfully to Trakt"
        except (traktException, traktAuthException, traktServerBusy) as e:
            logger.log("Could not connect to Trakt service: {0}".format(ex(e)),
                       logger.WARNING)
            return "Test notice failed to Trakt: {0}".format(ex(e))
Exemple #3
0
 def __init__(self):
     self.trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT)
     self.todoBacklog = []
     self.todoWanted = []
     self.ShowWatchlist = {}
     self.EpisodeWatchlist = {}
     self.Collectionlist = {}
     self.amActive = False
Exemple #4
0
    def addShowToBlacklist(self, indexer_id):
        # URL parameters
        data = {'shows': [{'ids': {'tvdb': indexer_id}}]}

        trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT)

        trakt_api.traktRequest("users/" + sickbeard.TRAKT_USERNAME +
                               "/lists/" + sickbeard.TRAKT_BLACKLIST_NAME +
                               "/items",
                               data,
                               method='POST')

        return self.redirect('/addShows/trendingShows/')
Exemple #5
0
    def update_library(ep_obj):
        """
        Sends a request to trakt indicating that the given episode is part of our library.

        ep_obj: The TVEpisode object to add to trakt
        """

        trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT)

        if sickbeard.USE_TRAKT:
            try:
                # URL parameters
                data = {
                    'shows': [{
                        'title': ep_obj.show.name,
                        'year': ep_obj.show.startyear,
                        'ids': {
                            ep_obj.idxr.slug: ep_obj.show.indexerid
                        },
                    }]
                }

                if sickbeard.TRAKT_SYNC_WATCHLIST and sickbeard.TRAKT_REMOVE_SERIESLIST:
                    trakt_api.traktRequest("sync/watchlist/remove",
                                           data,
                                           method='POST')

                # Add Season and Episode + Related Episodes
                data['shows'][0]['seasons'] = [{
                    'number': ep_obj.season,
                    'episodes': []
                }]

                for relEp_Obj in [ep_obj] + ep_obj.relatedEps:
                    data['shows'][0]['seasons'][0]['episodes'].append(
                        {'number': relEp_Obj.episode})

                if sickbeard.TRAKT_SYNC_WATCHLIST and sickbeard.TRAKT_REMOVE_WATCHLIST:
                    trakt_api.traktRequest("sync/watchlist/remove",
                                           data,
                                           method='POST')

                # update library
                trakt_api.traktRequest("sync/collection", data, method='POST')

            except (traktException, traktAuthException, traktServerBusy) as e:
                logger.log(
                    "Could not connect to Trakt service: {0}".format(ex(e)),
                    logger.WARNING)
Exemple #6
0
    def addShowToBlacklist(self):
        # URL parameters

        indexer_id = self.get_query_argument('indexer_id')
        if not indexer_id:
            raise HTTPError(404)

        data = {'shows': [{'ids': {'tvdb': indexer_id}}]}

        trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT)

        trakt_api.traktRequest("users/" + sickbeard.TRAKT_USERNAME +
                               "/lists/" + sickbeard.TRAKT_BLACKLIST_NAME +
                               "/items",
                               data,
                               method='POST')

        return self.redirect('/addShows/trendingShows/')
Exemple #7
0
    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()
Exemple #8
0
    def update_watchlist(show_obj=None,
                         s=None,
                         e=None,
                         data_show=None,
                         data_episode=None,
                         update="add"):
        """
        Sends a request to trakt indicating that the given episode is part of our library.

        show_obj: The TVShow object to add to trakt
        s: season number
        e: episode number
        data_show: structured object of shows trakt type
        data_episode: structured object of episodes trakt type
        update: type o action add or remove
        """

        trakt_api = TraktAPI(sickbeard.SSL_VERIFY, sickbeard.TRAKT_TIMEOUT)

        if sickbeard.USE_TRAKT:

            data = {}
            try:
                # URL parameters
                if show_obj is not None:
                    data = {
                        'shows': [{
                            'title': show_obj.name,
                            'year': show_obj.startyear,
                            'ids': {
                                show_obj.idxr.slug: show_obj.indexerid
                            },
                        }]
                    }
                elif data_show is not None:
                    data.update(data_show)
                else:
                    logger.log(
                        "there's a coding problem contact developer. It's needed to be provided at lest one of the two: data_show or show_obj",
                        logger.WARNING)
                    return False

                if data_episode is not None:
                    data['shows'][0].update(data_episode)

                elif s is not None:
                    # trakt URL parameters
                    season = {
                        'season': [{
                            'number': s,
                        }]
                    }

                    if e is not None:
                        # trakt URL parameters
                        episode = {'episodes': [{'number': e}]}

                        season['season'][0].update(episode)

                    data['shows'][0].update(season)

                trakt_url = "sync/watchlist"
                if update == "remove":
                    trakt_url += "/remove"

                trakt_api.traktRequest(trakt_url, data, method='POST')

            except (traktException, traktAuthException, traktServerBusy) as e:
                logger.log(
                    "Could not connect to Trakt service: {0}".format(ex(e)),
                    logger.WARNING)
                return False

        return True