Example #1
0
def completed_media_task():
    nefarious_settings = NefariousSettings.get()
    transmission_client = get_transmission_client(nefarious_settings)

    incomplete_kwargs = dict(collected=False,
                             transmission_torrent_hash__isnull=False)

    movies = WatchMovie.objects.filter(**incomplete_kwargs)
    tv_seasons = WatchTVSeason.objects.filter(**incomplete_kwargs)
    tv_episodes = WatchTVEpisode.objects.filter(**incomplete_kwargs)

    incomplete_media = list(movies) + list(tv_episodes) + list(tv_seasons)

    for media in incomplete_media:
        try:
            torrent = transmission_client.get_torrent(
                media.transmission_torrent_hash)
            if torrent.progress == 100:
                logging.info('Media completed: {}'.format(media))
                media.collected = True
                media.collected_date = datetime.utcnow()
                media.save()
        except KeyError:
            logging.info(
                "Media's torrent no longer present, removing reference: {}".
                format(media))
            media.transmission_torrent_hash = None
            media.save()
Example #2
0
    def blacklist_auto_retry(self, request, pk):
        watch_media = self.get_object()
        nefarious_settings = NefariousSettings.get()

        # add to blacklist
        logger_foreground.info('Blacklisting {}'.format(
            watch_media.transmission_torrent_hash))
        TorrentBlacklist.objects.get_or_create(
            hash=watch_media.transmission_torrent_hash,
            defaults=dict(name=str(watch_media), ))

        # unset previous details
        del_transmission_torrent_hash = watch_media.transmission_torrent_hash
        watch_media.transmission_torrent_hash = None
        watch_media.collected = False
        watch_media.collected_date = None
        watch_media.save()

        # re-queue search
        self._watch_media_task(watch_media_id=watch_media.id)

        # remove torrent and delete data
        logger_foreground.info('Removing blacklisted torrent hash: {}'.format(
            del_transmission_torrent_hash))
        transmission_client = get_transmission_client(
            nefarious_settings=nefarious_settings)
        transmission_client.remove_torrent([del_transmission_torrent_hash],
                                           delete_data=True)

        return Response(self.serializer_class(watch_media).data)
Example #3
0
 def __init__(self, watch_media_id: int):
     self.nefarious_settings = NefariousSettings.get()
     self.tmdb_client = get_tmdb_client(self.nefarious_settings)
     self.transmission_client = get_transmission_client(
         self.nefarious_settings)
     self.watch_media = self._get_watch_media(watch_media_id)
     self.tmdb_media = self._get_tmdb_media()
Example #4
0
def completed_media_task():
    nefarious_settings = NefariousSettings.get()
    transmission_client = get_transmission_client(nefarious_settings)

    incomplete_kwargs = dict(collected=False, transmission_torrent_hash__isnull=False)

    movies = WatchMovie.objects.filter(**incomplete_kwargs)
    tv_seasons = WatchTVSeason.objects.filter(**incomplete_kwargs)
    tv_episodes = WatchTVEpisode.objects.filter(**incomplete_kwargs)

    incomplete_media = list(movies) + list(tv_episodes) + list(tv_seasons)

    for media in incomplete_media:
        try:
            torrent = transmission_client.get_torrent(media.transmission_torrent_hash)
        except KeyError:
            # media's torrent reference no longer exists so remove the reference
            logging.info("Media's torrent no longer present, removing reference: {}".format(media))
            media.transmission_torrent_hash = None
            media.save()
        else:
            # download is complete
            if torrent.progress == 100:

                # flag media as completed
                logging.info('Media completed: {}'.format(media))
                media.collected = True
                media.collected_date = datetime.utcnow()
                media.save()

                # special handling for tv seasons
                if isinstance(media, WatchTVSeason):

                    # mark season request complete
                    for season_request in WatchTVSeasonRequest.objects.filter(watch_tv_show=media.watch_tv_show, season_number=media.season_number):
                        season_request.collected = True
                        season_request.save()

                    # delete any individual episodes now that we have the whole season
                    for episode in WatchTVEpisode.objects.filter(watch_tv_show=media.watch_tv_show, season_number=media.season_number):
                        episode.delete()

                # rename the torrent file/path
                renamed_torrent_name = get_renamed_torrent(torrent, media)
                logging.info('Renaming torrent file from "{}" to "{}"'.format(torrent.name, renamed_torrent_name))
                transmission_client.rename_torrent_path(torrent.id, torrent.name, renamed_torrent_name)

                # move data from staging path to actual complete path
                dir_name = (
                    nefarious_settings.transmission_movie_download_dir if isinstance(media, WatchMovie)
                    else nefarious_settings.transmission_tv_download_dir
                )
                transmission_session = transmission_client.session_stats()
                move_to_path = os.path.join(
                    transmission_session.download_dir,
                    dir_name.lstrip('/'),
                )
                logging.info('Moving torrent data to "{}"'.format(move_to_path))
                torrent.move_data(move_to_path)
Example #5
0
 def perform_destroy(self, instance: WatchMediaBase):
     # delete transmission result, including data, if it still exists
     nefarious_settings = NefariousSettings.get()
     transmission_client = get_transmission_client(nefarious_settings)
     transmission_client.remove_torrent(
         [instance.transmission_torrent_hash],
         delete_data=True)  # fails silently
     super().perform_destroy(instance)
Example #6
0
def destroy_transmission_result(instance: WatchMediaBase):
    # delete transmission result, including data, if it still exists
    nefarious_settings = NefariousSettings.get()
    try:
        transmission_client = get_transmission_client(nefarious_settings)
        transmission_client.remove_torrent(
            [instance.transmission_torrent_hash], delete_data=True, timeout=10)
    except Exception as e:
        logging.warning(str(e))
        logging.warning('could not destroy torrent in transmission')
Example #7
0
    def get(self, request):
        nefarious_settings = NefariousSettings.get()
        transmission_client = get_transmission_client(nefarious_settings)

        watch_movies = request.query_params.getlist('watch_movies', [])
        watch_tv_shows = request.query_params.getlist('watch_tv_shows', [])

        results = []
        querysets = []

        # movies
        if watch_movies:
            querysets.append(WatchMovie.objects.filter(id__in=watch_movies))
        # tv shows
        if watch_tv_shows:
            querysets.append(
                WatchTVEpisode.objects.filter(
                    watch_tv_show__id__in=watch_tv_shows))
            querysets.append(
                WatchTVSeason.objects.filter(
                    watch_tv_show__id__in=watch_tv_shows))

        for qs in querysets:

            for media in qs:

                if isinstance(media, WatchTVSeason):
                    media_serializer = WatchTVSeasonSerializer
                elif isinstance(media, WatchTVEpisode):
                    media_serializer = WatchTVEpisodeSerializer
                else:
                    media_serializer = WatchMovieSerializer

                result = {
                    'watchMedia': media_serializer(media).data,
                }

                if media.transmission_torrent_hash:

                    try:
                        torrent = transmission_client.get_torrent(
                            media.transmission_torrent_hash)
                    except (KeyError, ValueError
                            ):  # torrent no longer exists or was invalid
                        pass
                    except Exception as e:
                        logger_foreground.error(str(e))
                        raise e
                    else:
                        result['torrent'] = TransmissionTorrentSerializer(
                            torrent).data

                results.append(result)

        return Response(results)
Example #8
0
 def perform_destroy(self, instance: WatchMediaBase):
     # delete transmission result, including data, if it still exists
     nefarious_settings = NefariousSettings.get()
     try:
         transmission_client = get_transmission_client(nefarious_settings)
         transmission_client.remove_torrent(
             [instance.transmission_torrent_hash], delete_data=True)
     except:
         logging.warning(
             'could not connect to transmission to delete the torrent')
     super().perform_destroy(instance)
Example #9
0
    def get(self, request):
        nefarious_settings = NefariousSettings.get()
        transmission_client = get_transmission_client(nefarious_settings)

        watch_movies = request.query_params.getlist('watch_movies')
        watch_tv_episodes = request.query_params.getlist('watch_tv_episodes')
        watch_tv_seasons = request.query_params.getlist('watch_tv_seasons')

        querysets = []
        torrents = []
        torrent_hashes = []

        # movies
        if watch_movies:
            querysets.append(WatchMovie.objects.filter(id__in=watch_movies))
        # tv episodes
        if watch_tv_episodes:
            querysets.append(
                WatchTVEpisode.objects.filter(id__in=watch_tv_episodes))
        # tv seasons
        if watch_tv_seasons:
            querysets.append(
                WatchTVSeason.objects.filter(id__in=watch_tv_seasons))

        for query in querysets:
            torrent_hashes += [
                media.transmission_torrent_hash for media in query
                if media.transmission_torrent_hash
            ]

        for torrent_hash in torrent_hashes:

            try:
                torrent = transmission_client.get_torrent(torrent_hash)
                torrents.append(torrent)
            except (KeyError,
                    ValueError):  # torrent no longer exists or was invalid
                continue
            except Exception as e:
                logging.error(str(e))
                raise e

        return Response(
            TransmissionTorrentSerializer(torrents, many=True).data)
Example #10
0
    def post(self, request):
        nefarious_settings = NefariousSettings.get()
        torrent = request.data.get('torrent')
        media_type = request.data.get('media_type', MEDIA_TYPE_TV)
        if not is_magnet_url(torrent):
            torrent = swap_jackett_host(torrent, nefarious_settings)

        if not torrent:
            return Response({
                'success': False,
                'error': 'Missing torrent link'
            })

        try:
            torrent = trace_torrent_url(torrent)
        except Exception as e:
            return Response({
                'success': False,
                'error': 'An unknown error occurred',
                'error_detail': str(e)
            })

        logging.info('adding torrent: {}'.format(torrent))

        # add torrent
        transmission_client = get_transmission_client(nefarious_settings)
        transmission_session = transmission_client.session_stats()

        if media_type == MEDIA_TYPE_MOVIE:
            download_dir = os.path.join(
                transmission_session.download_dir,
                nefarious_settings.transmission_movie_download_dir.lstrip('/'))
        else:
            download_dir = os.path.join(
                transmission_session.download_dir,
                nefarious_settings.transmission_tv_download_dir.lstrip('/'))

        transmission_client.add_torrent(
            torrent,
            paused=True,
            download_dir=download_dir,
        )

        return Response({'success': True})
Example #11
0
def completed_media_task():
    nefarious_settings = NefariousSettings.get()
    transmission_client = get_transmission_client(nefarious_settings)

    incomplete_kwargs = dict(collected=False,
                             transmission_torrent_hash__isnull=False)

    movies = WatchMovie.objects.filter(**incomplete_kwargs)
    tv_seasons = WatchTVSeason.objects.filter(**incomplete_kwargs)
    tv_episodes = WatchTVEpisode.objects.filter(**incomplete_kwargs)

    incomplete_media = list(movies) + list(tv_episodes) + list(tv_seasons)

    for media in incomplete_media:
        try:
            torrent = transmission_client.get_torrent(
                media.transmission_torrent_hash)
        except KeyError:
            logging.info(
                "Media's torrent no longer present, removing reference: {}".
                format(media))
            media.transmission_torrent_hash = None
            media.save()
        else:
            if torrent.progress == 100:
                logging.info('Media completed: {}'.format(media))
                media.collected = True
                media.collected_date = datetime.utcnow()
                media.save()

                # if season is complete, mark season request complete
                if isinstance(media, WatchTVSeason):
                    for season_request in WatchTVSeasonRequest.objects.filter(
                            watch_tv_show=media.watch_tv_show,
                            season_number=media.season_number):
                        season_request.collected = True
                        season_request.save()
Example #12
0
    def post(self, request):
        result = {
            'success': True,
        }
        nefarious_settings = NefariousSettings.get()

        tmdb_media = request.data.get('tmdb_media', {})
        torrent_info = request.data.get('torrent', {})
        torrent_url = torrent_info.get('MagnetUri') or torrent_info.get('Link')

        if not torrent_url:
            return Response({
                'success': False,
                'error': 'Missing torrent link'
            })

        media_type = request.data.get('media_type', MEDIA_TYPE_TV)

        # validate tv
        if media_type == MEDIA_TYPE_TV:
            if 'season_number' not in request.data:
                return Response({
                    'success': False,
                    'error': 'Missing season_number'
                })

        if not is_magnet_url(torrent_url):
            torrent_url = swap_jackett_host(torrent_url, nefarious_settings)

        try:
            torrent_url = trace_torrent_url(torrent_url)
        except Exception as e:
            return Response({
                'success': False,
                'error': 'An unknown error occurred',
                'error_detail': str(e)
            })

        logger_foreground.info('adding torrent: {}'.format(torrent_url))

        # add torrent
        transmission_client = get_transmission_client(nefarious_settings)
        transmission_session = transmission_client.session_stats()

        tmdb = get_tmdb_client(nefarious_settings)

        # set download paths and associate torrent with watch instance
        if media_type == MEDIA_TYPE_MOVIE:
            tmdb_request = tmdb.Movies(tmdb_media['id'])
            tmdb_movie = tmdb_request.info()
            watch_media = WatchMovie(
                user=request.user,
                tmdb_movie_id=tmdb_movie['id'],
                name=tmdb_movie['title'],
                poster_image_url=nefarious_settings.get_tmdb_poster_url(
                    tmdb_movie['poster_path']),
                release_date=parse_date(tmdb_movie['release_date'] or ''),
            )
            watch_media.save()
            download_dir = os.path.join(
                transmission_session.download_dir,
                nefarious_settings.transmission_movie_download_dir.lstrip('/'))
            result['watch_movie'] = WatchMovieSerializer(watch_media).data
        else:
            tmdb_request = tmdb.TV(tmdb_media['id'])
            tmdb_show = tmdb_request.info()

            watch_tv_show, _ = WatchTVShow.objects.get_or_create(
                tmdb_show_id=tmdb_show['id'],
                defaults=dict(
                    user=request.user,
                    name=tmdb_show['name'],
                    poster_image_url=nefarious_settings.get_tmdb_poster_url(
                        tmdb_show['poster_path']),
                ))

            result['watch_tv_show'] = WatchTVShowSerializer(watch_tv_show).data

            # single episode
            if 'episode_number' in request.data:
                tmdb_request = tmdb.TV_Episodes(tmdb_media['id'],
                                                request.data['season_number'],
                                                request.data['episode_number'])
                tmdb_episode = tmdb_request.info()
                watch_media = WatchTVEpisode(
                    user=request.user,
                    watch_tv_show=watch_tv_show,
                    tmdb_episode_id=tmdb_episode['id'],
                    season_number=request.data['season_number'],
                    episode_number=request.data['episode_number'],
                    release_date=parse_date(tmdb_episode['air_date'] or ''))
                watch_media.save()
                result['watch_tv_episode'] = WatchTVEpisodeSerializer(
                    watch_media).data
            # entire season
            else:
                season_result = tmdb.TV_Seasons(tmdb_show['id'],
                                                request.data['season_number'])
                season_data = season_result.info()
                # create the season request
                watch_tv_season_request, _ = WatchTVSeasonRequest.objects.get_or_create(
                    watch_tv_show=watch_tv_show,
                    season_number=request.data['season_number'],
                    defaults=dict(
                        user=request.user,
                        collected=
                        True,  # set collected since we're directly downloading a torrent
                        release_date=parse_date(season_data['air_date']
                                                or '')),
                )
                # create the actual watch season instance
                watch_media = WatchTVSeason(
                    user=request.user,
                    watch_tv_show=watch_tv_show,
                    season_number=request.data['season_number'],
                    release_date=parse_date(season_data['air_date'] or ''))
                watch_media.save()

                # return the season request vs the watch instance
                result[
                    'watch_tv_season_request'] = WatchTVSeasonRequestSerializer(
                        watch_tv_season_request).data

            download_dir = os.path.join(
                transmission_session.download_dir,
                nefarious_settings.transmission_tv_download_dir.lstrip('/'))

        torrent = transmission_client.add_torrent(
            torrent_url,
            paused=settings.DEBUG,
            download_dir=download_dir,
        )
        watch_media.transmission_torrent_hash = torrent.hashString
        watch_media.save()

        return Response(result)
Example #13
0
def verify_settings_transmission(nefarious_settings: NefariousSettings):
    # verify transmission
    try:
        get_transmission_client(nefarious_settings)
    except TransmissionError:
        raise Exception('Could not connect to transmission')
Example #14
0
def completed_media_task():
    nefarious_settings = NefariousSettings.get()
    transmission_client = get_transmission_client(nefarious_settings)

    incomplete_kwargs = dict(collected=False,
                             transmission_torrent_hash__isnull=False)

    movies = WatchMovie.objects.filter(**incomplete_kwargs)
    tv_seasons = WatchTVSeason.objects.filter(**incomplete_kwargs)
    tv_episodes = WatchTVEpisode.objects.filter(**incomplete_kwargs)

    incomplete_media = list(movies) + list(tv_episodes) + list(tv_seasons)

    for media in incomplete_media:
        try:
            torrent = transmission_client.get_torrent(
                media.transmission_torrent_hash)
        except KeyError:
            # media's torrent reference no longer exists so remove the reference
            logging.info(
                "Media's torrent no longer present, removing reference: {}".
                format(media))
            media.transmission_torrent_hash = None
            media.save()
        else:
            # download is complete
            if torrent.progress == 100:

                # flag media as completed
                logging.info('Media completed: {}'.format(media))
                media.collected = True
                media.collected_date = datetime.utcnow()
                media.save()

                # special handling for tv seasons
                if isinstance(media, WatchTVSeason):

                    # mark season request complete
                    for season_request in WatchTVSeasonRequest.objects.filter(
                            watch_tv_show=media.watch_tv_show,
                            season_number=media.season_number):
                        season_request.collected = True
                        season_request.save()

                # get the sub path (ie. "movies/", "tv/') so we can move the data from staging
                sub_path = (nefarious_settings.transmission_movie_download_dir
                            if isinstance(media, WatchMovie) else
                            nefarious_settings.transmission_tv_download_dir
                            ).lstrip('/')

                # get the path and updated name for the data
                new_path, new_name = get_media_new_path_and_name(
                    media, torrent.name,
                    len(torrent.files()) == 1)

                # move the data
                transmission_session = transmission_client.session_stats()
                move_to_path = os.path.join(
                    transmission_session.download_dir,
                    sub_path,
                    new_path or '',
                )
                logging.info(
                    'Moving torrent data to "{}"'.format(move_to_path))
                torrent.move_data(move_to_path)

                # rename the data
                logging.info('Renaming torrent file from "{}" to "{}"'.format(
                    torrent.name, new_name))
                transmission_client.rename_torrent_path(
                    torrent.id, torrent.name, new_name)

                # send websocket message media was updated
                media_type, data = websocket.get_media_type_and_serialized_watch_media(
                    media)
                websocket.send_message(websocket.ACTION_UPDATED, media_type,
                                       data)

                # send complete message through webhook
                webhook.send_message('{} was downloaded'.format(media))
Example #15
0
    def fetch(self):
        logger_background.info('Processing request to watch {}'.format(
            self.watch_media))
        valid_search_results = []
        search = self._get_search_results()

        # save this attempt date
        self.watch_media.last_attempt_date = datetime.utcnow()
        self.watch_media.save()

        if search.ok:

            for result in search.results:
                if self.is_match(result['Title']):
                    valid_search_results.append(result)
                else:
                    logger_background.info('Not matched: {}'.format(
                        result['Title']))

            if valid_search_results:

                # trace the "torrent url" (sometimes magnet) in each valid result
                valid_search_results = self._results_with_valid_urls(
                    valid_search_results)

                while valid_search_results:

                    logger_background.info('Valid Search Results: {}'.format(
                        len(valid_search_results)))

                    # find the torrent result with the highest weight (i.e seeds)
                    best_result = self._get_best_torrent_result(
                        valid_search_results)

                    transmission_client = get_transmission_client(
                        self.nefarious_settings)
                    transmission_session = transmission_client.session_stats()

                    # add to transmission
                    torrent = transmission_client.add_torrent(
                        best_result['torrent_url'],
                        paused=
                        True,  # start paused to we can verify if the torrent has been blacklisted
                        download_dir=self._get_download_dir(
                            transmission_session),
                    )

                    # verify it's not blacklisted and save & start this torrent
                    if not TorrentBlacklist.objects.filter(
                            hash=torrent.hashString).exists():
                        logger_background.info('Adding torrent for {}'.format(
                            self.tmdb_media[self._get_tmdb_title_key()]))
                        logger_background.info(
                            'Added torrent {} with {} seeders'.format(
                                best_result['Title'], best_result['Seeders']))
                        logger_background.info(
                            'Starting torrent id: {} and hash {}'.format(
                                torrent.id, torrent.hashString))

                        # save torrent details on our watch instance
                        self._save_torrent_details(torrent)

                        # start the torrent
                        if not settings.DEBUG:
                            torrent.start()
                        return True
                    else:
                        # remove the blacklisted/paused torrent and continue to the next result
                        logger_background.info(
                            'BLACKLISTED: {} ({}) - trying next best result'.
                            format(best_result['Title'], torrent.hashString))
                        transmission_client.remove_torrent([torrent.id])
                        valid_search_results.remove(best_result)
                        continue
            else:
                logger_background.info('No valid search results for {}'.format(
                    self.tmdb_media[self._get_tmdb_title_key()]))
        else:
            logger_background.info('Search error: {}'.format(
                search.error_content))

        logger_background.info('Unable to find any results for {}'.format(
            self.tmdb_media[self._get_tmdb_title_key()]))

        return False
Example #16
0
def completed_media_task():
    nefarious_settings = NefariousSettings.get()
    transmission_client = get_transmission_client(nefarious_settings)

    incomplete_kwargs = dict(collected=False,
                             transmission_torrent_hash__isnull=False)

    movies = WatchMovie.objects.filter(**incomplete_kwargs)
    tv_seasons = WatchTVSeason.objects.filter(**incomplete_kwargs)
    tv_episodes = WatchTVEpisode.objects.filter(**incomplete_kwargs)

    incomplete_media = list(movies) + list(tv_episodes) + list(tv_seasons)

    for media in incomplete_media:
        try:
            torrent = transmission_client.get_torrent(
                media.transmission_torrent_hash)
        except KeyError:
            # media's torrent reference no longer exists so remove the reference
            logger_background.info(
                "Media's torrent no longer present, removing reference: {}".
                format(media))
            media.transmission_torrent_hash = None
            media.save()
        else:
            # download is complete
            if torrent.progress == 100:

                # flag media as completed
                logger_background.info('Media completed: {}'.format(media))

                # special handling for tv seasons
                if isinstance(media, WatchTVSeason):

                    # mark season request complete
                    for season_request in WatchTVSeasonRequest.objects.filter(
                            watch_tv_show=media.watch_tv_show,
                            season_number=media.season_number):
                        season_request.collected = True
                        season_request.save()

                # get the sub path (ie. "movies/", "tv/') so we can move the data from staging
                sub_path = (nefarious_settings.transmission_movie_download_dir
                            if isinstance(media, WatchMovie) else
                            nefarious_settings.transmission_tv_download_dir
                            ).lstrip('/')

                # get the path and updated name for the data
                new_path, new_name = get_media_new_path_and_name(
                    media, torrent.name,
                    len(torrent.files()) == 1)
                relative_path = os.path.join(
                    sub_path,  # i.e "movies" or "tv"
                    new_path or '',
                )

                # move the data to a new location
                transmission_session = transmission_client.session_stats()
                transmission_move_to_path = os.path.join(
                    transmission_session.download_dir,
                    relative_path,
                )
                logger_background.info('Moving torrent data to "{}"'.format(
                    transmission_move_to_path))
                torrent.move_data(transmission_move_to_path)

                # rename the data
                logger_background.info(
                    'Renaming torrent file from "{}" to "{}"'.format(
                        torrent.name, new_name))
                transmission_client.rename_torrent_path(
                    torrent.id, torrent.name, new_name)

                # save media as collected
                media.collected = True
                media.collected_date = timezone.now()
                media.save()

                # send websocket message media was updated
                media_type, data = websocket.get_media_type_and_serialized_watch_media(
                    media)
                websocket.send_message(websocket.ACTION_UPDATED, media_type,
                                       data)

                # send complete message through webhook
                webhook.send_message('{} was downloaded'.format(media))

                # define the import path
                import_path = os.path.join(
                    settings.INTERNAL_DOWNLOAD_PATH,
                    relative_path,
                    # new_path will be None if the torrent is already a directory so fall back to the new name
                    new_path or new_name,
                )

                # post-tasks
                post_tasks = [
                    # queue import of media to save the actual media paths
                    import_library_task.si(
                        'movie' if isinstance(media, WatchMovie) else
                        'tv',  # media type
                        media.user_id,  # user id
                        import_path,
                    ),
                ]

                # conditionally add subtitles task to post-tasks
                if nefarious_settings.should_save_subtitles() and isinstance(
                        media, (WatchMovie, WatchTVEpisode)):
                    post_tasks.append(
                        download_subtitles_task.si(media_type.lower(),
                                                   media.id))

                # queue post-tasks
                chain(*post_tasks)()
Example #17
0
def cross_seed_task(torrent_hash: str):
    # TODO - this isn't used and is a work in progress

    nefarious_settings = NefariousSettings.get()
    transmission_client = get_transmission_client(nefarious_settings)

    try:
        torrent = transmission_client.get_torrent(torrent_hash)
    except KeyError:
        logging.warning('{} no longer in transmission'.format(torrent_hash))
        return

    logging.info('Attempting cross seed for {}'.format(torrent.name))

    valid_results = []

    search = SearchTorrents(MEDIA_TYPE_MOVIE,
                            torrent.name,
                            search_seed_only=True)
    if search.ok:
        for result in search.results:
            transmission_client.add_torrent()
            normalized_title = regex.sub(ParserBase.word_delimiter_regex, ' ',
                                         torrent.name)
            if result['Title'].lower() in [
                    torrent.name.lower(),
                    normalized_title.lower()
            ]:
                # TODO - the sizes won't match due to the inaccuracy of the scraping values
                # add paused torrent and verify the sizes match
                valid_results.append(result)

    # trace the "torrent url" (sometimes magnet) in each valid result
    valid_results = results_with_valid_urls(valid_results, nefarious_settings)

    logging.info(valid_results)

    seed_only_indexers = get_seed_only_indexers(nefarious_settings)

    if valid_results:
        for seed_only_indexer in seed_only_indexers:

            logging.info(
                'Looking for cross seed results for indexer {}'.format(
                    seed_only_indexer))

            # filter results to this seed-only indexer
            indexer_results = [
                r for r in valid_results if r['TrackerId'] == seed_only_indexer
            ]
            if not indexer_results:
                logging.info(
                    'Indexer {} does not have any results for {}'.format(
                        seed_only_indexer, torrent.name))
                continue

            # get the "best" result
            best_result = get_best_torrent_result(indexer_results)

            logging.info('Cross seeding {} for indexer {}'.format(
                best_result['Title'], best_result['Tracker']))

            # add a new key to our result object with the traced torrent url
            best_result[
                'torrent_url'] = best_result['MagnetUri'] or trace_torrent_url(
                    swap_jackett_host(best_result['Link'], nefarious_settings))

            # add to transmission
            transmission_session = transmission_client.session_stats()
            torrent = transmission_client.add_torrent(
                best_result['torrent_url'],
                paused=True,  # TODO
                # TODO
                #download_dir=self._get_download_dir(transmission_session)
            )
    else:
        logging.info('No valid cross seeding options for {}'.format(
            torrent.name))