Пример #1
0
    def test_movie(self):
        # populate some required data
        nefarious_settings = NefariousSettings()
        # required tmdb config data for saving models
        nefarious_settings.tmdb_configuration = {
            'images': {
                'secure_base_url': 'https://image.tmdb.org/t/p/',
            },
        }
        tmdb_client = get_tmdb_client(nefarious_settings)
        # use the first super user account to assign media
        user = User.objects.create_superuser('test', '*****@*****.**', 'test')

        # import
        importer = MovieImporter(
            nefarious_settings=nefarious_settings,
            root_path='/test-download',
            tmdb_client=tmdb_client,
            user=user,
        )
        for test_result in self.movie_tests:
            # prepend '/movie' to the test path
            test_path = os.path.join('/movie', test_result[0])
            import_result = importer.ingest_path(test_path)
            if test_result[1] is False or import_result is False:
                self.assertEqual(
                    test_result[1], import_result,
                    '{} != {}'.format(test_result[1], import_result))
            else:
                watch_movie = WatchMovie(name=test_result[1])
                self.assertTrue(
                    watch_movie.name == import_result.name,
                    '{} != {}'.format(watch_movie.name, import_result.name))
Пример #2
0
    def __init__(self,
                 media_type: str,
                 query: str,
                 search_seed_only: bool = False):
        assert media_type in [MEDIA_TYPE_TV, MEDIA_TYPE_MOVIE]
        self.search_seed_only = search_seed_only
        self.nefarious_settings = NefariousSettings.get()

        params = {
            'apikey': self.nefarious_settings.jackett_token,
            'Query': query,
            'Category[]': self._categories(media_type),
            'Tracker[]': self._trackers(),
        }

        res = requests.get(get_jackett_search_url(self.nefarious_settings),
                           params,
                           timeout=90)

        if res.ok:
            response = res.json()
            self.results = response['Results']
        else:
            self.ok = False
            self.error_content = res.content
Пример #3
0
    def get(self, request, media_type, media_id):
        nefarious_settings = NefariousSettings.get()
        tmdb = get_tmdb_client(nefarious_settings)

        params = {
            'language': nefarious_settings.language,
        }

        if media_type == MEDIA_TYPE_MOVIE:
            movie = tmdb.Movies(media_id)
            response = movie.info(**params)
        else:
            tv = tmdb.TV(media_id)
            response = tv.info(**params)
            # omit season "0" -- special episodes
            response['seasons'] = [
                season for season in response['seasons']
                if season['season_number'] > 0
            ]
            for season in response['seasons']:
                seasons_request = tmdb.TV_Seasons(response['id'],
                                                  season['season_number'])
                seasons = seasons_request.info(**params)
                season['episodes'] = seasons['episodes']

        return Response(response)
Пример #4
0
def watch_tv_show_season_task(watch_tv_season_id: int):
    processor = WatchTVSeasonProcessor(watch_media_id=watch_tv_season_id)
    success = processor.fetch()

    # delete watch_tv_season and fallback to individual episodes
    if not success:
        watch_tv_season = get_object_or_404(WatchTVSeason, pk=watch_tv_season_id)
        logging.info('Failed fetching season {} - falling back to individual episodes'.format(watch_tv_season))
        nefarious_settings = NefariousSettings.get()
        tmdb = get_tmdb_client(nefarious_settings)
        season_request = tmdb.TV_Seasons(watch_tv_season.watch_tv_show.tmdb_show_id, watch_tv_season.season_number)
        season = season_request.info()

        # save individual episode watches
        watch_tv_episodes_tasks = []
        for episode in season['episodes']:
            watch_tv_episode, was_created = WatchTVEpisode.objects.get_or_create(
                user=watch_tv_season.user,
                watch_tv_show=watch_tv_season.watch_tv_show,
                tmdb_episode_id=episode['id'],
                season_number=watch_tv_season.season_number,
                episode_number=episode['episode_number'],
            )

            # build list of tasks to execute
            watch_tv_episodes_tasks.append(watch_tv_episode_task.si(watch_tv_episode.id))

        # remove the "watch season" now that we've requested to fetch all individual episodes
        watch_tv_season.delete()

        # execute tasks sequentially
        chain(*watch_tv_episodes_tasks)()
Пример #5
0
    def get(self, request):
        media_type = request.query_params.get('media_type', MEDIA_TYPE_TV)
        assert media_type in [MEDIA_TYPE_TV, MEDIA_TYPE_MOVIE]

        if 'tmdb_media_id' not in request.query_params:
            raise ValidationError({'tmdb_media_id': ['required parameter']})

        nefarious_settings = NefariousSettings.get()

        params = {
            'language': nefarious_settings.language,
        }

        # prepare query
        tmdb = get_tmdb_client(nefarious_settings)
        tmdb_media_id = request.query_params.get('tmdb_media_id')

        # search for media
        if media_type == MEDIA_TYPE_MOVIE:
            similar_results = tmdb.Movies(id=tmdb_media_id).recommendations(
                **params)
        else:
            similar_results = tmdb.TV(id=tmdb_media_id).recommendations(
                **params)

        return Response(similar_results)
Пример #6
0
def import_library_task(media_type: str, user_id: int):
    user = get_object_or_404(User, pk=user_id)
    nefarious_settings = NefariousSettings.get()
    tmdb_client = get_tmdb_client(nefarious_settings=nefarious_settings)

    if media_type == 'movie':
        download_path = os.path.join(
            settings.INTERNAL_DOWNLOAD_PATH,
            nefarious_settings.transmission_movie_download_dir)
        importer = MovieImporter(
            nefarious_settings=nefarious_settings,
            download_path=download_path,
            tmdb_client=tmdb_client,
            user=user,
        )
    else:
        download_path = os.path.join(
            settings.INTERNAL_DOWNLOAD_PATH,
            nefarious_settings.transmission_tv_download_dir)
        importer = TVImporter(
            nefarious_settings=nefarious_settings,
            download_path=download_path,
            tmdb_client=tmdb_client,
            user=user,
        )
    importer.ingest_root(download_path)
Пример #7
0
    def get(self, request):
        media_type = request.query_params.get('media_type',
                                              SEARCH_MEDIA_TYPE_TV)
        assert media_type in [SEARCH_MEDIA_TYPE_TV, SEARCH_MEDIA_TYPE_MOVIE]

        nefarious_settings = NefariousSettings.get()

        # prepare query
        tmdb = get_tmdb_client(nefarious_settings)
        page = request.query_params.get('page', 1)
        query = request.query_params.get('q')

        params = {
            'query': query,
            'page': page,
            'language': nefarious_settings.language,
        }

        # search for media
        search = tmdb.Search()

        if media_type == SEARCH_MEDIA_TYPE_MOVIE:
            results = search.movie(**params)
        else:
            results = search.tv(**params)

        return Response(results)
Пример #8
0
def import_library_task(media_type: str, user_id: int, sub_path: str = None):
    user = get_object_or_404(User, pk=user_id)
    nefarious_settings = NefariousSettings.get()
    tmdb_client = get_tmdb_client(nefarious_settings=nefarious_settings)

    if media_type == 'movie':
        root_path = os.path.join(
            settings.INTERNAL_DOWNLOAD_PATH,
            nefarious_settings.transmission_movie_download_dir)
        importer = MovieImporter(
            nefarious_settings=nefarious_settings,
            root_path=root_path,
            tmdb_client=tmdb_client,
            user=user,
        )
    else:
        root_path = os.path.join(
            settings.INTERNAL_DOWNLOAD_PATH,
            nefarious_settings.transmission_tv_download_dir)
        importer = TVImporter(
            nefarious_settings=nefarious_settings,
            root_path=root_path,
            tmdb_client=tmdb_client,
            user=user,
        )

    # prefer supplied sub path and fallback to root path
    path = sub_path or root_path

    logger_background.info('Importing {} library at {}'.format(
        media_type, path))

    # ingest
    importer.ingest_root(path)
Пример #9
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)
Пример #10
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()
Пример #11
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()
Пример #12
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)
Пример #13
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)
Пример #14
0
    def test_tv(self):
        # populate some required data
        nefarious_settings = NefariousSettings()
        # required tmdb config data for saving models
        nefarious_settings.tmdb_configuration = {
            'images': {
                'secure_base_url': 'https://image.tmdb.org/t/p/',
            },
        }
        tmdb_client = get_tmdb_client(nefarious_settings)
        # use the first super user account to assign media
        user = User.objects.create_superuser('test', '*****@*****.**', 'test')

        # import
        importer = TVImporter(
            nefarious_settings=nefarious_settings,
            download_path='/test-download',
            tmdb_client=tmdb_client,
            user=user,
        )
        for test_result in self.tv_tests:
            # prepend '/tv' to the test path
            test_path = os.path.join('/tv', test_result[0])
            import_result = importer.ingest_path(test_path)
            if test_result[1] is False or import_result is False:
                self.assertEqual(
                    test_result[1], import_result,
                    '{} != {}'.format(test_result[1], import_result))
            else:
                show = WatchTVShow(name=test_result[1])
                episode = WatchTVEpisode(watch_tv_show=show,
                                         season_number=test_result[2],
                                         episode_number=test_result[3])
                self.assertTrue(
                    episode.watch_tv_show.name ==
                    import_result.watch_tv_show.name,
                    '{} != {}'.format(episode.watch_tv_show.name,
                                      import_result.watch_tv_show.name))
                self.assertTrue(
                    episode.season_number == import_result.season_number,
                    '{} != {}'.format(episode.season_number,
                                      import_result.season_number))
                self.assertTrue(
                    episode.episode_number == import_result.episode_number,
                    '{} != {}'.format(episode.episode_number,
                                      import_result.episode_number))
Пример #15
0
def wanted_tv_season_task():
    tasks = []
    nefarious_settings = NefariousSettings.get()
    tmdb = get_tmdb_client(nefarious_settings)

    #
    # re-check for requested tv seasons that have had new episodes released from TMDB (which was stale previously)
    #

    for tv_season_request in WatchTVSeasonRequest.objects.filter(
            collected=False):
        season_request = tmdb.TV_Seasons(
            tv_season_request.watch_tv_show.tmdb_show_id,
            tv_season_request.season_number)
        season = season_request.info()

        now = datetime.utcnow()
        last_air_date = parse_date(season.get('air_date')
                                   or '')  # season air date

        # otherwise add any new episodes to our watch list
        for episode in season['episodes']:
            episode_air_date = parse_date(episode.get('air_date') or '')

            # if episode air date exists, use as last air date
            if episode_air_date:
                last_air_date = episode_air_date if not last_air_date or episode_air_date > last_air_date else last_air_date

            watch_tv_episode, was_created = WatchTVEpisode.objects.get_or_create(
                watch_tv_show=tv_season_request.watch_tv_show,
                season_number=tv_season_request.season_number,
                episode_number=episode['episode_number'],
                defaults=dict(
                    # add non-unique constraint fields for the default values
                    tmdb_episode_id=episode['id'],
                    user=tv_season_request.user,
                    release_date=episode_air_date,
                ))
            if was_created:

                logging.info('adding newly found episode {} for {}'.format(
                    episode['episode_number'], tv_season_request))

                # add episode to task queue
                tasks.append(watch_tv_episode_task.si(watch_tv_episode.id))

        # assume there's no new episodes for anything that's aired this long ago
        days_since_aired = (now.date() -
                            last_air_date).days if last_air_date else 0
        if days_since_aired > 30:
            logging.warning('completing old tv season request {}'.format(
                tv_season_request))
            tv_season_request.collected = True
            tv_season_request.save()

    # execute tasks sequentially
    chain(*tasks)()
Пример #16
0
    def create(self, validated_data):

        # save tmdb configuration settings on creation
        nefarious_settings = NefariousSettings(**validated_data)
        tmdb_client = get_tmdb_client(nefarious_settings)
        configuration = tmdb_client.Configuration()
        validated_data['tmdb_configuration'] = configuration.info()

        return super().create(validated_data)
Пример #17
0
def auto_watch_new_seasons_task():
    """
    look for newly aired seasons that the user wants to automatically watch
    """

    nefarious_settings = NefariousSettings.get()
    tmdb_client = get_tmdb_client(nefarious_settings)

    # cycle through every show that has auto-watch enabled
    for watch_show in WatchTVShow.objects.filter(auto_watch=True):
        tmdb_show = tmdb_client.TV(watch_show.tmdb_show_id)
        show_data = tmdb_show.info()

        added_season = False

        # find any season with a newer air date than the "auto watch" and queue it up
        for season in show_data['seasons']:
            air_date = parse_date(season['air_date'] or '')

            # air date is newer than our auto watch date
            if air_date and watch_show.auto_watch_date_updated and air_date >= watch_show.auto_watch_date_updated:

                # season & request params
                create_params = dict(watch_tv_show=watch_show,
                                     season_number=season['season_number'],
                                     defaults=dict(
                                         user=watch_show.user,
                                         release_date=air_date,
                                     ))

                # create a season request instance to keep up with slowly-released episodes
                WatchTVSeasonRequest.objects.get_or_create(**create_params)
                # also save a watch tv season instance to try and download the whole season immediately
                watch_tv_season, was_season_created = WatchTVSeason.objects.get_or_create(
                    **create_params)

                # season was created
                if was_season_created:
                    added_season = True
                    logging.info(
                        'Automatically watching newly aired season {}'.format(
                            watch_tv_season))
                    # send a websocket message for this new season
                    media_type, data = websocket.get_media_type_and_serialized_watch_media(
                        watch_tv_season)
                    send_websocket_message_task.delay(websocket.ACTION_UPDATED,
                                                      media_type, data)

                    # create a task to download the whole season (fallback to individual episodes if it fails)
                    watch_tv_show_season_task.delay(watch_tv_season.id)

        # new season added to show
        if added_season:
            # update auto watch date requested
            watch_show.auto_watch_date_updated = datetime.utcnow().date()
            watch_show.save()
Пример #18
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')
Пример #19
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)
Пример #20
0
def send_message(message: str):
    nefarious_settings = NefariousSettings.get()
    response = requests.post(nefarious_settings.webhook_url,
                             json={nefarious_settings.webhook_key: message},
                             timeout=5)
    try:
        response.raise_for_status()
    except Exception as e:
        logging.warning('webhook error for url {} and data key "{}"'.format(
            nefarious_settings.webhook_url, nefarious_settings.webhook_key))
        logging.exception(e)
Пример #21
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)
Пример #22
0
def refresh_tmdb_configuration():

    logging.info('Refreshing TMDB Configuration')

    nefarious_settings = NefariousSettings.get()

    tmdb_client = get_tmdb_client(nefarious_settings)
    configuration = tmdb_client.Configuration()

    nefarious_settings.tmdb_configuration = configuration.info()
    nefarious_settings.save()

    return nefarious_settings.tmdb_configuration
Пример #23
0
    def get(self, request, media_type, media_id):
        assert media_type in [MEDIA_TYPE_TV, MEDIA_TYPE_MOVIE]

        nefarious_settings = NefariousSettings.get()

        # prepare query
        tmdb = get_tmdb_client(nefarious_settings)

        if media_type == MEDIA_TYPE_MOVIE:
            result = tmdb.Movies(media_id)
        else:
            result = tmdb.TV(media_id)

        return Response(result.videos())
Пример #24
0
def refresh_tmdb_configuration():

    logger_background.info('Refreshing TMDB Configuration')

    nefarious_settings = NefariousSettings.get()

    tmdb_client = get_tmdb_client(nefarious_settings)
    configuration = tmdb_client.Configuration()

    nefarious_settings.tmdb_configuration = configuration.info()
    nefarious_settings.tmdb_languages = configuration.languages()
    nefarious_settings.save()

    return nefarious_settings.tmdb_configuration
Пример #25
0
def watch_tv_show_season_task(watch_tv_season_id: int):
    processor = WatchTVSeasonProcessor(watch_media_id=watch_tv_season_id)
    success = processor.fetch()

    watch_tv_season = get_object_or_404(WatchTVSeason, pk=watch_tv_season_id)

    # success so update the season request instance as "collected"
    if success:
        season_request = WatchTVSeasonRequest.objects.filter(
            watch_tv_show=watch_tv_season.watch_tv_show,
            season_number=watch_tv_season.season_number)
        if season_request.exists():
            season_request = season_request.first()
            season_request.collected = True
            season_request.save()
    # failed so delete season instance and fallback to trying individual episodes
    else:
        logging.info(
            'Failed fetching entire season {} - falling back to individual episodes'
            .format(watch_tv_season))
        nefarious_settings = NefariousSettings.get()
        tmdb = get_tmdb_client(nefarious_settings)
        season_request = tmdb.TV_Seasons(
            watch_tv_season.watch_tv_show.tmdb_show_id,
            watch_tv_season.season_number)
        season = season_request.info()

        # save individual episode watches
        watch_tv_episodes_tasks = []
        for episode in season['episodes']:
            watch_tv_episode, was_created = WatchTVEpisode.objects.get_or_create(
                tmdb_episode_id=episode['id'],
                # add non-unique constraint fields for the default values
                defaults=dict(
                    user=watch_tv_season.user,
                    watch_tv_show=watch_tv_season.watch_tv_show,
                    season_number=watch_tv_season.season_number,
                    episode_number=episode['episode_number'],
                    release_date=parse_date(episode.get('air_date') or ''),
                ))

            # build list of tasks to execute
            watch_tv_episodes_tasks.append(
                watch_tv_episode_task.si(watch_tv_episode.id))

        # remove the "watch season" now that we've requested to fetch all individual episodes
        watch_tv_season.delete()

        # execute tasks sequentially
        chain(*watch_tv_episodes_tasks)()
Пример #26
0
def send_message(message: str) -> bool:
    # apprise notifications - https://github.com/caronc/apprise
    nefarious_settings = NefariousSettings.get()
    if nefarious_settings.apprise_notification_url:
        apprise_instance = apprise.Apprise()
        apprise_instance.add(nefarious_settings.apprise_notification_url)
        try:
            return apprise_instance.notify(body=message, )
        except Exception as e:
            logger_background.warning(
                'apprise notification error for url {}'.format(
                    nefarious_settings.apprise_notification_url))
            logger_background.exception(e)
            return False
    return False
Пример #27
0
    def get(self, request, media_type):
        assert media_type in [MEDIA_TYPE_TV, MEDIA_TYPE_MOVIE]

        nefarious_settings = NefariousSettings.get()

        # prepare query
        tmdb = get_tmdb_client(nefarious_settings)
        args = request.query_params
        genres = tmdb.Genres()

        if media_type == MEDIA_TYPE_MOVIE:
            results = genres.movie_list(**args)
        else:
            results = genres.tv_list(**args)

        return Response(results)
Пример #28
0
    def get(self, request, media_type):
        assert media_type in [MEDIA_TYPE_TV, MEDIA_TYPE_MOVIE]

        nefarious_settings = NefariousSettings.get()

        # prepare query
        tmdb = get_tmdb_client(nefarious_settings)
        args = request.query_params
        discover = tmdb.Discover()

        if media_type == MEDIA_TYPE_MOVIE:
            results = discover.movie(**args)
        else:
            results = discover.tv(**args)

        return Response(results)
Пример #29
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})
Пример #30
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)