diff --git a/CHANGELOG.md b/CHANGELOG.md
index 167689d92..22234a0a2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
+## [4.11.4](https://github.com/Ombi-app/Ombi/compare/v4.11.3...v4.11.4) (2022-02-05)
+
+
+### Bug Fixes
+
+* **media-sync:** Add sanity checks upon media server sync ([#4493](https://github.com/Ombi-app/Ombi/issues/4493)) ([9915234](https://github.com/Ombi-app/Ombi/commit/9915234d38d4701c527081ccc21b566980375331)), closes [#4472](https://github.com/Ombi-app/Ombi/issues/4472)
+* **newsletter:** Fix newsletter not publishing double episodes ([#4495](https://github.com/Ombi-app/Ombi/issues/4495)) ([ddf63fb](https://github.com/Ombi-app/Ombi/commit/ddf63fbed0b9cbe458aec37318758c76b99b2de9))
+
+
+
+## [4.11.3](https://github.com/Ombi-app/Ombi/compare/v4.11.2...v4.11.3) (2022-02-03)
+
+
+### Bug Fixes
+
+* **API:** Fixed an issue where the API key couldn't delete a request [#4489](https://github.com/Ombi-app/Ombi/issues/4489) ([8e42dbf](https://github.com/Ombi-app/Ombi/commit/8e42dbf8f78caa51ca891bf3d702c6b0ac401f9c))
+
+
+
## [4.11.2](https://github.com/Ombi-app/Ombi/compare/v4.11.1...v4.11.2) (2022-02-01)
@@ -356,21 +375,3 @@
-## [4.2.10](https://github.com/Ombi-app/Ombi/compare/v4.2.9...v4.2.10) (2021-10-15)
-
-
-### Bug Fixes
-
-* :bug: Really really fix it this time? ([543d36e](https://github.com/Ombi-app/Ombi/commit/543d36e5615341bc8378cac377b843a3dbc1ef99))
-
-
-
-## [4.2.9](https://github.com/Ombi-app/Ombi/compare/v4.2.8...v4.2.9) (2021-10-15)
-
-
-### Bug Fixes
-
-* :fire: Really fix the base url issue this time ([9f36923](https://github.com/Ombi-app/Ombi/commit/9f36923c51bfabf9cb026f2da14f9947050af0d9))
-
-
-
diff --git a/README.md b/README.md
index 97f61b650..aacb9a2ea 100644
--- a/README.md
+++ b/README.md
@@ -114,6 +114,13 @@ Here are some of the features Ombi has:
+
+
+
+
+ Sephrat
+
+ |
@@ -128,13 +135,6 @@ Here are some of the features Ombi has:
Shaun McPeck
|
-
-
-
-
- Sephrat
-
- |
diff --git a/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs b/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs
index 8302ee3ee..4a19025de 100644
--- a/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs
+++ b/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs
@@ -1,12 +1,10 @@
-namespace Ombi.Api.Emby.Models.Movie
+using Ombi.Api.MediaServer.Models;
+
+namespace Ombi.Api.Emby.Models.Movie
{
- public class EmbyProviderids
+ public class EmbyProviderids: BaseProviderids
{
- public string Tmdb { get; set; }
- public string Imdb { get; set; }
public string TmdbCollection { get; set; }
-
- public string Tvdb { get; set; }
public string Zap2It { get; set; }
public string TvRage { get; set; }
}
diff --git a/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj b/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj
index f167146af..b524c9ce4 100644
--- a/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj
+++ b/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj
@@ -12,6 +12,7 @@
+
diff --git a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs
index 9b47f9a1a..0896ec4e9 100644
--- a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs
+++ b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs
@@ -1,12 +1,10 @@
-namespace Ombi.Api.Jellyfin.Models.Movie
+using Ombi.Api.MediaServer.Models;
+
+namespace Ombi.Api.Jellyfin.Models.Movie
{
- public class JellyfinProviderids
+ public class JellyfinProviderids: BaseProviderids
{
- public string Tmdb { get; set; }
- public string Imdb { get; set; }
public string TmdbCollection { get; set; }
-
- public string Tvdb { get; set; }
public string Zap2It { get; set; }
public string TvRage { get; set; }
}
diff --git a/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj b/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj
index f167146af..dfdb5a93f 100644
--- a/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj
+++ b/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj
@@ -13,6 +13,7 @@
+
\ No newline at end of file
diff --git a/src/Ombi.Api.MediaServer/Models/BaseProviderids.cs b/src/Ombi.Api.MediaServer/Models/BaseProviderids.cs
new file mode 100644
index 000000000..6044288c6
--- /dev/null
+++ b/src/Ombi.Api.MediaServer/Models/BaseProviderids.cs
@@ -0,0 +1,11 @@
+namespace Ombi.Api.MediaServer.Models
+{
+ public class BaseProviderids
+ {
+ public string Tmdb { get; set; }
+ public string Imdb { get; set; }
+ public string Tvdb { get; set; }
+ public bool Any() =>
+ !string.IsNullOrEmpty(Imdb) || !string.IsNullOrEmpty(Tmdb) || !string.IsNullOrEmpty(Tvdb);
+ }
+}
\ No newline at end of file
diff --git a/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj b/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj
new file mode 100644
index 000000000..f167146af
--- /dev/null
+++ b/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj
@@ -0,0 +1,18 @@
+
+
+
+ net6.0
+ 3.0.0.0
+ 3.0.0.0
+
+
+ 8.0
+ Debug;Release;NonUiBuild
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs
index cb7eaefd3..646cbdee0 100644
--- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs
+++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs
@@ -149,7 +149,7 @@ namespace Ombi.Schedule.Jobs.Emby
foreach (var tvShow in tv.Items)
{
processed++;
- if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb))
+ if (!tvShow.ProviderIds.Any())
{
_logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name);
continue;
@@ -249,6 +249,12 @@ namespace Ombi.Schedule.Jobs.Emby
var alreadyGoingToAdd = content.Any(x => x.EmbyId == movieInfo.Id);
if (existingMovie == null && !alreadyGoingToAdd)
{
+
+ if (!movieInfo.ProviderIds.Any())
+ {
+ _logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping.");
+ return;
+ }
_logger.LogDebug("Adding new movie {0}", movieInfo.Name);
content.Add(new EmbyContent
{
diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs
index c1ca48ef7..b3c1ffbab 100644
--- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs
+++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs
@@ -152,6 +152,13 @@ namespace Ombi.Schedule.Jobs.Emby
if (existingEpisode == null && !existingInList)
{
+ // Sanity checks
+ if (ep.IndexNumber == 0)
+ {
+ _logger.LogWarning($"Episode {ep.Name} has no episode number. Skipping.");
+ continue;
+ }
+
_logger.LogDebug("Adding new episode {0} to parent {1}", ep.Name, ep.SeriesName);
// add it
epToAdd.Add(new EmbyEpisode
diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs
index 60ee42210..fec5ca0ce 100644
--- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs
+++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs
@@ -127,7 +127,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
{
processed++;
- if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb))
+ if (!tvShow.ProviderIds.Any())
{
_logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name);
continue;
@@ -217,6 +217,11 @@ namespace Ombi.Schedule.Jobs.Jellyfin
var alreadyGoingToAdd = content.Any(x => x.JellyfinId == movieInfo.Id);
if (existingMovie == null && !alreadyGoingToAdd)
{
+ if (!movieInfo.ProviderIds.Any())
+ {
+ _logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping.");
+ return;
+ }
_logger.LogDebug("Adding new movie {0}", movieInfo.Name);
content.Add(new JellyfinContent
{
diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs
index 27e50c9b7..6e2daa7b3 100644
--- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs
+++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs
@@ -66,7 +66,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
public async Task Execute(IJobExecutionContext job)
{
var settings = await _settings.GetSettingsAsync();
-
+
Api = _apiFactory.CreateClient(settings);
await _notification.Clients.Clients(NotificationHub.AdminConnectionIds)
.SendAsync(NotificationHub.NotificationEvent, "Jellyfin Episode Sync Started");
@@ -128,6 +128,13 @@ namespace Ombi.Schedule.Jobs.Jellyfin
if (existingEpisode == null && !existingInList)
{
+ // Sanity checks
+ if (ep.IndexNumber == 0) // no check on season number, Season 0 can be Specials
+ {
+ _logger.LogWarning($"Episode {ep.Name} has no episode number. Skipping.");
+ continue;
+ }
+
_logger.LogDebug("Adding new episode {0} to parent {1}", ep.Name, ep.SeriesName);
// add it
epToAdd.Add(new JellyfinEpisode
diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs
index f965625f6..dbb343126 100644
--- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs
+++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs
@@ -726,28 +726,8 @@ namespace Ombi.Schedule.Jobs.Ombi
AddTvTitle(tvInfo);
- // Group by the season number
- var results = t.Episodes.GroupBy(p => p.SeasonNumber,
- (key, g) => new
- {
- SeasonNumber = key,
- Episodes = g.ToList(),
- EpisodeAirDate = tvInfo?.seasons?.Where(x => x.season_number == key)?.Select(x => x.air_date).FirstOrDefault()
- }
- );
-
- // Group the episodes
- var finalsb = new StringBuilder();
- foreach (var epInformation in results.OrderBy(x => x.SeasonNumber))
- {
- var orderedEpisodes = epInformation.Episodes.OrderBy(x => x.EpisodeNumber).ToList();
- var episodeString = StringHelper.BuildEpisodeList(orderedEpisodes.Select(x => x.EpisodeNumber));
- var episodeAirDate = epInformation.EpisodeAirDate;
- finalsb.Append($"{Texts.SeasonLabel} {epInformation.SeasonNumber} - {Texts.EpisodesLabel} {episodeString} {episodeAirDate}");
- finalsb.Append(" ");
- }
-
- AddTvEpisodesSummaryGenres(finalsb.ToString(), tvInfo);
+ var tvEpisodesString = GetTvEpisodesString(tvInfo, t.Episodes);
+ AddTvEpisodesSummaryGenres(tvEpisodesString, tvInfo);
}
catch (Exception e)
@@ -769,6 +749,44 @@ namespace Ombi.Schedule.Jobs.Ombi
}
}
+ private string GetTvEpisodesString(TvInfo tvInfo, ICollection episodes)
+ {
+ if (episodes.Count >= tvInfo.number_of_episodes)
+ {
+ // do not list individual episodes when the series is complete
+ return string.Empty;
+ }
+
+ var sb = new StringBuilder();
+ // Group by the season number
+ var seasons = episodes.GroupBy(p => p.SeasonNumber,
+ (key, g) => new
+ {
+ SeasonNumber = key,
+ Episodes = g.ToList(),
+ Header = tvInfo?.seasons?.Where(x => x.season_number == key).FirstOrDefault(),
+ }
+ );
+ // Group the episodes
+ foreach (var season in seasons.OrderBy(x => x.SeasonNumber))
+ {
+ string episodeList;
+ if (season.Episodes.Count >= season.Header.episode_count)
+ {
+ // do not list individual episodes when the season is complete
+ episodeList = string.Empty;
+ }
+ else
+ {
+ var orderedEpisodes = season.Episodes.OrderBy(x => x.EpisodeNumber).ToList();
+ episodeList = $"{Texts.EpisodesLabel} {StringHelper.BuildEpisodeList(orderedEpisodes.Select(x => x.EpisodeNumber))}";
+ }
+ var episodeAirDate = season.Header.air_date;
+ sb.Append($"{Texts.SeasonLabel} {season.SeasonNumber} - {episodeList} {episodeAirDate}");
+ sb.Append(" ");
+ }
+ return sb.ToString();
+ }
private void AddTvTitle(TvInfo tvInfo)
{
var title = "";
diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs
index df96457d0..bdb7e70bc 100644
--- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs
+++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs
@@ -342,6 +342,11 @@ namespace Ombi.Schedule.Jobs.Plex
}
}
+ if (!guids.Any())
+ {
+ Logger.LogWarning($"Movie {movie.title} has no relevant metadata. Skipping.");
+ continue;
+ }
var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray());
var item = new PlexServerContent
diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs
index 4a088ca7b..c17af088c 100644
--- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs
+++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs
@@ -179,6 +179,13 @@ namespace Ombi.Schedule.Jobs.Plex
episode.grandparentRatingKey = seriesExists.Key;
}
+ // Sanity checks
+ if (episode.index == 0)
+ {
+ _log.LogWarning($"Episode {episode.title} has no episode number. Skipping.");
+ continue;
+ }
+
ep.Add(new PlexEpisode
{
EpisodeNumber = episode.index,
diff --git a/src/Ombi.Store/Entities/EmbyEpisode.cs b/src/Ombi.Store/Entities/EmbyEpisode.cs
index 97fdb09b1..89103c580 100644
--- a/src/Ombi.Store/Entities/EmbyEpisode.cs
+++ b/src/Ombi.Store/Entities/EmbyEpisode.cs
@@ -57,11 +57,5 @@ namespace Ombi.Store.Entities
return content.OfType().FirstOrDefault(
x => x.EmbyId == this.EmbySeries.EmbyId);
}
-
- public override bool IsIn(IMediaServerContent content)
- {
- return content.Episodes.Cast().Any(x => x.EmbyId == this.EmbyId);
- }
-
}
}
\ No newline at end of file
diff --git a/src/Ombi.Store/Entities/JellyfinEpisode.cs b/src/Ombi.Store/Entities/JellyfinEpisode.cs
index 1c0ac423e..5b105003c 100644
--- a/src/Ombi.Store/Entities/JellyfinEpisode.cs
+++ b/src/Ombi.Store/Entities/JellyfinEpisode.cs
@@ -58,10 +58,5 @@ namespace Ombi.Store.Entities
return content.OfType().FirstOrDefault(
x => x.JellyfinId == this.JellyfinSeries.JellyfinId);
}
-
- public override bool IsIn(IMediaServerContent content)
- {
- return content.Episodes.Cast().Any(x => x.JellyfinId == this.JellyfinId);
- }
}
}
diff --git a/src/Ombi.Store/Entities/MediaServerContent.cs b/src/Ombi.Store/Entities/MediaServerContent.cs
index 3bccfea06..df50efc86 100644
--- a/src/Ombi.Store/Entities/MediaServerContent.cs
+++ b/src/Ombi.Store/Entities/MediaServerContent.cs
@@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations.Schema;
-using Ombi.Store.Repository;
+using System.Linq;
namespace Ombi.Store.Entities
{
@@ -42,6 +41,9 @@ namespace Ombi.Store.Entities
public IMediaServerContent Series { get; set; }
public abstract IMediaServerContent SeriesIsIn(ICollection content);
- public abstract bool IsIn(IMediaServerContent content);
+ public bool IsIn(IMediaServerContent content)
+ {
+ return content.Episodes.Any(x => x.SeasonNumber == this.SeasonNumber && x.EpisodeNumber == this.EpisodeNumber);
+ }
}
}
\ No newline at end of file
diff --git a/src/Ombi.Store/Entities/PlexEpisode.cs b/src/Ombi.Store/Entities/PlexEpisode.cs
index ac482d7ac..02cfc8a07 100644
--- a/src/Ombi.Store/Entities/PlexEpisode.cs
+++ b/src/Ombi.Store/Entities/PlexEpisode.cs
@@ -28,11 +28,5 @@ namespace Ombi.Store.Entities
return content.OfType().FirstOrDefault(
x => x.Key == this.PlexSeries.Key);
}
-
- public override bool IsIn(IMediaServerContent content)
- {
- return content.Episodes.Cast().Any(x => x.Key == this.Key);
- }
-
}
}
\ No newline at end of file
diff --git a/version.json b/version.json
index 447d806a2..2c5745167 100644
--- a/version.json
+++ b/version.json
@@ -1,3 +1,3 @@
{
- "version": "4.11.2"
+ "version": "4.11.4"
}
\ No newline at end of file
|