Example #1
0
    def run(self):
        self.started = True

        try:
            sickrage.app.log.info("Starting failed download search for: [" + self.show.name + "]")

            for epObj in self.segment:
                sickrage.app.log.info("Marking episode as bad: [" + epObj.pretty_name() + "]")

                FailedHistory.markFailed(epObj)

                (release, provider) = FailedHistory.findFailedRelease(epObj)
                if release:
                    FailedHistory.logFailed(release)
                    History.logFailed(epObj, release, provider)

                FailedHistory.revertFailedEpisode(epObj)

            search_result = searchProviders(self.show, self.segment, manualSearch=True, downCurQuality=False)
            if search_result:
                for result in search_result:
                    # just use the first result for now
                    sickrage.app.log.info("Downloading " + result.name + " from " + result.provider.name)
                    snatchEpisode(result)

                    # give the CPU a break
                    time.sleep(cpu_presets[sickrage.app.config.cpu_preset])
        except Exception:
            sickrage.app.log.debug(traceback.format_exc())
        finally:
            sickrage.app.log.info("Finished failed download search for: [" + self.show.name + "]")

        # Keep a list with the 100 last executed searches
        fifo(MANUAL_SEARCH_HISTORY, self, MANUAL_SEARCH_HISTORY_SIZE)
Example #2
0
    def run(self):
        self.started = True

        try:
            sickrage.app.log.info("Starting failed download search for: [" + self.show.name + "]")

            for epObj in self.segment:
                sickrage.app.log.info("Marking episode as bad: [" + epObj.pretty_name() + "]")

                FailedHistory.markFailed(epObj)

                (release, provider) = FailedHistory.findFailedRelease(epObj)
                if release:
                    FailedHistory.logFailed(release)
                    History.logFailed(epObj, release, provider)

                FailedHistory.revertFailedEpisode(epObj)

            search_result = searchProviders(self.show, self.segment, manualSearch=True, downCurQuality=False)
            if search_result:
                for result in search_result:
                    # just use the first result for now
                    sickrage.app.log.info("Downloading " + result.name + " from " + result.provider.name)
                    snatchEpisode(result)

                    # give the CPU a break
                    time.sleep(cpu_presets[sickrage.app.config.cpu_preset])
        except Exception:
            sickrage.app.log.debug(traceback.format_exc())
        finally:
            sickrage.app.log.info("Finished failed download search for: [" + self.show.name + "]")

        # Keep a list with the 100 last executed searches
        fifo(MANUAL_SEARCH_HISTORY, self, MANUAL_SEARCH_HISTORY_SIZE)
Example #3
0
def downloadSubtitles(subtitles_info):
    existing_subtitles = subtitles_info[b'subtitles']
    # First of all, check if we need subtitles
    languages = getNeededLanguages(existing_subtitles)
    if not languages:
        sickrage.LOGGER.debug('%s: No missing subtitles for S%02dE%02d' % (
            subtitles_info[b'show.indexerid'], subtitles_info[b'season'], subtitles_info[b'episode']))
        return existing_subtitles, None

    subtitles_path = getSubtitlesPath(subtitles_info[b'location']).encode(sickrage.SYS_ENCODING)
    video_path = subtitles_info[b'location'].encode(sickrage.SYS_ENCODING)
    providers = getEnabledServiceList()

    try:
        video = subliminal.scan_video(video_path, subtitles=False, embedded_subtitles=False)
    except Exception:
        sickrage.LOGGER.debug('%s: Exception caught in subliminal.scan_video for S%02dE%02d' %
                      (subtitles_info[b'show.indexerid'], subtitles_info[b'season'], subtitles_info[b'episode']))
        return existing_subtitles, None

    provider_configs = {'addic7ed': {'username': sickrage.ADDIC7ED_USER, 'password': sickrage.ADDIC7ED_PASS},
                        'legendastv': {'username': sickrage.LEGENDASTV_USER, 'password': sickrage.LEGENDASTV_PASS},
                        'opensubtitles': {'username': sickrage.OPENSUBTITLES_USER,
                                          'password': sickrage.OPENSUBTITLES_PASS}}

    pool = subliminal.api.ProviderPool(providers=providers, provider_configs=provider_configs)

    try:
        subtitles_list = pool.list_subtitles(video, languages)
        if not subtitles_list:
            sickrage.LOGGER.debug('%s: No subtitles found for S%02dE%02d on any provider' % (
                subtitles_info[b'show.indexerid'], subtitles_info[b'season'], subtitles_info[b'episode']))
            return existing_subtitles, None

        found_subtitles = pool.download_best_subtitles(subtitles_list, video, languages=languages,
                                                       hearing_impaired=sickrage.SUBTITLES_HEARING_IMPAIRED,
                                                       only_one=not sickrage.SUBTITLES_MULTI)

        save_subtitles(video, found_subtitles, directory=subtitles_path, single=not sickrage.SUBTITLES_MULTI)

        if not sickrage.EMBEDDED_SUBTITLES_ALL and sickrage.SUBTITLES_EXTRA_SCRIPTS and video_path.endswith(
                ('.mkv', '.mp4')):
            run_subs_extra_scripts(subtitles_info, found_subtitles, video, single=not sickrage.SUBTITLES_MULTI)

        current_subtitles = subtitlesLanguages(video_path)[0]
        new_subtitles = frozenset(current_subtitles).difference(existing_subtitles)

    except Exception:
        sickrage.LOGGER.info("Error occurred when downloading subtitles for: %s" % video_path)
        sickrage.LOGGER.error(traceback.format_exc())
        return existing_subtitles, None

    if sickrage.SUBTITLES_HISTORY:
        for subtitle in found_subtitles:
            sickrage.LOGGER.debug('history.logSubtitle %s, %s' % (subtitle.provider_name, subtitle.language.opensubtitles))
            History.logSubtitle(subtitles_info[b'show.indexerid'], subtitles_info[b'season'],
                                subtitles_info[b'episode'],
                                subtitles_info[b'status'], subtitle)

    return current_subtitles, new_subtitles
Example #4
0
    def run(self):
        super(FailedQueueItem, self).run()
        self.started = True

        try:
            for epObj in self.segment:
                sickrage.srCore.srLogger.info("Marking episode as bad: [" + epObj.prettyName() + "]")

                FailedHistory.markFailed(epObj)
                (release, provider) = FailedHistory.findFailedRelease(epObj)
                if release:
                    FailedHistory.logFailed(release)
                    History.logFailed(epObj, release, provider)

                FailedHistory.revertFailedEpisode(epObj)
                sickrage.srCore.srLogger.info("Beginning failed download search for: [" + epObj.prettyName() + "]")

            # If it is wanted, self.downCurQuality doesnt matter
            # if it isnt wanted, we need to make sure to not overwrite the existing ep that we reverted to!
            searchResult = searchProviders(self.show, self.segment, True, False)
            if searchResult:
                for result in searchResult:
                    # just use the first result for now
                    sickrage.srCore.srLogger.info("Downloading " + result.name + " from " + result.provider.name)
                    snatchEpisode(result)

                    # give the CPU a break
                    time.sleep(cpu_presets[sickrage.srCore.srConfig.CPU_PRESET])
        except Exception:
            sickrage.srCore.srLogger.debug(traceback.format_exc())

        ### Keep a list with the 100 last executed searches
        fifo(MANUAL_SEARCH_HISTORY, self, MANUAL_SEARCH_HISTORY_SIZE)
Example #5
0
    def run(self):
        self.started = True

        show_object = find_show(self.show_id)
        episode_object = show_object.get_episode(self.season, self.episode)

        try:
            sickrage.app.log.info("Starting failed download search for: [" +
                                  episode_object.name + "]")

            sickrage.app.log.info("Marking episode as bad: [" +
                                  episode_object.pretty_name() + "]")

            FailedHistory.mark_failed(self.show_id, self.season, self.episode)

            (release, provider) = FailedHistory.find_failed_release(
                self.show_id, self.season, self.episode)
            if release:
                FailedHistory.log_failed(release)
                History.log_failed(self.show_id, self.season, self.episode,
                                   release, provider)

            FailedHistory.revert_failed_episode(self.show_id, self.season,
                                                self.episode)

            search_result = search_providers(self.show_id,
                                             self.season,
                                             self.episode,
                                             manualSearch=True,
                                             downCurQuality=False)
            if search_result:
                snatch = all([(search_result.show_id, search_result.season,
                               episode)
                              not in sickrage.app.search_queue.SNATCH_HISTORY
                              for episode in search_result.episodes])

                if snatch:
                    [
                        sickrage.app.search_queue.fifo(
                            sickrage.app.search_queue.SNATCH_HISTORY,
                            (search_result.show_id, search_result.season,
                             episode),
                            sickrage.app.search_queue.SNATCH_HISTORY_SIZE)
                        for episode in search_result.episodes
                    ]

                    sickrage.app.log.info("Downloading " + search_result.name +
                                          " from " +
                                          search_result.provider.name)
                    snatch_episode(search_result)
        except Exception:
            sickrage.app.log.debug(traceback.format_exc())
        finally:
            sickrage.app.log.info("Finished failed download search for: [" +
                                  show_object.name + "]")
            sickrage.app.search_queue.fifo(
                sickrage.app.search_queue.MANUAL_SEARCH_HISTORY, self,
                sickrage.app.search_queue.MANUAL_SEARCH_HISTORY_SIZE)
Example #6
0
    def get(self):
        """Get snatch and download history"
        ---
        tags: [History]
        summary: Get snatch and download history
        description: Get snatch and download history
        responses:
          200:
            description: Success payload
            content:
              application/json:
                schema:
                  HistorySuccessSchema
          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
        """

        limit = int(self.get_argument('limit', sickrage.app.config.gui.history_limit or 100))

        results = []

        for row in History().get(limit):
            status, quality = Quality.split_composite_status(int(row["action"]))

            # if self.type and not status.lower() == self.type:
            #     continue

            row["status"] = status.display_name
            row["quality"] = quality.name
            row["date"] = datetime.datetime.fromordinal(row["date"].toordinal()).timestamp()

            del row["action"]

            row["series_id"] = row.pop("series_id")
            row['series_provider_id'] = row['series_provider_id'].name
            row["resource_path"] = os.path.dirname(row["resource"])
            row["resource"] = os.path.basename(row["resource"])

            row = convert_dict_keys_to_camelcase(row)

            results.append(row)

        return self.json_response(results)
Example #7
0
def download_subtitles(episode):
    existing_subtitles = episode.subtitles

    # First of all, check if we need subtitles
    languages = get_needed_languages(existing_subtitles)
    if not languages:
        sickrage.app.log.debug('%s: No missing subtitles for S%02dE%02d' % (
            episode.show.indexerid, episode.season, episode.episode))
        return existing_subtitles, None

    subtitles_path = get_subtitles_path(episode.location)
    video_path = episode.location
    providers = getEnabledServiceList()

    video = get_video(video_path, subtitles_path=subtitles_path, episode=episode)
    if not video:
        sickrage.app.log.debug('%s: Exception caught in subliminal.scan_video for S%02dE%02d' %
                               (episode.show.indexerid, episode.season,
                                episode.episode))
        return existing_subtitles, None

    provider_configs = {
        'addic7ed': {'username': sickrage.app.config.addic7ed_user,
                     'password': sickrage.app.config.addic7ed_pass},
        'itasa': {'username': sickrage.app.config.itasa_user,
                  'password': sickrage.app.config.itasa_pass},
        'legendastv': {'username': sickrage.app.config.legendastv_user,
                       'password': sickrage.app.config.legendastv_pass},
        'opensubtitles': {'username': sickrage.app.config.opensubtitles_user,
                          'password': sickrage.app.config.opensubtitles_pass}}

    pool = subliminal.ProviderPool(providers=providers, provider_configs=provider_configs)

    try:
        subtitles_list = pool.list_subtitles(video, languages)
        if not subtitles_list:
            sickrage.app.log.debug('%s: No subtitles found for S%02dE%02d on any provider' % (
                episode.show.indexerid, episode.season, episode.episode))
            return existing_subtitles, None

        found_subtitles = pool.download_best_subtitles(subtitles_list, video, languages=languages,
                                                       hearing_impaired=sickrage.app.config.subtitles_hearing_impaired,
                                                       only_one=not sickrage.app.config.subtitles_multi)

        save_subtitles(video, found_subtitles, directory=subtitles_path,
                       single=not sickrage.app.config.subtitles_multi)

        if not sickrage.app.config.embedded_subtitles_all and sickrage.app.config.subtitles_extra_scripts and video_path.endswith(
                ('.mkv', '.mp4')):
            run_subs_extra_scripts(episode, found_subtitles, video,
                                   single=not sickrage.app.config.subtitles_multi)

        new_subtitles = sorted({subtitle.language.opensubtitles for subtitle in found_subtitles})
        current_subtitles = sorted({subtitle for subtitle in new_subtitles + existing_subtitles if subtitle})
        if not sickrage.app.config.subtitles_multi and len(found_subtitles) == 1:
            new_code = found_subtitles[0].language.opensubtitles
            if new_code not in existing_subtitles:
                current_subtitles.remove(new_code)
            current_subtitles.append('und')

    except Exception:
        sickrage.app.log.info("Error occurred when downloading subtitles for: %s" % video_path)
        sickrage.app.log.error(traceback.format_exc())
        return existing_subtitles, None

    if sickrage.app.config.subtitles_history:
        from sickrage.core.tv.show.history import History
        for subtitle in found_subtitles:
            sickrage.app.log.debug(
                'history.logSubtitle %s, %s' % (subtitle.provider_name, subtitle.language.opensubtitles))
            History.logSubtitle(episode.show.indexerid,
                                episode.season,
                                episode.episode,
                                episode.status,
                                subtitle)

    return current_subtitles, new_subtitles
Example #8
0
    def get(self, *args, **kwargs):
        limit = self.get_argument('limit', None)

        if limit is None:
            if sickrage.app.config.history_limit:
                limit = int(sickrage.app.config.history_limit)
            else:
                limit = 100
        else:
            limit = int(limit)

        if sickrage.app.config.history_limit != limit:
            sickrage.app.config.history_limit = limit
            sickrage.app.config.save()

        compact = []

        for row in History().get(limit):
            action = {
                'action': row['action'],
                'provider': row['provider'],
                'release_group': row['release_group'],
                'resource': row['resource'],
                'time': row['date']
            }

            if not any(
                (history['show_id'] == row['show_id'] and history['season'] ==
                 row['season'] and history['episode'] == row['episode']
                 and history['quality'] == row['quality'])
                    for history in compact):

                history = {
                    'actions': [action],
                    'quality': row['quality'],
                    'resource': row['resource'],
                    'season': row['season'],
                    'episode': row['episode'],
                    'show_id': row['show_id'],
                    'show_name': row['show_name']
                }

                compact.append(history)
            else:
                index = [
                    i for i, item in enumerate(compact)
                    if item['show_id'] == row['show_id'] and item['season'] ==
                    row['season'] and item['episode'] == row['episode']
                    and item['quality'] == row['quality']
                ][0]

                history = compact[index]
                history['actions'].append(action)

                history['actions'].sort(key=lambda d: d['time'], reverse=True)

        submenu = [
            {
                'title': _('Clear History'),
                'path': '/history/clear',
                'icon': 'fas fa-trash',
                'class': 'clearhistory',
                'confirm': True
            },
            {
                'title': _('Trim History'),
                'path': '/history/trim',
                'icon': 'fas fa-cut',
                'class': 'trimhistory',
                'confirm': True
            },
        ]

        return self.render("/history.mako",
                           historyResults=History().get(limit),
                           compactResults=compact,
                           limit=limit,
                           submenu=submenu,
                           title=_('History'),
                           header=_('History'),
                           topmenu="history",
                           controller='root',
                           action='history')
Example #9
0
 async def get(self, *args, **kwargs):
     await self.run_task(History().trim)
     sickrage.app.alerts.message(
         _('Removed history entries older than 30 days'))
     return self.redirect("/history/")
Example #10
0
 async def get(self, *args, **kwargs):
     await self.run_task(History().clear)
     sickrage.app.alerts.message(_('History cleared'))
     return self.redirect("/history/")
Example #11
0
def snatchEpisode(result, endStatus=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param endStatus: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.ALLOW_HIGH_PRIORITY:
        # if it aired recently make it high priority
        for curEp in result.episodes:
            if datetime.date.today() - curEp.airdate <= datetime.timedelta(days=7):
                result.priority = 1
    if re.search(r"(^|[\. _-])(proper|repack)([\. _-]|$)", result.name, re.I) is not None:
        endStatus = SNATCHED_PROPER

    if result.url.startswith("magnet") or result.url.endswith("torrent"):
        result.resultType = "torrent"

    # NZBs can be sent straight to SAB or saved to disk
    if result.resultType in ("nzb", "nzbdata"):
        if sickrage.NZB_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        elif sickrage.NZB_METHOD == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.NZB_METHOD == "nzbget":
            is_proper = True if endStatus == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        else:
            sickrage.LOGGER.error("Unknown NZB action specified in config: " + sickrage.NZB_METHOD)
            dlResult = False

    # TORRENTs can be sent to clients or saved to disk
    elif result.resultType == "torrent":
        # torrents are saved to disk when blackhole mode
        if sickrage.TORRENT_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        else:
            if not result.content and not result.url.startswith("magnet"):
                result.content = result.provider.getURL(result.url, needBytes=True)

            if result.content or result.url.startswith("magnet"):
                client = getClientIstance(sickrage.TORRENT_METHOD)()
                dlResult = client.sendTORRENT(result)
            else:
                sickrage.LOGGER.warning("Torrent file content is empty")
                dlResult = False
    else:
        sickrage.LOGGER.error("Unknown result type, unable to download it (%r)" % result.resultType)
        dlResult = False

    if not dlResult:
        return False

    if sickrage.USE_FAILED_DOWNLOADS:
        FailedHistory.logSnatch(result)

    notifications.message("Episode snatched", result.name)

    History.logSnatch(result)

    # don't notify when we re-download an episode
    sql_l = []
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if isFirstBestMatch(result):
                curEpObj.status = Quality.compositeStatus(SNATCHED_BEST, result.quality)
            else:
                curEpObj.status = Quality.compositeStatus(endStatus, result.quality)

            sql_l.append(curEpObj.get_sql())

        if curEpObj.status not in Quality.DOWNLOADED:
            try:
                notify_snatch(curEpObj._format_pattern("%SN - %Sx%0E - %EN - %QN") + " from " + result.provider.name)
            except:
                sickrage.LOGGER.debug("Failed to send snatch notification")

            trakt_data.append((curEpObj.season, curEpObj.episode))

    data = sickrage.NOTIFIERS.trakt_notifier.trakt_episode_data_generate(trakt_data)

    if sickrage.USE_TRAKT and sickrage.TRAKT_SYNC_WATCHLIST:
        sickrage.LOGGER.debug(
            "Add episodes, showid: indexerid "
            + str(result.show.indexerid)
            + ", Title "
            + str(result.show.name)
            + " to Traktv Watchlist"
        )
        if data:
            sickrage.NOTIFIERS.trakt_notifier.update_watchlist(result.show, data_episode=data, update="add")

    if len(sql_l) > 0:
        main_db.MainDB().mass_action(sql_l)

    return True
Example #12
0
def snatchEpisode(result, endStatus=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param endStatus: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.app.config.allow_high_priority:
        # if it aired recently make it high priority
        for curEp in result.episodes:
            if date.today() - curEp.airdate <= timedelta(days=7):
                result.priority = 1

    if re.search(r'(^|[. _-])(proper|repack)([. _-]|$)', result.name,
                 re.I) is not None:
        endStatus = SNATCHED_PROPER

    # get result content
    result.content = result.provider.get_content(result.url)

    dlResult = False
    if result.resultType in ("nzb", "nzbdata"):
        if sickrage.app.config.nzb_method == "blackhole":
            dlResult = result.provider.download_result(result)
        elif sickrage.app.config.nzb_method == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.app.config.nzb_method == "nzbget":
            is_proper = True if endStatus == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        else:
            sickrage.app.log.error("Unknown NZB action specified in config: " +
                                   sickrage.app.config.nzb_method)
    elif result.resultType in ("torrent", "torznab"):
        # add public trackers to torrent result
        if not result.provider.private:
            result = result.provider.add_trackers(result)

        if sickrage.app.config.torrent_method == "blackhole":
            dlResult = result.provider.download_result(result)
        else:
            if any([result.content, result.url.startswith('magnet:')]):
                client = getClientIstance(sickrage.app.config.torrent_method)()
                dlResult = client.send_torrent(result)
            else:
                sickrage.app.log.warning("Torrent file content is empty")
    else:
        sickrage.app.log.error(
            "Unknown result type, unable to download it (%r)" %
            result.resultType)

    # no download results found
    if not dlResult:
        return False

    FailedHistory.logSnatch(result)

    sickrage.app.alerts.message(_('Episode snatched'), result.name)

    History.logSnatch(result)

    # don't notify when we re-download an episode
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if isFirstBestMatch(result):
                curEpObj.status = Quality.compositeStatus(
                    SNATCHED_BEST, result.quality)
            else:
                curEpObj.status = Quality.compositeStatus(
                    endStatus, result.quality)

            # save episode to DB
            curEpObj.save_to_db()

        if curEpObj.status not in Quality.DOWNLOADED:
            try:
                Notifiers.mass_notify_snatch(
                    curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN') +
                    " from " + result.provider.name)
            except:
                sickrage.app.log.debug("Failed to send snatch notification")

            trakt_data.append((curEpObj.season, curEpObj.episode))

    data = sickrage.app.notifier_providers[
        'trakt'].trakt_episode_data_generate(trakt_data)

    if sickrage.app.config.use_trakt and sickrage.app.config.trakt_sync_watchlist:
        sickrage.app.log.debug("Add episodes, showid: indexerid " +
                               str(result.show.indexerid) + ", Title " +
                               str(result.show.name) + " to Traktv Watchlist")
        if data:
            sickrage.app.notifier_providers['trakt'].update_watchlist(
                result.show, data_episode=data, update="add")

    return True
Example #13
0
def snatchEpisode(result, endStatus=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param endStatus: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.srCore.srConfig.ALLOW_HIGH_PRIORITY:
        # if it aired recently make it high priority
        for curEp in result.episodes:
            if date.today() - curEp.airdate <= timedelta(days=7):
                result.priority = 1

    if re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)', result.name, re.I) is not None:
        endStatus = SNATCHED_PROPER

    if result.url.startswith('magnet') or result.url.endswith('torrent'):
        result.resultType = 'torrent'

    dlResult = False
    if result.resultType in ("nzb", "nzbdata"):
        if sickrage.srCore.srConfig.NZB_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        elif sickrage.srCore.srConfig.NZB_METHOD == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.srCore.srConfig.NZB_METHOD == "nzbget":
            is_proper = True if endStatus == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        else:
            sickrage.srCore.srLogger.error(
                "Unknown NZB action specified in config: " + sickrage.srCore.srConfig.NZB_METHOD)
    elif result.resultType == "torrent":
        if sickrage.srCore.srConfig.TORRENT_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        else:
            if all([not result.content, not result.url.startswith('magnet:')]):
                result.content = sickrage.srCore.srWebSession.get(result.url).content

            if any([result.content, result.url.startswith('magnet:')]):
                # add public trackers to magnet url for non-private torrent providers
                if not result.provider.private and result.url.startswith('magnet:'):
                    result.url += '&tr='.join(
                        [x.strip() for x in sickrage.srCore.srConfig.TORRENT_TRACKERS.split(',') if x.strip()])

                client = getClientIstance(sickrage.srCore.srConfig.TORRENT_METHOD)()
                dlResult = client.sendTORRENT(result)
            else:
                sickrage.srCore.srLogger.warning("Torrent file content is empty")
    else:
        sickrage.srCore.srLogger.error("Unknown result type, unable to download it (%r)" % result.resultType)

    # no download results found
    if not dlResult:
        return False

    if sickrage.srCore.srConfig.USE_FAILED_DOWNLOADS:
        FailedHistory.logSnatch(result)

    sickrage.srCore.srNotifications.message('Episode snatched', result.name)

    History.logSnatch(result)

    # don't notify when we re-download an episode
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if isFirstBestMatch(result):
                curEpObj.status = Quality.compositeStatus(SNATCHED_BEST, result.quality)
            else:
                curEpObj.status = Quality.compositeStatus(endStatus, result.quality)

            # save episode to DB
            curEpObj.saveToDB()

        if curEpObj.status not in Quality.DOWNLOADED:
            try:
                srNotifiers.notify_snatch(
                    curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN') + " from " + result.provider.name)
            except:
                sickrage.srCore.srLogger.debug("Failed to send snatch notification")

            trakt_data.append((curEpObj.season, curEpObj.episode))

    data = sickrage.srCore.notifiersDict['trakt'].trakt_episode_data_generate(trakt_data)

    if sickrage.srCore.srConfig.USE_TRAKT and sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
        sickrage.srCore.srLogger.debug(
            "Add episodes, showid: indexerid " + str(result.show.indexerid) + ", Title " + str(
                result.show.name) + " to Traktv Watchlist")
        if data:
            sickrage.srCore.notifiersDict['trakt'].update_watchlist(result.show, data_episode=data, update="add")

    return True
Example #14
0
    def run(self):
        self.started = True

        sickrage.app.search_queue.TASK_HISTORY[self.id] = {
            'season': self.season,
            'episode': self.episode
        }

        show_object = find_show(self.series_id, self.series_provider_id)
        if not show_object:
            return

        episode_object = show_object.get_episode(self.season, self.episode)

        try:
            sickrage.app.log.info("Starting failed download search for: [" +
                                  episode_object.name + "]")

            WebSocketMessage(
                'SEARCH_QUEUE_STATUS_UPDATED', {
                    'seriesSlug': show_object.slug,
                    'episodeId': episode_object.episode_id,
                    'searchQueueStatus': episode_object.search_queue_status
                }).push()

            sickrage.app.log.info("Marking episode as bad: [" +
                                  episode_object.pretty_name() + "]")

            FailedHistory.mark_failed(self.series_id, self.series_provider_id,
                                      self.season, self.episode)

            (release, provider) = FailedHistory.find_failed_release(
                self.series_id, self.series_provider_id, self.season,
                self.episode)
            if release:
                FailedHistory.log_failed(release)
                History.log_failed(self.series_id, self.series_provider_id,
                                   self.season, self.episode, release,
                                   provider)

            FailedHistory.revert_failed_episode(self.series_id,
                                                self.series_provider_id,
                                                self.season, self.episode)

            search_result = search_providers(self.series_id,
                                             self.series_provider_id,
                                             self.season,
                                             self.episode,
                                             manualSearch=True,
                                             downCurQuality=False)

            if search_result:
                snatch = all([(search_result.series_id, search_result.season,
                               episode)
                              not in sickrage.app.search_queue.SNATCH_HISTORY
                              for episode in search_result.episodes])

                if snatch:
                    [
                        sickrage.app.search_queue.SNATCH_HISTORY.append(
                            (search_result.series_id, search_result.season,
                             episode)) for episode in search_result.episodes
                    ]

                    sickrage.app.log.info("Downloading " + search_result.name +
                                          " from " +
                                          search_result.provider.name)
                    snatch_episode(search_result)
        except Exception:
            sickrage.app.log.debug(traceback.format_exc())
        finally:
            WebSocketMessage(
                'SEARCH_QUEUE_STATUS_UPDATED', {
                    'seriesSlug': show_object.slug,
                    'episodeId': episode_object.episode_id,
                    'searchQueueStatus': episode_object.search_queue_status
                }).push()

            sickrage.app.log.info("Finished failed download search for: [" +
                                  show_object.name + "]")
Example #15
0
def snatchEpisode(result, endStatus=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param endStatus: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.app.config.allow_high_priority:
        # if it aired recently make it high priority
        for curEp in result.episodes:
            if date.today() - curEp.airdate <= timedelta(days=7):
                result.priority = 1

    if re.search(r'(^|[. _-])(proper|repack)([. _-]|$)', result.name, re.I) is not None:
        endStatus = SNATCHED_PROPER

    # get result content
    result.content = result.provider.get_content(result.url)

    dlResult = False
    if result.resultType in ("nzb", "nzbdata"):
        if sickrage.app.config.nzb_method == "blackhole":
            dlResult = result.provider.download_result(result)
        elif sickrage.app.config.nzb_method == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.app.config.nzb_method == "nzbget":
            is_proper = True if endStatus == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        else:
            sickrage.app.log.error("Unknown NZB action specified in config: " + sickrage.app.config.nzb_method)
    elif result.resultType in ("torrent", "torznab"):
        # add public trackers to torrent result
        if not result.provider.private:
            result = result.provider.add_trackers(result)

        if sickrage.app.config.torrent_method == "blackhole":
            dlResult = result.provider.download_result(result)
        else:
            if any([result.content, result.url.startswith('magnet:')]):
                client = getClientIstance(sickrage.app.config.torrent_method)()
                dlResult = client.send_torrent(result)
            else:
                sickrage.app.log.warning("Torrent file content is empty")
    else:
        sickrage.app.log.error("Unknown result type, unable to download it (%r)" % result.resultType)

    # no download results found
    if not dlResult:
        return False

    FailedHistory.logSnatch(result)

    sickrage.app.alerts.message(_('Episode snatched'), result.name)

    History.logSnatch(result)

    # don't notify when we re-download an episode
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if isFirstBestMatch(result):
                curEpObj.status = Quality.compositeStatus(SNATCHED_BEST, result.quality)
            else:
                curEpObj.status = Quality.compositeStatus(endStatus, result.quality)

            # save episode to DB
            curEpObj.save_to_db()

        if curEpObj.status not in Quality.DOWNLOADED:
            try:
                Notifiers.mass_notify_snatch(
                    curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN') + " from " + result.provider.name)
            except:
                sickrage.app.log.debug("Failed to send snatch notification")

            trakt_data.append((curEpObj.season, curEpObj.episode))

    data = sickrage.app.notifier_providers['trakt'].trakt_episode_data_generate(trakt_data)

    if sickrage.app.config.use_trakt and sickrage.app.config.trakt_sync_watchlist:
        sickrage.app.log.debug(
            "Add episodes, showid: indexerid " + str(result.show.indexerid) + ", Title " + str(
                result.show.name) + " to Traktv Watchlist")
        if data:
            sickrage.app.notifier_providers['trakt'].update_watchlist(result.show, data_episode=data, update="add")

    return True
Example #16
0
 def handle_get(self):
     History().trim()
     sickrage.app.alerts.message(
         _('Removed history entries older than 30 days'))
     return self.redirect("/history/")
Example #17
0
 def handle_get(self):
     History().clear()
     sickrage.app.alerts.message(_('History cleared'))
     return self.redirect("/history/")
Example #18
0
def download_subtitles(episode):
    existing_subtitles = episode.subtitles

    # First of all, check if we need subtitles
    languages = get_needed_languages(existing_subtitles)
    if not languages:
        sickrage.srCore.srLogger.debug('%s: No missing subtitles for S%02dE%02d' % (
            episode.show.indexerid, episode.season, episode.episode))
        return existing_subtitles, None

    subtitles_path = get_subtitles_path(episode.location)
    video_path = episode.location
    providers = getEnabledServiceList()

    video = get_video(video_path, subtitles_path=subtitles_path, episode=episode)
    if not video:
        sickrage.srCore.srLogger.debug('%s: Exception caught in subliminal.scan_video for S%02dE%02d' %
                                       (episode.show.indexerid, episode.season,
                                        episode.episode))
        return existing_subtitles, None

    provider_configs = {
        'addic7ed': {'username': sickrage.srCore.srConfig.ADDIC7ED_USER,
                     'password': sickrage.srCore.srConfig.ADDIC7ED_PASS},
        'itasa': {'username': sickrage.srCore.srConfig.ITASA_USER,
                  'password': sickrage.srCore.srConfig.ITASA_PASS},
        'legendastv': {'username': sickrage.srCore.srConfig.LEGENDASTV_USER,
                       'password': sickrage.srCore.srConfig.LEGENDASTV_PASS},
        'opensubtitles': {'username': sickrage.srCore.srConfig.OPENSUBTITLES_USER,
                          'password': sickrage.srCore.srConfig.OPENSUBTITLES_PASS}}

    pool = subliminal.ProviderPool(providers=providers, provider_configs=provider_configs)

    try:
        subtitles_list = pool.list_subtitles(video, languages)
        if not subtitles_list:
            sickrage.srCore.srLogger.debug('%s: No subtitles found for S%02dE%02d on any provider' % (
                episode.show.indexerid, episode.season, episode.episode))
            return existing_subtitles, None

        found_subtitles = pool.download_best_subtitles(subtitles_list, video, languages=languages,
                                                       hearing_impaired=sickrage.srCore.srConfig.SUBTITLES_HEARING_IMPAIRED,
                                                       only_one=not sickrage.srCore.srConfig.SUBTITLES_MULTI)

        save_subtitles(video, found_subtitles, directory=subtitles_path,
                       single=not sickrage.srCore.srConfig.SUBTITLES_MULTI)

        if not sickrage.srCore.srConfig.EMBEDDED_SUBTITLES_ALL and sickrage.srCore.srConfig.SUBTITLES_EXTRA_SCRIPTS and video_path.endswith(
                ('.mkv', '.mp4')):
            run_subs_extra_scripts(episode, found_subtitles, video,
                                   single=not sickrage.srCore.srConfig.SUBTITLES_MULTI)

        new_subtitles = sorted({subtitle.language.opensubtitles for subtitle in found_subtitles})
        current_subtitles = sorted({subtitle for subtitle in new_subtitles + existing_subtitles if subtitle})
        if not sickrage.srCore.srConfig.SUBTITLES_MULTI and len(found_subtitles) == 1:
            new_code = found_subtitles[0].language.opensubtitles
            if new_code not in existing_subtitles:
                current_subtitles.remove(new_code)
            current_subtitles.append('und')

    except Exception:
        sickrage.srCore.srLogger.info("Error occurred when downloading subtitles for: %s" % video_path)
        sickrage.srCore.srLogger.error(traceback.format_exc())
        return existing_subtitles, None

    if sickrage.srCore.srConfig.SUBTITLES_HISTORY:
        from sickrage.core.tv.show.history import History
        for subtitle in found_subtitles:
            sickrage.srCore.srLogger.debug(
                'history.logSubtitle %s, %s' % (subtitle.provider_name, subtitle.language.opensubtitles))
            History.logSubtitle(episode.show.indexerid,
                                episode.season,
                                episode.episode,
                                episode.status,
                                subtitle)

    return current_subtitles, new_subtitles
Example #19
0
def snatchEpisode(result, endStatus=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param endStatus: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.ALLOW_HIGH_PRIORITY:
        # if it aired recently make it high priority
        for curEp in result.episodes:
            if datetime.date.today() - curEp.airdate <= datetime.timedelta(
                    days=7):
                result.priority = 1
    if re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)', result.name,
                 re.I) is not None:
        endStatus = SNATCHED_PROPER

    if result.url.startswith('magnet') or result.url.endswith('torrent'):
        result.resultType = 'torrent'

    # NZBs can be sent straight to SAB or saved to disk
    if result.resultType in ("nzb", "nzbdata"):
        if sickrage.NZB_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        elif sickrage.NZB_METHOD == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.NZB_METHOD == "nzbget":
            is_proper = True if endStatus == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        else:
            sickrage.LOGGER.error("Unknown NZB action specified in config: " +
                                  sickrage.NZB_METHOD)
            dlResult = False

    # TORRENTs can be sent to clients or saved to disk
    elif result.resultType == "torrent":
        # torrents are saved to disk when blackhole mode
        if sickrage.TORRENT_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        else:
            if not result.content and not result.url.startswith('magnet'):
                result.content = result.provider.getURL(result.url,
                                                        needBytes=True)

            if result.content or result.url.startswith('magnet'):
                client = getClientIstance(sickrage.TORRENT_METHOD)()
                dlResult = client.sendTORRENT(result)
            else:
                sickrage.LOGGER.warning("Torrent file content is empty")
                dlResult = False
    else:
        sickrage.LOGGER.error(
            "Unknown result type, unable to download it (%r)" %
            result.resultType)
        dlResult = False

    if not dlResult:
        return False

    if sickrage.USE_FAILED_DOWNLOADS:
        FailedHistory.logSnatch(result)

    notifications.message('Episode snatched', result.name)

    History.logSnatch(result)

    # don't notify when we re-download an episode
    sql_l = []
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if isFirstBestMatch(result):
                curEpObj.status = Quality.compositeStatus(
                    SNATCHED_BEST, result.quality)
            else:
                curEpObj.status = Quality.compositeStatus(
                    endStatus, result.quality)

            sql_l.append(curEpObj.get_sql())

        if curEpObj.status not in Quality.DOWNLOADED:
            try:
                notify_snatch(
                    curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN') +
                    " from " + result.provider.name)
            except:
                sickrage.LOGGER.debug("Failed to send snatch notification")

            trakt_data.append((curEpObj.season, curEpObj.episode))

    data = sickrage.NOTIFIERS.trakt_notifier.trakt_episode_data_generate(
        trakt_data)

    if sickrage.USE_TRAKT and sickrage.TRAKT_SYNC_WATCHLIST:
        sickrage.LOGGER.debug("Add episodes, showid: indexerid " +
                              str(result.show.indexerid) + ", Title " +
                              str(result.show.name) + " to Traktv Watchlist")
        if data:
            sickrage.NOTIFIERS.trakt_notifier.update_watchlist(
                result.show, data_episode=data, update="add")

    if len(sql_l) > 0:
        main_db.MainDB().mass_action(sql_l)

    return True
Example #20
0
 def get(self, *args, **kwargs):
     History().clear()
     sickrage.app.alerts.message(_('History cleared'))
     return self.redirect("/history/")
Example #21
0
def snatchEpisode(result, endStatus=SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param endStatus: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.srCore.srConfig.ALLOW_HIGH_PRIORITY:
        # if it aired recently make it high priority
        for curEp in result.episodes:
            if date.today() - curEp.airdate <= timedelta(days=7):
                result.priority = 1

    if re.search(r'(^|[\. _-])(proper|repack)([\. _-]|$)', result.name, re.I) is not None:
        endStatus = SNATCHED_PROPER

    if result.url.startswith('magnet') or result.url.endswith('torrent'):
        result.resultType = 'torrent'

    dlResult = False
    if result.resultType in ("nzb", "nzbdata"):
        if sickrage.srCore.srConfig.NZB_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        elif sickrage.srCore.srConfig.NZB_METHOD == "sabnzbd":
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.srCore.srConfig.NZB_METHOD == "nzbget":
            is_proper = True if endStatus == SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        else:
            sickrage.srCore.srLogger.error(
                "Unknown NZB action specified in config: " + sickrage.srCore.srConfig.NZB_METHOD)
    elif result.resultType == "torrent":
        if sickrage.srCore.srConfig.TORRENT_METHOD == "blackhole":
            dlResult = _downloadResult(result)
        else:
            if all([not result.content, not result.url.startswith('magnet:')]):
                result.content = sickrage.srCore.srWebSession.get(result.url).content

            if any([result.content, result.url.startswith('magnet:')]):
                # add public trackers to magnet url for non-private torrent providers
                if not result.provider.private and result.url.startswith('magnet:'):
                    result.url += '&tr='.join(
                        [x.strip() for x in sickrage.srCore.srConfig.TORRENT_TRACKERS.split(',') if x.strip()])

                client = getClientIstance(sickrage.srCore.srConfig.TORRENT_METHOD)()
                dlResult = client.sendTORRENT(result)
            else:
                sickrage.srCore.srLogger.warning("Torrent file content is empty")
    else:
        sickrage.srCore.srLogger.error("Unknown result type, unable to download it (%r)" % result.resultType)

    # no download results found
    if not dlResult:
        return False

    if sickrage.srCore.srConfig.USE_FAILED_DOWNLOADS:
        FailedHistory.logSnatch(result)

    sickrage.srCore.srNotifications.message('Episode snatched', result.name)

    History.logSnatch(result)

    # don't notify when we re-download an episode
    sql_l = []
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if isFirstBestMatch(result):
                curEpObj.status = Quality.compositeStatus(SNATCHED_BEST, result.quality)
            else:
                curEpObj.status = Quality.compositeStatus(endStatus, result.quality)

            sql_q = curEpObj.saveToDB(False)
            if sql_q:
                sql_l.append(sql_q)

        if curEpObj.status not in Quality.DOWNLOADED:
            try:
                srNotifiers.notify_snatch(
                    curEpObj._format_pattern('%SN - %Sx%0E - %EN - %QN') + " from " + result.provider.name)
            except:
                sickrage.srCore.srLogger.debug("Failed to send snatch notification")

            trakt_data.append((curEpObj.season, curEpObj.episode))

    data = sickrage.srCore.notifiersDict.trakt_notifier.trakt_episode_data_generate(trakt_data)

    if sickrage.srCore.srConfig.USE_TRAKT and sickrage.srCore.srConfig.TRAKT_SYNC_WATCHLIST:
        sickrage.srCore.srLogger.debug(
            "Add episodes, showid: indexerid " + str(result.show.indexerid) + ", Title " + str(
                result.show.name) + " to Traktv Watchlist")
        if data:
            sickrage.srCore.notifiersDict.trakt_notifier.update_watchlist(result.show, data_episode=data, update="add")

    if len(sql_l) > 0:
        main_db.MainDB().mass_upsert(sql_l)
        del sql_l  # cleanup

    return True
Example #22
0
    def download_subtitles(self, show_id, season, episode, session=None):
        show_object = find_show(show_id, session=session)
        episode_object = show_object.get_episode(season, episode)

        existing_subtitles = episode_object.subtitles
        if not isinstance(existing_subtitles, list):
            existing_subtitles = []

        # First of all, check if we need subtitles
        languages = self.get_needed_languages(existing_subtitles)
        if not languages:
            sickrage.app.log.debug('%s: No missing subtitles for S%02dE%02d' %
                                   (show_id, season, episode))
            return existing_subtitles, None

        subtitles_path = self.get_subtitles_path(episode_object.location)
        video_path = episode_object.location
        providers = self.getEnabledServiceList()

        video = self.get_video(video_path,
                               subtitles_path=subtitles_path,
                               episode_object=episode_object)
        if not video:
            sickrage.app.log.debug(
                '%s: Exception caught in subliminal.scan_video for S%02dE%02d'
                % (show_id, season, episode))
            return existing_subtitles, None

        provider_configs = {
            'addic7ed': {
                'username': sickrage.app.config.addic7ed_user,
                'password': sickrage.app.config.addic7ed_pass
            },
            'itasa': {
                'username': sickrage.app.config.itasa_user,
                'password': sickrage.app.config.itasa_pass
            },
            'legendastv': {
                'username': sickrage.app.config.legendastv_user,
                'password': sickrage.app.config.legendastv_pass
            },
            'opensubtitles': {
                'username': sickrage.app.config.opensubtitles_user,
                'password': sickrage.app.config.opensubtitles_pass
            }
        }

        pool = subliminal.ProviderPool(providers=providers,
                                       provider_configs=provider_configs)

        try:
            subtitles_list = pool.list_subtitles(video, languages)
            if not subtitles_list:
                sickrage.app.log.debug(
                    '%s: No subtitles found for S%02dE%02d on any provider' %
                    (show_id, season, episode))
                return existing_subtitles, None

            found_subtitles = pool.download_best_subtitles(
                subtitles_list,
                video,
                languages=languages,
                hearing_impaired=sickrage.app.config.
                subtitles_hearing_impaired,
                only_one=not sickrage.app.config.subtitles_multi)

            save_subtitles(video,
                           found_subtitles,
                           directory=subtitles_path,
                           single=not sickrage.app.config.subtitles_multi)

            if not sickrage.app.config.embedded_subtitles_all and sickrage.app.config.subtitles_extra_scripts and video_path.endswith(
                ('.mkv', '.mp4')):
                self.run_subs_extra_scripts(
                    episode_object,
                    found_subtitles,
                    video,
                    single=not sickrage.app.config.subtitles_multi)

            new_subtitles = sorted({
                subtitle.language.opensubtitles
                for subtitle in found_subtitles
            })
            current_subtitles = sorted({
                subtitle
                for subtitle in new_subtitles + existing_subtitles if subtitle
            })
            if not sickrage.app.config.subtitles_multi and len(
                    found_subtitles) == 1:
                new_code = found_subtitles[0].language.opensubtitles
                if new_code not in existing_subtitles:
                    current_subtitles.remove(new_code)
                current_subtitles.append('und')

        except Exception as e:
            sickrage.app.log.error(
                "Error occurred when downloading subtitles for {}: {}".format(
                    video_path, e))
            return existing_subtitles, None

        if sickrage.app.config.subtitles_history:
            for subtitle in found_subtitles:
                sickrage.app.log.debug(
                    'history.logSubtitle %s, %s' %
                    (subtitle.provider_name, subtitle.language.opensubtitles))
                History.log_subtitle(show_id, season, episode,
                                     episode_object.status, subtitle)

        return current_subtitles, new_subtitles
Example #23
0
def snatch_episode(result, end_status=EpisodeStatus.SNATCHED):
    """
    Contains the internal logic necessary to actually "snatch" a result that
    has been found.

    :param result: SearchResult instance to be snatched.
    :param end_status: the episode status that should be used for the episode object once it's snatched.
    :return: boolean, True on success
    """

    if result is None:
        return False

    show_object = find_show(result.series_id, result.series_provider_id)

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    if sickrage.app.config.general.allow_high_priority:
        # if it aired recently make it high priority
        for episode_number in result.episodes:
            if date.today() - show_object.get_episode(result.season, episode_number).airdate <= timedelta(days=7):
                result.priority = 1

    if re.search(r'(^|[. _-])(proper|repack)([. _-]|$)', result.name, re.I) is not None:
        end_status = EpisodeStatus.SNATCHED_PROPER

    # get result content
    result.content = result.provider.get_content(result.url)

    dlResult = False
    if result.provider_type in (SearchProviderType.NZB, SearchProviderType.NZBDATA):
        if sickrage.app.config.general.nzb_method == NzbMethod.BLACKHOLE:
            dlResult = result.provider.download_result(result)
        elif sickrage.app.config.general.nzb_method == NzbMethod.SABNZBD:
            dlResult = SabNZBd.sendNZB(result)
        elif sickrage.app.config.general.nzb_method == NzbMethod.NZBGET:
            is_proper = True if end_status == EpisodeStatus.SNATCHED_PROPER else False
            dlResult = NZBGet.sendNZB(result, is_proper)
        elif sickrage.app.config.general.nzb_method == NzbMethod.DOWNLOAD_STATION:
            client = get_client_instance(sickrage.app.config.general.nzb_method.value, client_type='nzb')()
            dlResult = client.sendNZB(result)
    elif result.provider_type in (SearchProviderType.TORRENT, SearchProviderType.TORZNAB):
        # add public trackers to torrent result
        if not result.provider.private:
            result = result.provider.add_trackers(result)

        if sickrage.app.config.general.torrent_method == TorrentMethod.BLACKHOLE:
            dlResult = result.provider.download_result(result)
        else:
            if any([result.content, result.url.startswith('magnet:')]):
                client = get_client_instance(sickrage.app.config.general.torrent_method.value, client_type='torrent')()
                dlResult = client.send_torrent(result)
            else:
                sickrage.app.log.warning("Torrent file content is empty")
    else:
        sickrage.app.log.error("Unknown result type, unable to download it (%r)" % result.provider_type.display_name)

    # no download results found
    if not dlResult:
        return False

    FailedHistory.log_snatch(result)
    History.log_snatch(result)

    sickrage.app.alerts.message(_('Episode snatched'), result.name)

    trakt_data = []
    for episode_number in result.episodes:
        episode_obj = show_object.get_episode(result.season, episode_number)

        if is_first_best_match(result):
            episode_obj.status = Quality.composite_status(EpisodeStatus.SNATCHED_BEST, result.quality)
        else:
            episode_obj.status = Quality.composite_status(end_status, result.quality)

        episode_obj.save()

        # don't notify when we re-download an episode
        if episode_obj.status not in EpisodeStatus.composites(EpisodeStatus.DOWNLOADED):
            try:
                NotificationProvider.mass_notify_snatch(episode_obj._format_pattern('%SN - %Sx%0E - %EN - %QN') + " from " + result.provider.name)
            except Exception:
                sickrage.app.log.debug("Failed to send snatch notification")

            trakt_data.append((episode_obj.season, episode_obj.episode))

    data = sickrage.app.notification_providers['trakt'].trakt_episode_data_generate(trakt_data)

    if sickrage.app.config.trakt.enable and sickrage.app.config.trakt.sync_watchlist:
        if data:
            sickrage.app.notification_providers['trakt'].update_watchlist(show_object, data_episode=data, update="add")

    return True