First pass at newsletter refactoring

This commit is contained in:
Florian Dupret 2022-01-11 19:17:25 +01:00
commit 229a89f48a
19 changed files with 198 additions and 617 deletions

View file

@ -46,10 +46,10 @@ namespace Ombi.Core.Rule.Rules.Search
} }
} }
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<PlexEpisode> allEpisodes, EpisodeRequests episode, public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<IMediaServerEpisode> allEpisodes, EpisodeRequests episode,
SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log) SeasonRequests season, IMediaServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log)
{ {
PlexEpisode epExists = null; IMediaServerEpisode epExists = null;
try try
{ {
@ -79,66 +79,6 @@ namespace Ombi.Core.Rule.Rules.Search
log.LogError(e, "Exception thrown when attempting to check if something is available"); log.LogError(e, "Exception thrown when attempting to check if something is available");
} }
if (epExists != null)
{
episode.Available = true;
}
}
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<EmbyEpisode> allEpisodes, EpisodeRequests episode,
SeasonRequests season, EmbyContent item, bool useTheMovieDb, bool useTvDb)
{
EmbyEpisode epExists = null;
if (useImdb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.ImdbId == item.ImdbId);
}
if (useTheMovieDb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TheMovieDbId == item.TheMovieDbId);
}
if (useTvDb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TvDbId == item.TvDbId);
}
if (epExists != null)
{
episode.Available = true;
}
}
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<JellyfinEpisode> allEpisodes, EpisodeRequests episode,
SeasonRequests season, JellyfinContent item, bool useTheMovieDb, bool useTvDb)
{
JellyfinEpisode epExists = null;
if (useImdb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.ImdbId == item.ImdbId);
}
if (useTheMovieDb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TheMovieDbId == item.TheMovieDbId);
}
if (useTvDb)
{
epExists = await allEpisodes.FirstOrDefaultAsync(x =>
x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
x.Series.TvDbId == item.TvDbId);
}
if (epExists != null) if (epExists != null)
{ {
episode.Available = true; episode.Available = true;

View file

@ -1,6 +1,7 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces; using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Settings; using Ombi.Core.Settings;
@ -13,13 +14,15 @@ namespace Ombi.Core.Rule.Rules.Search
{ {
public class EmbyAvailabilityRule : BaseSearchRule, IRules<SearchViewModel> public class EmbyAvailabilityRule : BaseSearchRule, IRules<SearchViewModel>
{ {
public EmbyAvailabilityRule(IEmbyContentRepository repo, ISettingsService<EmbySettings> s) public EmbyAvailabilityRule(IEmbyContentRepository repo, ILogger<EmbyAvailabilityRule> log, ISettingsService<EmbySettings> s)
{ {
EmbyContentRepository = repo; EmbyContentRepository = repo;
Log = log;
EmbySettings = s; EmbySettings = s;
} }
private IEmbyContentRepository EmbyContentRepository { get; } private IEmbyContentRepository EmbyContentRepository { get; }
private ILogger Log { get; }
private ISettingsService<EmbySettings> EmbySettings { get; } private ISettingsService<EmbySettings> EmbySettings { get; }
public async Task<RuleResult> Execute(SearchViewModel obj) public async Task<RuleResult> Execute(SearchViewModel obj)
@ -89,7 +92,7 @@ namespace Ombi.Core.Rule.Rules.Search
{ {
foreach (var episode in season.Episodes) foreach (var episode in season.Episodes)
{ {
await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb); await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log);
} }
} }
} }

View file

@ -1,6 +1,7 @@
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core.Models.Search; using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces; using Ombi.Core.Rule.Interfaces;
using Ombi.Core.Settings; using Ombi.Core.Settings;
@ -13,13 +14,15 @@ namespace Ombi.Core.Rule.Rules.Search
{ {
public class JellyfinAvailabilityRule : BaseSearchRule, IRules<SearchViewModel> public class JellyfinAvailabilityRule : BaseSearchRule, IRules<SearchViewModel>
{ {
public JellyfinAvailabilityRule(IJellyfinContentRepository repo, ISettingsService<JellyfinSettings> s) public JellyfinAvailabilityRule(IJellyfinContentRepository repo, ILogger<JellyfinAvailabilityRule> log, ISettingsService<JellyfinSettings> s)
{ {
JellyfinContentRepository = repo; JellyfinContentRepository = repo;
Log = log;
JellyfinSettings = s; JellyfinSettings = s;
} }
private IJellyfinContentRepository JellyfinContentRepository { get; } private IJellyfinContentRepository JellyfinContentRepository { get; }
private ILogger Log { get; }
private ISettingsService<JellyfinSettings> JellyfinSettings { get; } private ISettingsService<JellyfinSettings> JellyfinSettings { get; }
public async Task<RuleResult> Execute(SearchViewModel obj) public async Task<RuleResult> Execute(SearchViewModel obj)
@ -104,7 +107,7 @@ namespace Ombi.Core.Rule.Rules.Search
{ {
foreach (var episode in season.Episodes) foreach (var episode in season.Episodes)
{ {
await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb); await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log);
} }
} }
} }

View file

@ -124,7 +124,7 @@ namespace Ombi.Schedule.Jobs.Emby
var tvDbId = child.ParentRequest.TvDbId; var tvDbId = child.ParentRequest.TvDbId;
var imdbId = child.ParentRequest.ImdbId; var imdbId = child.ParentRequest.ImdbId;
IQueryable<EmbyEpisode> seriesEpisodes = null; IQueryable<IMediaServerEpisode> seriesEpisodes = null;
if (useImdb) if (useImdb)
{ {
seriesEpisodes = embyEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString()); seriesEpisodes = embyEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());

View file

@ -151,7 +151,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
var tvDbId = child.ParentRequest.TvDbId; var tvDbId = child.ParentRequest.TvDbId;
var imdbId = child.ParentRequest.ImdbId; var imdbId = child.ParentRequest.ImdbId;
IQueryable<JellyfinEpisode> seriesEpisodes = null; IQueryable<IMediaServerEpisode> seriesEpisodes = null;
if (useImdb) if (useImdb)
{ {
seriesEpisodes = jellyfinEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString()); seriesEpisodes = jellyfinEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());

View file

@ -124,18 +124,22 @@ namespace Ombi.Schedule.Jobs.Ombi
var customization = await _customizationSettings.GetSettingsAsync(); var customization = await _customizationSettings.GetSettingsAsync();
// Get the Content // MOVIES
var plexContent = _plex.GetAll().Include(x => x.Episodes).AsNoTracking(); var plexContent = (IQueryable<IMediaServerContent>)_plex.GetAll().Include(x => x.Episodes).AsNoTracking();
var embyContent = _emby.GetAll().Include(x => x.Episodes).AsNoTracking(); var embyContent = (IQueryable<IMediaServerContent>)_emby.GetAll().Include(x => x.Episodes).AsNoTracking();
var jellyfinContent = _jellyfin.GetAll().Include(x => x.Episodes).AsNoTracking(); var jellyfinContent = (IQueryable<IMediaServerContent>)_jellyfin.GetAll().Include(x => x.Episodes).AsNoTracking();
var plexContentMoviesToSend = await getMoviesContent(plexContent, RecentlyAddedType.Plex);
var embyContentMoviesToSend = await getMoviesContent(embyContent, RecentlyAddedType.Emby);
var jellyfinContentMoviesToSend = await getMoviesContent(jellyfinContent, RecentlyAddedType.Jellyfin);
// MUSIC
var lidarrContent = _lidarrAlbumRepository.GetAll().AsNoTracking().ToList().Where(x => x.FullyAvailable); var lidarrContent = _lidarrAlbumRepository.GetAll().AsNoTracking().ToList().Where(x => x.FullyAvailable);
var addedLog = _recentlyAddedLog.GetAll().ToList(); var addedLog = _recentlyAddedLog.GetAll().ToList();
HashSet<int> addedPlexMovieLogIds, addedEmbyMoviesLogIds, addedJellyfinMoviesLogIds;
HashSet<string> addedAlbumLogIds; HashSet<string> addedAlbumLogIds;
GetRecentlyAddedMoviesData(addedLog, out addedPlexMovieLogIds, out addedEmbyMoviesLogIds, out addedJellyfinMoviesLogIds, out addedAlbumLogIds); GetRecentlyAddedMoviesData(addedLog, out addedAlbumLogIds);
// EPISODES
var addedPlexEpisodesLogIds = var addedPlexEpisodesLogIds =
addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Episode); addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Episode);
var addedEmbyEpisodesLogIds = var addedEmbyEpisodesLogIds =
@ -145,39 +149,14 @@ namespace Ombi.Schedule.Jobs.Ombi
// Filter out the ones that we haven't sent yet // Filter out the ones that we haven't sent yet
var plexContentLocalDataset = plexContent.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
var embyContentLocalDataset = embyContent.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
var jellyfinContentLocalDataset = jellyfinContent.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
var plexContentMoviesToSend = plexContentLocalDataset.Where(x => !addedPlexMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet();
var embyContentMoviesToSend = embyContentLocalDataset.Where(x => !addedEmbyMoviesLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet();
var jellyfinContentMoviesToSend = jellyfinContentLocalDataset.Where(x => !addedJellyfinMoviesLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet();
var lidarrContentAlbumsToSend = lidarrContent.Where(x => !addedAlbumLogIds.Contains(x.ForeignAlbumId)).ToHashSet(); var lidarrContentAlbumsToSend = lidarrContent.Where(x => !addedAlbumLogIds.Contains(x.ForeignAlbumId)).ToHashSet();
_log.LogInformation("Plex Movies to send: {0}", plexContentMoviesToSend.Count());
_log.LogInformation("Emby Movies to send: {0}", embyContentMoviesToSend.Count());
_log.LogInformation("Jellyfin Movies to send: {0}", jellyfinContentMoviesToSend.Count());
_log.LogInformation("Albums to send: {0}", lidarrContentAlbumsToSend.Count()); _log.LogInformation("Albums to send: {0}", lidarrContentAlbumsToSend.Count());
// Find the movies that do not yet have MovieDbIds
var needsMovieDbPlex = plexContent.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
var needsMovieDbEmby = embyContent.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
var needsMovieDbJellyfin = jellyfinContent.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
var newPlexMovies = await GetMoviesWithoutId(addedPlexMovieLogIds, needsMovieDbPlex);
var newEmbyMovies = await GetMoviesWithoutId(addedEmbyMoviesLogIds, needsMovieDbEmby);
var newJellyfinMovies = await GetMoviesWithoutId(addedJellyfinMoviesLogIds, needsMovieDbJellyfin);
plexContentMoviesToSend = plexContentMoviesToSend.Union(newPlexMovies).ToHashSet();
embyContentMoviesToSend = embyContentMoviesToSend.Union(newEmbyMovies).ToHashSet();
jellyfinContentMoviesToSend = jellyfinContentMoviesToSend.Union(newJellyfinMovies).ToHashSet();
plexContentMoviesToSend = plexContentMoviesToSend.DistinctBy(x => x.Id).ToHashSet();
embyContentMoviesToSend = embyContentMoviesToSend.DistinctBy(x => x.Id).ToHashSet();
jellyfinContentMoviesToSend = jellyfinContentMoviesToSend.DistinctBy(x => x.Id).ToHashSet();
var plexEpisodesToSend = var plexEpisodesToSend =
FilterPlexEpisodes(_plex.GetAllEpisodes().Include(x => x.Series).AsNoTracking(), addedPlexEpisodesLogIds); FilterEpisodes(_plex.GetAllEpisodes().Include(x => x.Series).AsNoTracking(), addedPlexEpisodesLogIds);
var embyEpisodesToSend = FilterEmbyEpisodes(_emby.GetAllEpisodes().Include(x => x.Series).AsNoTracking(), var embyEpisodesToSend = FilterEpisodes(_emby.GetAllEpisodes().Include(x => x.Series).AsNoTracking(),
addedEmbyEpisodesLogIds); addedEmbyEpisodesLogIds);
var jellyfinEpisodesToSend = FilterJellyfinEpisodes(_jellyfin.GetAllEpisodes().Include(x => x.Series).AsNoTracking(), var jellyfinEpisodesToSend = FilterEpisodes(_jellyfin.GetAllEpisodes().Include(x => x.Series).AsNoTracking(),
addedJellyfinEpisodesLogIds); addedJellyfinEpisodesLogIds);
_log.LogInformation("Plex Episodes to send: {0}", plexEpisodesToSend.Count()); _log.LogInformation("Plex Episodes to send: {0}", plexEpisodesToSend.Count());
@ -193,14 +172,36 @@ namespace Ombi.Schedule.Jobs.Ombi
var embym = embyContent.Where(x => x.Type == MediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10); var embym = embyContent.Where(x => x.Type == MediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10);
var jellyfinm = jellyfinContent.Where(x => x.Type == MediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10); var jellyfinm = jellyfinContent.Where(x => x.Type == MediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10);
var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet(); var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet();
var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet();
var jellyfint = _jellyfin.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); var jellyfint = _jellyfin.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet();
var lidarr = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); var lidarr = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet();
body = await BuildHtml(plexm, embym, jellyfinm, plext, embyt, jellyfint, lidarr, settings, embySettings, jellyfinSettings, plexSettings);
var moviesProviders = new List<IQueryable<IMediaServerContent>>() {
plexm,
embym,
jellyfinm
};
var seriesProviders = new List<IEnumerable<IMediaServerEpisode>>() {
plext,
embyt,
jellyfint
};
body = await BuildHtml(moviesProviders, seriesProviders, lidarr, settings, embySettings, jellyfinSettings, plexSettings);
} }
else else
{ {
body = await BuildHtml(plexContentMoviesToSend.AsQueryable(), embyContentMoviesToSend.AsQueryable(), jellyfinContentMoviesToSend.AsQueryable(), plexEpisodesToSend, embyEpisodesToSend, jellyfinEpisodesToSend, lidarrContentAlbumsToSend, settings, embySettings, jellyfinSettings, plexSettings); var moviesProviders = new List<IQueryable<IMediaServerContent>>() {
plexContentMoviesToSend.AsQueryable(),
embyContentMoviesToSend.AsQueryable(),
jellyfinContentMoviesToSend.AsQueryable()
};
var seriesProviders = new List<IEnumerable<IMediaServerEpisode>>() {
plexEpisodesToSend,
embyEpisodesToSend,
jellyfinEpisodesToSend
};
body = await BuildHtml(moviesProviders, seriesProviders, lidarrContentAlbumsToSend, settings, embySettings, jellyfinSettings, plexSettings);
if (body.IsNullOrEmpty()) if (body.IsNullOrEmpty())
{ {
return; return;
@ -224,7 +225,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (!users.Any()) if (!users.Any())
{ {
return; return;
} }
var messageContent = ParseTemplate(template, customization); var messageContent = ParseTemplate(template, customization);
var email = new NewsletterTemplate(); var email = new NewsletterTemplate();
@ -376,21 +377,32 @@ namespace Ombi.Schedule.Jobs.Ombi
.SendAsync(NotificationHub.NotificationEvent, "Newsletter Finished"); .SendAsync(NotificationHub.NotificationEvent, "Newsletter Finished");
} }
private void GetRecentlyAddedMoviesData(List<RecentlyAddedLog> addedLog, out HashSet<int> addedPlexMovieLogIds, out HashSet<int> addedEmbyMoviesLogIds, out HashSet<int> addedJellyfinMoviesLogIds, out HashSet<string> addedAlbumLogIds) private void GetRecentlyAddedMoviesData(List<RecentlyAddedLog> addedLog, out HashSet<string> addedAlbumLogIds)
{ {
var plexParent = addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Parent).ToList();
addedPlexMovieLogIds = plexParent != null && plexParent.Any() ? (plexParent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet<int>()) : new HashSet<int>();
var embyParent = addedLog.Where(x => x.Type == RecentlyAddedType.Emby && x.ContentType == ContentType.Parent);
addedEmbyMoviesLogIds = embyParent != null && embyParent.Any() ? (embyParent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet<int>()) : new HashSet<int>();
var jellyFinParent = addedLog.Where(x => x.Type == RecentlyAddedType.Jellyfin && x.ContentType == ContentType.Parent);
addedJellyfinMoviesLogIds = jellyFinParent != null && jellyFinParent.Any() ? (jellyFinParent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet<int>()) : new HashSet<int>();
var lidarrParent = addedLog.Where(x => x.Type == RecentlyAddedType.Lidarr && x.ContentType == ContentType.Album); var lidarrParent = addedLog.Where(x => x.Type == RecentlyAddedType.Lidarr && x.ContentType == ContentType.Album);
addedAlbumLogIds = lidarrParent != null && lidarrParent.Any() ? (lidarrParent?.Select(x => x.AlbumId)?.ToHashSet() ?? new HashSet<string>()) : new HashSet<string>(); addedAlbumLogIds = lidarrParent != null && lidarrParent.Any() ? (lidarrParent?.Select(x => x.AlbumId)?.ToHashSet() ?? new HashSet<string>()) : new HashSet<string>();
} }
private async Task<HashSet<IMediaServerContent>> getMoviesContent(IQueryable<IMediaServerContent> content, RecentlyAddedType recentlyAddedType)
{
var localDataset = content.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
// Filter out the ones that we haven't sent yet
var addedLog = _recentlyAddedLog.GetAll().ToList();
var plexParent = addedLog.Where(x => x.Type == recentlyAddedType
&& x.ContentType == ContentType.Parent).ToList();
var addedPlexMovieLogIds = plexParent != null && plexParent.Any() ? (plexParent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet<int>()) : new HashSet<int>();
var plexContentMoviesToSend = localDataset.Where(x => !addedPlexMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet();
_log.LogInformation("Movies to send: {0}", plexContentMoviesToSend.Count());
// Find the movies that do not yet have MovieDbIds
var needsMovieDbPlex = content.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet();
var newPlexMovies = await GetMoviesWithoutId(addedPlexMovieLogIds, needsMovieDbPlex);
plexContentMoviesToSend = plexContentMoviesToSend.Union(newPlexMovies).ToHashSet();
return plexContentMoviesToSend.DistinctBy(x => x.Id).ToHashSet();
}
public static string GenerateUnsubscribeLink(string applicationUrl, string id) public static string GenerateUnsubscribeLink(string applicationUrl, string id)
{ {
if (!applicationUrl.HasValue() || !id.HasValue()) if (!applicationUrl.HasValue() || !id.HasValue())
@ -406,7 +418,7 @@ namespace Ombi.Schedule.Jobs.Ombi
return b.ToString(); return b.ToString();
} }
private async Task<HashSet<PlexServerContent>> GetMoviesWithoutId(HashSet<int> addedMovieLogIds, HashSet<PlexServerContent> needsMovieDbPlex) private async Task<HashSet<IMediaServerContent>> GetMoviesWithoutId(HashSet<int> addedMovieLogIds, HashSet<IMediaServerContent> needsMovieDbPlex)
{ {
foreach (var movie in needsMovieDbPlex) foreach (var movie in needsMovieDbPlex)
{ {
@ -420,35 +432,7 @@ namespace Ombi.Schedule.Jobs.Ombi
return result.ToHashSet(); return result.ToHashSet();
} }
private async Task<HashSet<EmbyContent>> GetMoviesWithoutId(HashSet<int> addedMovieLogIds, HashSet<EmbyContent> needsMovieDbPlex) private async Task UpdateTheMovieDbId(IEnumerable<IMediaServerContent> content)
{
foreach (var movie in needsMovieDbPlex)
{
var id = await _refreshMetadata.GetTheMovieDbId(false, true, null, movie.ImdbId, movie.Title, true);
movie.TheMovieDbId = id.ToString();
}
var result = needsMovieDbPlex.Where(x => x.HasTheMovieDb && !addedMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId)));
await UpdateTheMovieDbId(result);
// Filter them out now
return result.ToHashSet();
}
private async Task<HashSet<JellyfinContent>> GetMoviesWithoutId(HashSet<int> addedMovieLogIds, HashSet<JellyfinContent> needsMovieDbJellyfin)
{
foreach (var movie in needsMovieDbJellyfin)
{
var id = await _refreshMetadata.GetTheMovieDbId(false, true, null, movie.ImdbId, movie.Title, true);
movie.TheMovieDbId = id.ToString();
}
var result = needsMovieDbJellyfin.Where(x => x.HasTheMovieDb && !addedMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId)));
await UpdateTheMovieDbId(result);
// Filter them out now
return result.ToHashSet();
}
private async Task UpdateTheMovieDbId(IEnumerable<PlexServerContent> content)
{ {
foreach (var movie in content) foreach (var movie in content)
{ {
@ -467,79 +451,15 @@ namespace Ombi.Schedule.Jobs.Ombi
await _plex.SaveChangesAsync(); await _plex.SaveChangesAsync();
} }
private async Task UpdateTheMovieDbId(IEnumerable<EmbyContent> content)
{
foreach (var movie in content)
{
if (!movie.HasTheMovieDb)
{
continue;
}
var entity = await _emby.Find(movie.Id);
entity.TheMovieDbId = movie.TheMovieDbId;
_emby.UpdateWithoutSave(entity);
}
await _plex.SaveChangesAsync();
}
private async Task UpdateTheMovieDbId(IEnumerable<JellyfinContent> content)
{
foreach (var movie in content)
{
if (!movie.HasTheMovieDb)
{
continue;
}
var entity = await _jellyfin.Find(movie.Id);
entity.TheMovieDbId = movie.TheMovieDbId;
_jellyfin.UpdateWithoutSave(entity);
}
await _plex.SaveChangesAsync();
}
public async Task Execute(IJobExecutionContext job) public async Task Execute(IJobExecutionContext job)
{ {
var newsletterSettings = await _newsletterSettings.GetSettingsAsync(); var newsletterSettings = await _newsletterSettings.GetSettingsAsync();
await Start(newsletterSettings, false); await Start(newsletterSettings, false);
} }
private HashSet<PlexEpisode> FilterPlexEpisodes(IEnumerable<PlexEpisode> source, IEnumerable<RecentlyAddedLog> recentlyAdded) private HashSet<IMediaServerEpisode> FilterEpisodes(IEnumerable<IMediaServerEpisode> source, IEnumerable<RecentlyAddedLog> recentlyAdded)
{ {
var itemsToReturn = new HashSet<PlexEpisode>(); var itemsToReturn = new HashSet<IMediaServerEpisode>();
foreach (var ep in source.Where(x => x.Series.HasTvDb))
{
var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId);
if (recentlyAdded.Any(x => x.ContentId == tvDbId && x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == ep.SeasonNumber))
{
continue;
}
itemsToReturn.Add(ep);
}
return itemsToReturn;
}
private HashSet<EmbyEpisode> FilterEmbyEpisodes(IEnumerable<EmbyEpisode> source, IEnumerable<RecentlyAddedLog> recentlyAdded)
{
var itemsToReturn = new HashSet<EmbyEpisode>();
foreach (var ep in source.Where(x => x.Series.HasTvDb))
{
var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId);
if (recentlyAdded.Any(x => x.ContentId == tvDbId && x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == ep.SeasonNumber))
{
continue;
}
itemsToReturn.Add(ep);
}
return itemsToReturn;
}
private HashSet<JellyfinEpisode> FilterJellyfinEpisodes(IEnumerable<JellyfinEpisode> source, IEnumerable<RecentlyAddedLog> recentlyAdded)
{
var itemsToReturn = new HashSet<JellyfinEpisode>();
foreach (var ep in source.Where(x => x.Series.HasTvDb)) foreach (var ep in source.Where(x => x.Series.HasTvDb))
{ {
var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId); var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId);
@ -564,17 +484,14 @@ namespace Ombi.Schedule.Jobs.Ombi
return resolver.ParseMessage(template, curlys); return resolver.ParseMessage(template, curlys);
} }
private async Task<string> BuildHtml(IQueryable<PlexServerContent> plexContentToSend, IQueryable<EmbyContent> embyContentToSend, IQueryable<JellyfinContent> jellyfinContentToSend, private async Task<string> BuildHtml(ICollection<IQueryable<IMediaServerContent>> contentToSend,
HashSet<PlexEpisode> plexEpisodes, HashSet<EmbyEpisode> embyEp, HashSet<JellyfinEpisode> jellyfinEp, HashSet<LidarrAlbumCache> albums, NewsletterSettings settings, EmbySettings embySettings, JellyfinSettings jellyfinSettings, ICollection<IEnumerable<IMediaServerEpisode>> episodes, HashSet<LidarrAlbumCache> albums, NewsletterSettings settings, EmbySettings embySettings, JellyfinSettings jellyfinSettings,
PlexSettings plexSettings) PlexSettings plexSettings)
{ {
var ombiSettings = await _ombiSettings.GetSettingsAsync(); var ombiSettings = await _ombiSettings.GetSettingsAsync();
var sb = new StringBuilder(); var sb = new StringBuilder();
var plexMovies = plexContentToSend.Where(x => x.Type == MediaType.Movie); if (!settings.DisableMovies)
var embyMovies = embyContentToSend.Where(x => x.Type == MediaType.Movie);
var jellyfinMovies = jellyfinContentToSend.Where(x => x.Type == MediaType.Movie);
if ((plexMovies.Any() || embyMovies.Any() || jellyfinMovies.Any()) && !settings.DisableMovies)
{ {
sb.Append("<h1 style=\"text-align: center; max-width: 1042px;\">New Movies</h1><br /><br />"); sb.Append("<h1 style=\"text-align: center; max-width: 1042px;\">New Movies</h1><br /><br />");
sb.Append( sb.Append(
@ -583,21 +500,10 @@ namespace Ombi.Schedule.Jobs.Ombi
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">"); sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">"); sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
sb.Append("<tr>"); sb.Append("<tr>");
if (plexSettings.Enable) foreach (var mediaServerContent in contentToSend)
{ {
await ProcessPlexMovies(plexMovies, sb, ombiSettings.DefaultLanguageCode, plexSettings.Servers.FirstOrDefault().ServerHostname ?? string.Empty); await ProcessMovies(mediaServerContent, sb, ombiSettings.DefaultLanguageCode, /*plexSettings.Servers?.FirstOrDefault()?.ServerHostname ?? */ string.Empty);
} }
if (embySettings.Enable)
{
await ProcessEmbyMovies(embyMovies, sb, ombiSettings.DefaultLanguageCode, embySettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
}
if (jellyfinSettings.Enable)
{
await ProcessJellyfinMovies(jellyfinMovies, sb, ombiSettings.DefaultLanguageCode, jellyfinSettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
}
sb.Append("</tr>"); sb.Append("</tr>");
sb.Append("</table>"); sb.Append("</table>");
sb.Append("</td>"); sb.Append("</td>");
@ -605,7 +511,7 @@ namespace Ombi.Schedule.Jobs.Ombi
sb.Append("</table>"); sb.Append("</table>");
} }
if ((plexEpisodes.Any() || embyEp.Any() || jellyfinEp.Any()) && !settings.DisableTv) if (!settings.DisableTv)
{ {
sb.Append("<br /><br /><h1 style=\"text-align: center; max-width: 1042px;\">New TV</h1><br /><br />"); sb.Append("<br /><br /><h1 style=\"text-align: center; max-width: 1042px;\">New TV</h1><br /><br />");
sb.Append( sb.Append(
@ -614,21 +520,10 @@ namespace Ombi.Schedule.Jobs.Ombi
sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">"); sb.Append("<td style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; \">");
sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">"); sb.Append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">");
sb.Append("<tr>"); sb.Append("<tr>");
if (plexSettings.Enable) foreach (var mediaServerContent in episodes)
{ {
await ProcessPlexTv(plexEpisodes, sb, ombiSettings.DefaultLanguageCode, plexSettings.Servers.FirstOrDefault().ServerHostname ?? string.Empty); await ProcessTv(mediaServerContent, sb, ombiSettings.DefaultLanguageCode, /* plexSettings.Servers.FirstOrDefault()?.ServerHostname ?? */ string.Empty);
} }
if (embySettings.Enable)
{
await ProcessEmbyTv(embyEp, sb, ombiSettings.DefaultLanguageCode, embySettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
}
if (jellyfinSettings.Enable)
{
await ProcessJellyfinTv(jellyfinEp, sb, ombiSettings.DefaultLanguageCode, jellyfinSettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty);
}
sb.Append("</tr>"); sb.Append("</tr>");
sb.Append("</table>"); sb.Append("</table>");
sb.Append("</td>"); sb.Append("</td>");
@ -657,7 +552,7 @@ namespace Ombi.Schedule.Jobs.Ombi
return sb.ToString(); return sb.ToString();
} }
private async Task ProcessPlexMovies(IQueryable<PlexServerContent> plexContentToSend, StringBuilder sb, string defaultLanguageCode, string mediaServerUrl) private async Task ProcessMovies(IQueryable<IMediaServerContent> plexContentToSend, StringBuilder sb, string defaultLanguageCode, string mediaServerUrl)
{ {
int count = 0; int count = 0;
var ordered = plexContentToSend.OrderByDescending(x => x.AddedAt); var ordered = plexContentToSend.OrderByDescending(x => x.AddedAt);
@ -681,7 +576,7 @@ namespace Ombi.Schedule.Jobs.Ombi
} }
catch (Exception e) catch (Exception e)
{ {
_log.LogError(e, "Error when Processing Plex Movies {0}", info.Title); _log.LogError(e, "Error when Processing Movies {0}", info.Title);
} }
finally finally
{ {
@ -731,112 +626,6 @@ namespace Ombi.Schedule.Jobs.Ombi
} }
} }
private async Task ProcessEmbyMovies(IQueryable<EmbyContent> embyContent, StringBuilder sb, string defaultLangaugeCode, string customUrl)
{
int count = 0;
var ordered = embyContent.OrderByDescending(x => x.AddedAt);
foreach (var content in ordered)
{
var theMovieDbId = content.TheMovieDbId;
if (!content.TheMovieDbId.HasValue())
{
var imdbId = content.ImdbId;
var findResult = await _movieApi.Find(imdbId, ExternalSource.imdb_id);
var result = findResult.movie_results?.FirstOrDefault();
if (result == null)
{
continue;
}
theMovieDbId = result.id.ToString();
}
var mediaurl = content.Url;
if (customUrl.HasValue())
{
mediaurl = customUrl;
}
var info = await _movieApi.GetMovieInformationWithExtraInfo(StringHelper.IntParseLinq(theMovieDbId), defaultLangaugeCode);
if (info == null)
{
continue;
}
try
{
CreateMovieHtmlContent(sb, info, mediaurl);
count += 1;
}
catch (Exception e)
{
_log.LogError(e, "Error when processing Emby Movies {0}", info.Title);
}
finally
{
EndLoopHtml(sb);
}
if (count == 2)
{
count = 0;
sb.Append("</tr>");
sb.Append("<tr>");
}
}
}
private async Task ProcessJellyfinMovies(IQueryable<JellyfinContent> embyContent, StringBuilder sb, string defaultLangaugeCode, string customUrl)
{
int count = 0;
var ordered = embyContent.OrderByDescending(x => x.AddedAt);
foreach (var content in ordered)
{
var theMovieDbId = content.TheMovieDbId;
if (!content.TheMovieDbId.HasValue())
{
var imdbId = content.ImdbId;
var findResult = await _movieApi.Find(imdbId, ExternalSource.imdb_id);
var result = findResult.movie_results?.FirstOrDefault();
if (result == null)
{
continue;
}
theMovieDbId = result.id.ToString();
}
var mediaurl = content.Url;
if (customUrl.HasValue())
{
mediaurl = customUrl;
}
var info = await _movieApi.GetMovieInformationWithExtraInfo(StringHelper.IntParseLinq(theMovieDbId), defaultLangaugeCode);
if (info == null)
{
continue;
}
try
{
CreateMovieHtmlContent(sb, info, mediaurl);
count += 1;
}
catch (Exception e)
{
_log.LogError(e, "Error when processing Jellyfin Movies {0}", info.Title);
}
finally
{
EndLoopHtml(sb);
}
if (count == 2)
{
count = 0;
sb.Append("</tr>");
sb.Append("<tr>");
}
}
}
private void CreateMovieHtmlContent(StringBuilder sb, MovieResponseDto info, string mediaurl) private void CreateMovieHtmlContent(StringBuilder sb, MovieResponseDto info, string mediaurl)
{ {
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/{info.BackdropPath}"); AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/{info.BackdropPath}");
@ -909,24 +698,23 @@ namespace Ombi.Schedule.Jobs.Ombi
AddGenres(sb, $"Type: {info.albumType}"); AddGenres(sb, $"Type: {info.albumType}");
} }
private async Task ProcessPlexTv(HashSet<PlexEpisode> plexContent, StringBuilder sb, string languageCode, string serverHostname) private async Task ProcessTv(IEnumerable<IMediaServerEpisode> episodes, StringBuilder sb, string languageCode, string serverHostname)
{ {
var series = new List<PlexServerContent>(); var series = new List<IMediaServerContent>();
foreach (var plexEpisode in plexContent) foreach (var episode in episodes)
{ {
var alreadyAdded = series.FirstOrDefault(x => x.Key == plexEpisode.PlexSeries.Key); var existingSeries = episode.SeriesIsIn(series);
if (alreadyAdded != null) if (existingSeries != null)
{ {
var episodeExists = alreadyAdded.PlexEpisodes.Any(x => x.Key == plexEpisode.Key); if (!episode.IsIn(existingSeries))
if (!episodeExists)
{ {
alreadyAdded.Episodes.Add(plexEpisode); existingSeries.Episodes.Add(episode);
} }
} }
else else
{ {
plexEpisode.Series.Episodes = new List<IMediaServerEpisode> { plexEpisode }; episode.Series.Episodes = new List<IMediaServerEpisode> { episode };
series.Add(plexEpisode.PlexSeries); series.Add(episode.Series);
} }
} }
@ -1035,214 +823,6 @@ namespace Ombi.Schedule.Jobs.Ombi
} }
} }
private async Task ProcessEmbyTv(HashSet<EmbyEpisode> embyContent, StringBuilder sb, string languageCode, string serverUrl)
{
var series = new List<EmbyContent>();
foreach (var episode in embyContent)
{
var alreadyAdded = series.FirstOrDefault(x => x.EmbyId == episode.EmbySeries.EmbyId);
if (alreadyAdded != null)
{
alreadyAdded.Episodes.Add(episode);
}
else
{
episode.Series.Episodes = new List<IMediaServerEpisode>
{
episode
};
series.Add(episode.EmbySeries);
}
}
int count = 0;
var orderedTv = series.OrderByDescending(x => x.AddedAt);
foreach (var t in orderedTv)
{
if (!t.TvDbId.HasValue())
{
continue;
}
int.TryParse(t.TvDbId, out var tvdbId);
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
if (info == null)
{
continue;
}
try
{
var banner = info.image?.original;
if (!string.IsNullOrEmpty(banner))
{
banner = banner.ToHttpsUrl(); // Always use the Https banners
}
var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode);
if (tvInfo != null && tvInfo.backdrop_path.HasValue())
{
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}");
}
else
{
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/");
}
AddPosterInsideTable(sb, banner);
AddMediaServerUrl(sb, serverUrl.HasValue() ? serverUrl : t.Url, banner);
AddInfoTable(sb);
AddTvTitle(sb, info, 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($"Season: {epInformation.SeasonNumber} - Episodes: {episodeString} {episodeAirDate}");
finalsb.Append("<br />");
}
AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo);
}
catch (Exception e)
{
_log.LogError(e, "Error when processing Emby TV {0}", t.Title);
}
finally
{
EndLoopHtml(sb);
count += 1;
}
if (count == 2)
{
count = 0;
sb.Append("</tr>");
sb.Append("<tr>");
}
}
}
private async Task ProcessJellyfinTv(HashSet<JellyfinEpisode> jellyfinContent, StringBuilder sb, string languageCode, string serverUrl)
{
var series = new List<JellyfinContent>();
foreach (var episode in jellyfinContent)
{
var alreadyAdded = series.FirstOrDefault(x => x.JellyfinId == episode.JellyfinSeries.JellyfinId);
if (alreadyAdded != null)
{
alreadyAdded.Episodes.Add(episode);
}
else
{
episode.Series.Episodes = new List<IMediaServerEpisode>
{
episode
};
series.Add(episode.JellyfinSeries);
}
}
int count = 0;
var orderedTv = series.OrderByDescending(x => x.AddedAt);
foreach (var t in orderedTv)
{
if (!t.TvDbId.HasValue())
{
continue;
}
int.TryParse(t.TvDbId, out var tvdbId);
var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId);
if (info == null)
{
continue;
}
try
{
var banner = info.image?.original;
if (!string.IsNullOrEmpty(banner))
{
banner = banner.ToHttpsUrl(); // Always use the Https banners
}
var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode);
if (tvInfo != null && tvInfo.backdrop_path.HasValue())
{
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}");
}
else
{
AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/");
}
AddPosterInsideTable(sb, banner);
AddMediaServerUrl(sb, serverUrl.HasValue() ? serverUrl : t.Url, banner);
AddInfoTable(sb);
AddTvTitle(sb, info, 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($"Season: {epInformation.SeasonNumber} - Episodes: {episodeString} {episodeAirDate}");
finalsb.Append("<br />");
}
AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo);
}
catch (Exception e)
{
_log.LogError(e, "Error when processing Jellyfin TV {0}", t.Title);
}
finally
{
EndLoopHtml(sb);
count += 1;
}
if (count == 2)
{
count = 0;
sb.Append("</tr>");
sb.Append("<tr>");
}
}
}
private void AddTvTitle(StringBuilder sb, Api.TvMaze.Models.TvMazeShow info, TvInfo tvInfo) private void AddTvTitle(StringBuilder sb, Api.TvMaze.Models.TvMazeShow info, TvInfo tvInfo)
{ {
var title = ""; var title = "";

View file

@ -86,7 +86,7 @@ namespace Ombi.Schedule.Jobs.Plex
var tvDbId = child.ParentRequest.TvDbId; var tvDbId = child.ParentRequest.TvDbId;
var imdbId = child.ParentRequest.ImdbId; var imdbId = child.ParentRequest.ImdbId;
IQueryable<PlexEpisode> seriesEpisodes = null; IQueryable<IMediaServerEpisode> seriesEpisodes = null;
if (useImdb) if (useImdb)
{ {
seriesEpisodes = plexEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString()); seriesEpisodes = plexEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());
@ -105,8 +105,7 @@ namespace Ombi.Schedule.Jobs.Plex
{ {
// Let's try and match the series by name // Let's try and match the series by name
seriesEpisodes = plexEpisodes.Where(x => seriesEpisodes = plexEpisodes.Where(x =>
x.Series.Title == child.Title && x.Series.Title == child.Title);
x.PlexSeries.ReleaseYear == child.ParentRequest.ReleaseDate.Year.ToString());
} }

View file

@ -226,7 +226,7 @@ namespace Ombi.Schedule.Jobs.Plex
await Repo.SaveChangesAsync(); await Repo.SaveChangesAsync();
if (content.Metadata != null) if (content.Metadata != null)
{ {
var episodesAdded = await EpisodeSync.ProcessEpsiodes(content.Metadata, allEps); var episodesAdded = await EpisodeSync.ProcessEpsiodes(content.Metadata, (IQueryable<PlexEpisode>)allEps);
episodesProcessed.AddRange(episodesAdded.Select(x => x.Id)); episodesProcessed.AddRange(episodesAdded.Select(x => x.Id));
} }
} }
@ -463,7 +463,7 @@ namespace Ombi.Schedule.Jobs.Plex
Repo.DeleteWithoutSave(existingContent); Repo.DeleteWithoutSave(existingContent);
// Because we have changed the rating key, we need to change all children too // Because we have changed the rating key, we need to change all children too
var episodeToChange = Repo.GetAllEpisodes().Where(x => x.GrandparentKey == oldKey); var episodeToChange = Repo.GetAllEpisodes().Cast<PlexEpisode>().Where(x => x.GrandparentKey == oldKey);
if (episodeToChange.Any()) if (episodeToChange.Any())
{ {
foreach (var e in episodeToChange) foreach (var e in episodeToChange)

View file

@ -113,7 +113,7 @@ namespace Ombi.Schedule.Jobs.Plex
{ {
var currentPosition = 0; var currentPosition = 0;
var resultCount = settings.EpisodeBatchSize == 0 ? 150 : settings.EpisodeBatchSize; var resultCount = settings.EpisodeBatchSize == 0 ? 150 : settings.EpisodeBatchSize;
var currentEpisodes = _repo.GetAllEpisodes(); var currentEpisodes = _repo.GetAllEpisodes().Cast<PlexEpisode>();
var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, resultCount); var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, resultCount);
_log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}"); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}");

View file

@ -26,8 +26,9 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore.Metadata; using System.Linq;
namespace Ombi.Store.Entities namespace Ombi.Store.Entities
{ {
@ -50,5 +51,16 @@ namespace Ombi.Store.Entities
get => (EmbyContent)Series; get => (EmbyContent)Series;
set => Series = value; set => Series = value;
} }
public override IMediaServerContent SeriesIsIn(List<IMediaServerContent> content)
{
return content.Cast<EmbyContent>().FirstOrDefault(
x => x.EmbyId == this.EmbySeries.EmbyId);
}
public override bool IsIn(IMediaServerContent content)
{
return content.Episodes.Cast<EmbyEpisode>().Any(x => x.EmbyId == this.EmbyId);
}
} }
} }

View file

@ -1,11 +1,13 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using Ombi.Store.Repository;
namespace Ombi.Store.Entities namespace Ombi.Store.Entities
{ {
public interface IMediaServerContent public interface IMediaServerContent
{ {
public int Id { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string ImdbId { get; set; } public string ImdbId { get; set; }
public string TvDbId { get; set; } public string TvDbId { get; set; }
@ -42,6 +44,8 @@ namespace Ombi.Store.Entities
public IMediaServerContent Series { get; set; } public IMediaServerContent Series { get; set; }
public IMediaServerContent SeriesIsIn(List<IMediaServerContent> content);
public bool IsIn(IMediaServerContent content);
} }
public enum MediaType public enum MediaType

View file

@ -26,7 +26,9 @@
#endregion #endregion
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata;
namespace Ombi.Store.Entities namespace Ombi.Store.Entities
@ -50,5 +52,15 @@ namespace Ombi.Store.Entities
get => (JellyfinContent)Series; get => (JellyfinContent)Series;
set => Series = value; set => Series = value;
} }
public override IMediaServerContent SeriesIsIn(List<IMediaServerContent> content)
{
return content.Cast<JellyfinContent>().FirstOrDefault(
x => x.JellyfinId == this.JellyfinSeries.JellyfinId);
}
public override bool IsIn(IMediaServerContent content)
{
return content.Episodes.Cast<JellyfinEpisode>().Any(x => x.JellyfinId == this.JellyfinId);
}
} }
} }

View file

@ -35,5 +35,8 @@ namespace Ombi.Store.Entities
public string Title { get; set; } public string Title { get; set; }
public IMediaServerContent Series { get; set; } public IMediaServerContent Series { get; set; }
public abstract IMediaServerContent SeriesIsIn(List<IMediaServerContent> content);
public abstract bool IsIn(IMediaServerContent content);
} }
} }

View file

@ -1,4 +1,6 @@
using System.ComponentModel.DataAnnotations.Schema; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace Ombi.Store.Entities namespace Ombi.Store.Entities
{ {
@ -20,5 +22,17 @@ namespace Ombi.Store.Entities
get => (PlexServerContent)Series; get => (PlexServerContent)Series;
set => Series = value; set => Series = value;
} }
public override IMediaServerContent SeriesIsIn(List<IMediaServerContent> content)
{
return content.Cast<PlexServerContent>().FirstOrDefault(
x => x.Key == this.PlexSeries.Key);
}
public override bool IsIn(IMediaServerContent content)
{
return content.Episodes.Cast<PlexEpisode>().Any(x => x.Key == this.Key);
}
} }
} }

View file

@ -69,20 +69,20 @@ namespace Ombi.Store.Repository
return await Db.EmbyContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.EmbyId == embyId); return await Db.EmbyContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.EmbyId == embyId);
} }
public async Task Update(EmbyContent existingContent) public async Task Update(IMediaServerContent existingContent)
{ {
Db.EmbyContent.Update(existingContent); Db.EmbyContent.Update((EmbyContent)existingContent);
await InternalSaveChanges(); await InternalSaveChanges();
} }
public IQueryable<EmbyEpisode> GetAllEpisodes() public IQueryable<IMediaServerEpisode> GetAllEpisodes()
{ {
return Db.EmbyEpisode.AsQueryable(); return Db.EmbyEpisode.AsQueryable();
} }
public async Task<EmbyEpisode> Add(EmbyEpisode content) public async Task<IMediaServerEpisode> Add(IMediaServerEpisode content)
{ {
await Db.EmbyEpisode.AddAsync(content); await Db.EmbyEpisode.AddAsync((EmbyEpisode)content);
await InternalSaveChanges(); await InternalSaveChanges();
return content; return content;
} }
@ -91,15 +91,15 @@ namespace Ombi.Store.Repository
return await Db.EmbyEpisode.FirstOrDefaultAsync(x => x.EmbyId == key); return await Db.EmbyEpisode.FirstOrDefaultAsync(x => x.EmbyId == key);
} }
public async Task AddRange(IEnumerable<EmbyEpisode> content) public async Task AddRange(IEnumerable<IMediaServerEpisode> content)
{ {
Db.EmbyEpisode.AddRange(content); Db.EmbyEpisode.AddRange((EmbyEpisode)content);
await InternalSaveChanges(); await InternalSaveChanges();
} }
public void UpdateWithoutSave(EmbyContent existingContent) public void UpdateWithoutSave(IMediaServerContent existingContent)
{ {
Db.EmbyContent.Update(existingContent); Db.EmbyContent.Update((EmbyContent)existingContent);
} }
} }

View file

@ -5,13 +5,8 @@ using Ombi.Store.Entities;
namespace Ombi.Store.Repository namespace Ombi.Store.Repository
{ {
public interface IMediaServerContentRepository<Content, Episode> : IExternalRepository<Content> where Content : Entity public interface IMediaServerContentRepository<Content, Episode> : IExternalRepository<Content>, IMediaServerContentRepositoryLight
where Content : Entity
{ {
Task Update(Content existingContent);
IQueryable<Episode> GetAllEpisodes();
Task<Episode> Add(Episode content);
Task AddRange(IEnumerable<Episode> content);
void UpdateWithoutSave(Content existingContent);
} }
} }

View file

@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public interface IMediaServerContentRepositoryLight
{
Task Update(IMediaServerContent existingContent);
IQueryable<IMediaServerEpisode> GetAllEpisodes();
Task<IMediaServerEpisode> Add(IMediaServerEpisode content);
Task AddRange(IEnumerable<IMediaServerEpisode> content);
void UpdateWithoutSave(IMediaServerContent existingContent);
}
}

View file

@ -69,20 +69,20 @@ namespace Ombi.Store.Repository
return await Db.JellyfinContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.JellyfinId == jellyfinId); return await Db.JellyfinContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.JellyfinId == jellyfinId);
} }
public async Task Update(JellyfinContent existingContent) public async Task Update(IMediaServerContent existingContent)
{ {
Db.JellyfinContent.Update(existingContent); Db.JellyfinContent.Update((JellyfinContent)existingContent);
await InternalSaveChanges(); await InternalSaveChanges();
} }
public IQueryable<JellyfinEpisode> GetAllEpisodes() public IQueryable<IMediaServerEpisode> GetAllEpisodes()
{ {
return Db.JellyfinEpisode.AsQueryable(); return Db.JellyfinEpisode.AsQueryable();
} }
public async Task<JellyfinEpisode> Add(JellyfinEpisode content) public async Task<IMediaServerEpisode> Add(IMediaServerEpisode content)
{ {
await Db.JellyfinEpisode.AddAsync(content); await Db.JellyfinEpisode.AddAsync((JellyfinEpisode)content);
await InternalSaveChanges(); await InternalSaveChanges();
return content; return content;
} }
@ -91,15 +91,15 @@ namespace Ombi.Store.Repository
return await Db.JellyfinEpisode.FirstOrDefaultAsync(x => x.JellyfinId == key); return await Db.JellyfinEpisode.FirstOrDefaultAsync(x => x.JellyfinId == key);
} }
public async Task AddRange(IEnumerable<JellyfinEpisode> content) public async Task AddRange(IEnumerable<IMediaServerEpisode> content)
{ {
Db.JellyfinEpisode.AddRange(content); Db.JellyfinEpisode.AddRange((JellyfinEpisode)content);
await InternalSaveChanges(); await InternalSaveChanges();
} }
public void UpdateWithoutSave(JellyfinContent existingContent) public void UpdateWithoutSave(IMediaServerContent existingContent)
{ {
Db.JellyfinContent.Update(existingContent); Db.JellyfinContent.Update((JellyfinContent)existingContent);
} }
} }

View file

@ -114,14 +114,14 @@ namespace Ombi.Store.Repository
.FirstOrDefaultAsync(predicate); .FirstOrDefaultAsync(predicate);
} }
public async Task Update(PlexServerContent existingContent) public async Task Update(IMediaServerContent existingContent)
{ {
Db.PlexServerContent.Update(existingContent); Db.PlexServerContent.Update((PlexServerContent)existingContent);
await InternalSaveChanges(); await InternalSaveChanges();
} }
public void UpdateWithoutSave(PlexServerContent existingContent) public void UpdateWithoutSave(IMediaServerContent existingContent)
{ {
Db.PlexServerContent.Update(existingContent); Db.PlexServerContent.Update((PlexServerContent)existingContent);
} }
public async Task UpdateRange(IEnumerable<PlexServerContent> existingContent) public async Task UpdateRange(IEnumerable<PlexServerContent> existingContent)
@ -130,7 +130,7 @@ namespace Ombi.Store.Repository
await InternalSaveChanges(); await InternalSaveChanges();
} }
public IQueryable<PlexEpisode> GetAllEpisodes() public IQueryable<IMediaServerEpisode> GetAllEpisodes()
{ {
return Db.PlexEpisode.Include(x => x.Series).AsQueryable(); return Db.PlexEpisode.Include(x => x.Series).AsQueryable();
} }
@ -145,9 +145,9 @@ namespace Ombi.Store.Repository
Db.PlexEpisode.Remove(content); Db.PlexEpisode.Remove(content);
} }
public async Task<PlexEpisode> Add(PlexEpisode content) public async Task<IMediaServerEpisode> Add(IMediaServerEpisode content)
{ {
await Db.PlexEpisode.AddAsync(content); await Db.PlexEpisode.AddAsync((PlexEpisode)content);
await InternalSaveChanges(); await InternalSaveChanges();
return content; return content;
} }
@ -162,9 +162,9 @@ namespace Ombi.Store.Repository
{ {
return await Db.PlexEpisode.FirstOrDefaultAsync(x => x.Key == key); return await Db.PlexEpisode.FirstOrDefaultAsync(x => x.Key == key);
} }
public async Task AddRange(IEnumerable<PlexEpisode> content) public async Task AddRange(IEnumerable<IMediaServerEpisode> content)
{ {
Db.PlexEpisode.AddRange(content); Db.PlexEpisode.AddRange((PlexEpisode)content);
await InternalSaveChanges(); await InternalSaveChanges();
} }
} }