Пример #1
0
    def run(self, force=False):
        if self.amActive:
            return

        self.amActive = True

        # set thread name
        threading.currentThread().setName(self.name)

        # init trakt api
        self.trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY,
                                  sickrage.srCore.srConfig.TRAKT_TIMEOUT)

        # add shows from tv watchlist
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
            self.todoWanted = []  # its about to all get re-added
            if len(sickrage.srCore.srConfig.ROOT_DIRS.split('|')) < 2:
                sickrage.srCore.srLogger.warning("No default root directory")
                return

            try:
                self.syncWatchlist()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

            try:
                # sync tv library with sickrage library
                self.syncLibrary()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

        self.amActive = False
Пример #2
0
    def test_notify(self, 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(sickrage.srCore.srConfig.SSL_VERIFY, sickrage.srCore.srConfig.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:
            sickrage.srCore.srLogger.warning("Could not connect to Trakt service: %s" % e)
            return "Test notice failed to Trakt: %s" % e
Пример #3
0
 def __init__(self, *args, **kwargs):
     self.name = "TRAKTSEARCHER"
     self.trakt_api = TraktAPI(sickrage.SSL_VERIFY, sickrage.TRAKT_TIMEOUT)
     self.todoBacklog = []
     self.todoWanted = []
     self.ShowWatchlist = {}
     self.EpisodeWatchlist = {}
     self.Collectionlist = {}
     self.amActive = False
Пример #4
0
    def run(self, force=False):
        if self.amActive:
            return

        self.amActive = True

        # set thread name
        threading.currentThread().setName(self.name)

        # init trakt api
        self.trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY, sickrage.srCore.srConfig.TRAKT_TIMEOUT)

        # add shows from tv watchlist
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
            self.todoWanted = []  # its about to all get re-added
            if len(sickrage.srCore.srConfig.ROOT_DIRS.split('|')) < 2:
                sickrage.srCore.srLogger.warning("No default root directory")
                return

            try:
                self.syncWatchlist()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

            try:
                # sync tv library with sickrage library
                self.syncLibrary()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

        self.amActive = False
Пример #5
0
    def update_library(self, 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_id = srIndexerApi(ep_obj.show.indexer).config['trakt_id']
        trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY,
                             sickrage.srCore.srConfig.TRAKT_TIMEOUT)

        if sickrage.srCore.srConfig.USE_TRAKT:
            try:
                # URL parameters
                data = {
                    'shows': [{
                        'title': ep_obj.show.name,
                        'year': ep_obj.show.startyear,
                        'ids': {},
                    }]
                }

                if trakt_id == 'tvdb_id':
                    data['shows'][0]['ids']['tvdb'] = ep_obj.show.indexerid
                else:
                    data['shows'][0]['ids']['tvrage'] = ep_obj.show.indexerid

                if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
                    if sickrage.srCore.srConfig.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 sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
                    if sickrage.srCore.srConfig.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:
                sickrage.srCore.srLogger.warning(
                    "Could not connect to Trakt service: %s" % e)
Пример #6
0
 def __init__(self, *args, **kwargs):
     self.name = "TRAKTSEARCHER"
     self.trakt_api = TraktAPI(sickrage.SSL_VERIFY, sickrage.TRAKT_TIMEOUT)
     self.todoBacklog = []
     self.todoWanted = []
     self.ShowWatchlist = {}
     self.EpisodeWatchlist = {}
     self.Collectionlist = {}
     self.amActive = False
Пример #7
0
    def update_library(self, 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_id = srIndexerApi(ep_obj.show.indexer).config['trakt_id']
        trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY, sickrage.srCore.srConfig.TRAKT_TIMEOUT)

        if sickrage.srCore.srConfig.USE_TRAKT:
            try:
                # URL parameters
                data = {
                    'shows': [
                        {
                            'title': ep_obj.show.name,
                            'year': ep_obj.show.startyear,
                            'ids': {},
                        }
                    ]
                }

                if trakt_id == 'tvdb_id':
                    data['shows'][0]['ids']['tvdb'] = ep_obj.show.indexerid
                else:
                    data['shows'][0]['ids']['tvrage'] = ep_obj.show.indexerid

                if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
                    if sickrage.srCore.srConfig.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 sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
                    if sickrage.srCore.srConfig.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:
                sickrage.srCore.srLogger.warning("Could not connect to Trakt service: %s" % e)
Пример #8
0
    def run(self):
        super(QueueItemAdd, self).run()

        sickrage.srCore.srLogger.info("Started adding show {}".format(self.showDir))

        index_name = srIndexerApi(self.indexer).name

        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = srIndexerApi(self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            sickrage.srCore.srLogger.info("{}: {}".format(index_name, repr(lINDEXER_API_PARMS)))

            t = srIndexerApi(self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]

            # 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 not getattr(s, 'seriesname'):
                sickrage.srCore.srLogger.error(
                    "Show in {} has no name on {}, probably the wrong language used to search with".format(self.showDir,
                                                                                                           index_name))
                sickrage.srCore.srNotifications.error("Unable to add show",
                                                      "Show in {} has no name on {}, probably the wrong language. Delete .nfo and add manually in the correct language".format(
                                                          self.showDir, index_name))
                return self._finishEarly()

            # if the show has no episodes/seasons
            if not len(s):
                sickrage.srCore.srLogger.error("Show " + str(s['seriesname']) + " is on " + str(
                    srIndexerApi(self.indexer).name) + " but contains no season/episode data.")
                sickrage.srCore.srNotifications.error("Unable to add show",
                                                      "Show " + str(s['seriesname']) + " is on " + str(srIndexerApi(
                                                          self.indexer).name) + " but contains no season/episode data.")
                return self._finishEarly()
        except Exception as e:
            sickrage.srCore.srLogger.error(
                "{}: Error while loading information from indexer {}. Error: {}".format(self.indexer_id, index_name,
                                                                                        e.message))

            sickrage.srCore.srNotifications.error(
                "Unable to add show",
                "Unable to look up the show in {} on {} using ID {}, not using the NFO. Delete .nfo and try adding manually again.".format(
                    self.showDir, index_name, self.indexer_id)
            )

            if sickrage.srCore.srConfig.USE_TRAKT:

                trakt_id = srIndexerApi(self.indexer).config['trakt_id']
                trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY, sickrage.srCore.srConfig.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')

            return self._finishEarly()

        try:
            self.show = TVShow(self.indexer, self.indexer_id, self.lang)
            self.show.loadFromIndexer()

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles or sickrage.srCore.srConfig.SUBTITLES_DEFAULT
            self.show.quality = self.quality or sickrage.srCore.srConfig.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders or sickrage.srCore.srConfig.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime or sickrage.srCore.srConfig.ANIME_DEFAULT
            self.show.scene = self.scene or sickrage.srCore.srConfig.SCENE_DEFAULT
            self.show.archive_firstmatch = self.archive or sickrage.srCore.srConfig.ARCHIVE_DEFAULT
            self.show.paused = self.paused or False

            # set up default new/missing episode status
            sickrage.srCore.srLogger.info(
                "Setting all current episodes to the specified default status: " + str(self.default_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 smartish 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 indexer_exception as e:
            sickrage.srCore.srLogger.error(
                "Unable to add show due to an error with " + srIndexerApi(
                    self.indexer).name + ": {}".format(e.message))
            if self.show:
                sickrage.srCore.srNotifications.error(
                    "Unable to add " + str(self.show.name) + " due to an error with " + srIndexerApi(
                        self.indexer).name + "")
            else:
                sickrage.srCore.srNotifications.error(
                    "Unable to add show due to an error with " + srIndexerApi(self.indexer).name + "")
            return self._finishEarly()

        except MultipleShowObjectsException:
            sickrage.srCore.srLogger.warning("The show in " + self.showDir + " is already in your show list, skipping")
            sickrage.srCore.srNotifications.error('Show skipped',
                                                  "The show in " + self.showDir + " is already in your show list")
            return self._finishEarly()

        except Exception as e:
            sickrage.srCore.srLogger.error("Error trying to add show: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())
            raise self._finishEarly()

        sickrage.srCore.srLogger.debug("Retrieving show info from TMDb")
        try:
            self.show.loadTMDbInfo()
        except Exception as e:
            sickrage.srCore.srLogger.error("Error loading TMDb info: {}".format(e.message))
            try:
                sickrage.srCore.srLogger.debug("Attempting to retrieve show info from IMDb")
                self.show.loadIMDbInfo()
            except Exception as e:
                sickrage.srCore.srLogger.error("Error loading IMDb info: {}".format(e.message))

        # Load XEM data to DB for show
        xem_refresh(self.show.indexerid, self.show.indexer, force=True)

        # check if show has XEM mapping so we can determin if searches should go by scene numbering or indexer numbering.
        if not self.scene and get_xem_numbering_for_show(self.show.indexerid, self.show.indexer):
            self.show.scene = 1

        try:
            self.show.saveToDB()
        except Exception as e:
            sickrage.srCore.srLogger.error("Error saving the show to the database: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())
            raise self._finishEarly()

        # add it to the show list
        sickrage.srCore.SHOWLIST.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as e:
            sickrage.srCore.srLogger.error(
                "Error with " + srIndexerApi(
                    self.show.indexer).name + ", not creating episode list: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())

        try:
            self.show.loadEpisodesFromDir()
        except Exception as e:
            sickrage.srCore.srLogger.debug("Error searching dir for episodes: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())

        # if they set default ep status to WANTED then run the backlog to search for episodes
        if self.show.default_ep_status == WANTED:
            sickrage.srCore.srLogger.info("Launching backlog for this show since its episodes are WANTED")
            sickrage.srCore.BACKLOGSEARCHER.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        if sickrage.srCore.srConfig.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickrage.srCore.TRAKTSEARCHER.manageNewShow(self.show)

            # add show to trakt.tv library
            if sickrage.srCore.srConfig.TRAKT_SYNC:
                sickrage.srCore.TRAKTSEARCHER.addShowToTraktLibrary(self.show)

            if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
                sickrage.srCore.srLogger.info("update watchlist")
                sickrage.srCore.notifiersDict.trakt_notifier.update_watchlist(show_obj=self.show)

        # After initial add, set to default_status_after.
        sickrage.srCore.srLogger.info(
            "Setting all future episodes to the specified default status: " + str(self.default_status_after))
        self.show.default_ep_status = self.default_status_after

        self.show.saveToDB()

        sickrage.srCore.NAMECACHE.buildNameCache(self.show)

        sickrage.srCore.srLogger.info("Finished adding show {}".format(self.showDir))
Пример #9
0
class srTraktSearcher(object):
    def __init__(self, *args, **kwargs):
        self.name = "TRAKTSEARCHER"
        self.trakt_api = None
        self.todoBacklog = []
        self.todoWanted = []
        self.ShowWatchlist = {}
        self.EpisodeWatchlist = {}
        self.Collectionlist = {}
        self.amActive = False

    def run(self, force=False):
        if self.amActive:
            return

        self.amActive = True

        # set thread name
        threading.currentThread().setName(self.name)

        # init trakt api
        self.trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY,
                                  sickrage.srCore.srConfig.TRAKT_TIMEOUT)

        # add shows from tv watchlist
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
            self.todoWanted = []  # its about to all get re-added
            if len(sickrage.srCore.srConfig.ROOT_DIRS.split('|')) < 2:
                sickrage.srCore.srLogger.warning("No default root directory")
                return

            try:
                self.syncWatchlist()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

            try:
                # sync tv library with sickrage library
                self.syncLibrary()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

        self.amActive = False

    def findShow(self, indexer, indexerid):
        traktShow = None

        try:
            library = self.trakt_api.traktRequest(
                "sync/collection/shows") or []

            if not library:
                sickrage.srCore.srLogger.warning(
                    "Could not connect to trakt service, aborting library check"
                )
                return

            if not len(library):
                sickrage.srCore.srLogger.debug(
                    "No shows found in your library, aborting library update")
                return

            traktShow = [
                x for x in library if int(indexerid) in [
                    int(x['show']['ids']['tvdb'] or 0),
                    int(x['show']['ids']['tvrage'] or 0)
                ]
            ]
        except traktException as e:
            sickrage.srCore.srLogger.warning(
                "Could not connect to Trakt service. Aborting library check. Error: %s"
                % repr(e))

        return traktShow

    def removeShowFromTraktLibrary(self, show_obj):
        if self.findShow(show_obj.indexer, show_obj.indexerid):
            trakt_id = srIndexerApi(show_obj.indexer).config['trakt_id']

            # URL parameters
            data = {
                'shows': [{
                    'title': show_obj.name,
                    'year': show_obj.startyear,
                    'ids': {}
                }]
            }

            if trakt_id == 'tvdb_id':
                data['shows'][0]['ids']['tvdb'] = show_obj.indexerid
            else:
                data['shows'][0]['ids']['tvrage'] = show_obj.indexerid

            sickrage.srCore.srLogger.debug("Removing %s from tv library" %
                                           show_obj.name)

            try:
                self.trakt_api.traktRequest("sync/collection/remove",
                                            data,
                                            method='POST')
            except traktException as e:
                sickrage.srCore.srLogger.warning(
                    "Could not connect to Trakt service. Aborting removing show %s from Trakt library. Error: %s"
                    % (show_obj.name, repr(e)))

    def addShowToTraktLibrary(self, show_obj):
        """
        Sends a request to trakt indicating that the given show and all its episodes is part of our library.

        show_obj: The TVShow object to add to trakt
        """
        data = {}

        if not self.findShow(show_obj.indexer, show_obj.indexerid):
            trakt_id = srIndexerApi(show_obj.indexer).config['trakt_id']
            # URL parameters
            data = {
                'shows': [{
                    'title': show_obj.name,
                    'year': show_obj.startyear,
                    'ids': {}
                }]
            }

            if trakt_id == 'tvdb_id':
                data['shows'][0]['ids']['tvdb'] = show_obj.indexerid
            else:
                data['shows'][0]['ids']['tvrage'] = show_obj.indexerid

        if len(data):
            sickrage.srCore.srLogger.debug("Adding %s to tv library" %
                                           show_obj.name)

            try:
                self.trakt_api.traktRequest("sync/collection",
                                            data,
                                            method='POST')
            except traktException as e:
                sickrage.srCore.srLogger.warning(
                    "Could not connect to Trakt service. Aborting adding show %s to Trakt library. Error: %s"
                    % (show_obj.name, repr(e)))
                return

    def syncLibrary(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug(
                "Sync SiCKRAGE with Trakt Collection")

            if self._getShowCollection():
                self.addEpisodeToTraktCollection()
                if sickrage.srCore.srConfig.TRAKT_SYNC_REMOVE:
                    self.removeEpisodeFromTraktCollection()

    def removeEpisodeFromTraktCollection(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_REMOVE and sickrage.srCore.srConfig.TRAKT_SYNC and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug(
                "COLLECTION::REMOVE::START - Look for Episodes to Remove From Trakt Collection"
            )

            trakt_data = []
            for s in [
                    x['doc']
                    for x in sickrage.srCore.mainDB.db.all('tv_shows',
                                                           with_doc=True)
            ]:
                for e in [
                        e['doc'] for e in sickrage.srCore.mainDB.db.get_many(
                            'tv_episodes', s['indexer_id'], with_doc=True)
                ]:
                    trakt_id = srIndexerApi(s["indexer"]).config['trakt_id']

                    if self._checkInList(trakt_id,
                                         str(e["showid"]),
                                         str(e["season"]),
                                         str(e["episode"]),
                                         List='Collection'):

                        if e["location"] == '':
                            sickrage.srCore.srLogger.debug(
                                "Removing Episode %s S%02dE%02d from collection"
                                % (s["show_name"], e["season"], e["episode"]))
                            trakt_data.append(
                                (e["showid"], s["indexer"], s["show_name"],
                                 s["startyear"], e["season"], e["episode"]))

            if len(trakt_data):
                try:
                    data = self.trakt_bulk_data_generate(trakt_data)
                    self.trakt_api.traktRequest("sync/collection/remove",
                                                data,
                                                method='POST')
                    self._getShowCollection()
                except traktException as e:
                    sickrage.srCore.srLogger.warning(
                        "Could not connect to Trakt service. Error: %s" % e)

            sickrage.srCore.srLogger.debug(
                "COLLECTION::REMOVE::FINISH - Look for Episodes to Remove From Trakt Collection"
            )

    def addEpisodeToTraktCollection(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug(
                "COLLECTION::ADD::START - Look for Episodes to Add to Trakt Collection"
            )

            trakt_data = []
            for s in [
                    x['doc']
                    for x in sickrage.srCore.mainDB.db.all('tv_shows',
                                                           with_doc=True)
            ]:
                for e in [
                        e['doc'] for e in sickrage.srCore.mainDB.db.get_many(
                            'tv_episodes', s['indexer_id'], with_doc=True)
                ]:
                    trakt_id = srIndexerApi(s["indexer"]).config['trakt_id']

                    if not self._checkInList(trakt_id,
                                             str(e["showid"]),
                                             str(e["season"]),
                                             str(e["episode"]),
                                             List='Collection'):
                        sickrage.srCore.srLogger.debug(
                            "Adding Episode %s S%02dE%02d to collection" %
                            (s["show_name"], e["season"], e["episode"]))
                        trakt_data.append(
                            (e["showid"], s["indexer"], s["show_name"],
                             s["startyear"], e["season"], e["episode"]))

            if len(trakt_data):
                try:
                    data = self.trakt_bulk_data_generate(trakt_data)
                    self.trakt_api.traktRequest("sync/collection",
                                                data,
                                                method='POST')
                    self._getShowCollection()
                except traktException as e:
                    sickrage.srCore.srLogger.warning(
                        "Could not connect to Trakt service. Error: %s" % e)

            sickrage.srCore.srLogger.debug(
                "COLLECTION::ADD::FINISH - Look for Episodes to Add to Trakt Collection"
            )

    def syncWatchlist(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug(
                "Sync SiCKRAGE with Trakt Watchlist")

            self.removeShowFromSickRage()

            if self._getShowWatchlist():
                self.addShowToTraktWatchList()
                self.updateShows()

            if self._getEpisodeWatchlist():
                self.removeEpisodeFromTraktWatchList()
                self.addEpisodeToTraktWatchList()
                self.updateEpisodes()

    def removeEpisodeFromTraktWatchList(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug(
                "WATCHLIST::REMOVE::START - Look for Episodes to Remove from Trakt Watchlist"
            )

            trakt_data = []
            for s in [
                    x['doc']
                    for x in sickrage.srCore.mainDB.db.all('tv_shows',
                                                           with_doc=True)
            ]:
                for e in [
                        e['doc'] for e in sickrage.srCore.mainDB.db.get_many(
                            'tv_episodes', s['indexer_id'], with_doc=True)
                ]:
                    trakt_id = srIndexerApi(s["indexer"]).config['trakt_id']

                    if self._checkInList(
                            trakt_id, str(e["showid"]), str(e["season"]),
                            str(e["episode"])
                    ) and e["status"] not in Quality.SNATCHED + Quality.SNATCHED_PROPER + [
                            UNKNOWN
                    ] + [WANTED]:
                        sickrage.srCore.srLogger.debug(
                            "Removing Episode %s S%02dE%02d from watchlist" %
                            (s["show_name"], e["season"], e["episode"]))
                        trakt_data.append(
                            (e["showid"], s["indexer"], s["show_name"],
                             s["startyear"], e["season"], e["episode"]))

            if len(trakt_data):
                try:
                    data = self.trakt_bulk_data_generate(trakt_data)
                    self.trakt_api.traktRequest("sync/watchlist/remove",
                                                data,
                                                method='POST')
                    self._getEpisodeWatchlist()
                except traktException as e:
                    sickrage.srCore.srLogger.warning(
                        "Could not connect to Trakt service. Error: %s" % e)

            sickrage.srCore.srLogger.debug(
                "WATCHLIST::REMOVE::FINISH - Look for Episodes to Remove from Trakt Watchlist"
            )

    def addEpisodeToTraktWatchList(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug(
                "WATCHLIST::ADD::START - Look for Episodes to Add to Trakt Watchlist"
            )

            trakt_data = []
            for s in [
                    x['doc']
                    for x in sickrage.srCore.mainDB.db.all('tv_shows',
                                                           with_doc=True)
            ]:
                for e in [
                        e['doc'] for e in sickrage.srCore.mainDB.db.get_many(
                            'tv_episodes', s['indexer_id'], with_doc=True)
                ]:
                    trakt_id = srIndexerApi(s["indexer"]).config['trakt_id']

                    if not self._checkInList(trakt_id, str(
                            e["showid"]), str(e["season"]), str(e["episode"])):
                        sickrage.srCore.srLogger.debug(
                            "Adding Episode %s S%02dE%02d to watchlist" %
                            (s["show_name"], e["season"], e["episode"]))
                        trakt_data.append(
                            (e["showid"], s["indexer"], s["show_name"],
                             s["startyear"], e["season"], e["episode"]))

            if len(trakt_data):
                try:
                    data = self.trakt_bulk_data_generate(trakt_data)
                    self.trakt_api.traktRequest("sync/watchlist",
                                                data,
                                                method='POST')
                    self._getEpisodeWatchlist()
                except traktException as e:
                    sickrage.srCore.srLogger.warning(
                        "Could not connect to Trakt service. Error %s" % e)

            sickrage.srCore.srLogger.debug(
                "WATCHLIST::ADD::FINISH - Look for Episodes to Add to Trakt Watchlist"
            )

    def addShowToTraktWatchList(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug(
                "SHOW_WATCHLIST::ADD::START - Look for Shows to Add to Trakt Watchlist"
            )

            if sickrage.srCore.SHOWLIST is not None:
                trakt_data = []

                for show in sickrage.srCore.SHOWLIST:
                    trakt_id = srIndexerApi(show.indexer).config['trakt_id']

                    if not self._checkInList(
                            trakt_id, str(
                                show.indexerid), '0', '0', List='Show'):
                        sickrage.srCore.srLogger.debug(
                            "Adding Show: Indexer %s %s - %s to Watchlist" %
                            (trakt_id, str(show.indexerid), show.name))
                        show_el = {
                            'title': show.name,
                            'year': show.startyear,
                            'ids': {}
                        }
                        if trakt_id == 'tvdb_id':
                            show_el['ids']['tvdb'] = show.indexerid
                        else:
                            show_el['ids']['tvrage'] = show.indexerid
                        trakt_data.append(show_el)

                if len(trakt_data):
                    try:
                        data = {'shows': trakt_data}
                        self.trakt_api.traktRequest("sync/watchlist",
                                                    data,
                                                    method='POST')
                        self._getShowWatchlist()
                    except traktException as e:
                        sickrage.srCore.srLogger.warning(
                            "Could not connect to Trakt service. Error: %s" %
                            e)

            sickrage.srCore.srLogger.debug(
                "SHOW_WATCHLIST::ADD::FINISH - Look for Shows to Add to Trakt Watchlist"
            )

    def removeShowFromSickRage(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT and sickrage.srCore.srConfig.TRAKT_REMOVE_SHOW_FROM_SICKRAGE:
            sickrage.srCore.srLogger.debug(
                "SHOW_SICKRAGE::REMOVE::START - Look for Shows to remove from SiCKRAGE"
            )

            if sickrage.srCore.SHOWLIST:
                for show in sickrage.srCore.SHOWLIST:
                    if show.status == "Ended":
                        try:
                            progress = self.trakt_api.traktRequest(
                                "shows/" + show.imdbid +
                                "/progress/watched") or {}
                        except traktException as e:
                            sickrage.srCore.srLogger.warning(
                                "Could not connect to Trakt service. Aborting removing show %s from SiCKRAGE. Error: %s"
                                % (show.name, repr(e)))
                            return

                        if 'aired' in progress and 'completed' in progress and progress[
                                'aired'] == progress['completed']:
                            sickrage.srCore.SHOWQUEUE.removeShow(show,
                                                                 full=True)
                            sickrage.srCore.srLogger.debug(
                                "Show: %s has been removed from SiCKRAGE" %
                                show.name)

            sickrage.srCore.srLogger.debug(
                "SHOW_SICKRAGE::REMOVE::FINISH - Trakt Show Watchlist")

    def updateShows(self):
        sickrage.srCore.srLogger.debug(
            "SHOW_WATCHLIST::CHECK::START - Trakt Show Watchlist")

        if not len(self.ShowWatchlist):
            sickrage.srCore.srLogger.debug(
                "No shows found in your watchlist, aborting watchlist update")
            return

        indexer = int(sickrage.srCore.srConfig.TRAKT_DEFAULT_INDEXER)
        trakt_id = srIndexerApi(indexer).config['trakt_id']

        for show_el in self.ShowWatchlist[trakt_id]:
            indexer_id = int(str(show_el))
            show = self.ShowWatchlist[trakt_id][show_el]

            # LOGGER.debug(u"Checking Show: %s %s %s" % (trakt_id, indexer_id, show['title']))
            if int(sickrage.srCore.srConfig.TRAKT_METHOD_ADD) != 2:
                self.addDefaultShow(indexer, indexer_id, show['title'],
                                    SKIPPED)
            else:
                self.addDefaultShow(indexer, indexer_id, show['title'], WANTED)

            if int(sickrage.srCore.srConfig.TRAKT_METHOD_ADD) == 1:
                newShow = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id)

                if newShow is not None:
                    setEpisodeToWanted(newShow, 1, 1)
                else:
                    self.todoWanted.append((indexer_id, 1, 1))
        sickrage.srCore.srLogger.debug(
            "SHOW_WATCHLIST::CHECK::FINISH - Trakt Show Watchlist")

    def updateEpisodes(self):
        """
        Sets episodes to wanted that are in trakt watchlist
        """
        sickrage.srCore.srLogger.debug(
            "SHOW_WATCHLIST::CHECK::START - Trakt Episode Watchlist")

        if not len(self.EpisodeWatchlist):
            sickrage.srCore.srLogger.debug(
                "No episode found in your watchlist, aborting episode update")
            return

        managed_show = []

        indexer = int(sickrage.srCore.srConfig.TRAKT_DEFAULT_INDEXER)
        trakt_id = srIndexerApi(indexer).config['trakt_id']

        for show_el in self.EpisodeWatchlist[trakt_id]:
            indexer_id = int(show_el)
            show = self.EpisodeWatchlist[trakt_id][show_el]

            newShow = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id)

            try:
                if newShow is None:
                    if indexer_id not in managed_show:
                        self.addDefaultShow(indexer, indexer_id, show['title'],
                                            SKIPPED)
                        managed_show.append(indexer_id)

                        for season_el in show['seasons']:
                            season = int(season_el)

                            for episode_el in show['seasons'][season_el][
                                    'episodes']:
                                self.todoWanted.append(
                                    (indexer_id, season, int(episode_el)))
                else:
                    if newShow.indexer == indexer:
                        for season_el in show['seasons']:
                            season = int(season_el)

                            for episode_el in show['seasons'][season_el][
                                    'episodes']:
                                setEpisodeToWanted(newShow, season,
                                                   int(episode_el))
            except TypeError:
                sickrage.srCore.srLogger.debug(
                    "Could not parse the output from trakt for %s " %
                    show["title"])
        sickrage.srCore.srLogger.debug(
            "SHOW_WATCHLIST::CHECK::FINISH - Trakt Episode Watchlist")

    @staticmethod
    def addDefaultShow(indexer, indexer_id, name, status):
        """
        Adds a new show with the default settings
        """
        if not findCertainShow(sickrage.srCore.SHOWLIST, int(indexer_id)):
            sickrage.srCore.srLogger.info("Adding show " + str(indexer_id))
            root_dirs = sickrage.srCore.srConfig.ROOT_DIRS.split('|')

            try:
                location = root_dirs[int(root_dirs[0]) + 1]
            except Exception:
                location = None

            if location:
                showPath = os.path.join(location, sanitizeFileName(name))
                dir_exists = makeDir(showPath)

                if not dir_exists:
                    sickrage.srCore.srLogger.warning(
                        "Unable to create the folder %s , can't add the show" %
                        showPath)
                    return
                else:
                    chmodAsParent(showPath)

                sickrage.srCore.SHOWQUEUE.addShow(
                    int(indexer),
                    int(indexer_id),
                    showPath,
                    default_status=status,
                    quality=int(sickrage.srCore.srConfig.QUALITY_DEFAULT),
                    flatten_folders=int(
                        sickrage.srCore.srConfig.FLATTEN_FOLDERS_DEFAULT),
                    paused=sickrage.srCore.srConfig.TRAKT_START_PAUSED,
                    default_status_after=status,
                    archive=sickrage.srCore.srConfig.ARCHIVE_DEFAULT)
            else:
                sickrage.srCore.srLogger.warning(
                    "There was an error creating the show, no root directory setting found"
                )
                return

    def manageNewShow(self, show):
        sickrage.srCore.srLogger.debug(
            "Checking if trakt watch list wants to search for episodes from new show "
            + show.name)
        episodes = [i for i in self.todoWanted if i[0] == show.indexerid]

        for episode in episodes:
            self.todoWanted.remove(episode)
            setEpisodeToWanted(show, episode[1], episode[2])

    def _checkInList(self, trakt_id, showid, season, episode, List=None):
        """
         Check in the Watchlist or CollectionList for Show
         Is the Show, Season and Episode in the trakt_id list (tvdb / tvrage)
        """
        # LOGGER.debug(u"Checking Show: %s %s %s " % (trakt_id, showid, List))

        if "Collection" == List:
            try:
                if self.Collectionlist[trakt_id][showid]['seasons'][season][
                        'episodes'][episode] == episode:
                    return True
            except Exception:
                return False
        elif "Show" == List:
            try:
                if self.ShowWatchlist[trakt_id][showid]['id'] == showid:
                    return True
            except Exception:
                return False
        else:
            try:
                if self.EpisodeWatchlist[trakt_id][showid]['seasons'][season][
                        'episodes'][episode] == episode:
                    return True
            except Exception:
                return False

    def _getShowWatchlist(self):
        """
        Get Watchlist and parse once into addressable structure
        """
        try:
            self.ShowWatchlist = {'tvdb_id': {}, 'tvrage_id': {}}
            TraktShowWatchlist = self.trakt_api.traktRequest(
                "sync/watchlist/shows")
            tvdb_id = 'tvdb'
            tvrage_id = 'tvrage'

            for watchlist_el in TraktShowWatchlist:
                tvdb = False
                tvrage = False

                if not watchlist_el['show']['ids']["tvdb"] is None:
                    tvdb = True

                if not watchlist_el['show']['ids']["tvrage"] is None:
                    tvrage = True

                title = watchlist_el['show']['title']
                year = str(watchlist_el['show']['year'])

                if tvdb:
                    showid = str(watchlist_el['show']['ids'][tvdb_id])
                    self.ShowWatchlist[tvdb_id + '_id'][showid] = {
                        'id': showid,
                        'title': title,
                        'year': year
                    }

                if tvrage:
                    showid = str(watchlist_el['show']['ids'][tvrage_id])
                    self.ShowWatchlist[tvrage_id + '_id'][showid] = {
                        'id': showid,
                        'title': title,
                        'year': year
                    }
        except traktException as e:
            sickrage.srCore.srLogger.warning(
                "Could not connect to trakt service, cannot download Show Watchlist: %s"
                % repr(e))
            return False
        return True

    def _getEpisodeWatchlist(self):
        """
         Get Watchlist and parse once into addressable structure
        """
        try:
            self.EpisodeWatchlist = {'tvdb_id': {}, 'tvrage_id': {}}
            TraktEpisodeWatchlist = self.trakt_api.traktRequest(
                "sync/watchlist/episodes")
            tvdb_id = 'tvdb'
            tvrage_id = 'tvrage'

            for watchlist_el in TraktEpisodeWatchlist:
                tvdb = False
                tvrage = False

                if not watchlist_el['show']['ids']["tvdb"] is None:
                    tvdb = True

                if not watchlist_el['show']['ids']["tvrage"] is None:
                    tvrage = True

                title = watchlist_el['show']['title']
                year = str(watchlist_el['show']['year'])
                season = str(watchlist_el['episode']['season'])
                episode = str(watchlist_el['episode']['number'])

                if tvdb:
                    showid = str(watchlist_el['show']['ids'][tvdb_id])

                    if showid not in self.EpisodeWatchlist[tvdb_id +
                                                           '_id'].keys():
                        self.EpisodeWatchlist[tvdb_id + '_id'][showid] = {
                            'id': showid,
                            'title': title,
                            'year': year,
                            'seasons': {}
                        }

                    if season not in self.EpisodeWatchlist[
                            tvdb_id + '_id'][showid]['seasons'].keys():
                        self.EpisodeWatchlist[
                            tvdb_id + '_id'][showid]['seasons'][season] = {
                                's': season,
                                'episodes': {}
                            }

                    if episode not in self.EpisodeWatchlist[tvdb_id + '_id'][
                            showid]['seasons'][season]['episodes'].keys():
                        self.EpisodeWatchlist[tvdb_id + '_id'][showid][
                            'seasons'][season]['episodes'][episode] = episode

                if tvrage:
                    showid = str(watchlist_el['show']['ids'][tvrage_id])

                    if showid not in self.EpisodeWatchlist[tvrage_id +
                                                           '_id'].keys():
                        self.EpisodeWatchlist[tvrage_id + '_id'][showid] = {
                            'id': showid,
                            'title': title,
                            'year': year,
                            'seasons': {}
                        }

                    if season not in self.EpisodeWatchlist[
                            tvrage_id + '_id'][showid]['seasons'].keys():
                        self.EpisodeWatchlist[
                            tvrage_id + '_id'][showid]['seasons'][season] = {
                                's': season,
                                'episodes': {}
                            }

                    if episode not in self.EpisodeWatchlist[tvrage_id + '_id'][
                            showid]['seasons'][season]['episodes'].keys():
                        self.EpisodeWatchlist[tvrage_id + '_id'][showid][
                            'seasons'][season]['episodes'][episode] = episode
        except traktException as e:
            sickrage.srCore.srLogger.warning(
                "Could not connect to trakt service, cannot download Episode Watchlist: %s"
                % repr(e))
            return False
        return True

    def _getShowCollection(self):
        """
        Get Collection and parse once into addressable structure
        """
        try:
            self.Collectionlist = {'tvdb_id': {}, 'tvrage_id': {}}
            sickrage.srCore.srLogger.debug("Getting Show Collection")
            TraktCollectionList = self.trakt_api.traktRequest(
                "sync/collection/shows")
            tvdb_id = 'tvdb'
            tvrage_id = 'tvrage'

            for watchlist_el in TraktCollectionList:
                tvdb = False
                tvrage = False

                if not watchlist_el['show']['ids']["tvdb"] is None:
                    tvdb = True

                if not watchlist_el['show']['ids']["tvrage"] is None:
                    tvrage = True

                title = watchlist_el['show']['title']
                year = str(watchlist_el['show']['year'])

                if 'seasons' in watchlist_el:
                    for season_el in watchlist_el['seasons']:
                        for episode_el in season_el['episodes']:
                            season = str(season_el['number'])
                            episode = str(episode_el['number'])

                            if tvdb:
                                showid = str(
                                    watchlist_el['show']['ids'][tvdb_id])

                                if showid not in self.Collectionlist[
                                        tvdb_id + '_id'].keys():
                                    self.Collectionlist[tvdb_id +
                                                        '_id'][showid] = {
                                                            'id': showid,
                                                            'title': title,
                                                            'year': year,
                                                            'seasons': {}
                                                        }

                                if season not in self.Collectionlist[
                                        tvdb_id +
                                        '_id'][showid]['seasons'].keys():
                                    self.Collectionlist[
                                        tvdb_id +
                                        '_id'][showid]['seasons'][season] = {
                                            's': season,
                                            'episodes': {}
                                        }

                                if episode not in self.Collectionlist[
                                        tvdb_id + '_id'][showid]['seasons'][
                                            season]['episodes'].keys():
                                    self.Collectionlist[
                                        tvdb_id +
                                        '_id'][showid]['seasons'][season][
                                            'episodes'][episode] = episode

                            if tvrage:
                                showid = str(
                                    watchlist_el['show']['ids'][tvrage_id])

                                if showid not in self.Collectionlist[
                                        tvrage_id + '_id'].keys():
                                    self.Collectionlist[tvrage_id +
                                                        '_id'][showid] = {
                                                            'id': showid,
                                                            'title': title,
                                                            'year': year,
                                                            'seasons': {}
                                                        }

                                if season not in self.Collectionlist[
                                        tvrage_id +
                                        '_id'][showid]['seasons'].keys():
                                    self.Collectionlist[
                                        tvrage_id +
                                        '_id'][showid]['seasons'][season] = {
                                            's': season,
                                            'episodes': {}
                                        }

                                if episode not in self.Collectionlist[
                                        tvrage_id + '_id'][showid]['seasons'][
                                            season]['episodes'].keys():
                                    self.Collectionlist[
                                        tvrage_id +
                                        '_id'][showid]['seasons'][season][
                                            'episodes'][episode] = episode
        except traktException as e:
            sickrage.srCore.srLogger.warning(
                "Could not connect to trakt service, cannot download Show Collection: %s"
                % repr(e))
            return False
        return True

    @staticmethod
    def trakt_bulk_data_generate(data):
        """
        Build the JSON structure to send back to Trakt
        """
        uniqueShows = {}
        uniqueSeasons = {}

        for showid, indexerid, show_name, startyear, season, episode in data:
            if showid not in uniqueShows:
                uniqueShows[showid] = {
                    'title': show_name,
                    'year': startyear,
                    'ids': {},
                    'seasons': []
                }
                trakt_id = srIndexerApi(indexerid).config['trakt_id']

                if trakt_id == 'tvdb_id':
                    uniqueShows[showid]['ids']["tvdb"] = showid
                else:
                    uniqueShows[showid]['ids']["tvrage"] = showid
                uniqueSeasons[showid] = []

        # Get the unique seasons per Show
        for showid, indexerid, show_name, startyear, season, episode in data:
            if season not in uniqueSeasons[showid]:
                uniqueSeasons[showid].append(season)

        # build the query
        traktShowList = []
        seasonsList = {}

        for searchedShow in uniqueShows:
            seasonsList[searchedShow] = []

            for searchedSeason in uniqueSeasons[searchedShow]:
                episodesList = []

                for showid, indexerid, show_name, startyear, season, episode in data:
                    if season == searchedSeason and showid == searchedShow:
                        episodesList.append({'number': episode})
                show = uniqueShows[searchedShow]
                show['seasons'].append({
                    'number': searchedSeason,
                    'episodes': episodesList
                })
                traktShowList.append(show)

        return {'shows': traktShowList}
Пример #10
0
    def run(self):
        sickrage.srCore.srLogger.info("Started adding show {}".format(
            self.show_name))

        index_name = srIndexerApi(self.indexer).name

        # make sure the Indexer IDs are valid
        try:

            lINDEXER_API_PARMS = srIndexerApi(self.indexer).api_params.copy()
            if self.lang:
                lINDEXER_API_PARMS['language'] = self.lang

            sickrage.srCore.srLogger.info("{}: {}".format(
                index_name, repr(lINDEXER_API_PARMS)))

            t = srIndexerApi(self.indexer).indexer(**lINDEXER_API_PARMS)
            s = t[self.indexer_id]
            if not s: return self._finishEarly()

            # 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 not getattr(s, 'seriesname'):
                sickrage.srCore.srLogger.error(
                    "Show in {} has no name on {}, probably the wrong language used to search with"
                    .format(self.showDir, index_name))
                sickrage.srCore.srNotifications.error(
                    "Unable to add show",
                    "Show in {} has no name on {}, probably the wrong language. Delete .nfo and add manually in the correct language"
                    .format(self.showDir, index_name))
                return self._finishEarly()

            # if the show has no episodes/seasons
            if not len(s):
                sickrage.srCore.srLogger.error(
                    "Show " + str(s['seriesname']) + " is on " +
                    str(srIndexerApi(self.indexer).name) +
                    " but contains no season/episode data.")
                sickrage.srCore.srNotifications.error(
                    "Unable to add show", "Show " + str(s['seriesname']) +
                    " is on " + str(srIndexerApi(self.indexer).name) +
                    " but contains no season/episode data.")
                return self._finishEarly()
        except Exception as e:
            sickrage.srCore.srLogger.error(
                "{}: Error while loading information from indexer {}. Error: {}"
                .format(self.indexer_id, index_name, e.message))

            sickrage.srCore.srNotifications.error(
                "Unable to add show",
                "Unable to look up the show in {} on {} using ID {}, not using the NFO. Delete .nfo and try adding manually again."
                .format(self.showDir, index_name, self.indexer_id))

            if sickrage.srCore.srConfig.USE_TRAKT:

                trakt_id = srIndexerApi(self.indexer).config['trakt_id']
                trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY,
                                     sickrage.srCore.srConfig.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')

            return self._finishEarly()

        try:
            self.show = TVShow(self.indexer, self.indexer_id, self.lang)

            self.show.loadFromIndexer()

            # set up initial values
            self.show.location = self.showDir
            self.show.subtitles = self.subtitles or sickrage.srCore.srConfig.SUBTITLES_DEFAULT
            self.show.quality = self.quality or sickrage.srCore.srConfig.QUALITY_DEFAULT
            self.show.flatten_folders = self.flatten_folders or sickrage.srCore.srConfig.FLATTEN_FOLDERS_DEFAULT
            self.show.anime = self.anime or sickrage.srCore.srConfig.ANIME_DEFAULT
            self.show.scene = self.scene or sickrage.srCore.srConfig.SCENE_DEFAULT
            self.show.archive_firstmatch = self.archive or sickrage.srCore.srConfig.ARCHIVE_DEFAULT
            self.show.paused = self.paused or False

            # set up default new/missing episode status
            sickrage.srCore.srLogger.info(
                "Setting all current episodes to the specified default status: "
                + str(self.default_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 smartish 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 indexer_exception as e:
            sickrage.srCore.srLogger.error(
                "Unable to add show due to an error with " +
                srIndexerApi(self.indexer).name + ": {}".format(e.message))
            if self.show:
                sickrage.srCore.srNotifications.error(
                    "Unable to add " + str(self.show.name) +
                    " due to an error with " +
                    srIndexerApi(self.indexer).name + "")
            else:
                sickrage.srCore.srNotifications.error(
                    "Unable to add show due to an error with " +
                    srIndexerApi(self.indexer).name + "")
            return self._finishEarly()

        except MultipleShowObjectsException:
            sickrage.srCore.srLogger.warning(
                "The show in " + self.showDir +
                " is already in your show list, skipping")
            sickrage.srCore.srNotifications.error(
                'Show skipped', "The show in " + self.showDir +
                " is already in your show list")
            return self._finishEarly()

        except Exception as e:
            sickrage.srCore.srLogger.error(
                "Error trying to add show: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())
            raise self._finishEarly()

        try:
            sickrage.srCore.srLogger.debug(
                "Attempting to retrieve show info from IMDb")
            self.show.loadIMDbInfo()
        except Exception as e:
            sickrage.srCore.srLogger.error(
                "Error loading IMDb info: {}".format(e.message))

        # Load XEM data to DB for show
        xem_refresh(self.show.indexerid, self.show.indexer, force=True)

        # check if show has XEM mapping so we can determin if searches should go by scene numbering or indexer numbering.
        if not self.scene and get_xem_numbering_for_show(
                self.show.indexerid, self.show.indexer):
            self.show.scene = 1

        try:
            self.show.saveToDB()
        except Exception as e:
            sickrage.srCore.srLogger.error(
                "Error saving the show to the database: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())
            raise self._finishEarly()

        # add it to the show list
        sickrage.srCore.SHOWLIST.append(self.show)

        try:
            self.show.loadEpisodesFromIndexer()
        except Exception as e:
            sickrage.srCore.srLogger.error(
                "Error with " + srIndexerApi(self.show.indexer).name +
                ", not creating episode list: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())

        try:
            self.show.loadEpisodesFromDir()
        except Exception as e:
            sickrage.srCore.srLogger.debug(
                "Error searching dir for episodes: {}".format(e.message))
            sickrage.srCore.srLogger.debug(traceback.format_exc())

        # if they set default ep status to WANTED then run the backlog to search for episodes
        if self.show.default_ep_status == WANTED:
            sickrage.srCore.srLogger.info(
                "Launching backlog for this show since its episodes are WANTED"
            )
            sickrage.srCore.BACKLOGSEARCHER.searchBacklog([self.show])

        self.show.writeMetadata()
        self.show.updateMetadata()
        self.show.populateCache()

        if sickrage.srCore.srConfig.USE_TRAKT:
            # if there are specific episodes that need to be added by trakt
            sickrage.srCore.TRAKTSEARCHER.manageNewShow(self.show)

            # add show to trakt.tv library
            if sickrage.srCore.srConfig.TRAKT_SYNC:
                sickrage.srCore.TRAKTSEARCHER.addShowToTraktLibrary(self.show)

            if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
                sickrage.srCore.srLogger.info("update watchlist")
                sickrage.srCore.notifiersDict.trakt_notifier.update_watchlist(
                    show_obj=self.show)

        # After initial add, set to default_status_after.
        sickrage.srCore.srLogger.info(
            "Setting all future episodes to the specified default status: " +
            str(self.default_status_after))
        self.show.default_ep_status = self.default_status_after

        self.show.saveToDB()

        sickrage.srCore.NAMECACHE.build(self.show)

        self.finish()

        sickrage.srCore.srLogger.info("Finished adding show {}".format(
            self.showDir))
Пример #11
0
    def update_watchlist(self, 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 traktv type
        data_episode: structured object of episodes traktv type
        update: type o action add or remove
        """

        trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY, sickrage.srCore.srConfig.TRAKT_TIMEOUT)

        if sickrage.srCore.srConfig.USE_TRAKT:

            data = {}
            try:
                # URL parameters
                if show_obj is not None:
                    trakt_id = srIndexerApi(show_obj.indexer).config['trakt_id']
                    data = {
                        'shows': [
                            {
                                'title': show_obj.name,
                                'year': show_obj.startyear,
                                'ids': {},
                            }
                        ]
                    }

                    if trakt_id == 'tvdb_id':
                        data['shows'][0]['ids']['tvdb'] = show_obj.indexerid
                    else:
                        data['shows'][0]['ids']['tvrage'] = show_obj.indexerid
                elif data_show is not None:
                    data.update(data_show)
                else:
                    sickrage.srCore.srLogger.warning(
                        "there's a coding problem contact developer. It's needed to be provided at lest one of the two: data_show or show_obj")
                    return False

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

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

                    if e is not None:
                        # traktv 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:
                sickrage.srCore.srLogger.warning("Could not connect to Trakt service: %s" % e)
                return False

        return True
Пример #12
0
class srTraktSearcher(object):
    def __init__(self, *args, **kwargs):
        self.name = "TRAKTSEARCHER"
        self.trakt_api = None
        self.todoBacklog = []
        self.todoWanted = []
        self.ShowWatchlist = {}
        self.EpisodeWatchlist = {}
        self.Collectionlist = {}
        self.amActive = False

    def run(self, force=False):
        if self.amActive:
            return

        self.amActive = True

        # set thread name
        threading.currentThread().setName(self.name)

        # init trakt api
        self.trakt_api = TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY, sickrage.srCore.srConfig.TRAKT_TIMEOUT)

        # add shows from tv watchlist
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
            self.todoWanted = []  # its about to all get re-added
            if len(sickrage.srCore.srConfig.ROOT_DIRS.split('|')) < 2:
                sickrage.srCore.srLogger.warning("No default root directory")
                return

            try:
                self.syncWatchlist()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

            try:
                # sync tv library with sickrage library
                self.syncLibrary()
            except Exception:
                sickrage.srCore.srLogger.debug(traceback.format_exc())

        self.amActive = False

    def findShow(self, indexer, indexerid):
        traktShow = None

        try:
            library = self.trakt_api.traktRequest("sync/collection/shows") or []

            if not library:
                sickrage.srCore.srLogger.warning("Could not connect to trakt service, aborting library check")
                return

            if not len(library):
                sickrage.srCore.srLogger.debug("No shows found in your library, aborting library update")
                return

            traktShow = [x for x in library if
                         int(indexerid) in [int(x['show']['ids']['tvdb'] or 0),
                                            int(x['show']['ids']['tvrage'] or 0)]]
        except traktException as e:
            sickrage.srCore.srLogger.warning("Could not connect to Trakt service. Aborting library check. Error: %s" % repr(e))

        return traktShow

    def removeShowFromTraktLibrary(self, show_obj):
        if self.findShow(show_obj.indexer, show_obj.indexerid):
            trakt_id = srIndexerApi(show_obj.indexer).config['trakt_id']

            # URL parameters
            data = {
                'shows': [
                    {
                        'title': show_obj.name,
                        'year': show_obj.startyear,
                        'ids': {}
                    }
                ]
            }

            if trakt_id == 'tvdb_id':
                data['shows'][0]['ids']['tvdb'] = show_obj.indexerid
            else:
                data['shows'][0]['ids']['tvrage'] = show_obj.indexerid

            sickrage.srCore.srLogger.debug("Removing %s from tv library" % show_obj.name)

            try:
                self.trakt_api.traktRequest("sync/collection/remove", data, method='POST')
            except traktException as e:
                sickrage.srCore.srLogger.warning(
                        "Could not connect to Trakt service. Aborting removing show %s from Trakt library. Error: %s" % (
                            show_obj.name, repr(e)))

    def addShowToTraktLibrary(self, show_obj):
        """
        Sends a request to trakt indicating that the given show and all its episodes is part of our library.

        show_obj: The TVShow object to add to trakt
        """
        data = {}

        if not self.findShow(show_obj.indexer, show_obj.indexerid):
            trakt_id = srIndexerApi(show_obj.indexer).config['trakt_id']
            # URL parameters
            data = {
                'shows': [
                    {
                        'title': show_obj.name,
                        'year': show_obj.startyear,
                        'ids': {}
                    }
                ]
            }

            if trakt_id == 'tvdb_id':
                data['shows'][0]['ids']['tvdb'] = show_obj.indexerid
            else:
                data['shows'][0]['ids']['tvrage'] = show_obj.indexerid

        if len(data):
            sickrage.srCore.srLogger.debug("Adding %s to tv library" % show_obj.name)

            try:
                self.trakt_api.traktRequest("sync/collection", data, method='POST')
            except traktException as e:
                sickrage.srCore.srLogger.warning(
                        "Could not connect to Trakt service. Aborting adding show %s to Trakt library. Error: %s" % (
                            show_obj.name, repr(e)))
                return

    def syncLibrary(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug("Sync SiCKRAGE with Trakt Collection")

            if self._getShowCollection():
                self.addEpisodeToTraktCollection()
                if sickrage.srCore.srConfig.TRAKT_SYNC_REMOVE:
                    self.removeEpisodeFromTraktCollection()

    def removeEpisodeFromTraktCollection(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_REMOVE and sickrage.srCore.srConfig.TRAKT_SYNC and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug("COLLECTION::REMOVE::START - Look for Episodes to Remove From Trakt Collection")

            sql_selection = 'SELECT tv_shows.indexer, tv_shows.startyear, showid, show_name, season, episode, tv_episodes.status, tv_episodes.location FROM tv_episodes,tv_shows WHERE tv_shows.indexer_id = tv_episodes.showid'
            episodes = main_db.MainDB().select(sql_selection)

            if episodes is not None:
                trakt_data = []

                for cur_episode in episodes:
                    trakt_id = srIndexerApi(cur_episode["indexer"]).config['trakt_id']

                    if self._checkInList(trakt_id, str(cur_episode["showid"]), str(cur_episode["season"]),
                                         str(cur_episode["episode"]), List='Collection'):
                        if cur_episode["location"] == '':
                            sickrage.srCore.srLogger.debug("Removing Episode %s S%02dE%02d from collection" %
                                                         (cur_episode["show_name"], cur_episode["season"], cur_episode["episode"]))
                            trakt_data.append(
                                    (cur_episode["showid"], cur_episode["indexer"], cur_episode["show_name"],
                                     cur_episode["startyear"], cur_episode["season"], cur_episode["episode"]))

                if len(trakt_data):
                    try:
                        data = self.trakt_bulk_data_generate(trakt_data)
                        self.trakt_api.traktRequest("sync/collection/remove", data, method='POST')
                        self._getShowCollection()
                    except traktException as e:
                        sickrage.srCore.srLogger.warning("Could not connect to Trakt service. Error: %s" % e)

            sickrage.srCore.srLogger.debug("COLLECTION::REMOVE::FINISH - Look for Episodes to Remove From Trakt Collection")

    def addEpisodeToTraktCollection(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug("COLLECTION::ADD::START - Look for Episodes to Add to Trakt Collection")

            sql_selection = 'SELECT tv_shows.indexer, tv_shows.startyear, showid, show_name, season, episode FROM tv_episodes,tv_shows WHERE tv_shows.indexer_id = tv_episodes.showid AND tv_episodes.status IN (' + ','.join(
                    [str(x) for x in Quality.DOWNLOADED + [ARCHIVED]]) + ')'
            episodes = main_db.MainDB().select(sql_selection)

            if episodes is not None:
                trakt_data = []

                for cur_episode in episodes:
                    trakt_id = srIndexerApi(cur_episode["indexer"]).config['trakt_id']

                    if not self._checkInList(trakt_id, str(cur_episode["showid"]), str(cur_episode["season"]),
                                             str(cur_episode["episode"]), List='Collection'):
                        sickrage.srCore.srLogger.debug("Adding Episode %s S%02dE%02d to collection" %
                                                     (cur_episode["show_name"], cur_episode["season"], cur_episode["episode"]))
                        trakt_data.append((cur_episode["showid"], cur_episode["indexer"], cur_episode["show_name"],
                                           cur_episode["startyear"], cur_episode["season"], cur_episode["episode"]))

                if len(trakt_data):
                    try:
                        data = self.trakt_bulk_data_generate(trakt_data)
                        self.trakt_api.traktRequest("sync/collection", data, method='POST')
                        self._getShowCollection()
                    except traktException as e:
                        sickrage.srCore.srLogger.warning("Could not connect to Trakt service. Error: %s" % e)

            sickrage.srCore.srLogger.debug("COLLECTION::ADD::FINISH - Look for Episodes to Add to Trakt Collection")

    def syncWatchlist(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug("Sync SiCKRAGE with Trakt Watchlist")

            self.removeShowFromSickRage()

            if self._getShowWatchlist():
                self.addShowToTraktWatchList()
                self.updateShows()

            if self._getEpisodeWatchlist():
                self.removeEpisodeFromTraktWatchList()
                self.addEpisodeToTraktWatchList()
                self.updateEpisodes()

    def removeEpisodeFromTraktWatchList(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug("WATCHLIST::REMOVE::START - Look for Episodes to Remove from Trakt Watchlist")

            sql_selection = 'SELECT tv_shows.indexer, tv_shows.startyear, showid, show_name, season, episode, tv_episodes.status FROM tv_episodes,tv_shows WHERE tv_shows.indexer_id = tv_episodes.showid'
            episodes = main_db.MainDB().select(sql_selection)

            if episodes is not None:
                trakt_data = []

                for cur_episode in episodes:
                    trakt_id = srIndexerApi(cur_episode["indexer"]).config['trakt_id']

                    if self._checkInList(trakt_id, str(cur_episode["showid"]), str(cur_episode["season"]),
                                         str(cur_episode["episode"])) and cur_episode[
                        "status"] not in Quality.SNATCHED + Quality.SNATCHED_PROPER + [UNKNOWN] + [WANTED]:
                        sickrage.srCore.srLogger.debug("Removing Episode %s S%02dE%02d from watchlist" %
                                                     (cur_episode["show_name"], cur_episode["season"], cur_episode["episode"]))
                        trakt_data.append((cur_episode["showid"], cur_episode["indexer"], cur_episode["show_name"],
                                           cur_episode["startyear"], cur_episode["season"], cur_episode["episode"]))

                if len(trakt_data):
                    try:
                        data = self.trakt_bulk_data_generate(trakt_data)
                        self.trakt_api.traktRequest("sync/watchlist/remove", data, method='POST')
                        self._getEpisodeWatchlist()
                    except traktException as e:
                        sickrage.srCore.srLogger.warning("Could not connect to Trakt service. Error: %s" % e)

                sickrage.srCore.srLogger.debug("WATCHLIST::REMOVE::FINISH - Look for Episodes to Remove from Trakt Watchlist")

    def addEpisodeToTraktWatchList(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug("WATCHLIST::ADD::START - Look for Episodes to Add to Trakt Watchlist")

            sql_selection = 'SELECT tv_shows.indexer, tv_shows.startyear, showid, show_name, season, episode FROM tv_episodes,tv_shows WHERE tv_shows.indexer_id = tv_episodes.showid AND tv_episodes.status IN (' + ','.join(
                    [str(x) for x in Quality.SNATCHED + Quality.SNATCHED_PROPER + [WANTED]]) + ')'
            episodes = main_db.MainDB().select(sql_selection)

            if episodes is not None:
                trakt_data = []

                for cur_episode in episodes:
                    trakt_id = srIndexerApi(cur_episode["indexer"]).config['trakt_id']

                    if not self._checkInList(trakt_id, str(cur_episode["showid"]), str(cur_episode["season"]),
                                             str(cur_episode["episode"])):
                        sickrage.srCore.srLogger.debug("Adding Episode %s S%02dE%02d to watchlist" %
                                                     (cur_episode["show_name"], cur_episode["season"], cur_episode["episode"]))
                        trakt_data.append((cur_episode["showid"], cur_episode["indexer"], cur_episode["show_name"],
                                           cur_episode["startyear"], cur_episode["season"],
                                           cur_episode["episode"]))

                if len(trakt_data):
                    try:
                        data = self.trakt_bulk_data_generate(trakt_data)
                        self.trakt_api.traktRequest("sync/watchlist", data, method='POST')
                        self._getEpisodeWatchlist()
                    except traktException as e:
                        sickrage.srCore.srLogger.warning("Could not connect to Trakt service. Error %s" % e)

            sickrage.srCore.srLogger.debug("WATCHLIST::ADD::FINISH - Look for Episodes to Add to Trakt Watchlist")

    def addShowToTraktWatchList(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT:
            sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::ADD::START - Look for Shows to Add to Trakt Watchlist")

            if sickrage.srCore.SHOWLIST is not None:
                trakt_data = []

                for show in sickrage.srCore.SHOWLIST:
                    trakt_id = srIndexerApi(show.indexer).config['trakt_id']

                    if not self._checkInList(trakt_id, str(show.indexerid), '0', '0', List='Show'):
                        sickrage.srCore.srLogger.debug(
                                "Adding Show: Indexer %s %s - %s to Watchlist" % (
                                    trakt_id, str(show.indexerid), show.name))
                        show_el = {'title': show.name, 'year': show.startyear, 'ids': {}}
                        if trakt_id == 'tvdb_id':
                            show_el['ids']['tvdb'] = show.indexerid
                        else:
                            show_el['ids']['tvrage'] = show.indexerid
                        trakt_data.append(show_el)

                if len(trakt_data):
                    try:
                        data = {'shows': trakt_data}
                        self.trakt_api.traktRequest("sync/watchlist", data, method='POST')
                        self._getShowWatchlist()
                    except traktException as e:
                        sickrage.srCore.srLogger.warning("Could not connect to Trakt service. Error: %s" % e)

            sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::ADD::FINISH - Look for Shows to Add to Trakt Watchlist")

    def removeShowFromSickRage(self):
        if sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST and sickrage.srCore.srConfig.USE_TRAKT and sickrage.srCore.srConfig.TRAKT_REMOVE_SHOW_FROM_SICKRAGE:
            sickrage.srCore.srLogger.debug("SHOW_SICKRAGE::REMOVE::START - Look for Shows to remove from SiCKRAGE")

            if sickrage.srCore.SHOWLIST:
                for show in sickrage.srCore.SHOWLIST:
                    if show.status == "Ended":
                        try:
                            progress = self.trakt_api.traktRequest("shows/" + show.imdbid + "/progress/watched") or {}
                        except traktException as e:
                            sickrage.srCore.srLogger.warning(
                                    "Could not connect to Trakt service. Aborting removing show %s from SiCKRAGE. Error: %s" % (
                                        show.name, repr(e)))
                            return

                        if 'aired' in progress and 'completed' in progress and progress['aired'] == progress[
                            'completed']:
                            sickrage.srCore.SHOWQUEUE.removeShow(show, full=True)
                            sickrage.srCore.srLogger.debug("Show: %s has been removed from SiCKRAGE" % show.name)

            sickrage.srCore.srLogger.debug("SHOW_SICKRAGE::REMOVE::FINISH - Trakt Show Watchlist")

    def updateShows(self):
        sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::START - Trakt Show Watchlist")

        if not len(self.ShowWatchlist):
            sickrage.srCore.srLogger.debug("No shows found in your watchlist, aborting watchlist update")
            return

        indexer = int(sickrage.srCore.srConfig.TRAKT_DEFAULT_INDEXER)
        trakt_id = srIndexerApi(indexer).config['trakt_id']

        for show_el in self.ShowWatchlist[trakt_id]:
            indexer_id = int(str(show_el))
            show = self.ShowWatchlist[trakt_id][show_el]

            # LOGGER.debug(u"Checking Show: %s %s %s" % (trakt_id, indexer_id, show['title']))
            if int(sickrage.srCore.srConfig.TRAKT_METHOD_ADD) != 2:
                self.addDefaultShow(indexer, indexer_id, show['title'], SKIPPED)
            else:
                self.addDefaultShow(indexer, indexer_id, show['title'], WANTED)

            if int(sickrage.srCore.srConfig.TRAKT_METHOD_ADD) == 1:
                newShow = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id)

                if newShow is not None:
                    setEpisodeToWanted(newShow, 1, 1)
                else:
                    self.todoWanted.append((indexer_id, 1, 1))
        sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::FINISH - Trakt Show Watchlist")

    def updateEpisodes(self):
        """
        Sets episodes to wanted that are in trakt watchlist
        """
        sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::START - Trakt Episode Watchlist")

        if not len(self.EpisodeWatchlist):
            sickrage.srCore.srLogger.debug("No episode found in your watchlist, aborting episode update")
            return

        managed_show = []

        indexer = int(sickrage.srCore.srConfig.TRAKT_DEFAULT_INDEXER)
        trakt_id = srIndexerApi(indexer).config['trakt_id']

        for show_el in self.EpisodeWatchlist[trakt_id]:
            indexer_id = int(show_el)
            show = self.EpisodeWatchlist[trakt_id][show_el]

            newShow = findCertainShow(sickrage.srCore.SHOWLIST, indexer_id)

            try:
                if newShow is None:
                    if indexer_id not in managed_show:
                        self.addDefaultShow(indexer, indexer_id, show['title'], SKIPPED)
                        managed_show.append(indexer_id)

                        for season_el in show['seasons']:
                            season = int(season_el)

                            for episode_el in show['seasons'][season_el]['episodes']:
                                self.todoWanted.append((indexer_id, season, int(episode_el)))
                else:
                    if newShow.indexer == indexer:
                        for season_el in show['seasons']:
                            season = int(season_el)

                            for episode_el in show['seasons'][season_el]['episodes']:
                                setEpisodeToWanted(newShow, season, int(episode_el))
            except TypeError:
                sickrage.srCore.srLogger.debug("Could not parse the output from trakt for %s " % show["title"])
        sickrage.srCore.srLogger.debug("SHOW_WATCHLIST::CHECK::FINISH - Trakt Episode Watchlist")

    @staticmethod
    def addDefaultShow(indexer, indexer_id, name, status):
        """
        Adds a new show with the default settings
        """
        if not findCertainShow(sickrage.srCore.SHOWLIST, int(indexer_id)):
            sickrage.srCore.srLogger.info("Adding show " + str(indexer_id))
            root_dirs = sickrage.srCore.srConfig.ROOT_DIRS.split('|')

            try:
                location = root_dirs[int(root_dirs[0]) + 1]
            except Exception:
                location = None

            if location:
                showPath = os.path.join(location, sanitizeFileName(name))
                dir_exists = makeDir(showPath)

                if not dir_exists:
                    sickrage.srCore.srLogger.warning("Unable to create the folder %s , can't add the show" % showPath)
                    return
                else:
                    chmodAsParent(showPath)

                sickrage.srCore.SHOWQUEUE.addShow(int(indexer), int(indexer_id), showPath,
                                                  default_status=status,
                                                  quality=int(sickrage.srCore.srConfig.QUALITY_DEFAULT),
                                                  flatten_folders=int(sickrage.srCore.srConfig.FLATTEN_FOLDERS_DEFAULT),
                                                  paused=sickrage.srCore.srConfig.TRAKT_START_PAUSED,
                                                  default_status_after=status,
                                                  archive=sickrage.srCore.srConfig.ARCHIVE_DEFAULT)
            else:
                sickrage.srCore.srLogger.warning("There was an error creating the show, no root directory setting found")
                return

    def manageNewShow(self, show):
        sickrage.srCore.srLogger.debug("Checking if trakt watch list wants to search for episodes from new show " + show.name)
        episodes = [i for i in self.todoWanted if i[0] == show.indexerid]

        for episode in episodes:
            self.todoWanted.remove(episode)
            setEpisodeToWanted(show, episode[1], episode[2])

    def _checkInList(self, trakt_id, showid, season, episode, List=None):
        """
         Check in the Watchlist or CollectionList for Show
         Is the Show, Season and Episode in the trakt_id list (tvdb / tvrage)
        """
        # LOGGER.debug(u"Checking Show: %s %s %s " % (trakt_id, showid, List))

        if "Collection" == List:
            try:
                if self.Collectionlist[trakt_id][showid]['seasons'][season]['episodes'][episode] == episode:
                    return True
            except Exception:
                return False
        elif "Show" == List:
            try:
                if self.ShowWatchlist[trakt_id][showid]['id'] == showid:
                    return True
            except Exception:
                return False
        else:
            try:
                if self.EpisodeWatchlist[trakt_id][showid]['seasons'][season]['episodes'][episode] == episode:
                    return True
            except Exception:
                return False

    def _getShowWatchlist(self):
        """
        Get Watchlist and parse once into addressable structure
        """
        try:
            self.ShowWatchlist = {'tvdb_id': {}, 'tvrage_id': {}}
            TraktShowWatchlist = self.trakt_api.traktRequest("sync/watchlist/shows")
            tvdb_id = 'tvdb'
            tvrage_id = 'tvrage'

            for watchlist_el in TraktShowWatchlist:
                tvdb = False
                tvrage = False

                if not watchlist_el['show']['ids']["tvdb"] is None:
                    tvdb = True

                if not watchlist_el['show']['ids']["tvrage"] is None:
                    tvrage = True

                title = watchlist_el['show']['title']
                year = str(watchlist_el['show']['year'])

                if tvdb:
                    showid = str(watchlist_el['show']['ids'][tvdb_id])
                    self.ShowWatchlist[tvdb_id + '_id'][showid] = {'id': showid, 'title': title, 'year': year}

                if tvrage:
                    showid = str(watchlist_el['show']['ids'][tvrage_id])
                    self.ShowWatchlist[tvrage_id + '_id'][showid] = {'id': showid, 'title': title, 'year': year}
        except traktException as e:
            sickrage.srCore.srLogger.warning("Could not connect to trakt service, cannot download Show Watchlist: %s" % repr(e))
            return False
        return True

    def _getEpisodeWatchlist(self):
        """
         Get Watchlist and parse once into addressable structure
        """
        try:
            self.EpisodeWatchlist = {'tvdb_id': {}, 'tvrage_id': {}}
            TraktEpisodeWatchlist = self.trakt_api.traktRequest("sync/watchlist/episodes")
            tvdb_id = 'tvdb'
            tvrage_id = 'tvrage'

            for watchlist_el in TraktEpisodeWatchlist:
                tvdb = False
                tvrage = False

                if not watchlist_el['show']['ids']["tvdb"] is None:
                    tvdb = True

                if not watchlist_el['show']['ids']["tvrage"] is None:
                    tvrage = True

                title = watchlist_el['show']['title']
                year = str(watchlist_el['show']['year'])
                season = str(watchlist_el['episode']['season'])
                episode = str(watchlist_el['episode']['number'])

                if tvdb:
                    showid = str(watchlist_el['show']['ids'][tvdb_id])

                    if showid not in self.EpisodeWatchlist[tvdb_id + '_id'].keys():
                        self.EpisodeWatchlist[tvdb_id + '_id'][showid] = {'id': showid, 'title': title, 'year': year,
                                                                          'seasons': {}}

                    if season not in self.EpisodeWatchlist[tvdb_id + '_id'][showid]['seasons'].keys():
                        self.EpisodeWatchlist[tvdb_id + '_id'][showid]['seasons'][season] = {'s': season,
                                                                                              'episodes': {}}

                    if episode not in self.EpisodeWatchlist[tvdb_id + '_id'][showid]['seasons'][season][
                        'episodes'].keys():
                        self.EpisodeWatchlist[tvdb_id + '_id'][showid]['seasons'][season]['episodes'][
                            episode] = episode

                if tvrage:
                    showid = str(watchlist_el['show']['ids'][tvrage_id])

                    if showid not in self.EpisodeWatchlist[tvrage_id + '_id'].keys():
                        self.EpisodeWatchlist[tvrage_id + '_id'][showid] = {'id': showid, 'title': title, 'year': year,
                                                                            'seasons': {}}

                    if season not in self.EpisodeWatchlist[tvrage_id + '_id'][showid]['seasons'].keys():
                        self.EpisodeWatchlist[tvrage_id + '_id'][showid]['seasons'][season] = {'s': season,
                                                                                                'episodes': {}}

                    if episode not in self.EpisodeWatchlist[tvrage_id + '_id'][showid]['seasons'][season][
                        'episodes'].keys():
                        self.EpisodeWatchlist[tvrage_id + '_id'][showid]['seasons'][season]['episodes'][
                            episode] = episode
        except traktException as e:
            sickrage.srCore.srLogger.warning("Could not connect to trakt service, cannot download Episode Watchlist: %s" % repr(e))
            return False
        return True

    def _getShowCollection(self):
        """
        Get Collection and parse once into addressable structure
        """
        try:
            self.Collectionlist = {'tvdb_id': {}, 'tvrage_id': {}}
            sickrage.srCore.srLogger.debug("Getting Show Collection")
            TraktCollectionList = self.trakt_api.traktRequest("sync/collection/shows")
            tvdb_id = 'tvdb'
            tvrage_id = 'tvrage'

            for watchlist_el in TraktCollectionList:
                tvdb = False
                tvrage = False

                if not watchlist_el['show']['ids']["tvdb"] is None:
                    tvdb = True

                if not watchlist_el['show']['ids']["tvrage"] is None:
                    tvrage = True

                title = watchlist_el['show']['title']
                year = str(watchlist_el['show']['year'])

                if 'seasons' in watchlist_el:
                    for season_el in watchlist_el['seasons']:
                        for episode_el in season_el['episodes']:
                            season = str(season_el['number'])
                            episode = str(episode_el['number'])

                            if tvdb:
                                showid = str(watchlist_el['show']['ids'][tvdb_id])

                                if showid not in self.Collectionlist[tvdb_id + '_id'].keys():
                                    self.Collectionlist[tvdb_id + '_id'][showid] = {'id': showid, 'title': title,
                                                                                    'year': year, 'seasons': {}}

                                if season not in self.Collectionlist[tvdb_id + '_id'][showid]['seasons'].keys():
                                    self.Collectionlist[tvdb_id + '_id'][showid]['seasons'][season] = {'s': season,
                                                                                                        'episodes': {}}

                                if episode not in self.Collectionlist[tvdb_id + '_id'][showid]['seasons'][season][
                                    'episodes'].keys():
                                    self.Collectionlist[tvdb_id + '_id'][showid]['seasons'][season]['episodes'][
                                        episode] = episode

                            if tvrage:
                                showid = str(watchlist_el['show']['ids'][tvrage_id])

                                if showid not in self.Collectionlist[tvrage_id + '_id'].keys():
                                    self.Collectionlist[tvrage_id + '_id'][showid] = {'id': showid, 'title': title,
                                                                                      'year': year, 'seasons': {}}

                                if season not in self.Collectionlist[tvrage_id + '_id'][showid]['seasons'].keys():
                                    self.Collectionlist[tvrage_id + '_id'][showid]['seasons'][season] = {'s': season,
                                                                                                          'episodes': {}}

                                if episode not in self.Collectionlist[tvrage_id + '_id'][showid]['seasons'][season][
                                    'episodes'].keys():
                                    self.Collectionlist[tvrage_id + '_id'][showid]['seasons'][season]['episodes'][
                                        episode] = episode
        except traktException as e:
            sickrage.srCore.srLogger.warning("Could not connect to trakt service, cannot download Show Collection: %s" % repr(e))
            return False
        return True

    @staticmethod
    def trakt_bulk_data_generate(data):
        """
        Build the JSON structure to send back to Trakt
        """
        uniqueShows = {}
        uniqueSeasons = {}

        for showid, indexerid, show_name, startyear, season, episode in data:
            if showid not in uniqueShows:
                uniqueShows[showid] = {'title': show_name, 'year': startyear, 'ids': {}, 'seasons': []}
                trakt_id = srIndexerApi(indexerid).config['trakt_id']

                if trakt_id == 'tvdb_id':
                    uniqueShows[showid]['ids']["tvdb"] = showid
                else:
                    uniqueShows[showid]['ids']["tvrage"] = showid
                uniqueSeasons[showid] = []

        # Get the unique seasons per Show
        for showid, indexerid, show_name, startyear, season, episode in data:
            if season not in uniqueSeasons[showid]:
                uniqueSeasons[showid].append(season)

        # build the query
        traktShowList = []
        seasonsList = {}

        for searchedShow in uniqueShows:
            seasonsList[searchedShow] = []

            for searchedSeason in uniqueSeasons[searchedShow]:
                episodesList = []

                for showid, indexerid, show_name, startyear, season, episode in data:
                    if season == searchedSeason and showid == searchedShow:
                        episodesList.append({'number': episode})
                show = uniqueShows[searchedShow]
                show['seasons'].append({'number': searchedSeason, 'episodes': episodesList})
                traktShowList.append(show)

        return {'shows': traktShowList}
Пример #13
0
 def trakt_api(self):
     return TraktAPI(sickrage.srCore.srConfig.SSL_VERIFY,
                     sickrage.srCore.srConfig.TRAKT_TIMEOUT)