public async Task <SenderResult> Send(ChildRequests model) { var sonarr = await SonarrSettings.GetSettingsAsync(); if (sonarr.Enabled) { var result = await SendToSonarr(model); if (result != null) { return(new SenderResult { Sent = true, Success = true }); } } var dog = await DogNzbSettings.GetSettingsAsync(); if (dog.Enabled) { var result = await SendToDogNzb(model, dog); if (!result.Failure) { return(new SenderResult { Sent = true, Success = true }); } return(new SenderResult { Message = result.ErrorMessage }); } var sr = await SickRageSettings.GetSettingsAsync(); if (sr.Enabled) { var result = await SendToSickRage(model, sr); if (result) { return(new SenderResult { Sent = true, Success = true }); } return(new SenderResult { Message = "Could not send to SickRage!" }); } return(new SenderResult { Success = true }); }
private async Task <Response> ChangeRootFolder(int id, int rootFolderId) { // Get all root folders var settings = await SonarrSettings.GetSettingsAsync(); var rootFolders = SonarrApi.GetRootFolders(settings.ApiKey, settings.FullUri); // Get Request var allRequests = await Service.GetAllAsync(); var request = allRequests.FirstOrDefault(x => x.Id == id); if (request == null) { return(Response.AsJson(new JsonResponseModel { Result = false })); } foreach (var folder in rootFolders) { if (folder.id.Equals(rootFolderId)) { request.RootFolderSelected = folder.id; break; } } await Service.UpdateRequestAsync(request); return(Response.AsJson(new JsonResponseModel { Result = true })); }
public async Task <SenderResult> Send(ChildRequests model) { try { var sonarr = await SonarrSettings.GetSettingsAsync(); if (sonarr.Enabled) { var result = await SendToSonarr(model, sonarr); if (result != null) { return(new SenderResult { Sent = true, Success = true }); } } var dog = await DogNzbSettings.GetSettingsAsync(); if (dog.Enabled) { var result = await SendToDogNzb(model, dog); if (!result.Failure) { return(new SenderResult { Sent = true, Success = true }); } return(new SenderResult { Message = result.ErrorMessage }); } var sr = await SickRageSettings.GetSettingsAsync(); if (sr.Enabled) { var result = await SendToSickRage(model, sr); if (result) { return(new SenderResult { Sent = true, Success = true }); } return(new SenderResult { Message = "Could not send to SickRage!" }); } return(new SenderResult { Success = true }); } catch (Exception e) { Logger.LogError(e, "Exception thrown when sending a movie to DVR app, added to the request queue"); // Check if already in request queue var existingQueue = await _requestQueueRepository.FirstOrDefaultAsync(x => x.RequestId == model.Id); if (existingQueue != null) { existingQueue.RetryCount++; existingQueue.Error = e.Message; await _requestQueueRepository.SaveChangesAsync(); } else { await _requestQueueRepository.Add(new RequestQueue { Dts = DateTime.UtcNow, Error = e.Message, RequestId = model.Id, Type = RequestType.TvShow, RetryCount = 0 }); _notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue); } } return(new SenderResult { Success = false, Message = "Something went wrong!" }); }
private async Task <Response> GetTvShows() { var settingsTask = PrSettings.GetSettingsAsync(); var requests = await Service.GetAllAsync(); requests = requests.Where(x => x.Type == RequestType.TvShow); var dbTv = requests; var settings = await settingsTask; if (settings.UsersCanViewOnlyOwnRequests && !IsAdmin) { dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList(); } IEnumerable <QualityModel> qualities = new List <QualityModel>(); if (IsAdmin) { try { var sonarrSettings = await SonarrSettings.GetSettingsAsync(); if (sonarrSettings.Enabled) { var result = Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async() => { return(await Task.Run(() => SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri))); }); qualities = result.Result.Select(x => new QualityModel { Id = x.id.ToString(), Name = x.name }).ToList(); } else { var sickRageSettings = await SickRageSettings.GetSettingsAsync(); if (sickRageSettings.Enabled) { qualities = sickRageSettings.Qualities.Select(x => new QualityModel { Id = x.Key, Name = x.Value }).ToList(); } } } catch (Exception e) { Log.Info(e); } } var viewModel = dbTv.Select(tv => new RequestViewModel { ProviderId = tv.ProviderId, Type = tv.Type, Status = tv.Status, ImdbId = tv.ImdbId, Id = tv.Id, PosterPath = tv.PosterPath, ReleaseDate = tv.ReleaseDate, ReleaseDateTicks = tv.ReleaseDate.Ticks, RequestedDate = tv.RequestedDate, RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(tv.RequestedDate, DateTimeOffset).Ticks, Released = DateTime.Now > tv.ReleaseDate, Approved = tv.Available || tv.Approved, Title = tv.Title, Overview = tv.Overview, RequestedUsers = IsAdmin ? tv.AllUsers.ToArray() : new string[] { }, ReleaseYear = tv.ReleaseDate.Year.ToString(), Available = tv.Available, Admin = IsAdmin, IssueId = tv.IssueId, TvSeriesRequestType = tv.SeasonsRequested, Qualities = qualities.ToArray(), Episodes = tv.Episodes.ToArray(), }).ToList(); return(Response.AsJson(viewModel)); }
private async Task <Response> UpdateRequestsAsync(RequestedModel[] requestedModels) { var cpSettings = await CpService.GetSettingsAsync(); var updatedRequests = new List <RequestedModel>(); foreach (var r in requestedModels) { if (r.Type == RequestType.Movie) { if (cpSettings.Enabled) { var res = SendMovie(cpSettings, r, CpApi); if (res) { r.Approved = true; updatedRequests.Add(r); } else { Log.Error("Could not approve and send the movie {0} to couch potato!", r.Title); } } else { r.Approved = true; updatedRequests.Add(r); } } if (r.Type == RequestType.TvShow) { var sender = new TvSenderOld(SonarrApi, SickRageApi); // TODO put back var sr = await SickRageSettings.GetSettingsAsync(); var sonarr = await SonarrSettings.GetSettingsAsync(); if (sr.Enabled) { var res = sender.SendToSickRage(sr, r); if (res?.result == "success") { r.Approved = true; updatedRequests.Add(r); } else { Log.Error("Could not approve and send the TV {0} to SickRage!", r.Title); Log.Error("SickRage Message: {0}", res?.message); } } else if (sonarr.Enabled) { var res = await sender.SendToSonarr(sonarr, r); if (!string.IsNullOrEmpty(res?.title)) { r.Approved = true; updatedRequests.Add(r); } else { Log.Error("Could not approve and send the TV {0} to Sonarr!", r.Title); res?.ErrorMessages?.ForEach(x => Log.Error("Error messages: {0}", x)); } } else { r.Approved = true; updatedRequests.Add(r); } } } try { var result = await Service.BatchUpdateAsync(updatedRequests); return(Response.AsJson(result ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "We could not approve all of the requests. Please try again or check the logs." })); } catch (Exception e) { Log.Fatal(e); return(Response.AsJson(new JsonResponseModel { Result = false, Message = "Something bad happened, please check the logs!" })); } }
private async Task <Response> RequestTvAndUpdateStatus(RequestedModel request, string qualityId) { var sender = new TvSenderOld(SonarrApi, SickRageApi); // TODO put back var sonarrSettings = await SonarrSettings.GetSettingsAsync(); if (sonarrSettings.Enabled) { Log.Trace("Sending to Sonarr"); var result = await sender.SendToSonarr(sonarrSettings, request, qualityId); Log.Trace("Sonarr Result: "); Log.Trace(result.DumpJson()); if (!string.IsNullOrEmpty(result.title)) { Log.Info("Sent successfully, Approving request now."); request.Approved = true; var requestResult = await Service.UpdateRequestAsync(request); Log.Trace("Approval result: {0}", requestResult); if (requestResult) { return(Response.AsJson(new JsonResponseModel { Result = true })); } return (Response.AsJson(new JsonResponseModel { Result = false, Message = "Updated Sonarr but could not approve it in PlexRequests :(" })); } return(Response.AsJson(ValidationHelper.SendSonarrError(result.ErrorMessages))); } var srSettings = await SickRageSettings.GetSettingsAsync(); if (srSettings.Enabled) { Log.Trace("Sending to SickRage"); var result = sender.SendToSickRage(srSettings, request, qualityId); Log.Trace("SickRage Result: "); Log.Trace(result.DumpJson()); if (result?.result == "success") { Log.Info("Sent successfully, Approving request now."); request.Approved = true; var requestResult = await Service.UpdateRequestAsync(request); Log.Trace("Approval result: {0}", requestResult); return(Response.AsJson(requestResult ? new JsonResponseModel { Result = true } : new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" })); } return(Response.AsJson(new JsonResponseModel { Result = false, Message = result?.message != null ? "<b>Message From SickRage: </b>" + result.message : "Could not add the series to SickRage" })); } request.Approved = true; var res = await Service.UpdateRequestAsync(request); return(Response.AsJson(res ? new JsonResponseModel { Result = true, Message = "This has been approved, but It has not been sent to Sonarr/SickRage because it has not been configured" } : new JsonResponseModel { Result = false, Message = "Updated SickRage but could not approve it in PlexRequests :(" })); }
private async Task <Response> GetTvShows() { var requests = await Service.GetAllAsync(); requests = requests.Where(x => x.Type == RequestType.TvShow); var dbTv = requests; if (Security.HasPermissions(User, Permissions.UsersCanViewOnlyOwnRequests) && !IsAdmin) { dbTv = dbTv.Where(x => x.UserHasRequested(Username)).ToList(); } IEnumerable <QualityModel> qualities = new List <QualityModel>(); IEnumerable <RootFolderModel> rootFolders = new List <RootFolderModel>(); var sonarrSettings = await SonarrSettings.GetSettingsAsync(); if (IsAdmin) { try { if (sonarrSettings.Enabled) { var result = await Cache.GetOrSetAsync(CacheKeys.SonarrQualityProfiles, async() => { return(await Task.Run(() => SonarrApi.GetProfiles(sonarrSettings.ApiKey, sonarrSettings.FullUri))); }); qualities = result.Select(x => new QualityModel { Id = x.id.ToString(), Name = x.name }).ToList(); var rootFoldersResult = await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async() => { return(await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri))); }); rootFolders = rootFoldersResult.Select(x => new RootFolderModel { Id = x.id.ToString(), Path = x.path, FreeSpace = x.freespace }).ToList(); } else { var sickRageSettings = await SickRageSettings.GetSettingsAsync(); if (sickRageSettings.Enabled) { qualities = sickRageSettings.Qualities.Select(x => new QualityModel { Id = x.Key, Name = x.Value }).ToList(); } } } catch (Exception e) { Log.Info(e); } } var canManageRequest = Security.HasAnyPermissions(User, Permissions.Administrator, Permissions.ManageRequests); var allowViewUsers = Security.HasAnyPermissions(User, Permissions.Administrator, Permissions.ViewUsers); var viewModel = dbTv.Select(tv => new RequestViewModel { ProviderId = tv.ProviderId, Type = tv.Type, Status = tv.Status, ImdbId = tv.ImdbId, Id = tv.Id, PosterPath = tv.PosterPath?.Contains("http:") ?? false ? tv.PosterPath?.Replace("http:", "https:") : tv.PosterPath ?? string.Empty, // We make the poster path https on request, but this is just incase ReleaseDate = tv.ReleaseDate, ReleaseDateTicks = tv.ReleaseDate.Ticks, RequestedDate = tv.RequestedDate, RequestedDateTicks = DateTimeHelper.OffsetUTCDateTime(tv.RequestedDate, DateTimeOffset).Ticks, Released = DateTime.Now > tv.ReleaseDate, Approved = tv.Available || tv.Approved, Title = tv.Title, Overview = tv.Overview, RequestedUsers = canManageRequest || allowViewUsers ? tv.AllUsers.ToArray() : new string[] { }, ReleaseYear = tv.ReleaseDate.Year.ToString(), Available = tv.Available, Admin = canManageRequest, IssueId = tv.IssueId, Denied = tv.Denied, DeniedReason = tv.DeniedReason, TvSeriesRequestType = tv.SeasonsRequested, Qualities = qualities.ToArray(), Episodes = tv.Episodes.ToArray(), RootFolders = rootFolders.ToArray(), HasRootFolders = rootFolders.Any(), CurrentRootPath = sonarrSettings.Enabled ? GetRootPath(tv.RootFolderSelected, sonarrSettings).Result : null }).ToList(); return(Response.AsJson(viewModel)); }
/// <summary> /// Send the request to Sonarr to process /// </summary> /// <param name="s"></param> /// <param name="model"></param> /// <param name="qualityId">This is for any qualities overriden from the UI</param> /// <returns></returns> public async Task <NewSeries> SendToSonarr(ChildRequests model, string qualityId = null) { var s = await SonarrSettings.GetSettingsAsync(); if (!s.Enabled) { return(null); } if (string.IsNullOrEmpty(s.ApiKey)) { return(null); } var qualityProfile = 0; if (!string.IsNullOrEmpty(qualityId)) // try to parse the passed in quality, otherwise use the settings default quality { int.TryParse(qualityId, out qualityProfile); } if (qualityProfile <= 0) { int.TryParse(s.QualityProfile, out qualityProfile); } // Get the root path from the rootfolder selected. // For some reason, if we haven't got one use the first root folder in Sonarr // TODO make this overrideable via the UI var rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s); try { // Does the series actually exist? var allSeries = await SonarrApi.GetSeries(s.ApiKey, s.FullUri); var existingSeries = allSeries.FirstOrDefault(x => x.tvdbId == model.ParentRequest.TvDbId); if (existingSeries == null) { // Time to add a new one var newSeries = new NewSeries { title = model.ParentRequest.Title, imdbId = model.ParentRequest.ImdbId, tvdbId = model.ParentRequest.TvDbId, cleanTitle = model.ParentRequest.Title, monitored = true, seasonFolder = s.SeasonFolders, rootFolderPath = rootFolderPath, qualityProfileId = qualityProfile, titleSlug = model.ParentRequest.Title, addOptions = new AddOptions { ignoreEpisodesWithFiles = true, // There shouldn't be any episodes with files, this is a new season ignoreEpisodesWithoutFiles = true, // We want all missing searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly. } }; // Montitor the correct seasons, // If we have that season in the model then it's monitored! var seasonsToAdd = new List <Season>(); for (var i = 1; i < model.ParentRequest.TotalSeasons + 1; i++) { var index = i; var season = new Season { seasonNumber = i, monitored = model.SeasonRequests.Any(x => x.SeasonNumber == index) }; seasonsToAdd.Add(season); } newSeries.seasons = seasonsToAdd; var result = await SonarrApi.AddSeries(newSeries, s.ApiKey, s.FullUri); existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri); await SendToSonarr(model, existingSeries, s); } else { await SendToSonarr(model, existingSeries, s); } return(new NewSeries { id = existingSeries.id, seasons = existingSeries.seasons.ToList(), cleanTitle = existingSeries.cleanTitle, title = existingSeries.title, tvdbId = existingSeries.tvdbId }); } catch (Exception e) { Logger.LogError(LoggingEvents.SonarrSender, e, "Exception thrown when attempting to send series over to Sonarr"); throw; } }
/// <summary> /// Send the request to Sonarr to process /// </summary> /// <param name="s"></param> /// <param name="model"></param> /// <returns></returns> public async Task <NewSeries> SendToSonarr(ChildRequests model) { var s = await SonarrSettings.GetSettingsAsync(); if (!s.Enabled) { return(null); } if (string.IsNullOrEmpty(s.ApiKey)) { return(null); } int qualityToUse; string rootFolderPath; string seriesType; var profiles = await UserQualityProfiles.GetAll().FirstOrDefaultAsync(x => x.UserId == model.RequestedUserId); if (model.SeriesType == SeriesType.Anime) { // Get the root path from the rootfolder selected. // For some reason, if we haven't got one use the first root folder in Sonarr rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPathAnime), s); int.TryParse(s.QualityProfileAnime, out qualityToUse); if (profiles != null) { if (profiles.SonarrRootPathAnime > 0) { rootFolderPath = await GetSonarrRootPath(profiles.SonarrRootPathAnime, s); } if (profiles.SonarrQualityProfileAnime > 0) { qualityToUse = profiles.SonarrQualityProfileAnime; } } seriesType = "anime"; } else { int.TryParse(s.QualityProfile, out qualityToUse); // Get the root path from the rootfolder selected. // For some reason, if we haven't got one use the first root folder in Sonarr rootFolderPath = await GetSonarrRootPath(model.ParentRequest.RootFolder ?? int.Parse(s.RootPath), s); if (profiles != null) { if (profiles.SonarrRootPath > 0) { rootFolderPath = await GetSonarrRootPath(profiles.SonarrRootPath, s); } if (profiles.SonarrQualityProfile > 0) { qualityToUse = profiles.SonarrQualityProfile; } } seriesType = "standard"; } // Overrides on the request take priority if (model.ParentRequest.QualityOverride.HasValue) { qualityToUse = model.ParentRequest.QualityOverride.Value; } try { // Does the series actually exist? var allSeries = await SonarrApi.GetSeries(s.ApiKey, s.FullUri); var existingSeries = allSeries.FirstOrDefault(x => x.tvdbId == model.ParentRequest.TvDbId); if (existingSeries == null) { // Time to add a new one var newSeries = new NewSeries { title = model.ParentRequest.Title, imdbId = model.ParentRequest.ImdbId, tvdbId = model.ParentRequest.TvDbId, cleanTitle = model.ParentRequest.Title, monitored = true, seasonFolder = s.SeasonFolders, rootFolderPath = rootFolderPath, qualityProfileId = qualityToUse, titleSlug = model.ParentRequest.Title, seriesType = seriesType, addOptions = new AddOptions { ignoreEpisodesWithFiles = false, // There shouldn't be any episodes with files, this is a new season ignoreEpisodesWithoutFiles = false, // We want all missing searchForMissingEpisodes = false // we want dont want to search yet. We want to make sure everything is unmonitored/monitored correctly. } }; // Montitor the correct seasons, // If we have that season in the model then it's monitored! var seasonsToAdd = GetSeasonsToCreate(model); newSeries.seasons = seasonsToAdd; var result = await SonarrApi.AddSeries(newSeries, s.ApiKey, s.FullUri); existingSeries = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri); await SendToSonarr(model, existingSeries, s); } else { await SendToSonarr(model, existingSeries, s); } return(new NewSeries { id = existingSeries.id, seasons = existingSeries.seasons.ToList(), cleanTitle = existingSeries.cleanTitle, title = existingSeries.title, tvdbId = existingSeries.tvdbId }); } catch (Exception e) { Logger.LogError(LoggingEvents.SonarrSender, e, "Exception thrown when attempting to send series over to Sonarr"); throw; } }