diff --git a/PlexRequests.Api.Interfaces/ISonarrApi.cs b/PlexRequests.Api.Interfaces/ISonarrApi.cs index 215e85652..5c5594ad8 100644 --- a/PlexRequests.Api.Interfaces/ISonarrApi.cs +++ b/PlexRequests.Api.Interfaces/ISonarrApi.cs @@ -36,7 +36,8 @@ namespace PlexRequests.Api.Interfaces List GetProfiles(string apiKey, Uri baseUrl); SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, - int seasonCount, int[] seasons, string apiKey, Uri baseUrl, bool monitored = true); + int seasonCount, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, + bool searchForMissingEpisodes = false); SystemStatus SystemStatus(string apiKey, Uri baseUrl); diff --git a/PlexRequests.Api/SonarrApi.cs b/PlexRequests.Api/SonarrApi.cs index c80e6c39c..6cc8019f3 100644 --- a/PlexRequests.Api/SonarrApi.cs +++ b/PlexRequests.Api/SonarrApi.cs @@ -64,7 +64,7 @@ namespace PlexRequests.Api return obj; } - public SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int seasonCount, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true) + public SonarrAddSeries AddSeries(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int seasonCount, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false) { Log.Debug("Adding series {0}", title); Log.Debug("Seasons = {0}, out of {1} seasons", seasons.DumpJson(), seasonCount); @@ -86,6 +86,16 @@ namespace PlexRequests.Api monitored = monitor }; + if (!searchForMissingEpisodes) + { + options.addOptions = new AddOptions + { + searchForMissingEpisodes = false, + ignoreEpisodesWithFiles = true, + ignoreEpisodesWithoutFiles = true + }; + } + for (var i = 1; i <= seasonCount; i++) { var season = new Season @@ -107,9 +117,8 @@ namespace PlexRequests.Api try { var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling AddSeries for Sonarr, Retrying {0}", timespan), new TimeSpan[] { - TimeSpan.FromSeconds (2), - TimeSpan.FromSeconds(5), - TimeSpan.FromSeconds(10) + TimeSpan.FromSeconds (1), + TimeSpan.FromSeconds(2), }); result = policy.Execute(() => Api.ExecuteJson(request, baseUrl)); diff --git a/PlexRequests.Helpers/PlexHelper.cs b/PlexRequests.Helpers/PlexHelper.cs index aaf152421..941417dc4 100644 --- a/PlexRequests.Helpers/PlexHelper.cs +++ b/PlexRequests.Helpers/PlexHelper.cs @@ -26,17 +26,20 @@ #endregion using System; +using NLog; namespace PlexRequests.Helpers { public class PlexHelper { + + private static Logger Log = LogManager.GetCurrentClassLogger(); public static string GetProviderIdFromPlexGuid(string guid) { if (string.IsNullOrEmpty(guid)) return guid; - var guidSplit = guid.Split(new[] {'/', '?'}, StringSplitOptions.RemoveEmptyEntries); + var guidSplit = guid.Split(new[] { '/', '?' }, StringSplitOptions.RemoveEmptyEntries); if (guidSplit.Length > 1) { return guidSplit[1]; @@ -50,15 +53,23 @@ namespace PlexRequests.Helpers //guid="com.plexapp.agents.thetvdb://269586/2/8?lang=en" if (string.IsNullOrEmpty(guid)) return null; + try + { + var guidSplit = guid.Split(new[] { '/', '?' }, StringSplitOptions.RemoveEmptyEntries); + if (guidSplit.Length > 2) + { + ep.ProviderId = guidSplit[1]; + ep.SeasonNumber = int.Parse(guidSplit[2]); + ep.EpisodeNumber = int.Parse(guidSplit[3]); + } + return ep; - var guidSplit = guid.Split(new[] { '/', '?' }, StringSplitOptions.RemoveEmptyEntries); - if (guidSplit.Length > 2) + } + catch (Exception e) { - ep.ProviderId = guidSplit[1]; - ep.SeasonNumber = int.Parse(guidSplit[2]); - ep.EpisodeNumber = int.Parse(guidSplit[3]); + Log.Error(e); + return ep; } - return ep; } } diff --git a/PlexRequests.Store/RequestedModel.cs b/PlexRequests.Store/RequestedModel.cs index 7f9f44996..212f52203 100644 --- a/PlexRequests.Store/RequestedModel.cs +++ b/PlexRequests.Store/RequestedModel.cs @@ -108,9 +108,29 @@ namespace PlexRequests.Store Other = 4, // Provide a message } - public class EpisodesModel + public class EpisodesModel : IEquatable { public int SeasonNumber { get; set; } public int EpisodeNumber { get; set; } + public bool Equals(EpisodesModel other) + { + // Check whether the compared object is null. + if (ReferenceEquals(other, null)) return false; + + //Check whether the compared object references the same data. + if (ReferenceEquals(this, other)) return true; + + //Check whether the properties are equal. + return SeasonNumber.Equals(other.SeasonNumber) && EpisodeNumber.Equals(other.EpisodeNumber); + } + + public override int GetHashCode() + { + var hashSeason = SeasonNumber.GetHashCode(); + var hashEp = EpisodeNumber.GetHashCode(); + + //Calculate the hash code. + return hashSeason + hashEp; + } } } diff --git a/PlexRequests.UI/Content/requests.js b/PlexRequests.UI/Content/requests.js index cbd9136fd..c5e08ce07 100644 --- a/PlexRequests.UI/Content/requests.js +++ b/PlexRequests.UI/Content/requests.js @@ -592,6 +592,7 @@ function tvLoad() { context.episodes = tvObject; var html = searchTemplate(context); $tvl.append(html); + tvObject = new Array(); }); diff --git a/PlexRequests.UI/Helpers/TvSender.cs b/PlexRequests.UI/Helpers/TvSender.cs index 0c05b5bd6..fa89804fe 100644 --- a/PlexRequests.UI/Helpers/TvSender.cs +++ b/PlexRequests.UI/Helpers/TvSender.cs @@ -75,7 +75,7 @@ namespace PlexRequests.UI.Helpers var seriesTask = GetSonarrSeries(sonarrSettings, model.ProviderId); if (episodeRequest) - { + { // Does series exist? var series = await seriesTask; if (series != null) @@ -83,6 +83,7 @@ namespace PlexRequests.UI.Helpers // Series Exists // Request the episodes in the existing series await RequestEpisodesWithExistingSeries(model, series, sonarrSettings); + return new SonarrAddSeries {title = series.title}; } else { @@ -91,29 +92,22 @@ namespace PlexRequests.UI.Helpers sonarrSettings.SeasonFolders, sonarrSettings.RootPath, 0, new int[0], sonarrSettings.ApiKey, sonarrSettings.FullUri, false)); - if (string.IsNullOrEmpty(addResult?.title)) + + // Get the series that was just added + series = await GetSonarrSeries(sonarrSettings, model.ProviderId); + series.monitored = false; // Un-monitor the series + + // Un-monitor all seasons + foreach (var season in series.seasons) { - var sw = new Stopwatch(); - sw.Start(); - while (series == null) - { - await Task.Delay(TimeSpan.FromSeconds(5)); - series = await GetSonarrSeries(sonarrSettings, model.ProviderId); - - // Check how long we have been doing this for - if (sw.Elapsed > TimeSpan.FromSeconds(30)) - { - // 30 seconds is a long time, it's not going to work. - throw new ApiRequestException("Sonarr still didn't have the series added after 30 seconds."); - } - } - sw.Stop(); - - // Update the series, Since we cannot add as unmonitoed due to the following bug: https://github.com/Sonarr/Sonarr/issues/1404 - SonarrApi.UpdateSeries(series, sonarrSettings.ApiKey, sonarrSettings.FullUri); + season.monitored = false; } - // We now have the series in Sonarr + // Update the series, Since we cannot add as un-monitored due to the following bug: https://github.com/Sonarr/Sonarr/issues/1404 + SonarrApi.UpdateSeries(series, sonarrSettings.ApiKey, sonarrSettings.FullUri); + + + // We now have the series in Sonarr, update it to request the episodes. await RequestEpisodesWithExistingSeries(model, series, sonarrSettings); return addResult; diff --git a/PlexRequests.UI/Modules/SearchModule.cs b/PlexRequests.UI/Modules/SearchModule.cs index 0f815b123..a33c5165e 100644 --- a/PlexRequests.UI/Modules/SearchModule.cs +++ b/PlexRequests.UI/Modules/SearchModule.cs @@ -585,8 +585,16 @@ namespace PlexRequests.UI.Modules if (episodeRequest) { difference = GetListDifferences(existingRequest.Episodes, episodeModel.Episodes).ToList(); - if (!difference.Any()) + if (difference.Any()) { + existingRequest.Episodes = episodeModel.Episodes + .Select(r => + new EpisodesModel + { + SeasonNumber = r.SeasonNumber, + EpisodeNumber = r.EpisodeNumber + }).ToList(); + return await AddUserToRequest(existingRequest, settings, fullShowName); } // We have an episode that has not yet been requested, let's continue @@ -730,7 +738,7 @@ namespace PlexRequests.UI.Modules private async Task AddUserToRequest(RequestedModel existingRequest, PlexRequestSettings settings, string fullShowName) { // check if the current user is already marked as a requester for this show, if not, add them - if (!existingRequest.UserHasRequested(Username)) + if (!existingRequest.UserHasRequested(Username) || existingRequest.Episodes.Any()) { existingRequest.RequestedUsers.Add(Username); await RequestService.UpdateRequestAsync(existingRequest); @@ -1092,17 +1100,17 @@ namespace PlexRequests.UI.Modules return Response.AsJson(new JsonResponseModel { Result = true, Message = message }); } - private IEnumerable GetListDifferences(IEnumerable model, IEnumerable request) + private IEnumerable GetListDifferences(IEnumerable existing, IEnumerable request) { var newRequest = request .Select(r => - new Store.EpisodesModel + new EpisodesModel { SeasonNumber = r.SeasonNumber, EpisodeNumber = r.EpisodeNumber }).ToList(); - return newRequest.Except(model); + return newRequest.Except(existing); } } }