Пример #1
0
    def perform_create(self, serializer):
        super().perform_create(serializer)

        # save a watch tv season instance to try and download the whole season immediately
        watch_tv_season, _ = WatchTVSeason.objects.get_or_create(
            watch_tv_show=WatchTVShow.objects.get(
                id=serializer.data['watch_tv_show']),
            season_number=serializer.data['season_number'],
            defaults=dict(
                # add non-unique constraint fields for the default values
                user=self.request.user, ),
        )
        # 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)

        # delete any individual episodes (including in transmission) now that we're watching the entire season
        for episode in WatchTVEpisode.objects.filter(
                watch_tv_show=watch_tv_season.watch_tv_show,
                season_number=watch_tv_season.season_number):
            # send a websocket message for this removed episode
            media_type, data = websocket.get_media_type_and_serialized_watch_media(
                episode)
            send_websocket_message_task.delay(websocket.ACTION_REMOVED,
                                              media_type, data)
            # delete from transmission
            destroy_transmission_result(episode)
            # delete the episode
            episode.delete()

        # 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)
Пример #2
0
 def perform_destroy(self, instance):
     # send websocket message first then remove
     media_type, data = websocket.get_media_type_and_serialized_watch_media(
         instance)
     send_websocket_message_task.delay(websocket.ACTION_REMOVED, media_type,
                                       data)
     super().perform_destroy(instance)
Пример #3
0
 def perform_create(self, serializer):
     # create instance first then send websocket message
     super().perform_create(serializer)
     # send websocket message media was updated
     media_type, data = websocket.get_media_type_and_serialized_watch_media(
         serializer.instance)
     send_websocket_message_task.delay(websocket.ACTION_UPDATED, media_type,
                                       data)
Пример #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()

                # 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))
Пример #5
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)()