Beispiel #1
0
        private async Task <Result <PlexDownloadClient> > CreateDownloadClientAsync(DownloadTask downloadTask)
        {
            if (downloadTask == null)
            {
                return(ResultExtensions.IsNull(nameof(downloadTask)).LogError());
            }

            var authenticateDownloadTaskResult = await AuthenticateDownloadTask(downloadTask);

            if (authenticateDownloadTaskResult.IsFailed)
            {
                return(authenticateDownloadTaskResult.ToResult().LogError());
            }

            // Create download client
            var newClient = _plexDownloadClientFactory(downloadTask);

            newClient.Parts = _userSettings.AdvancedSettings.DownloadManager.DownloadSegments;


            // Setup the client
            var setupResult = await newClient.SetupAsync(downloadTask.DownloadWorkerTasks);

            if (setupResult.IsFailed)
            {
                return(setupResult.ToResult());
            }

            SetupSubscriptions(newClient);
            _downloadsList.Add(newClient);
            return(Result.Ok(newClient));
        }
Beispiel #2
0
        /// <summary>
        /// Checks if a <see cref="DownloadTask"/> with this Id or ratingKey has already been added.
        /// </summary>
        /// <param name="downloadTask">The <see cref="DownloadTask"/> to check for.</param>
        /// <returns>True if it already exists.</returns>
        private async Task <Result <bool> > DownloadTaskExistsAsync(DownloadTask downloadTask)
        {
            if (downloadTask == null)
            {
                return(ResultExtensions.IsNull(nameof(downloadTask)).LogError());
            }

            Result <DownloadTask> downloadTaskDB;

            // Download tasks added here might not contain an Id, which is why we also search on ratingKey.
            if (downloadTask.Id > 0)
            {
                // First check if there is an downloadClient with that downloadTask, as that is faster
                var downloadClient = _downloadsList.Find(x => x.DownloadTaskId == downloadTask.Id);
                if (downloadClient != null)
                {
                    return(Result.Ok(true));
                }

                // Check Database
                downloadTaskDB = await _mediator.Send(new GetDownloadTaskByIdQuery(downloadTask.Id));
            }
            else if (downloadTask.RatingKey > 0)
            {
                // First check if there is an downloadClient with that downloadTask, as that is faster
                var downloadClient = _downloadsList.Find(x => x.DownloadTask.RatingKey == downloadTask.RatingKey);
                if (downloadClient != null)
                {
                    return(Result.Ok(true));
                }

                // Check DataBase
                downloadTaskDB = await _mediator.Send(new GetDownloadTaskByRatingKeyQuery(downloadTask.RatingKey));
            }
            else
            {
                return(Result.Fail("There was no valid Id or RatingKey available in the downloadTask").LogError());
            }

            if (downloadTaskDB.IsFailed)
            {
                if (downloadTaskDB.Has404NotFoundError())
                {
                    return(Result.Ok(false));
                }

                return(downloadTaskDB.ToResult());
            }

            // The only possibility now is that the DownloadTask exists
            return(Result.Ok(true));
        }
Beispiel #3
0
        public async Task <Result <string> > GetPlexServerTokenWithUrl(int plexServerId, string serverUrl, int plexAccountId = 0)
        {
            if (string.IsNullOrEmpty(serverUrl))
            {
                return(ResultExtensions.IsNull(nameof(serverUrl)));
            }

            var token = await GetPlexServerTokenAsync(plexServerId, plexAccountId);

            if (token.IsFailed)
            {
                return(token);
            }

            // TODO verify that download=1 is not needed.
            return(Result.Ok($"{serverUrl}?X-Plex-Token={token.Value}"));
        }
Beispiel #4
0
        /// <inheritdoc/>
        public async Task <Result> StopDownload(List <int> downloadTaskIds = null)
        {
            if (downloadTaskIds == null)
            {
                return(ResultExtensions.IsNull(nameof(downloadTaskIds)));
            }

            // Retrieve download client
            foreach (int downloadTaskId in downloadTaskIds)
            {
                var downloadClient = GetDownloadClient(downloadTaskId);
                if (downloadClient.IsSuccess)
                {
                    await downloadClient.Value.Stop();
                }
            }

            return(Result.Ok());
        }
        /// <summary>
        /// Refresh the <see cref="PlexLibrary"/>, by first deleting all (related) media and the re-adding the media again.
        /// </summary>
        /// <param name="plexLibrary">The <see cref="PlexLibrary"/> to refresh.</param>
        /// <returns></returns>
        private async Task <Result> RefreshPlexMovieLibrary(PlexLibrary plexLibrary)
        {
            if (plexLibrary == null)
            {
                return(ResultExtensions.IsNull(nameof(plexLibrary)));
            }

            // Update the MetaData of this library
            var updateMetaDataResult = plexLibrary.UpdateMetaData();

            if (updateMetaDataResult.IsFailed)
            {
                return(updateMetaDataResult);
            }

            var updateResult = await _mediator.Send(new UpdatePlexLibraryByIdCommand(plexLibrary));

            if (updateResult.IsFailed)
            {
                return(updateResult.ToResult());
            }

            var deleteResult = await _mediator.Send(new DeleteMediaFromPlexLibraryCommand(plexLibrary.Id));

            if (deleteResult.IsFailed)
            {
                return(deleteResult.ToResult());
            }

            var createResult = await _mediator.Send(new CreateUpdateOrDeletePlexMoviesCommand(plexLibrary));

            if (createResult.IsFailed)
            {
                return(createResult.ToResult());
            }

            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, plexLibrary.MediaCount, plexLibrary.MediaCount);

            return(Result.Ok());
        }
        /// <summary>
        /// Retrieves all tvshow, season and episode data and stores it in the database.
        /// </summary>
        /// <param name="authToken"></param>
        /// <param name="plexLibrary"></param>
        /// <returns></returns>
        private async Task <Result> RefreshPlexTvShowLibrary(string authToken, PlexLibrary plexLibrary)
        {
            if (plexLibrary == null)
            {
                return(ResultExtensions.IsNull("plexLibrary").LogError());
            }

            if (plexLibrary.Type != PlexMediaType.TvShow)
            {
                return(Result.Fail("PlexLibrary is not of type TvShow").LogError());
            }

            if (plexLibrary.TvShows.Count == 0)
            {
                return(Result.Fail("PlexLibrary does not contain any TvShows and thus cannot request the corresponding media").LogError());
            }

            var result = await _mediator.Send(new GetPlexLibraryByIdWithServerQuery(plexLibrary.Id));

            if (result.IsFailed)
            {
                return(result);
            }

            // Request seasons and episodes for every tv show
            var plexLibraryDb = result.Value;
            var serverUrl     = plexLibraryDb.PlexServer.ServerUrl;
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 0, 3);

            var timer = new Stopwatch();

            timer.Start();

            var rawSeasonDataResult = await _plexServiceApi.GetAllSeasonsAsync(authToken, serverUrl, plexLibrary.Key);

            if (rawSeasonDataResult.IsFailed)
            {
                return(rawSeasonDataResult.ToResult());
            }

            // Phase 1 of 4: Season data was retrieved successfully.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 1, 4);

            var rawEpisodesDataResult = await _plexServiceApi.GetAllEpisodesAsync(authToken, serverUrl, plexLibrary.Key);

            if (rawEpisodesDataResult.IsFailed)
            {
                return(rawEpisodesDataResult.ToResult());
            }

            // Phase 2 of 4: Episode data was retrieved successfully.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 2, 4);

            foreach (var plexTvShow in plexLibrary.TvShows)
            {
                plexTvShow.Seasons = rawSeasonDataResult.Value.FindAll(x => x.ParentKey == plexTvShow.Key);
                foreach (var plexTvShowSeason in plexTvShow.Seasons)
                {
                    plexTvShowSeason.PlexLibraryId = plexLibrary.Id;
                    plexTvShowSeason.PlexLibrary   = plexLibrary;
                    plexTvShowSeason.TvShow        = plexTvShow;
                    plexTvShowSeason.Episodes      = rawEpisodesDataResult.Value.FindAll(x => x.ParentKey == plexTvShowSeason.Key);

                    // Set libraryId in each episode
                    plexTvShowSeason.Episodes.ForEach(x => x.PlexLibraryId = plexLibrary.Id);
                    plexTvShowSeason.MediaSize = plexTvShowSeason.Episodes.Sum(x => x.MediaSize);
                }

                plexTvShow.MediaSize = plexTvShow.Seasons.Sum(x => x.MediaSize);
            }

            // Phase 3 of 4: PlexLibrary media data was parsed successfully.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 3, 4);

            Log.Debug($"Finished retrieving all media for library {plexLibraryDb.Title} in {timer.Elapsed.TotalSeconds}");
            timer.Restart();

            // Update the MetaData of this library
            var updateMetaDataResult = plexLibrary.UpdateMetaData();

            if (updateMetaDataResult.IsFailed)
            {
                return(updateMetaDataResult);
            }

            var updateResult = await _mediator.Send(new UpdatePlexLibraryByIdCommand(plexLibrary));

            if (updateResult.IsFailed)
            {
                return(updateResult.ToResult());
            }

            var deleteResult = await _mediator.Send(new DeleteMediaFromPlexLibraryCommand(plexLibrary.Id));

            if (deleteResult.IsFailed)
            {
                return(deleteResult.ToResult());
            }

            var createResult = await _mediator.Send(new CreateUpdateOrDeletePlexTvShowsCommand(plexLibrary));

            if (createResult.IsFailed)
            {
                return(createResult.ToResult());
            }

            Log.Debug($"Finished updating all media in the database for library {plexLibraryDb.Title} in {timer.Elapsed.TotalSeconds}");

            // Phase 4 of 4: Database has been successfully updated with new library data.
            await _signalRService.SendLibraryProgressUpdate(plexLibrary.Id, 4, 4);

            return(Result.Ok());
        }