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)); }
/// <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)); }
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}")); }
/// <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()); }