Example #1
0
    def move_torrent(info_hash, release_names):
        """Move torrent to a given seeding folder after PP."""
        if release_names:
            # Log 'release' or 'releases'
            s = 's' if len(release_names) > 1 else ''
            release_names = ', '.join(release_names)
        else:
            s = ''
            release_names = 'N/A'

        log.debug('Trying to move torrent after post-processing')
        client = torrent.get_client_class(app.TORRENT_METHOD)()
        torrent_moved = False
        try:
            torrent_moved = client.move_torrent(info_hash)
        except AttributeError:
            log.warning("Your client doesn't support moving torrents to new location")
            return False

        if torrent_moved:
            log.debug("Moved torrent for release{s} '{release}' with hash: {hash} to: '{path}'", {
                      'release': release_names, 'hash': info_hash, 'path': app.TORRENT_SEED_LOCATION, 's': s})
            return True
        else:
            log.warning("Couldn't move torrent for release{s} '{release}' with hash: {hash} to: '{path}'. "
                        'Please check logs.', {'release': release_names, 'hash': info_hash, 'path': app.TORRENT_SEED_LOCATION, 's': s})
            return False
Example #2
0
    def move_torrent(info_hash, release_names):
        """Move torrent to a given seeding folder after PP."""
        if release_names:
            # Log 'release' or 'releases'
            s = 's' if len(release_names) > 1 else ''
            release_names = ', '.join(release_names)
        else:
            s = ''
            release_names = 'N/A'

        logger.log('Trying to move torrent after post-processing', logger.DEBUG)
        client = torrent.get_client_class(app.TORRENT_METHOD)()
        torrent_moved = False
        try:
            torrent_moved = client.move_torrent(info_hash)
        except AttributeError:
            logger.log("Your client doesn't support moving torrents to new location", logger.WARNING)
            return False

        if torrent_moved:
            logger.log("Moved torrent for release{s} '{release}' with hash: {hash} to: '{path}'".format
                       (release=release_names, hash=info_hash, path=app.TORRENT_SEED_LOCATION, s=s),
                       logger.DEBUG)
            return True
        else:
            logger.log("Couldn't move torrent for release{s} '{release}' with hash: {hash} to: '{path}'. "
                       "Please check logs.".format(release=release_names, hash=info_hash, s=s,
                                                   path=app.TORRENT_SEED_LOCATION), logger.WARNING)
            return False
Example #3
0
    def move_torrent(info_hash, release_names):
        """Move torrent to a given seeding folder after PP."""
        if not os.path.isdir(app.TORRENT_SEED_LOCATION):
            logger.log(
                'Not possible to move torrent after post-processing because seed location is invalid',
                logger.WARNING)
            return False

        if release_names:
            # Log 'release' or 'releases'
            s = 's' if len(release_names) > 1 else ''
            release_names = ', '.join(release_names)
        else:
            s = ''
            release_names = 'N/A'

        logger.log('Trying to move torrent after post-processing',
                   logger.DEBUG)
        client = torrent.get_client_class(app.TORRENT_METHOD)()

        try:
            torrent_moved = client.move_torrent(info_hash)
        except (requests.exceptions.RequestException,
                socket.gaierror) as error:
            logger.log(
                "Couldn't connect to client to move torrent for release{s} '{release}' with hash: {hash} "
                "to: '{path}'. Error: {error}".format(
                    release=release_names,
                    hash=info_hash,
                    error=error.message,
                    path=app.TORRENT_SEED_LOCATION,
                    s=s), logger.WARNING)
            return False
        except AttributeError:
            logger.log(
                "Your client doesn't support moving torrents to new location",
                logger.WARNING)
            return False

        if torrent_moved:
            logger.log(
                "Moved torrent for release{s} '{release}' with hash: {hash} to: '{path}'"
                .format(release=release_names,
                        hash=info_hash,
                        path=app.TORRENT_SEED_LOCATION,
                        s=s), logger.DEBUG)
            return True
        else:
            logger.log(
                "Couldn't move torrent for release{s} '{release}' with hash: {hash} to: '{path}'. "
                "Please check logs.".format(release=release_names,
                                            hash=info_hash,
                                            s=s,
                                            path=app.TORRENT_SEED_LOCATION),
                logger.WARNING)
            return False
Example #4
0
def test_get_client_class(p):
    # Given
    client_name = p['client']
    expected = p['expected']

    # When
    actual = sut.get_client_class(client_name)

    # Then
    assert expected == actual
Example #5
0
    def run(self, force=False):
        """Start the Download Handler Thread."""
        if self.amActive:
            log.debug(
                'Download handler is still running, not starting it again')
            return

        self.amActive = True
        # Push an update to any open Web UIs through the WebSocket
        ws.Message('QueueItemUpdate', self._to_json).push()

        try:
            if app.USE_TORRENTS and app.TORRENT_METHOD != 'blackhole':
                torrent_client = torrent.get_client_class(app.TORRENT_METHOD)()
                self._update_status(torrent_client)
                self._check_postprocess(torrent_client)
                self._check_torrent_ratio(torrent_client)
                self._clean(torrent_client)
        except NotImplementedError:
            log.warning(
                'Feature not currently implemented for this torrent client({torrent_client})',
                torrent_client=app.TORRENT_METHOD)
        except (RequestException, DownloadClientConnectionException) as error:
            log.warning(
                'Unable to connect to {torrent_client}. Error: {error}',
                torrent_client=app.TORRENT_METHOD,
                error=error)
        except Exception as error:
            log.exception(
                'Exception while checking torrent status. with error: {error}',
                {'error': error})

        try:
            if app.USE_NZBS and app.NZB_METHOD != 'blackhole':
                nzb_client = sab if app.NZB_METHOD == 'sabnzbd' else nzbget
                self._update_status(nzb_client)
                self._check_postprocess(nzb_client)
                self._clean(nzb_client)
        except NotImplementedError:
            log.warning(
                'Feature not currently implemented for this torrent client({torrent_client})',
                torrent_client=app.TORRENT_METHOD)
        except (RequestException, DownloadClientConnectionException) as error:
            log.warning(
                'Unable to connect to {torrent_client}. Error: {error}',
                torrent_client=app.TORRENT_METHOD,
                error=error)
        except Exception as error:
            log.exception(
                'Exception while checking torrent status. with error: {error}',
                {'error': error})

        self.amActive = False
        # Push an update to any open Web UIs through the WebSocket
        ws.Message('QueueItemUpdate', self._to_json).push()
Example #6
0
    def run(self, force=False):
        """Start the Torrent Checker Thread."""
        if not (app.USE_TORRENTS and app.REMOVE_FROM_CLIENT):
            return

        self.amActive = True

        try:
            client = torrent.get_client_class(app.TORRENT_METHOD)()
            client.remove_ratio_reached()
        except Exception as e:
            logger.debug('Failed to check torrent status. Error: {error}', error=e)

        self.amActive = False
Example #7
0
    def run(self, force=False):
        """Start the Torrent Checker Thread."""
        self.amActive = True

        try:
            client = torrent.get_client_class(app.TORRENT_METHOD)()
            client.remove_ratio_reached()
        except NotImplementedError:
            logger.warning(
                'Feature not currently implemented for this torrent client({torrent_client})',
                torrent_client=app.TORRENT_METHOD)
        except Exception:
            logger.exception('Exception while checking torrent status.')
        finally:
            self.amActive = False
Example #8
0
    def testTorrent(torrent_method=None,
                    host=None,
                    username=None,
                    password=None):
        # @TODO: Move this to the validation section of each PATCH/PUT method for torrents
        host = config.clean_url(host)

        try:
            client = torrent.get_client_class(torrent_method)

            _, acces_msg = client(host, username,
                                  password).test_authentication()
        except Exception as error:
            logger.log(
                'Error while testing {torrent} connection: {error}'.format(
                    torrent=torrent_method or 'torrent', error=error),
                logger.WARNING)
            return 'Error while testing connection. Check warning logs.'

        return acces_msg
Example #9
0
def snatch_episode(result):
    """
    Snatch a result that has been found.

    :param result: SearchResult instance to be snatched.
    :return: boolean, True on success
    """
    if result is None:
        return False

    result.priority = 0  # -1 = low, 0 = normal, 1 = high
    is_proper = False

    if app.ALLOW_HIGH_PRIORITY:
        # if it aired recently make it high priority
        for cur_ep in result.episodes:
            if datetime.date.today() - cur_ep.airdate <= datetime.timedelta(
                    days=7):
                result.priority = 1

    if result.proper_tags:
        log.debug(u'Found proper tags for {0}. Snatching as PROPER',
                  result.name)
        is_proper = True
        end_status = SNATCHED_PROPER
    else:
        end_status = SNATCHED

    # Binsearch.info requires you to download the nzb through a post.
    if result.provider.kind() == 'BinSearchProvider':
        result.result_type = 'nzbdata'
        nzb_data = result.provider.download_nzb_for_post(result)
        result.extra_info.append(nzb_data)

        if not nzb_data:
            log.warning(
                'Error trying to get the nzb data from provider binsearch, no data returned'
            )
            return False

    # NZBs can be sent straight to SAB or saved to disk
    if result.result_type in (u'nzb', u'nzbdata'):
        if app.NZB_METHOD == u'blackhole':
            result_downloaded = _download_result(result)
        elif app.NZB_METHOD == u'sabnzbd':
            result_downloaded = sab.send_nzb(result)
        elif app.NZB_METHOD == u'nzbget':
            result_downloaded = nzbget.sendNZB(result, is_proper)
        else:
            log.error(u'Unknown NZB action specified in config: {0}',
                      app.NZB_METHOD)
            result_downloaded = False

    # Torrents can be sent to clients or saved to disk
    elif result.result_type == u'torrent':
        # torrents are saved to disk when blackhole mode
        if app.TORRENT_METHOD == u'blackhole':
            result_downloaded = _download_result(result)
        else:
            if not result.content and not result.url.startswith(u'magnet:'):
                if result.provider.login():
                    if result.provider.kind() == 'TorznabProvider':
                        result.url = result.provider.get_redirect_url(
                            result.url)

                    if not result.url.startswith(u'magnet:'):
                        result.content = result.provider.get_content(
                            result.url)

            if result.content or result.url.startswith(u'magnet:'):
                client = torrent.get_client_class(app.TORRENT_METHOD)()
                result_downloaded = client.send_torrent(result)
            else:
                log.warning(u'Torrent file content is empty: {0}', result.name)
                result_downloaded = False
    else:
        log.error(u'Unknown result type, unable to download it: {0!r}',
                  result.result_type)
        result_downloaded = False

    if not result_downloaded:
        return False

    if app.USE_FAILED_DOWNLOADS:
        failed_history.log_snatch(result)

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

    history.log_snatch(result)

    # don't notify when we re-download an episode
    sql_l = []
    trakt_data = []
    for curEpObj in result.episodes:
        with curEpObj.lock:
            if is_first_best_match(result):
                curEpObj.status = SNATCHED_BEST
                curEpObj.quality = result.quality
            else:
                curEpObj.status = end_status
                curEpObj.quality = result.quality
            # Reset all others fields to the snatched status
            # New snatch by default doesn't have nfo/tbn
            curEpObj.hasnfo = False
            curEpObj.hastbn = False

            # We can't reset location because we need to know what we are replacing
            # curEpObj.location = ''

            # Release name and group are parsed in PP
            curEpObj.release_name = ''
            curEpObj.release_group = ''

            # Need to reset subtitle settings because it's a different file
            curEpObj.subtitles = list()
            curEpObj.subtitles_searchcount = 0
            curEpObj.subtitles_lastsearch = u'0001-01-01 00:00:00'

            # Need to store the correct is_proper. Not use the old one
            curEpObj.is_proper = True if result.proper_tags else False
            curEpObj.version = 0

            curEpObj.manually_searched = result.manually_searched

            sql_l.append(curEpObj.get_sql())

        if curEpObj.status != common.DOWNLOADED:
            notify_message = curEpObj.formatted_filename(
                u'%SN - %Sx%0E - %EN - %QN')
            if all([
                    app.SEEDERS_LEECHERS_IN_NOTIFY, result.seeders
                    not in (-1, None), result.leechers not in (-1, None)
            ]):
                notifiers.notify_snatch(
                    u'{0} with {1} seeders and {2} leechers from {3}'.format(
                        notify_message, result.seeders, result.leechers,
                        result.provider.name), is_proper)
            else:
                notifiers.notify_snatch(
                    u'{0} from {1}'.format(notify_message,
                                           result.provider.name), is_proper)

            if app.USE_TRAKT and app.TRAKT_SYNC_WATCHLIST:
                trakt_data.append((curEpObj.season, curEpObj.episode))
                log.info(
                    u'Adding {0} {1} to Trakt watchlist',
                    result.series.name,
                    episode_num(curEpObj.season, curEpObj.episode),
                )

    if trakt_data:
        data_episode = notifiers.trakt_notifier.trakt_episode_data_generate(
            trakt_data)
        if data_episode:
            notifiers.trakt_notifier.update_watchlist(
                result.series, data_episode=data_episode, update=u'add')

    if sql_l:
        main_db_con = db.DBConnection()
        main_db_con.mass_action(sql_l)

    return True