From 20c4ce8b7d2fa8380dff579a3694ec94169a31b0 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sat, 18 Mar 2017 22:14:46 +0000 Subject: [PATCH 1/2] Fixed a sonarr deseralization error. --- Ombi.Api.Models/Sonarr/SonarrAddSeries.cs | 18 ++++++++++++++++-- Ombi.Api/ApiRequest.cs | 10 ++++------ Ombi.UI/Modules/SearchModule.cs | 16 ++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Ombi.Api.Models/Sonarr/SonarrAddSeries.cs b/Ombi.Api.Models/Sonarr/SonarrAddSeries.cs index 881770e0c..4b0e24fe7 100644 --- a/Ombi.Api.Models/Sonarr/SonarrAddSeries.cs +++ b/Ombi.Api.Models/Sonarr/SonarrAddSeries.cs @@ -25,7 +25,7 @@ namespace Ombi.Api.Models.Sonarr { public SonarrAddSeries() { - images = new List(); + images = new List(); } public AddOptions addOptions { get; set; } public string title { get; set; } @@ -40,7 +40,7 @@ namespace Ombi.Api.Models.Sonarr public string imdbId { get; set; } public string titleSlug { get; set; } public int id { get; set; } - public List images { get; set; } + public List images { get; set; } [JsonIgnore] public List ErrorMessages { get; set; } } @@ -51,4 +51,18 @@ namespace Ombi.Api.Models.Sonarr public bool ignoreEpisodesWithoutFiles { get; set; } public bool searchForMissingEpisodes { get; set; } } + + public class Addoptions + { + public bool searchForMissingEpisodes { get; set; } + public bool ignoreEpisodesWithFiles { get; set; } + public bool ignoreEpisodesWithoutFiles { get; set; } + } + + public class SonarrImage + { + public string coverType { get; set; } + public string url { get; set; } + } + } diff --git a/Ombi.Api/ApiRequest.cs b/Ombi.Api/ApiRequest.cs index c399eae45..655bea670 100644 --- a/Ombi.Api/ApiRequest.cs +++ b/Ombi.Api/ApiRequest.cs @@ -45,7 +45,7 @@ namespace Ombi.Api MissingMemberHandling = MissingMemberHandling.Ignore }; - private static Logger Log = LogManager.GetCurrentClassLogger(); + private static readonly Logger Log = LogManager.GetCurrentClassLogger(); /// /// An API request handler /// @@ -58,8 +58,7 @@ namespace Ombi.Api var client = new RestClient { BaseUrl = baseUri }; var response = client.Execute(request); Log.Trace($"Request made to {response.ResponseUri} with status code {response.StatusCode}. The response was {response.Content}"); - - if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created) + if ((int)response.StatusCode < 300) return response.Data; else throw new ApiRequestException($"Got StatusCode={response.StatusCode} for {response.ResponseUri}."); @@ -78,8 +77,7 @@ namespace Ombi.Api var client = new RestClient { BaseUrl = baseUri }; var response = client.Execute(request); Log.Trace($"Request made to {response.ResponseUri} with status code {response.StatusCode}. The response was {response.Content}"); - - if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created) + if ((int)response.StatusCode < 300) return DeserializeXml(response.Content); else throw new ApiRequestException($"Got StatusCode={response.StatusCode} for {response.ResponseUri}."); @@ -92,7 +90,7 @@ namespace Ombi.Api var response = client.Execute(request); Log.Trace($"Request made to {response.ResponseUri} with status code {response.StatusCode}. The response was {response.Content}"); - if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created) + if ((int)response.StatusCode < 300) return JsonConvert.DeserializeObject(response.Content, _settings); else throw new ApiRequestException($"Got StatusCode={response.StatusCode} for {response.ResponseUri}."); diff --git a/Ombi.UI/Modules/SearchModule.cs b/Ombi.UI/Modules/SearchModule.cs index c321f4724..185392a14 100644 --- a/Ombi.UI/Modules/SearchModule.cs +++ b/Ombi.UI/Modules/SearchModule.cs @@ -864,6 +864,14 @@ namespace Ombi.UI.Modules private async Task RequestMovie(int movieId) { + if(string.IsNullOrEmpty(Username)) + { + return Response.AsJson(new JsonResponseModel + { + Result = false, + Message = "Your session has expired, please refresh the page" + }); + } if (Security.HasPermissions(User, Permissions.ReadOnlyUser) || !Security.HasPermissions(User, Permissions.RequestMovie)) { return @@ -1031,6 +1039,14 @@ namespace Ombi.UI.Modules /// private async Task RequestTvShow(int showId, string seasons) { + if (string.IsNullOrEmpty(Username)) + { + return Response.AsJson(new JsonResponseModel + { + Result = false, + Message = "Your session has expired, please refresh the page" + }); + } if (Security.HasPermissions(User, Permissions.ReadOnlyUser) || !Security.HasPermissions(User, Permissions.RequestTvShow)) { return From 3be69cbd619b651afc79ea61a621f41d429e80f0 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 24 Mar 2017 23:23:19 +0000 Subject: [PATCH 2/2] Fixes around the newsletter. We will now correctly show newly added shows and also newly added episodes. #1163 --- .../EmbyRecentlyAddedNewsletter.cs | 115 +++++++++---- .../PlexRecentlyAddedNewsletter.cs | 152 ++++++++++++------ 2 files changed, 188 insertions(+), 79 deletions(-) diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs index fed884060..6c6be9ec5 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs @@ -134,40 +134,100 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter newsletter.MovieCount = info.Count; info.Clear(); - foreach (var t in filteredSeries) + + // Check if there are any epiosdes, then get the series info. + // Otherwise then just add the series to the newsletter + if (filteredEp.Any()) { - var i = Api.GetInformation(t.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, - embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); - var ep = filteredEp.Where(x => x.ParentId == t.EmbyId).ToList(); - var item = new EmbyRecentlyAddedModel - { - EmbyContent = t, - EmbyInformation = i, - }; - if (ep.Any() && embySettings.EnableEpisodeSearching) + var recentlyAddedModel = new List(); + foreach (var embyEpisodes in filteredEp) { + // Let's sleep, Emby can't keep up with us. + Thread.Sleep(1000); try { - var episodeList = new List(); - foreach (var embyEpisodese in ep) + + // Find related series item + var relatedSeries = series.FirstOrDefault(x => x.EmbyId == embyEpisodes.ParentId); + + if (relatedSeries == null) { - var epInfo = Api.GetInformation(embyEpisodese.EmbyId, - Ombi.Api.Models.Emby.EmbyMediaType.Episode, - embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); - episodeList.Add(epInfo.EpisodeInformation); - Thread.Sleep(600); // Let's not try and overload the server + continue; } - item.EpisodeInformation = episodeList; + + // Get series information + var i = Api.GetInformation(relatedSeries.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, + embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + + var episodeInfo = Api.GetInformation(embyEpisodes.EmbyId, + Ombi.Api.Models.Emby.EmbyMediaType.Episode, + embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + // Check if we already have this series + var existingSeries = recentlyAddedModel.FirstOrDefault(x => + x.EmbyInformation.SeriesInformation.Id.Equals(i.SeriesInformation.Id, + StringComparison.CurrentCultureIgnoreCase)); + + if (existingSeries != null) + { + existingSeries.EpisodeInformation.Add(episodeInfo.EpisodeInformation); + } + else + { + recentlyAddedModel.Add(new EmbyRecentlyAddedModel + { + EmbyInformation = i, + EpisodeInformation = new List() { episodeInfo.EpisodeInformation }, + EmbyContent = relatedSeries + }); + } + } catch (JsonReaderException) { - Log.Error( - "Failed getting episode information, we may have overloaded Emby's api... Waiting and we will skip this one and go to the next"); + Log.Error("Failed getting information from Emby, we may have overloaded Emby's api... Waiting and we will skip this one and go to the next"); Thread.Sleep(1000); } } - info.Add(item); + info.AddRange(recentlyAddedModel); + } + else + { + foreach (var t in filteredSeries) + { + var i = Api.GetInformation(t.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, + embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + var ep = filteredEp.Where(x => x.ParentId == t.EmbyId).ToList(); + var item = new EmbyRecentlyAddedModel + { + EmbyContent = t, + EmbyInformation = i, + }; + if (ep.Any() && embySettings.EnableEpisodeSearching) + { + try + { + var episodeList = new List(); + foreach (var embyEpisodese in ep) + { + var epInfo = Api.GetInformation(embyEpisodese.EmbyId, + Ombi.Api.Models.Emby.EmbyMediaType.Episode, + embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + episodeList.Add(epInfo.EpisodeInformation); + Thread.Sleep(600); // Let's not try and overload the server + } + item.EpisodeInformation = episodeList; + } + catch (JsonReaderException) + { + Log.Error( + "Failed getting episode information, we may have overloaded Emby's api... Waiting and we will skip this one and go to the next"); + Thread.Sleep(1000); + } + } + + info.Add(item); + } } GenerateTvHtml(info, sb); newsletter.TvCount = info.Count; @@ -297,7 +357,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter try { var info = TvApi.ShowLookupByTheTvDbId(int.Parse(seriesItem.ProviderIds.Tvdb)); - if(info == null)continue; + if (info == null) continue; var banner = info.image?.original; if (!string.IsNullOrEmpty(banner)) @@ -329,16 +389,17 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter foreach (var embyEpisodeInformation in results.OrderBy(x => x.ParentIndexNumber)) { var epSb = new StringBuilder(); - for (var i = 0; i < embyEpisodeInformation.IndexNumber.Count; i++) + var orderedEpisodes = embyEpisodeInformation.IndexNumber.OrderBy(x => x.IndexNumber).ToList(); + for (var i = 0; i < orderedEpisodes.Count; i++) { - var ep = embyEpisodeInformation.IndexNumber[i]; - if (i < embyEpisodeInformation.IndexNumber.Count) + var ep = orderedEpisodes[i]; + if (i < embyEpisodeInformation.IndexNumber.Count - 1) { epSb.Append($"{ep.IndexNumber},"); } else { - epSb.Append(ep); + epSb.Append(ep.IndexNumber); } } AddParagraph(sb, $"Season: {embyEpisodeInformation.ParentIndexNumber}, Episode: {epSb}"); @@ -359,7 +420,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter } finally { - if(endLoop) + if (endLoop) EndLoopHtml(sb); } } diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs index 8bf2c548b..a5426e229 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs @@ -97,6 +97,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter { public PlexMetadata Metadata { get; set; } public PlexContent Content { get; set; } + public List EpisodeMetadata { get; set; } } private Newsletter GetHtml(bool test) @@ -137,36 +138,82 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter newsletter.MovieCount = info.Count; info.Clear(); - foreach (var t in filteredSeries) + if (filteredEp.Any()) { - var i = Api.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri, t.ItemId); - if (i.Directory == null) + var recentlyAddedModel = new List(); + foreach (var plexEpisodes in filteredEp) { - continue; + // Find related series item + var relatedSeries = series.FirstOrDefault(x => x.ProviderId == plexEpisodes.ProviderId); + + if (relatedSeries == null) + { + continue; + } + + // Get series information + var i = Api.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri, relatedSeries.ItemId); + var episodeInfo = Api.GetEpisodeMetaData(plexSettings.PlexAuthToken, plexSettings.FullUri, plexEpisodes.RatingKey); + // Check if we already have this series + var existingSeries = recentlyAddedModel.FirstOrDefault(x => + x.Metadata.Directory.RatingKey == i.Directory.RatingKey); + + if (existingSeries != null) + { + existingSeries.EpisodeMetadata.Add(episodeInfo); + } + else + { + recentlyAddedModel.Add(new PlexRecentlyAddedModel + { + Metadata = i, + EpisodeMetadata = new List() {episodeInfo}, + Content = relatedSeries + }); + } } - //var ep = filteredEp.Where(x => x.ShowTitle == t.Title); - info.Add(new PlexRecentlyAddedModel + + info.AddRange(recentlyAddedModel); + } + else + { + foreach (var t in filteredSeries) { - Metadata = i, - Content = t - }); - //if (ep.Any()) - //{ - // var episodeList = new List(); - // foreach (var embyEpisodese in ep) - // { - // var epInfo = Api.GetInformation(embyEpisodese.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Episode, - // embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); - // episodeList.Add(epInfo.EpisodeInformation); - // } - // info.Add(new EmbyRecentlyAddedModel - // { - // EmbyContent = t, - // EmbyInformation = i, - // EpisodeInformation = episodeList - // }); - //} + var i = Api.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri, t.ItemId); + if (i.Directory == null) + { + continue; + + } + //var ep = filteredEp.Where(x => x.ShowTitle == t.Title); + + if (filteredEp.Any()) + { + var episodeList = new List(); + foreach (var ep in filteredEp) + { + var epInfo = Api.GetEpisodeMetaData(plexSettings.PlexAuthToken, plexSettings.FullUri, + ep.RatingKey); + episodeList.Add(epInfo); + } + + info.Add(new PlexRecentlyAddedModel + { + Metadata = i, + Content = t, + EpisodeMetadata = episodeList + }); + } + else + { + info.Add(new PlexRecentlyAddedModel + { + Metadata = i, + Content = t + }); + } + } } GenerateTvHtml(info, sb); newsletter.TvCount = info.Count; @@ -294,9 +341,7 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter ""); foreach (var t in orderedTv) { - //var seriesItem = t.EmbyInformation.SeriesInformation; - //var relatedEpisodes = t.EpisodeInformation; - + var relatedEpisodes = t.EpisodeMetadata ?? new List(); try { @@ -319,31 +364,34 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter Header(sb, 3, title); EndTag(sb, "a"); - //var results = relatedEpisodes.GroupBy(p => p.ParentIndexNumber, - // (key, g) => new - // { - // ParentIndexNumber = key, - // IndexNumber = g.ToList() - // } - //); + // Group by the ParentIndex (season number) + var results = relatedEpisodes.GroupBy(p => p.Video.FirstOrDefault()?.ParentIndex, + (key, g) => new + { + ParentIndexNumber = key, + IndexNumber = g.ToList() + } + ); // Group the episodes - //foreach (var embyEpisodeInformation in results.OrderBy(x => x.ParentIndexNumber)) - //{ - // var epSb = new StringBuilder(); - // for (var i = 0; i < embyEpisodeInformation.IndexNumber.Count; i++) - // { - // var ep = embyEpisodeInformation.IndexNumber[i]; - // if (i < embyEpisodeInformation.IndexNumber.Count) - // { - // epSb.Append($"{ep.IndexNumber},"); - // } - // else - // { - // epSb.Append(ep); - // } - // } - // AddParagraph(sb, $"Season: {embyEpisodeInformation.ParentIndexNumber}, Episode: {epSb}"); - //} + foreach (var epInformation in results.OrderBy(x => x.ParentIndexNumber)) + { + var orderedEpisodes = epInformation.IndexNumber.OrderBy(x => Convert.ToInt32(x.Video.FirstOrDefault().Index)).ToList(); + var epSb = new StringBuilder(); + for (var i = 0; i < orderedEpisodes.Count; i++) + { + var ep = orderedEpisodes[i]; + if (i <= orderedEpisodes.Count - 1) + { + epSb.Append($"{ep.Video.FirstOrDefault().Index},"); + } + else + { + epSb.Append($"{ep.Video.FirstOrDefault().Index}"); + } + + } + AddParagraph(sb, $"Season: {epInformation.ParentIndexNumber}, Episode: {epSb}"); + } if (info.genres.Any()) {