Example #1
0
def _anidb_exceptions_fetcher():
    if should_refresh('anidb'):
        sickrage.app.log.info("Checking for AniDB scene exception updates")
        for show in get_show_list():
            if show.is_anime and show.indexer == 1:
                try:
                    anime = Anime(None,
                                  name=show.name,
                                  tvdbid=show.indexer_id,
                                  autoCorrectName=True)
                except Exception:
                    continue
                else:
                    if anime.name and anime.name != show.name:
                        anidb_exception_dict[show.indexer_id] = [{
                            anime.name: -1
                        }]

        set_last_refresh('anidb')

    for anidb_ex in anidb_exception_dict:
        if anidb_ex in exception_dict:
            exception_dict[anidb_ex] = exception_dict[
                anidb_ex] + anidb_exception_dict[anidb_ex]
        else:
            exception_dict[anidb_ex] = anidb_exception_dict[anidb_ex]

    return anidb_exception_dict
Example #2
0
    def remove_episodes_from_trakt_collection(self):
        trakt_data = []

        sickrage.app.log.debug(
            "COLLECTION::REMOVE::START - Look for Episodes to Remove From Trakt Collection"
        )

        for s in get_show_list():
            for e in s.episodes:
                if e.location:
                    continue

                trakt_id = IndexerApi(s.indexer).trakt_id
                if self._check_in_list(trakt_id, str(e.showid), e.season,
                                       e.episode, 'Collection'):
                    sickrage.app.log.debug(
                        "Removing Episode %s S%02dE%02d from collection" %
                        (s.name, e.season, e.episode))
                    trakt_data.append((e.showid, s.indexer, s.name,
                                       s.startyear, e.season, e.episode))

        if len(trakt_data):
            try:
                TraktAPI()["sync/collection"].remove(
                    self.trakt_bulk_data_generate(trakt_data))
                self._get_show_collection()
            except Exception as e:
                sickrage.app.log.warning(
                    "Could not connect to Trakt service. Error: %s" % e)

        sickrage.app.log.debug(
            "COLLECTION::REMOVE::FINISH - Look for Episodes to Remove From Trakt Collection"
        )
Example #3
0
    async def get(self, *args, **kwargs):
        def titler(x):
            return (remove_article(x), x)[not x or sickrage.app.config.sort_article]

        episodes = {}
        for result in self.db_session.query(TVEpisode).order_by(TVEpisode.season, TVEpisode.episode):
            if result.showid not in episodes:
                episodes[result.showid] = {}

            if result.season not in episodes[result.showid]:
                episodes[result.showid][result.season] = []

            episodes[result.showid][result.season].append(result.episode)

        if len(sickrage.app.config.api_key) == 32:
            apikey = sickrage.app.config.api_key
        else:
            apikey = _('API Key not generated')

        api_commands = {}
        for command, api_call in ApiHandler(self.application, self.request).api_calls.items():
            api_commands[command] = await api_call(self.application, self.request, **{'help': 1}).run()

        return self.render(
            'api_builder.mako',
            title=_('API Builder'),
            header=_('API Builder'),
            shows=sorted(get_show_list(), key=cmp_to_key(lambda x, y: titler(x.name) < titler(y.name))),
            episodes=episodes,
            apikey=apikey,
            api_commands=api_commands,
            controller='root',
            action='api_builder'
        )
Example #4
0
    def add_episodes_to_trakt_collection(self):
        trakt_data = []

        sickrage.app.log.debug(
            "COLLECTION::SYNC::START - Look for Episodes to Add to Trakt Collection"
        )

        for s in get_show_list():
            for e in s.episodes:
                trakt_id = IndexerApi(s.indexer).trakt_id
                if not self._check_in_list(trakt_id, str(e.showid), e.season,
                                           e.episode, 'Collection'):
                    sickrage.app.log.debug(
                        "Adding Episode %s S%02dE%02d to collection" %
                        (s.name, e.season, e.episode))
                    trakt_data.append((e.showid, s.indexer, s.name,
                                       s.startyear, e.season, e.episode))

        if len(trakt_data):
            try:
                TraktAPI()["sync/collection"].add(
                    self.trakt_bulk_data_generate(trakt_data))
                self._get_show_collection()
            except Exception as e:
                sickrage.app.log.warning(
                    "Could not connect to Trakt service. Error: %s" % e)

        sickrage.app.log.debug(
            "COLLECTION::ADD::FINISH - Look for Episodes to Add to Trakt Collection"
        )
Example #5
0
    def remove_episodes_from_trakt_watch_list(self):
        trakt_data = []

        sickrage.app.log.debug(
            "WATCHLIST::REMOVE::START - Look for Episodes to Remove from Trakt Watchlist"
        )

        for s in get_show_list():
            for e in s.episodes:
                series_provider_trakt_id = s.series_provider.trakt_id
                if self._check_in_list(series_provider_trakt_id,
                                       str(e.series_id), e.season, e.episode):
                    sickrage.app.log.debug(
                        f"Removing Episode {s.name} S{e.season:02d}E{e.episode:02d} from watchlist"
                    )
                    trakt_data.append(
                        (e.series_id, s.series_provider_id, s.name,
                         s.startyear, e.season, e.episode))

        if len(trakt_data):
            try:
                data = self.trakt_bulk_data_generate(trakt_data)
                TraktAPI()["sync/watchlist"].remove(data)
                self._get_episode_watchlist()
            except Exception as e:
                sickrage.app.log.warning(
                    f"Could not connect to Trakt service. Error: {e}")

        sickrage.app.log.debug(
            "WATCHLIST::REMOVE::FINISH - Look for Episodes to Remove from Trakt Watchlist"
        )
Example #6
0
    def remove_episodes_from_trakt_watch_list(self):
        trakt_data = []

        sickrage.app.log.debug(
            "WATCHLIST::REMOVE::START - Look for Episodes to Remove from Trakt Watchlist"
        )

        for s in get_show_list():
            for e in s.episodes:
                trakt_id = IndexerApi(s.indexer).trakt_id
                if self._check_in_list(trakt_id, str(e.showid), e.season,
                                       e.episode):
                    sickrage.app.log.debug(
                        "Removing Episode %s S%02dE%02d from watchlist" %
                        (s.name, e.season, e.episode))
                    trakt_data.append((e.showid, s.indexer, s.name,
                                       s.startyear, e.season, e.episode))

        if len(trakt_data):
            try:
                data = self.trakt_bulk_data_generate(trakt_data)
                TraktAPI()["sync/watchlist"].remove(data)
                self._get_episode_watchlist()
            except Exception as e:
                sickrage.app.log.warning(
                    "Could not connect to Trakt service. Error: %s" % e)

        sickrage.app.log.debug(
            "WATCHLIST::REMOVE::FINISH - Look for Episodes to Remove from Trakt Watchlist"
        )
Example #7
0
    def add_episodes_to_trakt_collection(self):
        trakt_data = []

        sickrage.app.log.debug(
            "COLLECTION::SYNC::START - Look for Episodes to Add to Trakt Collection"
        )

        for s in get_show_list():
            for e in s.episodes:
                trakt_id = s.series_provider.trakt_id
                if not self._check_in_list(trakt_id, str(e.series_id),
                                           e.season, e.episode, 'Collection'):
                    sickrage.app.log.debug(
                        f"Adding Episode {s.name} S{e.season:02d}E{e.episode:02d} to collection"
                    )
                    trakt_data.append(
                        (e.series_id, s.series_provider_id, s.name,
                         s.startyear, e.season, e.episode))

        if len(trakt_data):
            try:
                TraktAPI()["sync/collection"].add(
                    self.trakt_bulk_data_generate(trakt_data))
                self._get_show_collection()
            except Exception as e:
                sickrage.app.log.warning(
                    f"Could not connect to Trakt service. Error: {e}")

        sickrage.app.log.debug(
            "COLLECTION::ADD::FINISH - Look for Episodes to Add to Trakt Collection"
        )
Example #8
0
    def remove_episodes_from_trakt_collection(self):
        trakt_data = []

        sickrage.app.log.debug(
            "COLLECTION::REMOVE::START - Look for Episodes to Remove From Trakt Collection"
        )

        for s in get_show_list():
            for e in s.episodes:
                if e.location:
                    continue

                series_provider_trakt_id = s.series_provider.trakt_id
                if self._check_in_list(series_provider_trakt_id,
                                       str(e.series_id), e.season, e.episode,
                                       'Collection'):
                    sickrage.app.log.debug(
                        f"Removing Episode {s.name} S{e.season:02d}E{e.episode:02d} from collection"
                    )
                    trakt_data.append(
                        (e.series_id, s.series_provider_id, s.name,
                         s.startyear, e.season, e.episode))

        if len(trakt_data):
            try:
                TraktAPI()["sync/collection"].remove(
                    self.trakt_bulk_data_generate(trakt_data))
                self._get_show_collection()
            except Exception as e:
                sickrage.app.log.warning(
                    f"Could not connect to Trakt service. Error: {e}")

        sickrage.app.log.debug(
            "COLLECTION::REMOVE::FINISH - Look for Episodes to Remove From Trakt Collection"
        )
Example #9
0
    def add_episodes_to_trakt_watch_list(self):
        session = sickrage.app.main_db.session()

        trakt_data = []

        sickrage.app.log.debug(
            "WATCHLIST::ADD::START - Look for Episodes to Add to Trakt Watchlist"
        )

        for s in get_show_list():
            for e in session.query(MainDB.TVEpisode).filter_by(
                    showid=s.indexer_id).filter(~MainDB.TVEpisode.episode.in_(
                        Quality.SNATCHED + Quality.SNATCHED_PROPER +
                        [UNKNOWN] + [WANTED])):
                trakt_id = IndexerApi(s.indexer).trakt_id
                if self._check_in_list(trakt_id, str(e.showid), e.season,
                                       e.episode):
                    sickrage.app.log.debug(
                        "Adding Episode %s S%02dE%02d to watchlist" %
                        (s.name, e.season, e.episode))
                    trakt_data.append((e.showid, s.indexer, s.name,
                                       s.startyear, e.season, e.episode))

        if len(trakt_data):
            try:
                data = self.trakt_bulk_data_generate(trakt_data)
                TraktAPI()["sync/watchlist"].add(data)
                self._get_episode_watchlist()
            except Exception as e:
                sickrage.app.log.warning(
                    "Could not connect to Trakt service. Error %s" % e)

        sickrage.app.log.debug(
            "WATCHLIST::ADD::FINISH - Look for Episodes to Add to Trakt Watchlist"
        )
Example #10
0
    def get(self, limit=100, action=None):
        """
        :param limit: The maximum number of elements to return
        :param action: The type of action to filter in the history. Either 'downloaded' or 'snatched'. Anything else or
                        no value will return everything (up to ``limit``)
        :return: The last ``limit`` elements of type ``action`` in the history
        """

        session = sickrage.app.main_db.session()

        data = []

        action = action.lower() if isinstance(action, str) else ''
        limit = int(limit)

        if action == 'downloaded':
            actions = EpisodeStatus.composites(EpisodeStatus.DOWNLOADED)
        elif action == 'snatched':
            actions = EpisodeStatus.composites(EpisodeStatus.SNATCHED)
        else:
            actions = []

        for show in get_show_list():
            if limit == 0:
                if len(actions) > 0:
                    dbData = session.query(MainDB.History).filter_by(
                        series_id=show.series_id).filter(
                            MainDB.History.action.in_(actions)).order_by(
                                MainDB.History.date.desc())
                else:
                    dbData = session.query(MainDB.History).filter_by(
                        series_id=show.series_id).order_by(
                            MainDB.History.date.desc())
            else:
                if len(actions) > 0:
                    dbData = session.query(MainDB.History).filter_by(
                        series_id=show.series_id).filter(
                            MainDB.History.action.in_(actions)).order_by(
                                MainDB.History.date.desc()).limit(limit)
                else:
                    dbData = session.query(MainDB.History).filter_by(
                        series_id=show.series_id).order_by(
                            MainDB.History.date.desc()).limit(limit)

            for result in dbData:
                data.append({
                    'action': result.action,
                    'date': result.date,
                    'provider': result.provider,
                    'release_group': result.release_group,
                    'quality': result.quality,
                    'resource': result.resource,
                    'season': result.season,
                    'episode': result.episode,
                    'series_id': result.series_id,
                    'series_provider_id': result.series_provider_id,
                    'show_name': show.name
                })

        return data
Example #11
0
    def get(self, *args, **kwargs):
        """
        Display the new show page which collects a tvdb id, folder, and extra options and
        posts them to addNewShow
        """

        show_list = self.get_argument('list', 'trending')
        limit = self.get_argument('limit', None) or 10

        trakt_shows = []

        shows, black_list = getattr(TraktAPI()['shows'], show_list)(
            extended="full", limit=int(limit) + get_show_list().count()), False

        while len(trakt_shows) < int(limit):
            trakt_shows += [
                x for x in shows if 'tvdb' in x.ids
                and not find_show(int(x.ids['tvdb']), session=self.db_session)
            ]

        return self.render(
            "/home/trakt_shows.mako",
            title="Trakt {} Shows".format(show_list.capitalize()),
            header="Trakt {} Shows".format(show_list.capitalize()),
            enable_anime_options=False,
            black_list=black_list,
            trakt_shows=trakt_shows[:int(limit)],
            trakt_list=show_list,
            limit=limit,
            controller='home',
            action="trakt_shows")
Example #12
0
    def calendar(self):
        """ Provides a subscribeable URL for iCal subscriptions
        """

        utc = dateutil.tz.gettz('GMT')

        sickrage.app.log.info("Receiving iCal request from %s" % self.request.remote_ip)

        # Create a iCal string
        ical = 'BEGIN:VCALENDAR\r\n'
        ical += 'VERSION:2.0\r\n'
        ical += 'X-WR-CALNAME:SiCKRAGE\r\n'
        ical += 'X-WR-CALDESC:SiCKRAGE\r\n'
        ical += 'PRODID://SiCKRAGE Upcoming Episodes//\r\n'

        # Limit dates
        past_date = datetime.date.today() + datetime.timedelta(weeks=-52)
        future_date = datetime.date.today() + datetime.timedelta(weeks=52)

        # Get all the shows that are not paused and are currently on air (from kjoconnor Fork)
        for show in get_show_list():
            if show.status.lower() not in ['continuing', 'returning series'] or show.paused:
                continue

            for episode in show.episodes:
                if not past_date <= episode.airdate < future_date:
                    continue

                air_date_time = sickrage.app.tz_updater.parse_date_time(episode.airdate, show.airs,
                                                                        show.network).astimezone(utc)
                air_date_time_end = air_date_time + datetime.timedelta(minutes=try_int(show.runtime, 60))

                # Create event for episode
                ical += 'BEGIN:VEVENT\r\n'
                ical += 'DTSTART:' + air_date_time.strftime("%Y%m%d") + 'T' + air_date_time.strftime("%H%M%S") + 'Z\r\n'
                ical += 'DTEND:' + air_date_time_end.strftime("%Y%m%d") + 'T' + air_date_time_end.strftime(
                    "%H%M%S") + 'Z\r\n'
                if sickrage.app.config.general.calendar_icons:
                    ical += 'X-GOOGLE-CALENDAR-CONTENT-ICON:https://www.sickrage.ca/favicon.ico\r\n'
                    ical += 'X-GOOGLE-CALENDAR-CONTENT-DISPLAY:CHIP\r\n'
                ical += 'SUMMARY: {0} - {1}x{2} - {3}\r\n'.format(show.name, episode.season, episode.episode, episode.name)
                ical += 'UID:SiCKRAGE-' + str(datetime.date.today().isoformat()) + '-' + \
                        show.name.replace(" ", "-") + '-E' + str(episode.episode) + \
                        'S' + str(episode.season) + '\r\n'
                if episode.description:
                    ical += 'DESCRIPTION: {0} on {1} \\n\\n {2}\r\n'.format(
                        (show.airs or '(Unknown airs)'),
                        (show.network or 'Unknown network'),
                        episode.description.splitlines()[0])
                else:
                    ical += 'DESCRIPTION:' + (show.airs or '(Unknown airs)') + ' on ' + (
                            show.network or 'Unknown network') + '\r\n'

                ical += 'END:VEVENT\r\n'

        # Ending the iCal
        ical += 'END:VCALENDAR'

        return ical
Example #13
0
    def handle_get(self):
        def titler(x):
            return (remove_article(x), x)[not x
                                          or sickrage.app.config.sort_article]

        episodes = {}

        for show_object in get_show_list():
            if show_object.indexer_id not in episodes:
                episodes[show_object.indexer_id] = {}

            for episode_object in show_object.episodes:
                if episode_object.season not in episodes[
                        show_object.indexer_id]:
                    episodes[show_object.indexer_id][
                        episode_object.season] = []

                episodes[show_object.indexer_id][episode_object.season].append(
                    episode_object.episode)

        if len(sickrage.app.config.api_key) == 32:
            apikey = sickrage.app.config.api_key
        else:
            apikey = _('API Key not generated')

        api_commands = {}
        for command, api_call in ApiHandler(self.application,
                                            self.request).api_calls.items():
            api_commands[command] = api_call(self.application, self.request,
                                             **{
                                                 'help': 1
                                             }).run()

        return self.render(
            'api_builder.mako',
            title=_('API Builder'),
            header=_('API Builder'),
            shows=sorted(
                get_show_list(),
                key=cmp_to_key(lambda x, y: titler(x.name) < titler(y.name))),
            episodes=base64.b64encode(json.dumps(episodes).encode()).decode(),
            apikey=apikey,
            api_commands=api_commands,
            controller='root',
            action='api_builder')
Example #14
0
    def get(self, series_slug=None):
        """Get list of series or specific series information"
        ---
        tags: [Series]
        summary: Manually search for episodes on search providers
        description: Manually search for episodes on search providers
        parameters:
        - in: path
          schema:
            SeriesPath
        responses:
          200:
            description: Success payload
            content:
              application/json:
                schema:
                  SeriesSuccessSchema
          400:
            description: Bad request; Check `errors` for any validation errors
            content:
              application/json:
                schema:
                  BadRequestSchema
          401:
            description: Returned if your JWT token is missing or expired
            content:
              application/json:
                schema:
                  NotAuthorizedSchema
          404:
            description: Returned if the given series slug does not exist or no series results.
            content:
              application/json:
                schema:
                  NotFoundSchema
        """

        if not series_slug:
            all_series = {}

            for show in get_show_list():
                if sickrage.app.show_queue.is_being_removed(show.series_id):
                    continue

                all_series[show.slug] = show.to_json(progress=True)

            return self.write_json(all_series)

        series = find_show_by_slug(series_slug)
        if series is None:
            return self.send_error(
                404,
                error=
                f"Unable to find the specified series using slug: {series_slug}"
            )

        return self.write_json(series.to_json(episodes=True, details=True))
Example #15
0
    def search_backlog(self, show_id=None, session=None):
        if self.amActive:
            sickrage.app.log.debug(
                "Backlog is still running, not starting it again")
            return

        self.amActive = True
        self.amPaused = False

        show_list = [find_show(show_id, session=session)
                     ] if show_id else get_show_list(session=session)

        cur_date = datetime.date.today()
        from_date = datetime.date.min

        if not show_id and self.forced:
            sickrage.app.log.info(
                "Running limited backlog on missed episodes " +
                str(sickrage.app.config.backlog_days) + " day(s) old")
            from_date = datetime.date.today() - datetime.timedelta(
                days=sickrage.app.config.backlog_days)
        else:
            sickrage.app.log.info(
                'Running full backlog search on missed episodes for selected shows'
            )

        # go through non air-by-date shows and see if they need any episodes
        for curShow in show_list:
            if curShow.paused:
                sickrage.app.log.debug(
                    "Skipping search for {} because the show is paused".format(
                        curShow.name))
                continue

            wanted = self._get_wanted(curShow, from_date)
            if not wanted:
                sickrage.app.log.debug(
                    "Nothing needs to be downloaded for {}, skipping".format(
                        curShow.name))
                continue

            for season, episode in wanted:
                if (curShow.indexer_id, season,
                        episode) in sickrage.app.search_queue.SNATCH_HISTORY:
                    sickrage.app.search_queue.SNATCH_HISTORY.remove(
                        (curShow.indexer_id, season, episode))

                sickrage.app.io_loop.add_callback(
                    sickrage.app.search_queue.put,
                    BacklogQueueItem(curShow.indexer_id, season, episode))

            if from_date == datetime.date.min and not show_id:
                self._set_last_backlog_search(curShow, cur_date)

        self.amActive = False
Example #16
0
    def handle_get(self):
        shows_list = sorted([x for x in get_show_list() if not sickrage.app.show_queue.is_being_removed(x.indexer_id)],
                            key=cmp_to_key(lambda x, y: x.name < y.name))

        return self.render('manage/mass_update.mako',
                           shows_list=shows_list,
                           title=_('Mass Update'),
                           header=_('Mass Update'),
                           topmenu='manage',
                           controller='manage',
                           action='mass_update')
Example #17
0
    def task(self, force=False):
        """
        Runs the daily searcher, queuing selected episodes for search
        :param force: Force search
        """
        if self.running and not force:
            return

        try:
            self.running = True

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

            # find new released episodes and update their statuses
            for curShow in get_show_list():
                if curShow.paused:
                    sickrage.app.log.debug(
                        "Skipping search for {} because the show is paused".
                        format(curShow.name))
                    continue

                for tv_episode in curShow.new_episodes:
                    tv_episode.status = tv_episode.show.default_ep_status if tv_episode.season > 0 else EpisodeStatus.SKIPPED
                    tv_episode.save()
                    sickrage.app.log.info(
                        'Setting status ({status}) for show airing today: {name} {special}'
                        .format(
                            name=tv_episode.pretty_name(),
                            status=tv_episode.status.display_name,
                            special='(specials are not supported)'
                            if not tv_episode.season > 0 else '',
                        ))

                wanted = self._get_wanted(curShow, datetime.date.today())
                if not wanted:
                    sickrage.app.log.debug(
                        "Nothing needs to be downloaded for {}, skipping".
                        format(curShow.name))
                    continue

                for season, episode in wanted:
                    if (curShow.series_id, season, episode
                        ) in sickrage.app.search_queue.SNATCH_HISTORY:
                        sickrage.app.search_queue.SNATCH_HISTORY.remove(
                            (curShow.series_id, season, episode))

                    sickrage.app.search_queue.put(
                        DailySearchTask(curShow.series_id,
                                        curShow.series_provider_id, season,
                                        episode))
        finally:
            self.running = False
Example #18
0
    def selectSeries(self, allSeries, *args, **kwargs):
        try:
            # try to pick a show that's in my show list
            showIDList = [int(x.indexer_id) for x in get_show_list()]
            for curShow in allSeries:
                if int(curShow['id']) in showIDList:
                    return curShow
        except Exception:
            pass

        # if nothing matches then return first result
        return allSeries[0]
Example #19
0
    def get(self, *args, **kwargs):
        which_subs = self.get_argument('whichSubs', None)

        ep_counts = {}
        show_names = {}
        sorted_show_ids = []
        status_results = []

        if which_subs:
            for s in get_show_list(session=self.db_session):
                if not s.subtitles == 1:
                    continue

                for e in s.episodes:
                    if e.season != 0 and (str(e.status).endswith('4')
                                          or str(e.status).endswith('6')):
                        status_results += [{
                            'show_name': s.name,
                            'indexer_id': s.indexer_id,
                            'subtitles': e.subtitles
                        }]

            for cur_status_result in sorted(status_results,
                                            key=lambda k: k['show_name']):
                if which_subs == 'all':
                    if not frozenset(
                            Subtitles().wanted_languages()).difference(
                                cur_status_result["subtitles"].split(',')):
                        continue
                elif which_subs in cur_status_result["subtitles"]:
                    continue

                cur_indexer_id = int(cur_status_result["indexer_id"])
                if cur_indexer_id not in ep_counts:
                    ep_counts[cur_indexer_id] = 1
                else:
                    ep_counts[cur_indexer_id] += 1

                show_names[cur_indexer_id] = cur_status_result["show_name"]
                if cur_indexer_id not in sorted_show_ids:
                    sorted_show_ids.append(cur_indexer_id)

        return self.render("/manage/subtitles_missed.mako",
                           whichSubs=which_subs,
                           show_names=show_names,
                           ep_counts=ep_counts,
                           sorted_show_ids=sorted_show_ids,
                           title=_('Missing Subtitles'),
                           header=_('Missing Subtitles'),
                           topmenu='manage',
                           controller='manage',
                           action='subtitles_missed')
Example #20
0
    def run(self, force=False):
        """
        Runs the daily searcher, queuing selected episodes for search
        :param force: Force search
        """
        if self.amActive and not force:
            return

        self.amActive = True

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

        # find new released episodes and update their statuses
        for curShow in get_show_list():
            if curShow.paused:
                sickrage.app.log.debug(
                    "Skipping search for {} because the show is paused".format(
                        curShow.name))
                continue

            for tv_episode in curShow.new_episodes:
                tv_episode.status = tv_episode.show.default_ep_status if tv_episode.season > 0 else common.SKIPPED
                tv_episode.save()
                sickrage.app.log.info(
                    'Setting status ({status}) for show airing today: {name} {special}'
                    .format(
                        name=tv_episode.pretty_name(),
                        status=common.statusStrings[tv_episode.status],
                        special='(specials are not supported)'
                        if not tv_episode.season > 0 else '',
                    ))

            wanted = self._get_wanted(curShow, datetime.date.today())
            if not wanted:
                sickrage.app.log.debug(
                    "Nothing needs to be downloaded for {}, skipping".format(
                        curShow.name))
                continue

            for season, episode in wanted:
                if (curShow.indexer_id, season,
                        episode) in sickrage.app.search_queue.SNATCH_HISTORY:
                    sickrage.app.search_queue.SNATCH_HISTORY.remove(
                        (curShow.indexer_id, season, episode))

                sickrage.app.io_loop.add_callback(
                    sickrage.app.search_queue.put,
                    DailySearchQueueItem(curShow.indexer_id, season, episode))

        self.amActive = False
Example #21
0
    def search_backlog(self, series_id=None, series_provider_id=None):
        self.amPaused = False

        show_list = [
            find_show(series_id, series_provider_id)
        ] if series_id and series_provider_id else get_show_list()

        from_date = datetime.date.min

        if not series_id and self.forced:
            sickrage.app.log.info(
                "Running limited backlog on missed episodes " +
                str(sickrage.app.config.general.backlog_days) + " day(s) old")
            from_date = datetime.date.today() - datetime.timedelta(
                days=sickrage.app.config.general.backlog_days)
        else:
            sickrage.app.log.info(
                'Running full backlog search on missed episodes for all shows')

        # go through non air-by-date shows and see if they need any episodes
        for curShow in show_list:
            if curShow.paused:
                sickrage.app.log.debug(
                    "Skipping search for {} because the show is paused".format(
                        curShow.name))
                continue

            wanted = self._get_wanted(curShow, from_date)
            if not wanted:
                sickrage.app.log.debug(
                    "Nothing needs to be downloaded for {}, skipping".format(
                        curShow.name))
                continue

            for season, episode in wanted:
                if (curShow.series_id, season,
                        episode) in sickrage.app.search_queue.SNATCH_HISTORY:
                    sickrage.app.search_queue.SNATCH_HISTORY.remove(
                        (curShow.series_id, season, episode))

                sickrage.app.search_queue.put(
                    BacklogSearchTask(curShow.series_id,
                                      curShow.series_provider_id, season,
                                      episode))

            if from_date == datetime.date.min and not series_id:
                self._set_last_backlog_search(curShow, datetime.datetime.now())
                curShow.save()
Example #22
0
    def get(self, *args, **kwargs):
        show_counts = {}
        show_cats = {}
        show_results = {}

        for curShow in get_show_list(session=self.db_session):
            if curShow.paused:
                continue

            ep_cats = {}
            ep_counts = {
                Overview.SKIPPED: 0,
                Overview.WANTED: 0,
                Overview.QUAL: 0,
                Overview.GOOD: 0,
                Overview.UNAIRED: 0,
                Overview.SNATCHED: 0,
                Overview.SNATCHED_PROPER: 0,
                Overview.SNATCHED_BEST: 0,
                Overview.MISSED: 0,
            }

            show_results[curShow.indexer_id] = []

            for curResult in sorted(curShow.episodes,
                                    key=lambda x: (x.season, x.episode),
                                    reverse=True):
                cur_ep_cat = curShow.get_overview(int(curResult.status or -1))
                if cur_ep_cat:
                    ep_cats["{}x{}".format(curResult.season,
                                           curResult.episode)] = cur_ep_cat
                    ep_counts[cur_ep_cat] += 1

                show_results[curShow.indexer_id] += [curResult]

            show_counts[curShow.indexer_id] = ep_counts
            show_cats[curShow.indexer_id] = ep_cats

        return self.render("/manage/backlog_overview.mako",
                           showCounts=show_counts,
                           showCats=show_cats,
                           showResults=show_results,
                           title=_('Backlog Overview'),
                           header=_('Backlog Overview'),
                           topmenu='manage',
                           controller='manage',
                           action='backlog_overview')
Example #23
0
    def _generate_recipients(self, show):
        addrs = []

        # Grab the global recipients
        for addr in sickrage.app.config.email_list.split(','):
            if len(addr.strip()) > 0:
                addrs.append(addr)

        # Grab the recipients for the show
        for s in show:
            for subs in [x for x in get_show_list() if x.name == s]:
                if subs.notify_list:
                    for addr in subs.notify_list.split(','):
                        if len(addr.strip()) > 0:
                            addrs.append(addr)

        addrs = set(addrs)
        sickrage.app.log.debug('Notification recipients: %s' % addrs)
        return addrs
Example #24
0
    def add_episodes_to_trakt_watch_list(self):
        trakt_data = []

        sickrage.app.log.debug(
            "WATCHLIST::ADD::START - Look for Episodes to Add to Trakt Watchlist"
        )

        for show_object in get_show_list():
            for episode_object in show_object.episodes:
                if episode_object.status in flatten([
                        EpisodeStatus.composites(EpisodeStatus.SNATCHED),
                        EpisodeStatus.composites(
                            EpisodeStatus.SNATCHED_PROPER),
                        EpisodeStatus.UNKNOWN, EpisodeStatus.WANTED
                ]):
                    continue

                trakt_id = show_object.series_provider.trakt_id
                if self._check_in_list(trakt_id, str(show_object.series_id),
                                       episode_object.season,
                                       episode_object.episode):
                    sickrage.app.log.debug(
                        f"Adding Episode {show_object.name} S{episode_object.season:02d}E{episode_object.episode:02d} to watchlist"
                    )
                    trakt_data.append(
                        (show_object.series_id, show_object.series_provider_id,
                         show_object.name, show_object.startyear,
                         episode_object.season, episode_object.episode))

        if len(trakt_data):
            try:
                data = self.trakt_bulk_data_generate(trakt_data)
                TraktAPI()["sync/watchlist"].add(data)
                self._get_episode_watchlist()
            except Exception as e:
                sickrage.app.log.warning(
                    f"Could not connect to Trakt service. Error {e}")

        sickrage.app.log.debug(
            "WATCHLIST::ADD::FINISH - Look for Episodes to Add to Trakt Watchlist"
        )
Example #25
0
    def run(self, force=False, session=None):
        """
        Runs the daily searcher, queuing selected episodes for search
        :param force: Force search
        """
        if self.amActive and not force:
            return

        self.amActive = True

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

        # find new released episodes and update their statuses
        new_episode_finder()

        for curShow in get_show_list(session=session):
            if curShow.paused:
                sickrage.app.log.debug(
                    "Skipping search for {} because the show is paused".format(
                        curShow.name))
                continue

            wanted = self._get_wanted(curShow, datetime.date.today())
            if not wanted:
                sickrage.app.log.debug(
                    "Nothing needs to be downloaded for {}, skipping".format(
                        curShow.name))
                continue

            for season, episode in wanted:
                if (curShow.indexer_id, season,
                        episode) in sickrage.app.search_queue.SNATCH_HISTORY:
                    sickrage.app.search_queue.SNATCH_HISTORY.remove(
                        (curShow.indexer_id, season, episode))

                sickrage.app.io_loop.add_callback(
                    sickrage.app.search_queue.put,
                    DailySearchQueueItem(curShow.indexer_id, season, episode))

        self.amActive = False
Example #26
0
    def add_episodes_to_trakt_watch_list(self):
        trakt_data = []

        sickrage.app.log.debug(
            "WATCHLIST::ADD::START - Look for Episodes to Add to Trakt Watchlist"
        )

        for show_object in get_show_list():
            for episode_object in show_object.episodes:
                if episode_object.status in Quality.SNATCHED + Quality.SNATCHED_PROPER + [
                        UNKNOWN, WANTED
                ]:
                    continue

                trakt_id = IndexerApi(show_object.indexer).trakt_id
                if self._check_in_list(trakt_id, str(show_object.indexer_id),
                                       episode_object.season,
                                       episode_object.episode):
                    sickrage.app.log.debug(
                        "Adding Episode %s S%02dE%02d to watchlist" %
                        (show_object.name, episode_object.season,
                         episode_object.episode))
                    trakt_data.append(
                        (show_object.indexer_id, show_object.indexer,
                         show_object.name, show_object.startyear,
                         episode_object.season, episode_object.episode))

        if len(trakt_data):
            try:
                data = self.trakt_bulk_data_generate(trakt_data)
                TraktAPI()["sync/watchlist"].add(data)
                self._get_episode_watchlist()
            except Exception as e:
                sickrage.app.log.warning(
                    "Could not connect to Trakt service. Error %s" % e)

        sickrage.app.log.debug(
            "WATCHLIST::ADD::FINISH - Look for Episodes to Add to Trakt Watchlist"
        )
Example #27
0
    def get(self, *args, **kwargs):
        which_status = self.get_argument('whichStatus', None)

        ep_counts = {}
        show_names = {}
        sorted_show_ids = []
        status_list = []

        if which_status:
            status_list = [int(which_status)]
            if int(which_status) == SNATCHED:
                status_list = Quality.SNATCHED + Quality.SNATCHED_PROPER + Quality.SNATCHED_BEST

        # if we have no status then this is as far as we need to go
        if len(status_list):
            for show in sorted(get_show_list(session=self.db_session), key=lambda d: d.name):
                for episode in show.episodes:
                    if episode.season != 0 and episode.status in status_list:
                        if show.indexer_id not in ep_counts:
                            ep_counts[show.indexer_id] = 1
                        else:
                            ep_counts[show.indexer_id] += 1

                        show_names[show.indexer_id] = show.name
                        if show.indexer_id not in sorted_show_ids:
                            sorted_show_ids.append(show.indexer_id)

        return self.render(
            "/manage/episode_statuses.mako",
            title="Episode Overview",
            header="Episode Overview",
            topmenu='manage',
            whichStatus=which_status,
            show_names=show_names,
            ep_counts=ep_counts,
            sorted_show_ids=sorted_show_ids,
            controller='manage',
            action='episode_statuses'
        )
Example #28
0
    def add_show_to_trakt_watch_list(self):
        trakt_data = []

        sickrage.app.log.debug(
            "SHOW_WATCHLIST::ADD::START - Look for Shows to Add to Trakt Watchlist"
        )

        for show in get_show_list():
            if not self._check_in_list(
                    IndexerApi(show.indexer).trakt_id, str(show.indexer_id), 0,
                    0, 'Show'):
                sickrage.app.log.debug(
                    "Adding Show: Indexer %s %s - %s to Watchlist" %
                    (IndexerApi(show.indexer).trakt_id, str(
                        show.indexer_id), show.name))

                show_el = {
                    'title': show.name,
                    'year': show.startyear,
                    'ids': {
                        IndexerApi(show.indexer).trakt_id: show.indexer_id
                    }
                }

                trakt_data.append(show_el)

        if len(trakt_data):
            try:
                data = {'shows': trakt_data}
                TraktAPI()["sync/watchlist"].add(data)
                self._get_show_watchlist()
            except Exception as e:
                sickrage.app.log.warning(
                    "Could not connect to Trakt service. Error: %s" % e)

        sickrage.app.log.debug(
            "SHOW_WATCHLIST::ADD::FINISH - Look for Shows to Add to Trakt Watchlist"
        )
Example #29
0
    def add_show_to_trakt_watch_list(self):
        trakt_data = []

        sickrage.app.log.debug(
            "SHOW_WATCHLIST::ADD::START - Look for Shows to Add to Trakt Watchlist"
        )

        for show in get_show_list():
            series_provider_trakt_id = show.series_provider.trakt_id

            if not self._check_in_list(series_provider_trakt_id,
                                       str(show.series_id), 0, 0, 'Show'):
                sickrage.app.log.debug(
                    f"Adding Show: Series Provider {series_provider_trakt_id} {str(show.series_id)} - {show.name} to Watchlist"
                )

                show_el = {
                    'title': show.name,
                    'year': show.startyear,
                    'ids': {
                        series_provider_trakt_id: show.series_id
                    }
                }

                trakt_data.append(show_el)

        if len(trakt_data):
            try:
                data = {'shows': trakt_data}
                TraktAPI()["sync/watchlist"].add(data)
                self._get_show_watchlist()
            except Exception as e:
                sickrage.app.log.warning(
                    f"Could not connect to Trakt service. Error: {e}")

        sickrage.app.log.debug(
            "SHOW_WATCHLIST::ADD::FINISH - Look for Shows to Add to Trakt Watchlist"
        )
Example #30
0
    def remove_show_from_sick_rage(self):
        sickrage.app.log.debug(
            "SHOW_SICKRAGE::REMOVE::START - Look for Shows to remove from SiCKRAGE"
        )

        for show in get_show_list():
            if show.status == "Ended":
                try:
                    progress = TraktAPI()["shows"].get(show.imdb_id)
                except Exception as e:
                    sickrage.app.log.warning(
                        "Could not connect to Trakt service. Aborting removing show %s from SiCKRAGE. Error: %s"
                        % (show.name, repr(e)))
                    return

                if progress.status in ['canceled', 'ended']:
                    sickrage.app.show_queue.remove_show(show.indexer_id,
                                                        full=True)
                    sickrage.app.log.debug(
                        "Show: %s has been removed from SiCKRAGE" % show.name)

        sickrage.app.log.debug(
            "SHOW_SICKRAGE::REMOVE::FINISH - Trakt Show Watchlist")