From 7c37458e3b594650398225186730f5e00921ae19 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Thu, 30 Mar 2017 08:07:59 +0100 Subject: [PATCH 1/9] slightly increased the wait time for the emby newsletter also fixed a potential error in the plex user checker --- Ombi.Services/Jobs/PlexUserChecker.cs | 3 ++- .../EmbyRecentlyAddedNewsletter.cs | 26 ++----------------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/Ombi.Services/Jobs/PlexUserChecker.cs b/Ombi.Services/Jobs/PlexUserChecker.cs index 7a56ddeee..1ea679b02 100644 --- a/Ombi.Services/Jobs/PlexUserChecker.cs +++ b/Ombi.Services/Jobs/PlexUserChecker.cs @@ -31,6 +31,7 @@ using System; using System.Linq; using NLog; using Ombi.Api.Interfaces; +using Ombi.Api.Models.Plex; using Ombi.Core; using Ombi.Core.SettingModels; using Ombi.Core.Users; @@ -89,7 +90,7 @@ namespace Ombi.Services.Jobs var localUsers = LocalUserRepository.GetAll().ToList(); // Regular users - foreach (var user in plexUsers.User) + foreach (var user in plexUsers?.User ?? new UserFriends[]{}) { var dbUser = dbUsers.FirstOrDefault(x => x.PlexUserId == user.Id); if (dbUser != null) diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs index 6c6be9ec5..b3830fc58 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs @@ -159,9 +159,11 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter var i = Api.GetInformation(relatedSeries.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + Thread.Sleep(200); 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, @@ -197,35 +199,11 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter { 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); } } From a744c80cb998c5d21ee0a144ae324ae57a096a0d Mon Sep 17 00:00:00 2001 From: Jamie Date: Thu, 30 Mar 2017 08:45:09 +0100 Subject: [PATCH 2/9] Update appveyor.yml --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 8444784af..2357e7eaa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,11 +1,11 @@ -version: 2.1.{build} +version: 2.2.{build} configuration: Release assembly_info: patch: true file: '**\AssemblyInfo.*' - assembly_version: '2.1.0' + assembly_version: '2.2.0' assembly_file_version: '{version}' - assembly_informational_version: '2.1.0' + assembly_informational_version: '2.2.0' before_build: - cmd: appveyor-retry nuget restore build: From 72ad2a79f40efc4f504e1c8b273bfdddf4b68ca5 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Thu, 30 Mar 2017 09:12:14 +0100 Subject: [PATCH 3/9] Translation changes --- Ombi.UI/Resources/UI.da.resx | 3 + Ombi.UI/Resources/UI.de.resx | 87 ++++++++++--------- Ombi.UI/Resources/UI.resx | 3 + Ombi.UI/Resources/UI.sv.resx | 139 ++++++++++++++++-------------- Ombi.UI/Resources/UI1.Designer.cs | 9 ++ 5 files changed, 137 insertions(+), 104 deletions(-) diff --git a/Ombi.UI/Resources/UI.da.resx b/Ombi.UI/Resources/UI.da.resx index e4164aeed..b558151c7 100644 --- a/Ombi.UI/Resources/UI.da.resx +++ b/Ombi.UI/Resources/UI.da.resx @@ -486,4 +486,7 @@ En baggrund proces kører i øjeblikket, så der kan være nogle uventede problemer. Dette bør ikke tage for lang tid. + + Beklager, men denne funktionalitet er i øjeblikket kun for brugere med Plex konti! + \ No newline at end of file diff --git a/Ombi.UI/Resources/UI.de.resx b/Ombi.UI/Resources/UI.de.resx index b90c69e83..629629c5d 100644 --- a/Ombi.UI/Resources/UI.de.resx +++ b/Ombi.UI/Resources/UI.de.resx @@ -121,10 +121,10 @@ Anmelden - Möchten Sie einen Film oder eine Serie schauen, die momentan noch nicht auf {0}ist? Dann loggen Sie sich unten ein und fordern Sie das Material an! + Möchten Sie einen Film oder eine Serie schauen, die momentan noch nicht in {0} verfügbar ist? Dann melden Sie sich an und erstellen eine Anfrage! - Deine Login-Daten werden nur zur Authorisierung deines Plex-Konto verwendet. + Deine Anmeldedaten werden nur zur Authorisierung deines Plex-Konto verwendet. Benutzername @@ -139,7 +139,7 @@ Anmelden - Irgendetwas ist falsch gelaufen + Irgendetwas ist schief gelaufen Erfolg @@ -169,10 +169,10 @@ Passwort ändern - Ausloggen + Abmelden - Es ist ein neues Update verfügbar! Klicke + Aktualisierung verfügbar! Hier klicken Englisch @@ -211,7 +211,7 @@ Alben - Möchtest Du etwas schauen, das derzeit nicht auf {0} ist?! Kein Problem! Suche einfach unten danach und frage es an! + Möchtest du etwas schauen, das derzeit nicht in {0} verfügbar ist?! Kein Problem! Suche unten einfach danach und frage es an! Suche @@ -226,7 +226,7 @@ Momentan im Kino - Sende mir eine Benachrichtigung, wenn die Serien oder die Filme, die ich angefordert habe, hinzugefügt wurden. + Sende mir eine Benachrichtigung, wenn eine eigene Anfrage erfüllt wurde.. Speichern @@ -235,10 +235,10 @@ Verfügbar - angefordert + angefragt - Anfordern + Anfragen Alle Staffeln @@ -250,7 +250,7 @@ Neueste Staffel - Auswählen + Staffel auswählen Problem melden @@ -265,7 +265,7 @@ Falscher Inhalt - Wiedergabe-Probleme + Wiedergabeprobleme Sonstiges @@ -283,7 +283,7 @@ Schliessen - Fügen ein Problem hinzu + Füge ein Problem hinzu Änderungen speichern @@ -292,13 +292,13 @@ Staffel - Herzlich willkommen + Willkommen Anfragen - Unten befinden sich alle Anfragen aller Benutzer. Hier ist auch der aktuelle Status des beantragten Titels ersichtlich. + Unten befinden sich alle Anfragen aller Benutzer und der Status zu jeder Anfrage.. Filme @@ -370,13 +370,13 @@ Veröffentlichung - Staffeln angefragt + angefragte Staffeln - Beantragt von + Angefragt von - Angefragt vor + Angefragt am Toggle Dropdown @@ -406,37 +406,37 @@ wurde erfolgreich hinzugefügt! - wurde schon angefragt + wurde bereits angefragt! - Wir konnten nicht prüfen ob {0} bereits auf {1}ist. Bist du sicher dass alles richtig installiert ist? + Wir konnten nicht prüfen ob {0} bereits in {1} verfügbar ist. Bist du sicher, dass alles richtig eingerichtet ist? - Etwas ging etwas schief beim Hinzufügen des Filmes zu CouchPotato! Bitte überprüfe deine Einstellungen. + Etwas ging etwas schief beim hinzufügen des Filmes zu CouchPotato! Bitte überprüfe deine Einstellungen. - Du hast dein wöchentliches Anfragekontingent für neue Filme erreicht. Bitte kontaktiere den Administrator. + Limit für wöchentliche Filmanfragen erreicht. Bitte kontaktiere den Administrator. - ist bereits auf {0}! + Bereits verfügbar in Plex! - Etwas ging etwas schief beim Hinzufügen des Filmes zu SickRage! Bitte überprüfe deine Einstellungen. + Etwas ging etwas schief beim hinzufügen des Filmes zu SickRage! Bitte überprüfe deine Einstellungen. - Das Anfragen für Serien ist momentan nicht richtig konfiguriert. Bitte kontaktiere den Administrator. + Die Anfrage für Serien ist momentan nicht richtig eingerichtet. Bitte kontaktiere den Administrator. - Du hast dein wöchentliches Anfragekontingent für neue Alben erreicht. Bitte kontaktiere den Administrator. + Limit für wöchentliche Albumanfragen erreicht. Bitte kontaktiere den Administrator. Wir konnten den Interpreten auf MusicBrainz leider nicht finden. Bitte versuche es später erneut oder kontaktiere den Administrator. - Du hast dein wöchentliches Anfragekontingent für neue Serien erreicht. Bitte kontaktiere den Administrator. + Limit für wöchentliche Serienanfragen erreicht. Bitte kontaktiere den Administrator. - Entschuldige, aber dein Administrator hat diese Funktion noch nicht freigeschaltet. + Entschuldige, der Administrator hat diese Funktion noch nicht freigeschaltet. Wir konnten diese Meldung nicht entfernen. @@ -448,42 +448,51 @@ Französisch - Wähle Episode + Wählen Sie ihre Episode - Falscher Benutzername oder Passwort + Falscher Benutzer oder Passwort - Es gibt noch keinen Release-Termin. + Es gibt noch keine Informationen zum Veröffentlichsdatum Zeige in Plex - Spende zum Serveradministrator + Spenden an Bibliothek Inhaber - Verfügbar auf Plex + Verfügbar in Plex - Filmstatus + Film Status - Noch nicht angefragt + Noch nicht veröffentlicht Genehmigung ausstehend - Anfrage wird bearbeitet. + In Bearbeitung - Anfrage verweigert. + Anfrage abgelehnt. - TV-Show-Status + Serien Status - Ein Hintergrundprozess läuft gerade, der zu unerwartetem Verhalten führen könnte. Dies sollte nicht allzu lange dauern. + Aufgrund der Indexierung aller verfügbaren Filme und Serien auf dem Plex Server kann es zu unerwarteten Problemen kommen. Dies sollte nicht zu lange dauern. - + + Entschuldige, diese Funktion ist momentan nur für Plex Benutzer freigeschaltet. + + + Benutzerverwaltung + + + Benutze die andere Anmeldeseite, wenn du ein Adminstrator bist + + \ No newline at end of file diff --git a/Ombi.UI/Resources/UI.resx b/Ombi.UI/Resources/UI.resx index 24519826e..be364539d 100644 --- a/Ombi.UI/Resources/UI.resx +++ b/Ombi.UI/Resources/UI.resx @@ -499,4 +499,7 @@ Actors + + Sorry, but this functionality is currently only for users with Plex accounts + \ No newline at end of file diff --git a/Ombi.UI/Resources/UI.sv.resx b/Ombi.UI/Resources/UI.sv.resx index 3d21b5df0..2dc28e02d 100644 --- a/Ombi.UI/Resources/UI.sv.resx +++ b/Ombi.UI/Resources/UI.sv.resx @@ -121,13 +121,13 @@ Logga in - Vill du titta på en film eller TV-show, men det är inte närvarande på {0}? Logga in nedan med användarnamn och lösenord !! + Vill du se en film eller serie som för närvarande inte finns på {0}? Logga in här! Dina inloggningsuppgifter används endast för att autentisera ditt Plex-konto. - Användarnamn + användarnamn Användarnamn @@ -151,16 +151,16 @@ Sök - Begäran + Önsningar - Frågor + Problem Donera - admin + Admin Inställningar @@ -172,10 +172,10 @@ Logga ut - Det finns en ny uppdatering tillgänglig! Klick + Det finns en uppdatering! Klicka - Svenska + Engelska Spanska @@ -196,25 +196,25 @@ Italienska - Här + här! - dutch + Nederländska - Fråga + Problem Filmer - Tv program + Serier Album - Vill titta på något som inte är närvarande på {0}?! Inga problem! Bara söka efter den nedan och begär det ! + Vill du se en film eller serie som för närvarande inte finns på {0}? Inga problem, önska den nedan! Sök @@ -226,10 +226,10 @@ Kommer snart - Teater + På bio - Skicka mig ett meddelande när objekt jag har begärt har lagts till! + Skicka mig ett meddelande när mina önskade objekt finns tillgängliga Spara @@ -238,7 +238,7 @@ Tillgänglig - Begärd + Önskad Alla säsonger @@ -250,10 +250,10 @@ Senaste säsongen - Välj + Välj säsong - Rapporten fråga + Rapportera problem Fel ljud @@ -271,7 +271,7 @@ Annat - Spår räknas + Antal spår Land @@ -283,28 +283,28 @@ Stäng - Lägg till en fråga + Rapportera problem - Spara Ändringar + Spara ändringar - Årstid + Säsong Välkommen - Begäran + Önskning - Nedan kan du se din och alla andra förfrågningar, liksom deras nedladdning och godkännandestatus. + Nedan kan du se alla önskningar och följa deras status. Filmer - Tv program + Serier Album @@ -316,10 +316,10 @@ Godkänn filmer - Radera TV-program + Radera serier - Godkänna TV-program + Godkänn serier Radera musik @@ -334,46 +334,46 @@ Godkänd - Ej Godkänd + Ej godkänd Tillgänglig - Inte tillgängligt + Ej tillgänglig - Släppte ut + Släppt - Inte släppt + Ej släppt - Beställning + Sortera Filter - Senaste förfrågningar + Senaste önskningar - Äldsta önskemål + Äldsta önskningar - Senaste versionerna + Senaste releaser - Äldsta meddelanden + Äldsta releaser - Släpptes + Utgivningsdatum - Säsonger Requested + Säsonger önskade - Begärd av + Önskat av Önskat datum @@ -385,13 +385,13 @@ Godkänn - ta bort + Radera - Ej tillgänglig + Markera som ej tillgänglig - Tillgänglig + Markera som tillgänglig Godkänd @@ -403,46 +403,46 @@ Problem - Pall är tillagd korrekt + lades till - har redan begärts + har redan önskats - Vi kunde inte kontrollera om {0} är i {1}, är du säker det är korrekt installation? + Vi kunde inte kontrollera om {0} finns på {1}. Kontrollera att inställningarna är korrekta. - Något gick fel att lägga till filmen i CouchPotato! Kontrollera inställningarna. + Kunde inte lägga till filmen i CouchPotato. Kontrollera att inställningarna är korrekta. - Du har nått din weekly begäran gräns för filmer! Kontakta din admin. + Du har nått din veckoönskningsgräns för filmer. Kontakta din administratör. - är redan i {0} + finns redan på {0}. - Något gick fel att lägga till filmen i SickRage! Kontrollera inställningarna. + Kunde inte lägga till filmen i SickRage. Kontrollera att inställningarna är korrekta. - Begäran av TV-program är inte korrekt inställd. Kontakta din admin. + Det går för närvarande inte att önska serier. Kontakta din administratör. - Du har nått din weekly begäran gräns för album! Kontakta din admin. + Du har nått din veckoönskningsgräns för album. Kontakta din administratör. - Vi kunde inte hitta artisten på MusicBrainz. Försök igen senare eller kontakta din admin + Vi kunde inte hitta artisten på MusicBrainz. Kontakta din administratör. - Du har nått din weekly begäran gräns för TV-program! Kontakta din admin. + Du har nått din veckoönskningsgräns för serier. Kontakta din administratör. - Ledsen, men administratören har ännu inte aktiverat denna funktion. + Denna funktion är inte aktiverad. - Vi kunde inte ta bort denna anmälan eftersom du aldrig haft det + Notisen kunde inte tas bort eftersom den inte varit aktiverad. - Kunde inte spara, försök igen + Kunde inte spara, försök igen. Franska @@ -454,36 +454,45 @@ Felaktig användare eller lösenord - Det finns ingen information tillgänglig för release datum + Ingen information om utgivningsdatum finns. - Vy I Plex + Visa på Plex - Donera till bibliotek Ansvarig + Donera till biblioteksansvarig - Tillgänglig den + Tillgänglig på - Film status + Filmstatus - Inte Begärd ännu + Ej önskad ännu Väntar på godkännande - Bearbetning förfrågan + Behandlar önskning - Förfrågan nekad + Önskning nekad - Visa status + Seriestatus - En bakgrundsprocess är igång, så det kan finnas några oväntade beteende. Detta bör inte ta alltför lång tid. + För närvarande körs bakgrundsindexeringar av innehåller på Plex. Detta kan medföra vissa störningar, men funktionaliteten bör vara återställd inom kort! + + + Denna funktion är tyvärr endast tillgänglig för Plex-användare. + + + Användarhantering + + + Om du är administratör, vänligen använd den andra inloggningssidan. \ No newline at end of file diff --git a/Ombi.UI/Resources/UI1.Designer.cs b/Ombi.UI/Resources/UI1.Designer.cs index 338720039..cdd5fc196 100644 --- a/Ombi.UI/Resources/UI1.Designer.cs +++ b/Ombi.UI/Resources/UI1.Designer.cs @@ -825,6 +825,15 @@ namespace Ombi.UI.Resources { } } + /// + /// Looks up a localized string similar to Sorry, but this functionality is currently only for users with Plex accounts. + /// + public static string Search_ErrorPlexAccountOnly { + get { + return ResourceManager.GetString("Search_ErrorPlexAccountOnly", resourceCulture); + } + } + /// /// Looks up a localized string similar to First Season. /// From b941d32b60e142e3a8a4260a163c4fd53555130c Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 30 Mar 2017 21:03:47 +0100 Subject: [PATCH 4/9] Fixed an issue where the emby newsletter was always showing series. --- .../EmbyRecentlyAddedNewsletter.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs index 6c6be9ec5..c2a8dc9d6 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs @@ -255,6 +255,14 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter AddedAt = DateTime.UtcNow }); } + foreach (var s in filteredSeries) + { + RecentlyAddedLog.Insert(new RecentlyAddedLog + { + ProviderId = s.ProviderId, + AddedAt = DateTime.UtcNow + }); + } } From 8a55de2b71b5472fccabd1bcb842ea140095f871 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 30 Mar 2017 21:09:55 +0100 Subject: [PATCH 5/9] For test emails, if there is no new content then just grab some old data. --- .../PlexRecentlyAddedNewsletter.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs index 6ac7d76db..1f9601b07 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/PlexRecentlyAddedNewsletter.cs @@ -121,6 +121,12 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter var filteredSeries = series.Where(x => recentlyAdded.All(c => c.ProviderId != x.ProviderId)).ToList(); var info = new List(); + + if (test && !filteredMovies.Any()) + { + // if this is a test make sure we show something + filteredMovies = movie.Take(5).ToList(); + } foreach (var m in filteredMovies) { var i = Api.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri, m.ItemId); @@ -178,6 +184,11 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter } else { + if (test && !filteredSeries.Any()) + { + // if this is a test make sure we show something + filteredSeries = series.Take(5).ToList(); + } foreach (var t in filteredSeries) { var i = Api.GetMetadata(plexSettings.PlexAuthToken, plexSettings.FullUri, t.ItemId); From ddefbf31db289d8f2a856faebdbb9191a4d67598 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 30 Mar 2017 22:46:51 +0100 Subject: [PATCH 6/9] Made a start on the new Sonarr integration. the Latest series option works. --- Ombi.Api.Interfaces/ISonarrApi.cs | 3 + Ombi.Api/SonarrApi.cs | 59 +++++- Ombi.Core/Ombi.Core.csproj | 5 +- Ombi.Core/{ => Tv}/TvSender.cs | 2 + Ombi.Core/{ => Tv}/TvSenderOld.cs | 0 Ombi.Core/Tv/TvSenderV2.cs | 244 ++++++++++++++++++++++++ Ombi.Services/Jobs/PlexEpisodeCacher.cs | 10 +- Ombi.UI/Modules/SearchModule.cs | 7 +- 8 files changed, 315 insertions(+), 15 deletions(-) rename Ombi.Core/{ => Tv}/TvSender.cs (99%) rename Ombi.Core/{ => Tv}/TvSenderOld.cs (100%) create mode 100644 Ombi.Core/Tv/TvSenderV2.cs diff --git a/Ombi.Api.Interfaces/ISonarrApi.cs b/Ombi.Api.Interfaces/ISonarrApi.cs index bce750901..06dd4ee75 100644 --- a/Ombi.Api.Interfaces/ISonarrApi.cs +++ b/Ombi.Api.Interfaces/ISonarrApi.cs @@ -56,5 +56,8 @@ namespace Ombi.Api.Interfaces Series UpdateSeries(Series series, string apiKey, Uri baseUrl); SonarrSeasonSearchResult SearchForSeason(int seriesId, int seasonNumber, string apiKey, Uri baseUrl); SonarrSeriesSearchResult SearchForSeries(int seriesId, string apiKey, Uri baseUrl); + + + SonarrAddSeries AddSeries(SonarrAddSeries series, string apiKey, Uri baseUrl); } } \ No newline at end of file diff --git a/Ombi.Api/SonarrApi.cs b/Ombi.Api/SonarrApi.cs index 3cf8565e8..afbe74e72 100644 --- a/Ombi.Api/SonarrApi.cs +++ b/Ombi.Api/SonarrApi.cs @@ -148,6 +148,42 @@ namespace Ombi.Api return result; } + public SonarrAddSeries AddSeries(SonarrAddSeries series,string apiKey, Uri baseUrl) + { + + var request = new RestRequest + { + Resource = "/api/Series?", + Method = Method.POST + }; + + Log.Debug("Sonarr API Options:"); + Log.Debug(series.DumpJson()); + + request.AddHeader("X-Api-Key", apiKey); + request.AddJsonBody(series); + + SonarrAddSeries result; + try + { + var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => Log.Error(exception, "Exception when calling AddSeries for Sonarr, Retrying {0}", timespan), new TimeSpan[] { + TimeSpan.FromSeconds (2) + }); + + result = policy.Execute(() => Api.ExecuteJson(request, baseUrl)); + } + catch (JsonSerializationException jse) + { + Log.Error(jse); + var error = Api.ExecuteJson>(request, baseUrl); + var messages = error?.Select(x => x.errorMessage).ToList(); + messages?.ForEach(x => Log.Error(x)); + result = new SonarrAddSeries { ErrorMessages = messages }; + } + + return result; + } + public SonarrAddSeries AddSeriesNew(int tvdbId, string title, int qualityId, bool seasonFolders, string rootPath, int[] seasons, string apiKey, Uri baseUrl, bool monitor = true, bool searchForMissingEpisodes = false) { var request = new RestRequest @@ -244,7 +280,18 @@ namespace Ombi.Api TimeSpan.FromSeconds(5) }); - return policy.Execute(() => Api.ExecuteJson>(request, baseUrl)); + var series = policy.Execute(() => Api.ExecuteJson>(request, baseUrl)); + + // Remove the 'specials from the object' + foreach (var s in series) + { + var seasonToRemove = s.seasons.FirstOrDefault(x => x.seasonNumber == 0); + if (seasonToRemove != null) + { + s.seasons.Remove(seasonToRemove); + } + } + return series; } catch (Exception e) { @@ -266,7 +313,15 @@ namespace Ombi.Api Log.Error(exception, "Exception when calling GetSeries by ID for Sonarr, Retrying {0}", timespan)); - return policy.Execute(() => Api.ExecuteJson(request, baseUrl)); + var series = policy.Execute(() => Api.ExecuteJson(request, baseUrl)); + + // Remove the specials season + var toRemove = series.seasons.FirstOrDefault(x => x.seasonNumber == 0); + if (toRemove != null) + { + series.seasons.Remove(toRemove); + } + return series; } catch (Exception e) { diff --git a/Ombi.Core/Ombi.Core.csproj b/Ombi.Core/Ombi.Core.csproj index 49c37b597..3ad547420 100644 --- a/Ombi.Core/Ombi.Core.csproj +++ b/Ombi.Core/Ombi.Core.csproj @@ -155,8 +155,9 @@ - - + + + diff --git a/Ombi.Core/TvSender.cs b/Ombi.Core/Tv/TvSender.cs similarity index 99% rename from Ombi.Core/TvSender.cs rename to Ombi.Core/Tv/TvSender.cs index 3f6d5f86e..f43910c94 100644 --- a/Ombi.Core/TvSender.cs +++ b/Ombi.Core/Tv/TvSender.cs @@ -87,6 +87,8 @@ namespace Ombi.Core var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.FullRootPath : await GetRootPath(model.RootFolderSelected, sonarrSettings); + + if (episodeRequest) { // Does series exist? diff --git a/Ombi.Core/TvSenderOld.cs b/Ombi.Core/Tv/TvSenderOld.cs similarity index 100% rename from Ombi.Core/TvSenderOld.cs rename to Ombi.Core/Tv/TvSenderOld.cs diff --git a/Ombi.Core/Tv/TvSenderV2.cs b/Ombi.Core/Tv/TvSenderV2.cs new file mode 100644 index 000000000..08833ff4e --- /dev/null +++ b/Ombi.Core/Tv/TvSenderV2.cs @@ -0,0 +1,244 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: TvSenderV2.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using NLog; +using Ombi.Api.Interfaces; +using Ombi.Api.Models.SickRage; +using Ombi.Api.Models.Sonarr; +using Ombi.Core.SettingModels; +using Ombi.Helpers; +using Ombi.Store; + +namespace Ombi.Core.Tv +{ + public class TvSenderV2 + { + public TvSenderV2(ISonarrApi sonarrApi, ISickRageApi srApi, ICacheProvider cache) + { + SonarrApi = sonarrApi; + SickrageApi = srApi; + Cache = cache; + } + private ISonarrApi SonarrApi { get; } + private ISickRageApi SickrageApi { get; } + private ICacheProvider Cache { get; } + private static Logger _log = LogManager.GetCurrentClassLogger(); + + + public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model) + { + return await SendToSonarr(sonarrSettings, model, string.Empty); + } + + + public async Task SendToSonarr(SonarrSettings sonarrSettings, RequestedModel model, + string qualityId) + { + 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(sonarrSettings.QualityProfile, out qualityProfile); + } + var rootFolderPath = model.RootFolderSelected <= 0 ? sonarrSettings.FullRootPath : await GetSonarrRootPath(model.RootFolderSelected, sonarrSettings); + + var episodeRequest = model.Episodes.Any(); + var requestAll = model.SeasonsRequested?.Equals("All", StringComparison.CurrentCultureIgnoreCase); + var first = model.SeasonsRequested?.Equals("First", StringComparison.CurrentCultureIgnoreCase); + var latest = model.SeasonsRequested?.Equals("Latest", StringComparison.CurrentCultureIgnoreCase); + var specificSeasonRequest = model.SeasonList?.Any(); + + if (episodeRequest) + { + return await ProcessSonarrEpisodeRequest(sonarrSettings, model, qualityProfile, rootFolderPath); + } + + if (requestAll ?? false) + { + return await ProcessSonarrRequestAll(sonarrSettings, model, qualityProfile, rootFolderPath); + } + + if (first ?? false) + { + return await ProcessSonarrRequestFirstSeason(sonarrSettings, model, qualityProfile, rootFolderPath); + } + + if (latest ?? false) + { + return await ProcessSonarrRequestLatestSeason(sonarrSettings, model, qualityProfile, rootFolderPath); + } + + if (specificSeasonRequest ?? false) + { + return await ProcessSonarrRequestSpecificSeason(sonarrSettings, model, qualityProfile, rootFolderPath); + } + + return null; + } + + private async Task ProcessSonarrRequestSpecificSeason(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + { + throw new NotImplementedException(); + } + + private async Task ProcessSonarrRequestLatestSeason(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + { + // Does the series exist? + + var series = await GetSonarrSeries(sonarrSettings, model.ProviderId); + if (series == null) + { + //WORKS + // Add the series + var seriesToAdd = new SonarrAddSeries + { + seasonFolder = sonarrSettings.SeasonFolders, + title = model.Title, + qualityProfileId = qualityId, + tvdbId = model.ProviderId, + titleSlug = model.Title, + seasons = new List(), + rootFolderPath = rootFolderPath, + monitored = true, // Montior the series + images = new List(), + addOptions = new AddOptions + { + ignoreEpisodesWithFiles = true, // We don't really care about these + ignoreEpisodesWithoutFiles = false, // We want to get the whole season + searchForMissingEpisodes = true // we want to search for missing + } + }; + + for (var i = 1; i <= model.SeasonCount; i++) + { + var season = new Season + { + seasonNumber = i, + // ReSharper disable once SimplifyConditionalTernaryExpression + monitored = true ? model.SeasonList.Length == 0 || model.SeasonList.Any(x => x == i) : false + }; + seriesToAdd.seasons.Add(season); + } + + return SonarrApi.AddSeries(seriesToAdd, sonarrSettings.ApiKey, sonarrSettings.FullUri); + } + else + { + // Mark the latest as monitored and search + // Also make sure the series is now monitored otherwise we won't search for it + series.monitored = true; + foreach (var seasons in series.seasons) + { + if (model.SeasonList.Any(x => x == seasons.seasonNumber)) + { + seasons.monitored = true; + } + } + + // Send the update command + series = SonarrApi.UpdateSeries(series, sonarrSettings.ApiKey, sonarrSettings.FullUri); + SonarrApi.SearchForSeries(series.id, sonarrSettings.ApiKey, sonarrSettings.FullUri); + return new SonarrAddSeries{title = series.title}; + } + } + + private async Task ProcessSonarrRequestFirstSeason(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + { + throw new NotImplementedException(); + } + + private async Task ProcessSonarrRequestAll(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + { + throw new NotImplementedException(); + } + + private async Task ProcessSonarrEpisodeRequest(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + { + // Does the series exist? + + var series = await GetSonarrSeries(sonarrSettings, model.ProviderId); + if (series == null) + { + // Add the series + } + + return null; + } + + public SickRageTvAdd SendToSickRage(SickRageSettings sickRageSettings, RequestedModel model) + { + return SendToSickRage(sickRageSettings, model, sickRageSettings.QualityProfile); + } + + public SickRageTvAdd SendToSickRage(SickRageSettings sickRageSettings, RequestedModel model, string qualityId) + { + _log.Info("Sending to SickRage {0}", model.Title); + if (sickRageSettings.Qualities.All(x => x.Key != qualityId)) + { + qualityId = sickRageSettings.QualityProfile; + } + + var apiResult = SickrageApi.AddSeries(model.ProviderId, model.SeasonCount, model.SeasonList, qualityId, + sickRageSettings.ApiKey, sickRageSettings.FullUri); + + var result = apiResult.Result; + + + return result; + } + + private async Task GetSonarrSeries(SonarrSettings sonarrSettings, int showId) + { + var task = await Task.Run(() => SonarrApi.GetSeries(sonarrSettings.ApiKey, sonarrSettings.FullUri)).ConfigureAwait(false); + var selectedSeries = task.FirstOrDefault(series => series.tvdbId == showId); + + return selectedSeries; + } + + private async Task GetSonarrRootPath(int pathId, SonarrSettings sonarrSettings) + { + var rootFoldersResult = await Cache.GetOrSetAsync(CacheKeys.SonarrRootFolders, async () => + { + return await Task.Run(() => SonarrApi.GetRootFolders(sonarrSettings.ApiKey, sonarrSettings.FullUri)); + }); + + foreach (var r in rootFoldersResult.Where(r => r.id == pathId)) + { + return r.path; + } + return string.Empty; + } + } +} \ No newline at end of file diff --git a/Ombi.Services/Jobs/PlexEpisodeCacher.cs b/Ombi.Services/Jobs/PlexEpisodeCacher.cs index 58ebe7fd3..26820de94 100644 --- a/Ombi.Services/Jobs/PlexEpisodeCacher.cs +++ b/Ombi.Services/Jobs/PlexEpisodeCacher.cs @@ -152,15 +152,7 @@ namespace Ombi.Services.Jobs return; } - var jobs = Job.GetJobs(); - var job = jobs.FirstOrDefault(x => x.Name.Equals(JobNames.EpisodeCacher, StringComparison.CurrentCultureIgnoreCase)); - if (job != null) - { - if (job.LastRun > DateTime.Now.AddHours(-11)) // If it's been run in the last 11 hours - { - return; - } - } + Job.SetRunning(true, JobNames.EpisodeCacher); CacheEpisodes(s); } diff --git a/Ombi.UI/Modules/SearchModule.cs b/Ombi.UI/Modules/SearchModule.cs index 185392a14..0d52ae6c6 100644 --- a/Ombi.UI/Modules/SearchModule.cs +++ b/Ombi.UI/Modules/SearchModule.cs @@ -46,6 +46,7 @@ using Ombi.Core; using Ombi.Core.Models; using Ombi.Core.Queue; using Ombi.Core.SettingModels; +using Ombi.Core.Tv; using Ombi.Helpers; using Ombi.Helpers.Analytics; using Ombi.Helpers.Permissions; @@ -1119,10 +1120,11 @@ namespace Ombi.UI.Modules RequestedUsers = new List { Username }, Issues = IssueState.None, ImdbId = showInfo.externals?.imdb ?? string.Empty, - SeasonCount = showInfo.Season.Count, TvDbId = showId.ToString() }; + var totalSeasons = showInfo.Season.GroupBy(x => x.SeasonNumber); + model.SeasonCount = totalSeasons.Count(); var seasonsList = new List(); switch (seasons) { @@ -1884,7 +1886,8 @@ namespace Ombi.UI.Modules { model.Approved = true; var s = await sonarrSettings; - var sender = new TvSenderOld(SonarrApi, SickrageApi, Cache); // TODO put back + //var sender = new TvSenderV2(SonarrApi, SickrageApi, Cache); + var sender = new TvSenderOld(SonarrApi, SickrageApi, Cache); if (s.Enabled) { var result = await sender.SendToSonarr(s, model); From d0c994a9253b570b60568d333ae826786c2a21b9 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Mon, 3 Apr 2017 11:14:22 +0100 Subject: [PATCH 7/9] Added a retry policy around the emby newsletter --- .../EmbyRecentlyAddedNewsletter.cs | 110 ++++++++++-------- Ombi.Services/Ombi.Services.csproj | 1 + 2 files changed, 65 insertions(+), 46 deletions(-) diff --git a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs index b3830fc58..5dda578ca 100644 --- a/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs +++ b/Ombi.Services/Jobs/RecentlyAddedNewsletter/EmbyRecentlyAddedNewsletter.cs @@ -45,6 +45,7 @@ using Ombi.Store.Models.Emby; using Ombi.Store.Repository; using TMDbLib.Objects.Exceptions; using EmbyMediaType = Ombi.Store.Models.Plex.EmbyMediaType; +using Polly; namespace Ombi.Services.Jobs.RecentlyAddedNewsletter { @@ -121,14 +122,20 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter var info = new List(); foreach (var m in filteredMovies) { - - var i = Api.GetInformation(m.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Movie, - embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); - info.Add(new EmbyRecentlyAddedModel + var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => + Log.Error(exception, "Exception thrown when processing an emby movie for the newsletter, Retrying {0}", timespan)); + var result = policy.Execute(() => { - EmbyInformation = i, - EmbyContent = m + var i = Api.GetInformation(m.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Movie, + embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + + return new EmbyRecentlyAddedModel + { + EmbyInformation = i, + EmbyContent = m + }; }); + info.Add(result); } GenerateMovieHtml(info, sb); newsletter.MovieCount = info.Count; @@ -142,46 +149,49 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter var recentlyAddedModel = new List(); foreach (var embyEpisodes in filteredEp) { - // Let's sleep, Emby can't keep up with us. - Thread.Sleep(1000); try { + var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => + Log.Error(exception, "Exception thrown when processing an emby episode for the newsletter, Retrying {0}", timespan)); - // Find related series item - var relatedSeries = series.FirstOrDefault(x => x.EmbyId == embyEpisodes.ParentId); - - if (relatedSeries == null) + policy.Execute(() => { - continue; - } + // Find related series item + var relatedSeries = series.FirstOrDefault(x => x.EmbyId == embyEpisodes.ParentId); - // Get series information - var i = Api.GetInformation(relatedSeries.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, - embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); - - Thread.Sleep(200); - 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 + if (relatedSeries == null) { - EmbyInformation = i, - EpisodeInformation = new List() { episodeInfo.EpisodeInformation }, - EmbyContent = relatedSeries - }); - } + return; + } + + // Get series information + var i = Api.GetInformation(relatedSeries.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, + embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + + Thread.Sleep(200); + 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) @@ -197,13 +207,21 @@ namespace Ombi.Services.Jobs.RecentlyAddedNewsletter { foreach (var t in filteredSeries) { - var i = Api.GetInformation(t.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, - embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); - var item = new EmbyRecentlyAddedModel + + + var policy = RetryHandler.RetryAndWaitPolicy((exception, timespan) => + Log.Error(exception, "Exception thrown when processing an emby series for the newsletter, Retrying {0}", timespan)); + var item = policy.Execute(() => { - EmbyContent = t, - EmbyInformation = i, - }; + var i = Api.GetInformation(t.EmbyId, Ombi.Api.Models.Emby.EmbyMediaType.Series, + embySettings.ApiKey, embySettings.AdministratorId, embySettings.FullUri); + var model = new EmbyRecentlyAddedModel + { + EmbyContent = t, + EmbyInformation = i, + }; + return model; + }); info.Add(item); } } diff --git a/Ombi.Services/Ombi.Services.csproj b/Ombi.Services/Ombi.Services.csproj index 725f1a4ab..d3ca25f5d 100644 --- a/Ombi.Services/Ombi.Services.csproj +++ b/Ombi.Services/Ombi.Services.csproj @@ -48,6 +48,7 @@ ..\packages\NLog.4.3.6\lib\net45\NLog.dll True + From 858171e92a427197404b7a34b49166a50e00ef8a Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Mon, 3 Apr 2017 20:54:34 +0100 Subject: [PATCH 8/9] small bit of work --- Ombi.Core/Tv/TvSenderV2.cs | 152 ++++++++++++++++++++++++++----------- Ombi.UI/Bootstrapper.cs | 4 +- 2 files changed, 108 insertions(+), 48 deletions(-) diff --git a/Ombi.Core/Tv/TvSenderV2.cs b/Ombi.Core/Tv/TvSenderV2.cs index 08833ff4e..d3ad64fa4 100644 --- a/Ombi.Core/Tv/TvSenderV2.cs +++ b/Ombi.Core/Tv/TvSenderV2.cs @@ -87,41 +87,65 @@ namespace Ombi.Core.Tv if (requestAll ?? false) { - return await ProcessSonarrRequestAll(sonarrSettings, model, qualityProfile, rootFolderPath); + return await ProcessSonarrRequestSeason(sonarrSettings, model, qualityProfile, rootFolderPath); } if (first ?? false) { - return await ProcessSonarrRequestFirstSeason(sonarrSettings, model, qualityProfile, rootFolderPath); + return await ProcessSonarrRequestSeason(sonarrSettings, model, qualityProfile, rootFolderPath); } if (latest ?? false) { - return await ProcessSonarrRequestLatestSeason(sonarrSettings, model, qualityProfile, rootFolderPath); + return await ProcessSonarrRequestSeason(sonarrSettings, model, qualityProfile, rootFolderPath); } if (specificSeasonRequest ?? false) { - return await ProcessSonarrRequestSpecificSeason(sonarrSettings, model, qualityProfile, rootFolderPath); + return await ProcessSonarrRequestSeason(sonarrSettings, model, qualityProfile, rootFolderPath); } return null; } - private async Task ProcessSonarrRequestSpecificSeason(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + + + private async Task ProcessSonarrRequestSeason(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) { - throw new NotImplementedException(); + // Does the series exist? + var series = await GetSonarrSeries(sonarrSettings, model.ProviderId); + if (series == null) + { + //WORKS + // Add the series + return AddSeries(sonarrSettings, model, rootFolderPath, qualityId); + } + + // Also make sure the series is now monitored otherwise we won't search for it + series.monitored = true; + foreach (var seasons in series.seasons) + { + if (model.SeasonList.Any(x => x == seasons.seasonNumber)) + { + seasons.monitored = true; + } + } + + // Send the update command + series = SonarrApi.UpdateSeries(series, sonarrSettings.ApiKey, sonarrSettings.FullUri); + SonarrApi.SearchForSeries(series.id, sonarrSettings.ApiKey, sonarrSettings.FullUri); + return new SonarrAddSeries{title = series.title}; } - private async Task ProcessSonarrRequestLatestSeason(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + + + private async Task ProcessSonarrEpisodeRequest(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) { // Does the series exist? var series = await GetSonarrSeries(sonarrSettings, model.ProviderId); if (series == null) { - //WORKS - // Add the series var seriesToAdd = new SonarrAddSeries { seasonFolder = sonarrSettings.SeasonFolders, @@ -136,8 +160,8 @@ namespace Ombi.Core.Tv addOptions = new AddOptions { ignoreEpisodesWithFiles = true, // We don't really care about these - ignoreEpisodesWithoutFiles = false, // We want to get the whole season - searchForMissingEpisodes = true // we want to search for missing + ignoreEpisodesWithoutFiles = true, // We do not want to grab random episodes missing + searchForMissingEpisodes = false // we want don't want to search for the missing episodes either } }; @@ -146,55 +170,91 @@ namespace Ombi.Core.Tv var season = new Season { seasonNumber = i, - // ReSharper disable once SimplifyConditionalTernaryExpression - monitored = true ? model.SeasonList.Length == 0 || model.SeasonList.Any(x => x == i) : false + monitored = false // Do not monitor any seasons }; seriesToAdd.seasons.Add(season); } - return SonarrApi.AddSeries(seriesToAdd, sonarrSettings.ApiKey, sonarrSettings.FullUri); + // Add the series now + var result = SonarrApi.AddSeries(seriesToAdd, sonarrSettings.ApiKey, sonarrSettings.FullUri); + + await RequestEpisodesForSonarr(model, result.id, sonarrSettings); + } else { - // Mark the latest as monitored and search - // Also make sure the series is now monitored otherwise we won't search for it - series.monitored = true; - foreach (var seasons in series.seasons) - { - if (model.SeasonList.Any(x => x == seasons.seasonNumber)) - { - seasons.monitored = true; - } - } - - // Send the update command - series = SonarrApi.UpdateSeries(series, sonarrSettings.ApiKey, sonarrSettings.FullUri); - SonarrApi.SearchForSeries(series.id, sonarrSettings.ApiKey, sonarrSettings.FullUri); - return new SonarrAddSeries{title = series.title}; + await RequestEpisodesForSonarr(model, series.id, sonarrSettings); } + + return new SonarrAddSeries(){title = model.Title}; } - private async Task ProcessSonarrRequestFirstSeason(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) + public SonarrAddSeries AddSeries(SonarrSettings sonarrSettings, RequestedModel model, string rootFolderPath, int qualityId) { - throw new NotImplementedException(); - } - - private async Task ProcessSonarrRequestAll(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) - { - throw new NotImplementedException(); - } - - private async Task ProcessSonarrEpisodeRequest(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) - { - // Does the series exist? - - var series = await GetSonarrSeries(sonarrSettings, model.ProviderId); - if (series == null) + //WORKS + // Add the series + var seriesToAdd = new SonarrAddSeries { - // Add the series + seasonFolder = sonarrSettings.SeasonFolders, + title = model.Title, + qualityProfileId = qualityId, + tvdbId = model.ProviderId, + titleSlug = model.Title, + seasons = new List(), + rootFolderPath = rootFolderPath, + monitored = true, // Montior the series + images = new List(), + addOptions = new AddOptions + { + ignoreEpisodesWithFiles = true, // We don't really care about these + ignoreEpisodesWithoutFiles = false, // We want to get the whole season + searchForMissingEpisodes = true // we want to search for missing + } + }; + + for (var i = 1; i <= model.SeasonCount; i++) + { + var season = new Season + { + seasonNumber = i, + monitored = model.SeasonList.Length == 0 || model.SeasonList.Any(x => x == i) + }; + seriesToAdd.seasons.Add(season); } - return null; + return SonarrApi.AddSeries(seriesToAdd, sonarrSettings.ApiKey, sonarrSettings.FullUri); + } + + private async Task RequestEpisodesForSonarr(RequestedModel model, int showId, SonarrSettings sonarrSettings) + { + // Now lookup all episodes + var ep = SonarrApi.GetEpisodes(showId.ToString(), sonarrSettings.ApiKey, sonarrSettings.FullUri); + var episodes = ep?.ToList() ?? new List(); + + var internalEpisodeIds = new List(); + var tasks = new List(); + foreach (var r in model.Episodes) + { + // Match the episode and season number. + // If the episode is monitored we might not be searching for it. + var episode = + episodes.FirstOrDefault( + x => x.episodeNumber == r.EpisodeNumber && x.seasonNumber == r.SeasonNumber); + if (episode == null) + { + continue; + } + var episodeInfo = SonarrApi.GetEpisode(episode.id.ToString(), sonarrSettings.ApiKey, + sonarrSettings.FullUri); + episodeInfo.monitored = true; // Set the episode to monitored + tasks.Add(Task.Run(() => SonarrApi.UpdateEpisode(episodeInfo, sonarrSettings.ApiKey, + sonarrSettings.FullUri))); + internalEpisodeIds.Add(episode.id); + } + + await Task.WhenAll(tasks.ToArray()); + + SonarrApi.SearchForEpisodes(internalEpisodeIds.ToArray(), sonarrSettings.ApiKey, sonarrSettings.FullUri); } public SickRageTvAdd SendToSickRage(SickRageSettings sickRageSettings, RequestedModel model) diff --git a/Ombi.UI/Bootstrapper.cs b/Ombi.UI/Bootstrapper.cs index acb9d871e..ee480294d 100644 --- a/Ombi.UI/Bootstrapper.cs +++ b/Ombi.UI/Bootstrapper.cs @@ -142,8 +142,8 @@ namespace Ombi.UI pipelines.AfterRequest.AddItemToEndOfPipeline((ctx) => { ctx.Response.WithHeader("Access-Control-Allow-Origin", "*") - .WithHeader("Access-Control-Allow-Methods", "POST,GET") - .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type"); + .WithHeader("Access-Control-Allow-Methods", "POST,GET") + .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type"); }); base.RequestStartup(container, pipelines, context); From 4836ab7e6c2429dc9f56a2714f1e016258d82617 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Mon, 3 Apr 2017 21:11:59 +0100 Subject: [PATCH 9/9] Finished reworking the Sonarr Integration. Seems to be working as expected, faster and most stable. It's Not A Toomah! --- Ombi.Core/Tv/TvSenderV2.cs | 14 ++++++-------- Ombi.Services/Jobs/PlexEpisodeCacher.cs | 8 ++++---- Ombi.UI/Modules/SearchModule.cs | 7 ++++--- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/Ombi.Core/Tv/TvSenderV2.cs b/Ombi.Core/Tv/TvSenderV2.cs index d3ad64fa4..11a97f498 100644 --- a/Ombi.Core/Tv/TvSenderV2.cs +++ b/Ombi.Core/Tv/TvSenderV2.cs @@ -120,24 +120,21 @@ namespace Ombi.Core.Tv // Add the series return AddSeries(sonarrSettings, model, rootFolderPath, qualityId); } - + // Also make sure the series is now monitored otherwise we won't search for it series.monitored = true; foreach (var seasons in series.seasons) { - if (model.SeasonList.Any(x => x == seasons.seasonNumber)) - { - seasons.monitored = true; - } + seasons.monitored = true; } // Send the update command series = SonarrApi.UpdateSeries(series, sonarrSettings.ApiKey, sonarrSettings.FullUri); SonarrApi.SearchForSeries(series.id, sonarrSettings.ApiKey, sonarrSettings.FullUri); - return new SonarrAddSeries{title = series.title}; + return new SonarrAddSeries { title = series.title }; } - + private async Task ProcessSonarrEpisodeRequest(SonarrSettings sonarrSettings, RequestedModel model, int qualityId, string rootFolderPath) { @@ -186,7 +183,7 @@ namespace Ombi.Core.Tv await RequestEpisodesForSonarr(model, series.id, sonarrSettings); } - return new SonarrAddSeries(){title = model.Title}; + return new SonarrAddSeries() { title = model.Title }; } public SonarrAddSeries AddSeries(SonarrSettings sonarrSettings, RequestedModel model, string rootFolderPath, int qualityId) @@ -217,6 +214,7 @@ namespace Ombi.Core.Tv var season = new Season { seasonNumber = i, + // The model.SeasonList.Lenth is 0 when this is a "request all" monitored = model.SeasonList.Length == 0 || model.SeasonList.Any(x => x == i) }; seriesToAdd.seasons.Add(season); diff --git a/Ombi.Services/Jobs/PlexEpisodeCacher.cs b/Ombi.Services/Jobs/PlexEpisodeCacher.cs index 26820de94..6939ae924 100644 --- a/Ombi.Services/Jobs/PlexEpisodeCacher.cs +++ b/Ombi.Services/Jobs/PlexEpisodeCacher.cs @@ -109,7 +109,7 @@ namespace Ombi.Services.Jobs var metadata = PlexApi.GetEpisodeMetaData(settings.PlexAuthToken, settings.FullUri, video.RatingKey); // Loop through the metadata and create the model to insert into the DB - foreach (var metadataVideo in metadata.Video) + foreach (var metadataVideo in metadata?.Video ?? new List