mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
refactor(newsletter): ♻️ Media servers + newsletter refactoring (#4463)
* Abstract media servers content into interfaces * Media server entities into abstract classes * Abstract media server content repository * First pass at newsletter refactoring * Minor code clean up * Attempt at abstracting repositories (WIP) * Fixed cast issue * Corrected the other properties * A step towards newsletter refactoring * Clean up leftovers * Fix broken episodes db interaction * Save absolute URL for Plex content Let's be consistent with Emby and Jellyfin * Fix broken integration with Plex libraries * Fix error when multiple media servers configured * Fix newsletter being sent if no movies or episodes * Fix broken tests * Remove unneccesary logs * Expose stored media server URL No need to recalculate it + Plex URL was broken due to an earlier change * Remove unused variable * Remove obsolete tests URLs are now fetched from database directly * Retro-compatibility for Plex content URL Solves URL for media synced before absolute URL was saved in PlexServerContent * chore: added some obsoletes * fix: removed the unsub link when not present Co-authored-by: tidusjar <tidusjar@gmail.com>
This commit is contained in:
parent
32ee4e88ec
commit
0ff0a704ff
46 changed files with 595 additions and 1148 deletions
4
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
4
src/.idea/.idea.Ombi/.idea/contentModel.xml
generated
|
@ -929,7 +929,7 @@
|
|||
<e p="EmbyConfiguration.cs" t="Include" />
|
||||
<e p="EmbyConnectUser.cs" t="Include" />
|
||||
<e p="EmbyItemContainer.cs" t="Include" />
|
||||
<e p="EmbyMediaType.cs" t="Include" />
|
||||
<e p="MediaType.cs" t="Include" />
|
||||
<e p="EmbyPolicy.cs" t="Include" />
|
||||
<e p="EmbySystemInfo.cs" t="Include" />
|
||||
<e p="EmbyUser.cs" t="Include" />
|
||||
|
@ -1876,7 +1876,7 @@
|
|||
<e p="PlexAvailabilityChecker.cs" t="Include" />
|
||||
<e p="PlexContentSync.cs" t="Include" />
|
||||
<e p="PlexEpisodeSync.cs" t="Include" />
|
||||
<e p="PlexMediaType.cs" t="Include" />
|
||||
<e p="MediaType.cs" t="Include" />
|
||||
<e p="PlexRecentlyAddedSync.cs" t="Include" />
|
||||
<e p="PlexUserImporter.cs" t="Include" />
|
||||
</e>
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
namespace Ombi.Api.Emby.Models
|
||||
{
|
||||
public enum EmbyMediaType
|
||||
{
|
||||
Movie = 0,
|
||||
Series = 1,
|
||||
Music = 2,
|
||||
Episode = 3
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
namespace Ombi.Api.Jellyfin.Models
|
||||
{
|
||||
public enum JellyfinMediaType
|
||||
{
|
||||
Movie = 0,
|
||||
Series = 1,
|
||||
Music = 2,
|
||||
Episode = 3
|
||||
}
|
||||
}
|
|
@ -182,11 +182,11 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
{
|
||||
new PlexServerContent
|
||||
{
|
||||
Type = PlexMediaTypeEntity.Show,
|
||||
Type = MediaType.Series,
|
||||
TheMovieDbId = "1",
|
||||
Title = "Test",
|
||||
ReleaseYear = "2001",
|
||||
Episodes = new List<PlexEpisode>
|
||||
Episodes = new List<IMediaServerEpisode>
|
||||
{
|
||||
new PlexEpisode
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Models.Search;
|
||||
|
@ -18,12 +19,14 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
public void Setup()
|
||||
{
|
||||
ContextMock = new Mock<IEmbyContentRepository>();
|
||||
LoggerMock = new Mock<ILogger<EmbyAvailabilityRule>>();
|
||||
SettingsMock = new Mock<ISettingsService<EmbySettings>>();
|
||||
Rule = new EmbyAvailabilityRule(ContextMock.Object, SettingsMock.Object);
|
||||
Rule = new EmbyAvailabilityRule(ContextMock.Object, LoggerMock.Object, SettingsMock.Object);
|
||||
}
|
||||
|
||||
private EmbyAvailabilityRule Rule { get; set; }
|
||||
private Mock<IEmbyContentRepository> ContextMock { get; set; }
|
||||
private Mock<ILogger<EmbyAvailabilityRule>> LoggerMock { get; set; }
|
||||
private Mock<ISettingsService<EmbySettings>> SettingsMock { get; set; }
|
||||
|
||||
[Test]
|
||||
|
@ -44,66 +47,6 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
Assert.True(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Has_Custom_Url_When_Specified_In_Settings()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings
|
||||
{
|
||||
Enable = true,
|
||||
Servers = new List<EmbyServers>
|
||||
{
|
||||
new EmbyServers
|
||||
{
|
||||
ServerHostname = "http://test.com/",
|
||||
ServerId = "8"
|
||||
}
|
||||
}
|
||||
});
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
EmbyId = 1.ToString(),
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.EmbyUrl, Is.EqualTo("http://test.com/web/index.html#!/item?id=1&serverId=8"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Uses_Default_Url_When()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings
|
||||
{
|
||||
Enable = true,
|
||||
Servers = new List<EmbyServers>
|
||||
{
|
||||
new EmbyServers
|
||||
{
|
||||
ServerHostname = string.Empty,
|
||||
ServerId = "8"
|
||||
}
|
||||
}
|
||||
});
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
EmbyId = 1.ToString()
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.EmbyUrl, Is.EqualTo("https://app.emby.media/web/index.html#!/item?id=1&serverId=8"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_NotAvailable_WhenNotFoundInEmby()
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Ombi.Core.Models.Search;
|
||||
|
@ -18,12 +19,14 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
public void Setup()
|
||||
{
|
||||
ContextMock = new Mock<IJellyfinContentRepository>();
|
||||
LoggerMock = new Mock<ILogger<JellyfinAvailabilityRule>>();
|
||||
SettingsMock = new Mock<ISettingsService<JellyfinSettings>>();
|
||||
Rule = new JellyfinAvailabilityRule(ContextMock.Object, SettingsMock.Object);
|
||||
Rule = new JellyfinAvailabilityRule(ContextMock.Object, LoggerMock.Object, SettingsMock.Object);
|
||||
}
|
||||
|
||||
private JellyfinAvailabilityRule Rule { get; set; }
|
||||
private Mock<IJellyfinContentRepository> ContextMock { get; set; }
|
||||
private Mock<ILogger<JellyfinAvailabilityRule>> LoggerMock { get; set; }
|
||||
private Mock<ISettingsService<JellyfinSettings>> SettingsMock { get; set; }
|
||||
|
||||
[Test]
|
||||
|
@ -44,36 +47,6 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
Assert.True(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Has_Custom_Url_When_Specified_In_Settings()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings
|
||||
{
|
||||
Enable = true,
|
||||
Servers = new List<JellyfinServers>
|
||||
{
|
||||
new JellyfinServers
|
||||
{
|
||||
ServerHostname = "http://test.com/",
|
||||
ServerId = "8"
|
||||
}
|
||||
}
|
||||
});
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
JellyfinId = 1.ToString(),
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.That(search.JellyfinUrl, Is.EqualTo("http://test.com/web/index.html#!/details?id=1&serverId=8"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Uses_Default_Url_When()
|
||||
{
|
||||
|
|
|
@ -30,26 +30,26 @@ namespace Ombi.Core.Engine
|
|||
|
||||
public IEnumerable<RecentlyAddedMovieModel> GetRecentlyAddedMovies(DateTime from, DateTime to)
|
||||
{
|
||||
var plexMovies = _plex.GetAll().Where(x => x.Type == PlexMediaTypeEntity.Movie && x.AddedAt > from && x.AddedAt < to);
|
||||
var embyMovies = _emby.GetAll().Where(x => x.Type == EmbyMediaType.Movie && x.AddedAt > from && x.AddedAt < to);
|
||||
var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == JellyfinMediaType.Movie && x.AddedAt > from && x.AddedAt < to);
|
||||
var plexMovies = _plex.GetAll().Where(x => x.Type == MediaType.Movie && x.AddedAt > from && x.AddedAt < to);
|
||||
var embyMovies = _emby.GetAll().Where(x => x.Type == MediaType.Movie && x.AddedAt > from && x.AddedAt < to);
|
||||
var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == MediaType.Movie && x.AddedAt > from && x.AddedAt < to);
|
||||
|
||||
return GetRecentlyAddedMovies(plexMovies, embyMovies, jellyfinMovies).Take(30);
|
||||
}
|
||||
|
||||
public IEnumerable<RecentlyAddedMovieModel> GetRecentlyAddedMovies()
|
||||
{
|
||||
var plexMovies = _plex.GetAll().Where(x => x.Type == PlexMediaTypeEntity.Movie);
|
||||
var embyMovies = _emby.GetAll().Where(x => x.Type == EmbyMediaType.Movie);
|
||||
var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == JellyfinMediaType.Movie);
|
||||
var plexMovies = _plex.GetAll().Where(x => x.Type == MediaType.Movie);
|
||||
var embyMovies = _emby.GetAll().Where(x => x.Type == MediaType.Movie);
|
||||
var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == MediaType.Movie);
|
||||
return GetRecentlyAddedMovies(plexMovies, embyMovies, jellyfinMovies);
|
||||
}
|
||||
|
||||
public IEnumerable<RecentlyAddedTvModel> GetRecentlyAddedTv(DateTime from, DateTime to, bool groupBySeason)
|
||||
{
|
||||
var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == PlexMediaTypeEntity.Show && x.AddedAt > from && x.AddedAt < to);
|
||||
var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == EmbyMediaType.Series && x.AddedAt > from && x.AddedAt < to);
|
||||
var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == JellyfinMediaType.Series && x.AddedAt > from && x.AddedAt < to);
|
||||
var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == MediaType.Series && x.AddedAt > from && x.AddedAt < to);
|
||||
var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series && x.AddedAt > from && x.AddedAt < to);
|
||||
var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series && x.AddedAt > from && x.AddedAt < to);
|
||||
|
||||
return GetRecentlyAddedTv(plexTv, embyTv, jellyfinTv, groupBySeason).Take(30);
|
||||
}
|
||||
|
@ -57,9 +57,9 @@ namespace Ombi.Core.Engine
|
|||
|
||||
public IEnumerable<RecentlyAddedTvModel> GetRecentlyAddedTv(bool groupBySeason)
|
||||
{
|
||||
var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == PlexMediaTypeEntity.Show);
|
||||
var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == EmbyMediaType.Series);
|
||||
var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == JellyfinMediaType.Series);
|
||||
var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == MediaType.Series);
|
||||
var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series);
|
||||
var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series);
|
||||
|
||||
return GetRecentlyAddedTv(plexTv, embyTv, jellyfinTv, groupBySeason);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if (p.Type == PlexMediaTypeEntity.Movie)
|
||||
if (p.Type == MediaType.Movie)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if (e.Type == EmbyMediaType.Movie)
|
||||
if (e.Type == MediaType.Movie)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
|
@ -152,7 +152,7 @@ namespace Ombi.Core.Engine
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if (e.Type == JellyfinMediaType.Movie)
|
||||
if (e.Type == MediaType.Movie)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
{
|
||||
var tvRequest = (ChildRequests) obj;
|
||||
|
||||
var tvContent = _plexContent.GetAll().Include(x => x.Episodes).Where(x => x.Type == PlexMediaTypeEntity.Show);
|
||||
var tvContent = _plexContent.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series);
|
||||
// We need to do a check on the TVDBId
|
||||
var anyMovieDbMatches = await tvContent.FirstOrDefaultAsync(x => x.TheMovieDbId.Length > 0 && x.TheMovieDbId == tvRequest.Id.ToString());
|
||||
if (anyMovieDbMatches == null)
|
||||
|
|
|
@ -46,10 +46,10 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
}
|
||||
}
|
||||
|
||||
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<PlexEpisode> allEpisodes, EpisodeRequests episode,
|
||||
SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log)
|
||||
public static async Task SingleEpisodeCheck(bool useImdb, IQueryable<IMediaServerEpisode> allEpisodes, EpisodeRequests episode,
|
||||
SeasonRequests season, IMediaServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log)
|
||||
{
|
||||
PlexEpisode epExists = null;
|
||||
IMediaServerEpisode epExists = null;
|
||||
try
|
||||
{
|
||||
|
||||
|
@ -79,66 +79,6 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
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)
|
||||
{
|
||||
episode.Available = true;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Settings;
|
||||
|
@ -13,13 +14,15 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
{
|
||||
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;
|
||||
Log = log;
|
||||
EmbySettings = s;
|
||||
}
|
||||
|
||||
private IEmbyContentRepository EmbyContentRepository { get; }
|
||||
private ILogger Log { get; }
|
||||
private ISettingsService<EmbySettings> EmbySettings { get; }
|
||||
|
||||
public async Task<RuleResult> Execute(SearchViewModel obj)
|
||||
|
@ -64,19 +67,7 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
if (item != null)
|
||||
{
|
||||
obj.Available = true;
|
||||
var s = await EmbySettings.GetSettingsAsync();
|
||||
if (s.Enable)
|
||||
{
|
||||
var server = s.Servers.FirstOrDefault();
|
||||
if ((server?.ServerHostname ?? string.Empty).HasValue())
|
||||
{
|
||||
obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, server?.ServerId, server?.ServerHostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, server?.ServerId, null);
|
||||
}
|
||||
}
|
||||
obj.EmbyUrl = item.Url;
|
||||
|
||||
if (obj.Type == RequestType.TvShow)
|
||||
{
|
||||
|
@ -89,7 +80,7 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Ombi.Core.Models.Search;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Settings;
|
||||
|
@ -13,13 +14,15 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
{
|
||||
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;
|
||||
Log = log;
|
||||
JellyfinSettings = s;
|
||||
}
|
||||
|
||||
private IJellyfinContentRepository JellyfinContentRepository { get; }
|
||||
private ILogger Log { get; }
|
||||
private ISettingsService<JellyfinSettings> JellyfinSettings { get; }
|
||||
|
||||
public async Task<RuleResult> Execute(SearchViewModel obj)
|
||||
|
@ -78,20 +81,7 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
useTheMovieDb = true;
|
||||
}
|
||||
obj.Available = true;
|
||||
var s = await JellyfinSettings.GetSettingsAsync();
|
||||
if (s.Enable)
|
||||
{
|
||||
var server = s.Servers.FirstOrDefault(x => x.ServerHostname != null);
|
||||
if ((server?.ServerHostname ?? string.Empty).HasValue())
|
||||
{
|
||||
obj.JellyfinUrl = JellyfinHelper.GetJellyfinMediaUrl(item.JellyfinId, server?.ServerId, server?.ServerHostname);
|
||||
}
|
||||
else
|
||||
{
|
||||
var firstServer = s.Servers?.FirstOrDefault();
|
||||
obj.JellyfinUrl = JellyfinHelper.GetJellyfinMediaUrl(item.JellyfinId, firstServer.ServerId, firstServer.FullUri);
|
||||
}
|
||||
}
|
||||
obj.JellyfinUrl = item.Url;
|
||||
|
||||
if (obj.Type == RequestType.TvShow)
|
||||
{
|
||||
|
@ -104,7 +94,7 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
var useId = false;
|
||||
var useTvDb = false;
|
||||
|
||||
PlexMediaTypeEntity type = ConvertType(obj.Type);
|
||||
MediaType type = ConvertType(obj.Type);
|
||||
|
||||
if (obj.ImdbId.HasValue())
|
||||
{
|
||||
|
@ -90,7 +90,15 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
useTheMovieDb = true;
|
||||
}
|
||||
obj.Available = true;
|
||||
if (item.Url.StartsWith("http"))
|
||||
{
|
||||
obj.PlexUrl = item.Url;
|
||||
}
|
||||
else
|
||||
{
|
||||
// legacy content
|
||||
obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host);
|
||||
}
|
||||
obj.Quality = item.Quality;
|
||||
|
||||
if (obj.Type == RequestType.TvShow)
|
||||
|
@ -115,12 +123,12 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
return Success();
|
||||
}
|
||||
|
||||
private PlexMediaTypeEntity ConvertType(RequestType type) =>
|
||||
private MediaType ConvertType(RequestType type) =>
|
||||
type switch
|
||||
{
|
||||
RequestType.Movie => PlexMediaTypeEntity.Movie,
|
||||
RequestType.TvShow => PlexMediaTypeEntity.Show,
|
||||
_ => PlexMediaTypeEntity.Movie,
|
||||
RequestType.Movie => MediaType.Movie,
|
||||
RequestType.TvShow => MediaType.Series,
|
||||
_ => MediaType.Movie,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -104,11 +104,11 @@ namespace Ombi.Helpers
|
|||
return new ProviderId();
|
||||
}
|
||||
|
||||
public static string GetPlexMediaUrl(string machineId, int mediaId)
|
||||
public static string GetPlexMediaUrl(string machineId, int mediaId, string plexHost)
|
||||
{
|
||||
var url =
|
||||
$"web/#!/server/{machineId}/details?key=%2flibrary%2Fmetadata%2F{mediaId}";
|
||||
return url;
|
||||
return BuildPlexMediaUrl(url, plexHost);
|
||||
}
|
||||
|
||||
public static string BuildPlexMediaUrl(string savedUrl, string plexHost)
|
||||
|
|
|
@ -30,6 +30,7 @@ namespace Ombi.Notifications.Templates
|
|||
private const string TableLocation = "{@RECENTLYADDED}";
|
||||
private const string IntroText = "{@INTRO}";
|
||||
private const string Unsubscribe = "{@UNSUBSCRIBE}";
|
||||
private const string UnsubscribeText = "{@UNSUBSCRIBETEXT}";
|
||||
|
||||
|
||||
public string LoadTemplate(string subject, string intro, string tableHtml, string logo, string unsubscribeLink)
|
||||
|
@ -41,6 +42,7 @@ namespace Ombi.Notifications.Templates
|
|||
sb.Replace(DateKey, DateTime.Now.ToString("f"));
|
||||
sb.Replace(Logo, string.IsNullOrEmpty(logo) ? OmbiLogo : logo);
|
||||
sb.Replace(Unsubscribe, string.IsNullOrEmpty(unsubscribeLink) ? string.Empty : unsubscribeLink);
|
||||
sb.Replace(UnsubscribeText, string.IsNullOrEmpty(unsubscribeLink) ? string.Empty : "Unsubscrible");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
|
|
@ -453,7 +453,7 @@
|
|||
<tbody>
|
||||
<tr>
|
||||
<td class="content-block powered-by" valign="top" align="center" style="font-family: sans-serif; vertical-align: top; padding-bottom: 10px; padding-top: 10px; color: #999999; font-size: 12px; text-align: center;">
|
||||
<a href="{@UNSUBSCRIBE}" style="font-weight: 400; font-size: 12px; text-align: center; color: #ff761b;">Unsubscribe</a>
|
||||
<a href="{@UNSUBSCRIBE}" style="font-weight: 400; font-size: 12px; text-align: center; color: #ff761b;">{@UNSUBSCRIBETEXT}</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
|
||||
var tvDbId = child.ParentRequest.TvDbId;
|
||||
var imdbId = child.ParentRequest.ImdbId;
|
||||
IQueryable<EmbyEpisode> seriesEpisodes = null;
|
||||
IQueryable<IMediaServerEpisode> seriesEpisodes = null;
|
||||
if (useImdb)
|
||||
{
|
||||
seriesEpisodes = embyEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());
|
||||
|
|
|
@ -16,7 +16,7 @@ using Ombi.Schedule.Jobs.Ombi;
|
|||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Quartz;
|
||||
using EmbyMediaType = Ombi.Store.Entities.EmbyMediaType;
|
||||
using MediaType = Ombi.Store.Entities.MediaType;
|
||||
|
||||
namespace Ombi.Schedule.Jobs.Emby
|
||||
{
|
||||
|
@ -165,10 +165,10 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
ImdbId = tvShow.ProviderIds?.Imdb,
|
||||
TheMovieDbId = tvShow.ProviderIds?.Tmdb,
|
||||
Title = tvShow.Name,
|
||||
Type = EmbyMediaType.Series,
|
||||
Type = MediaType.Series,
|
||||
EmbyId = tvShow.Id,
|
||||
Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id, server?.ServerId, server.ServerHostname),
|
||||
AddedAt = DateTime.UtcNow
|
||||
AddedAt = DateTime.UtcNow,
|
||||
});
|
||||
}
|
||||
else
|
||||
|
@ -255,10 +255,10 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
ImdbId = movieInfo.ProviderIds.Imdb,
|
||||
TheMovieDbId = movieInfo.ProviderIds?.Tmdb,
|
||||
Title = movieInfo.Name,
|
||||
Type = EmbyMediaType.Movie,
|
||||
Type = MediaType.Movie,
|
||||
EmbyId = movieInfo.Id,
|
||||
Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname),
|
||||
AddedAt = DateTime.UtcNow,
|
||||
AddedAt = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
|
@ -151,7 +151,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
|
||||
var tvDbId = child.ParentRequest.TvDbId;
|
||||
var imdbId = child.ParentRequest.ImdbId;
|
||||
IQueryable<JellyfinEpisode> seriesEpisodes = null;
|
||||
IQueryable<IMediaServerEpisode> seriesEpisodes = null;
|
||||
if (useImdb)
|
||||
{
|
||||
seriesEpisodes = jellyfinEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString());
|
||||
|
|
|
@ -14,7 +14,7 @@ using Ombi.Schedule.Jobs.Ombi;
|
|||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Quartz;
|
||||
using JellyfinMediaType = Ombi.Store.Entities.JellyfinMediaType;
|
||||
using MediaType = Ombi.Store.Entities.MediaType;
|
||||
|
||||
namespace Ombi.Schedule.Jobs.Jellyfin
|
||||
{
|
||||
|
@ -143,7 +143,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
ImdbId = tvShow.ProviderIds?.Imdb,
|
||||
TheMovieDbId = tvShow.ProviderIds?.Tmdb,
|
||||
Title = tvShow.Name,
|
||||
Type = JellyfinMediaType.Series,
|
||||
Type = MediaType.Series,
|
||||
JellyfinId = tvShow.Id,
|
||||
Url = JellyfinHelper.GetJellyfinMediaUrl(tvShow.Id, server?.ServerId, server.ServerHostname),
|
||||
AddedAt = DateTime.UtcNow
|
||||
|
@ -223,10 +223,10 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
ImdbId = movieInfo.ProviderIds.Imdb,
|
||||
TheMovieDbId = movieInfo.ProviderIds?.Tmdb,
|
||||
Title = movieInfo.Name,
|
||||
Type = JellyfinMediaType.Movie,
|
||||
Type = MediaType.Movie,
|
||||
JellyfinId = movieInfo.Id,
|
||||
Url = JellyfinHelper.GetJellyfinMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname),
|
||||
AddedAt = DateTime.UtcNow,
|
||||
AddedAt = DateTime.UtcNow
|
||||
});
|
||||
}
|
||||
else
|
||||
|
|
|
@ -5,7 +5,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
public abstract class HtmlTemplateGenerator
|
||||
{
|
||||
protected virtual void AddBackgroundInsideTable(StringBuilder sb, string url)
|
||||
protected StringBuilder sb;
|
||||
protected virtual void AddBackgroundInsideTable(string url)
|
||||
{
|
||||
sb.Append("<td align=\"center\" valign=\"top\" width=\"500\" height=\"252\" class=\"media-card\" style=\"font-size: 14px; font-family: 'Open Sans', Helvetica, Arial, sans-serif; vertical-align: top; padding: 3px; width: 500px; min-width: 500px; max-width: 500px; height: 252px; max-height: 252px; \">");
|
||||
sb.AppendFormat("<table class=\"card-bg\" width=\"500\" height=\"252\" background=\"url(0)\" bgcolor=\"#1f1f1f\" style=\"background-image: url(0); border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 500px; background-color: #1f1f1f; background-position: center; background-size: cover; background-repeat: no-repeat; background-clip: padding-box; border: 2px solid rgba(255, 118, 27, .4); height: 252px; max-height: 252px; \">", url);
|
||||
|
@ -14,14 +15,14 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
sb.Append("<table class=\"bg-tint\" width=\"100%\" bgcolor=\"rgba(0, 0, 0, .6)\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background-color: rgba(0, 0, 0, .6); \">");
|
||||
}
|
||||
|
||||
protected virtual void AddPosterInsideTable(StringBuilder sb, string url)
|
||||
protected virtual void AddPosterInsideTable(string url)
|
||||
{
|
||||
sb.Append("<tr>");
|
||||
sb.Append("<td class=\"poster-container\" width=\"150\" height=\"225\" valign=\"top\" style=\"ont-family: sans-serif; font-size: 14px; vertical-align: top; width: 150px; min-width: 150px; height: 225px; max-height: 225px; min-height: 225px; \">");
|
||||
sb.AppendFormat("<table class=\"poster-img\" width=\"100%\" style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; \">", url);
|
||||
}
|
||||
|
||||
protected virtual void AddMediaServerUrl(StringBuilder sb, string mediaurl, string url)
|
||||
protected virtual void AddMediaServerUrl(string mediaurl, string url)
|
||||
{
|
||||
if (url.HasValue())
|
||||
{
|
||||
|
@ -41,14 +42,14 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
sb.Append("</td>");
|
||||
}
|
||||
|
||||
protected virtual void AddInfoTable(StringBuilder sb)
|
||||
protected virtual void AddInfoTable()
|
||||
{
|
||||
sb.Append(
|
||||
"<td class=\"movie-info\" height=\"227\" valign=\"top\" align=\"left\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; font-size: 14px; vertical-align: top; padding-left: 4px; text-align: left; height: 227px; \">");
|
||||
sb.Append("<table style=\"border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; height: 100%; \">");
|
||||
}
|
||||
|
||||
protected virtual void AddTitle(StringBuilder sb, string url, string title)
|
||||
protected virtual void AddTitle( string url, string title)
|
||||
{
|
||||
sb.Append("<tr class=\"title\" valign=\"top\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif;font-size: 22px;line-height: 24px;vertical-align: top;max-width: 320px;display: block;height: 50px;min-height: 50px;max-height: 50px; \">");
|
||||
sb.Append("<td>");
|
||||
|
@ -59,7 +60,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void AddParagraph(StringBuilder sb, string text)
|
||||
protected virtual void AddParagraph(string text)
|
||||
{
|
||||
sb.Append("<tr class=\"description\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif;height: 130px;max-height: 130px;max-width: 320px;overflow: hidden;text-overflow: ellipsis;display: block;font-size: 14px !important;text-align: justify;\" valign=\"top\">");
|
||||
sb.Append("<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
|
@ -68,7 +69,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void AddTvParagraph(StringBuilder sb, string episodes, string summary)
|
||||
protected virtual void AddTvParagraph(string episodes, string summary)
|
||||
{
|
||||
sb.Append("<tr class=\"description\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif;height: 130px;max-height: 130px;max-width: 320px;overflow: hidden;text-overflow: ellipsis;display: block;font-size: 14px !important;text-align: justify;\" valign=\"top\">");
|
||||
sb.Append("<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
|
@ -78,7 +79,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
sb.Append("</tr>");
|
||||
}
|
||||
|
||||
protected virtual void AddGenres(StringBuilder sb, string text)
|
||||
protected virtual void AddGenres(string text)
|
||||
{
|
||||
sb.Append("<tr class=\"meta\" style=\"font-family: 'Open Sans', Helvetica, Arial, sans-serif; max-width: 300px; min-width: 300px; padding: 3px 7px; margin-top: 10px; line-height: 1; text-align: left; white-space: nowrap; vertical-align: middle; background-color: rgba(255, 118, 27, 0.5); color: #fff; border-radius: 2px; overflow: hidden; display: block; font-size: 0.9rem;\" align=\"left\" valign=\"middle\" bgcolor=\"rgba(255, 118, 27, 0.5)\">");
|
||||
sb.Append("<td style=\"font-family: sans-serif; font-size: 14px; vertical-align: top; \">");
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -116,12 +116,12 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
// Ensure we check that we have not linked this item to a request
|
||||
var allMovies = await _plexRepo.GetAll().Where(x =>
|
||||
x.Type == PlexMediaTypeEntity.Movie && x.RequestId == null && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync();
|
||||
x.Type == MediaType.Movie && x.RequestId == null && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync();
|
||||
await StartPlexMovies(allMovies);
|
||||
|
||||
// Now Tv
|
||||
var allTv = await _plexRepo.GetAll().Where(x =>
|
||||
x.Type == PlexMediaTypeEntity.Show && x.RequestId == null && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync();
|
||||
x.Type == MediaType.Series && x.RequestId == null && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync();
|
||||
await StartPlexTv(allTv);
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
private async Task StartEmbyTv()
|
||||
{
|
||||
var allTv = await _embyRepo.GetAll().Where(x =>
|
||||
x.Type == EmbyMediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync();
|
||||
x.Type == MediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync();
|
||||
|
||||
foreach (var show in allTv)
|
||||
{
|
||||
|
@ -213,7 +213,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
private async Task StartJellyfinTv()
|
||||
{
|
||||
var allTv = await _jellyfinRepo.GetAll().Where(x =>
|
||||
x.Type == JellyfinMediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync();
|
||||
x.Type == MediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync();
|
||||
|
||||
foreach (var show in allTv)
|
||||
{
|
||||
|
@ -278,7 +278,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
private async Task StartEmbyMovies(EmbySettings settings)
|
||||
{
|
||||
var allMovies = await _embyRepo.GetAll().Where(x =>
|
||||
x.Type == EmbyMediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync();
|
||||
x.Type == MediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync();
|
||||
foreach (var movie in allMovies)
|
||||
{
|
||||
movie.ImdbId.HasValue();
|
||||
|
@ -333,7 +333,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
private async Task StartJellyfinMovies(JellyfinSettings settings)
|
||||
{
|
||||
var allMovies = await _jellyfinRepo.GetAll().Where(x =>
|
||||
x.Type == JellyfinMediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync();
|
||||
x.Type == MediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync();
|
||||
foreach (var movie in allMovies)
|
||||
{
|
||||
movie.ImdbId.HasValue();
|
||||
|
|
|
@ -86,7 +86,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
|
||||
var tvDbId = child.ParentRequest.TvDbId;
|
||||
var imdbId = child.ParentRequest.ImdbId;
|
||||
IQueryable<PlexEpisode> seriesEpisodes = null;
|
||||
IQueryable<IMediaServerEpisode> seriesEpisodes = null;
|
||||
if (useImdb)
|
||||
{
|
||||
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
|
||||
seriesEpisodes = plexEpisodes.Where(x =>
|
||||
x.Series.Title == child.Title &&
|
||||
x.Series.ReleaseYear == child.ParentRequest.ReleaseDate.Year.ToString());
|
||||
x.Series.Title == child.Title);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
await Repo.SaveChangesAsync();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
{
|
||||
var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title
|
||||
&& x.ReleaseYear == movie.year.ToString()
|
||||
&& x.Type == PlexMediaTypeEntity.Movie);
|
||||
&& x.Type == MediaType.Movie);
|
||||
// The rating key keeps changing
|
||||
//var existing = await Repo.GetByKey(movie.ratingKey);
|
||||
if (existing != null)
|
||||
|
@ -349,9 +349,9 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
AddedAt = DateTime.Now,
|
||||
Key = movie.ratingKey,
|
||||
ReleaseYear = movie.year.ToString(),
|
||||
Type = PlexMediaTypeEntity.Movie,
|
||||
Type = MediaType.Movie,
|
||||
Title = movie.title,
|
||||
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey),
|
||||
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey, servers.ServerHostname),
|
||||
Seasons = new List<PlexSeasonsContent>(),
|
||||
Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty
|
||||
};
|
||||
|
@ -411,7 +411,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
// Let's try and match
|
||||
var existingContent = await Repo.GetFirstContentByCustom(x => x.Title == show.title
|
||||
&& x.ReleaseYear == show.year.ToString()
|
||||
&& x.Type == PlexMediaTypeEntity.Show);
|
||||
&& x.Type == MediaType.Series);
|
||||
|
||||
// Just double check the rating key, since this is our unique constraint
|
||||
var existingKey = await Repo.GetByKey(show.ratingKey);
|
||||
|
@ -463,7 +463,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
Repo.DeleteWithoutSave(existingContent);
|
||||
|
||||
// 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())
|
||||
{
|
||||
foreach (var e in episodeToChange)
|
||||
|
@ -553,9 +553,9 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
AddedAt = DateTime.Now,
|
||||
Key = show.ratingKey,
|
||||
ReleaseYear = show.year.ToString(),
|
||||
Type = PlexMediaTypeEntity.Show,
|
||||
Type = MediaType.Series,
|
||||
Title = show.title,
|
||||
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey),
|
||||
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey, servers.ServerHostname),
|
||||
Seasons = new List<PlexSeasonsContent>()
|
||||
};
|
||||
await GetProviderIds(showMetadata, item);
|
||||
|
@ -567,19 +567,19 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
if (item.ImdbId.HasValue())
|
||||
{
|
||||
existingImdb = await Repo.GetAll().AnyAsync(x =>
|
||||
x.ImdbId == item.ImdbId && x.Type == PlexMediaTypeEntity.Show);
|
||||
x.ImdbId == item.ImdbId && x.Type == MediaType.Series);
|
||||
}
|
||||
|
||||
if (item.TheMovieDbId.HasValue())
|
||||
{
|
||||
existingMovieDbId = await Repo.GetAll().AnyAsync(x =>
|
||||
x.TheMovieDbId == item.TheMovieDbId && x.Type == PlexMediaTypeEntity.Show);
|
||||
x.TheMovieDbId == item.TheMovieDbId && x.Type == MediaType.Series);
|
||||
}
|
||||
|
||||
if (item.TvDbId.HasValue())
|
||||
{
|
||||
existingTvDbId = await Repo.GetAll().AnyAsync(x =>
|
||||
x.TvDbId == item.TvDbId && x.Type == PlexMediaTypeEntity.Show);
|
||||
x.TvDbId == item.TvDbId && x.Type == MediaType.Series);
|
||||
}
|
||||
|
||||
if (existingImdb || existingTvDbId || existingMovieDbId)
|
||||
|
|
|
@ -113,7 +113,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
{
|
||||
var currentPosition = 0;
|
||||
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);
|
||||
_log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}");
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
|
@ -42,20 +43,20 @@ namespace Ombi.Store.Context
|
|||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
builder.Entity<PlexServerContent>().HasMany(x => x.Episodes)
|
||||
.WithOne(x => x.Series)
|
||||
builder.Entity<PlexServerContent>().HasMany(x => (ICollection<PlexEpisode>) x.Episodes)
|
||||
.WithOne(x => (PlexServerContent) x.Series)
|
||||
.HasPrincipalKey(x => x.Key)
|
||||
.HasForeignKey(x => x.GrandparentKey);
|
||||
|
||||
builder.Entity<EmbyEpisode>()
|
||||
.HasOne(p => p.Series)
|
||||
.WithMany(b => b.Episodes)
|
||||
.HasOne(p => (EmbyContent) p.Series)
|
||||
.WithMany(b => (ICollection<EmbyEpisode>) b.Episodes)
|
||||
.HasPrincipalKey(x => x.EmbyId)
|
||||
.HasForeignKey(p => p.ParentId);
|
||||
|
||||
builder.Entity<JellyfinEpisode>()
|
||||
.HasOne(p => p.Series)
|
||||
.WithMany(b => b.Episodes)
|
||||
.HasOne(p => (JellyfinContent) p.Series)
|
||||
.WithMany(b => (ICollection<JellyfinEpisode>) b.Episodes)
|
||||
.HasPrincipalKey(x => x.JellyfinId)
|
||||
.HasForeignKey(p => p.ParentId);
|
||||
|
||||
|
|
|
@ -32,40 +32,13 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Ombi.Store.Entities
|
||||
{
|
||||
[Table("EmbyContent")]
|
||||
public class EmbyContent : Entity
|
||||
public class EmbyContent : MediaServerContent
|
||||
{
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OBSOLETE, Cannot delete due to DB migration issues with SQLite
|
||||
/// </summary>
|
||||
[Obsolete("Cannot delete due to DB migration issues with SQLite")]
|
||||
public string ProviderId { get; set; }
|
||||
public string EmbyId { get; set; }
|
||||
public EmbyMediaType Type { get; set; }
|
||||
public DateTime AddedAt { get; set; }
|
||||
|
||||
public string ImdbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
public string TvDbId { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public ICollection<EmbyEpisode> Episodes { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool HasImdb => !string.IsNullOrEmpty(ImdbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTvDb => !string.IsNullOrEmpty(TvDbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId);
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Emby;
|
||||
}
|
||||
|
||||
public enum EmbyMediaType
|
||||
{
|
||||
Movie = 0,
|
||||
Series = 1,
|
||||
Music = 2
|
||||
}
|
||||
}
|
|
@ -26,18 +26,16 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ombi.Store.Entities
|
||||
{
|
||||
[Table("EmbyEpisode")]
|
||||
public class EmbyEpisode : Entity
|
||||
public class EmbyEpisode : MediaServerEpisode
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string EmbyId { get; set; }
|
||||
public int EpisodeNumber { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
/// <summary>
|
||||
/// NOT USED
|
||||
|
@ -47,7 +45,23 @@ namespace Ombi.Store.Entities
|
|||
public string TvDbId { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
[NotMapped]
|
||||
public EmbyContent EmbySeries
|
||||
{
|
||||
get => (EmbyContent)Series;
|
||||
set => Series = value;
|
||||
}
|
||||
|
||||
public override IMediaServerContent SeriesIsIn(ICollection<IMediaServerContent> content)
|
||||
{
|
||||
return content.OfType<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);
|
||||
}
|
||||
|
||||
public EmbyContent Series { get; set; }
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace Ombi.Store.Entities
|
||||
{
|
||||
public abstract class Entity
|
||||
public abstract class Entity: IEntity
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
|
|
10
src/Ombi.Store/Entities/IEntity.cs
Normal file
10
src/Ombi.Store/Entities/IEntity.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Ombi.Store.Entities
|
||||
{
|
||||
public interface IEntity
|
||||
{
|
||||
[Key]
|
||||
public int Id { get; set; }
|
||||
}
|
||||
}
|
57
src/Ombi.Store/Entities/IMediaServerContent.cs
Normal file
57
src/Ombi.Store/Entities/IMediaServerContent.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Ombi.Store.Entities
|
||||
{
|
||||
public interface IMediaServerContent: IEntity
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public string TvDbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
public MediaType Type { get; set; }
|
||||
public RecentlyAddedType RecentlyAddedType{ get; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public ICollection<IMediaServerEpisode> Episodes { get; set; }
|
||||
|
||||
public DateTime AddedAt { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool HasImdb => !string.IsNullOrEmpty(ImdbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTvDb => !string.IsNullOrEmpty(TvDbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId);
|
||||
}
|
||||
|
||||
public interface IMediaServerEpisode
|
||||
{
|
||||
public int EpisodeNumber { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public string Title { get; set; }
|
||||
/// <summary>
|
||||
/// The Season key
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The parent key.
|
||||
/// </value>
|
||||
|
||||
|
||||
public IMediaServerContent Series { get; set; }
|
||||
public IMediaServerContent SeriesIsIn(ICollection<IMediaServerContent> content);
|
||||
public bool IsIn(IMediaServerContent content);
|
||||
}
|
||||
|
||||
public enum MediaType
|
||||
{
|
||||
Movie = 0,
|
||||
Series = 1,
|
||||
Music = 2,
|
||||
Episode = 3
|
||||
}
|
||||
}
|
|
@ -32,40 +32,14 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Ombi.Store.Entities
|
||||
{
|
||||
[Table("JellyfinContent")]
|
||||
public class JellyfinContent : Entity
|
||||
public class JellyfinContent : MediaServerContent
|
||||
{
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// OBSOLETE, Cannot delete due to DB migration issues with SQLite
|
||||
/// </summary>
|
||||
|
||||
[Obsolete("Cannot delete due to DB migration issues with SQLite")]
|
||||
public string ProviderId { get; set; }
|
||||
public string JellyfinId { get; set; }
|
||||
public JellyfinMediaType Type { get; set; }
|
||||
public DateTime AddedAt { get; set; }
|
||||
|
||||
public string ImdbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
public string TvDbId { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public ICollection<JellyfinEpisode> Episodes { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool HasImdb => !string.IsNullOrEmpty(ImdbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTvDb => !string.IsNullOrEmpty(TvDbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId);
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Jellyfin;
|
||||
}
|
||||
|
||||
public enum JellyfinMediaType
|
||||
{
|
||||
Movie = 0,
|
||||
Series = 1,
|
||||
Music = 2
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,18 +26,17 @@
|
|||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
namespace Ombi.Store.Entities
|
||||
{
|
||||
[Table("JellyfinEpisode")]
|
||||
public class JellyfinEpisode : Entity
|
||||
public class JellyfinEpisode : MediaServerEpisode
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string JellyfinId { get; set; }
|
||||
public int EpisodeNumber { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public string ParentId { get; set; }
|
||||
/// <summary>
|
||||
/// NOT USED
|
||||
|
@ -47,7 +46,22 @@ namespace Ombi.Store.Entities
|
|||
public string TvDbId { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
[NotMapped]
|
||||
public JellyfinContent JellyfinSeries
|
||||
{
|
||||
get => (JellyfinContent)Series;
|
||||
set => Series = value;
|
||||
}
|
||||
|
||||
public JellyfinContent Series { get; set; }
|
||||
public override IMediaServerContent SeriesIsIn(ICollection<IMediaServerContent> content)
|
||||
{
|
||||
return content.OfType<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
47
src/Ombi.Store/Entities/MediaServerContent.cs
Normal file
47
src/Ombi.Store/Entities/MediaServerContent.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Ombi.Store.Repository;
|
||||
|
||||
namespace Ombi.Store.Entities
|
||||
{
|
||||
public abstract class MediaServerContent: Entity, IMediaServerContent
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public string TvDbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
public MediaType Type { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public ICollection<IMediaServerEpisode> Episodes { get; set; }
|
||||
|
||||
public DateTime AddedAt { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool HasImdb => !string.IsNullOrEmpty(ImdbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTvDb => !string.IsNullOrEmpty(TvDbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId);
|
||||
|
||||
[NotMapped]
|
||||
public abstract RecentlyAddedType RecentlyAddedType { get; }
|
||||
}
|
||||
|
||||
public abstract class MediaServerEpisode: Entity, IMediaServerEpisode
|
||||
{
|
||||
public int EpisodeNumber { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
public IMediaServerContent Series { get; set; }
|
||||
|
||||
public abstract IMediaServerContent SeriesIsIn(ICollection<IMediaServerContent> content);
|
||||
public abstract bool IsIn(IMediaServerContent content);
|
||||
}
|
||||
}
|
|
@ -1,30 +1,38 @@
|
|||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
|
||||
namespace Ombi.Store.Entities
|
||||
{
|
||||
[Table("PlexEpisode")]
|
||||
public class PlexEpisode : Entity
|
||||
public class PlexEpisode : MediaServerEpisode
|
||||
{
|
||||
public int EpisodeNumber { get; set; }
|
||||
public int SeasonNumber { get; set; }
|
||||
public int Key { get; set; } // RatingKey
|
||||
public string Title { get; set; }
|
||||
/// <summary>
|
||||
/// The Season key
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The parent key.
|
||||
/// </value>
|
||||
public int ParentKey { get; set; }
|
||||
/// <summary>
|
||||
/// The Series key
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The grandparent key.
|
||||
/// </value>
|
||||
public int GrandparentKey { get; set; }
|
||||
[NotMapped]
|
||||
public PlexServerContent PlexSeries
|
||||
{
|
||||
get => (PlexServerContent)Series;
|
||||
set => Series = value;
|
||||
}
|
||||
|
||||
public override IMediaServerContent SeriesIsIn(ICollection<IMediaServerContent> content)
|
||||
{
|
||||
return content.OfType<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);
|
||||
}
|
||||
|
||||
public PlexServerContent Series { get; set; }
|
||||
}
|
||||
}
|
|
@ -32,37 +32,20 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace Ombi.Store.Entities
|
||||
{
|
||||
[Table("PlexServerContent")]
|
||||
public class PlexServerContent : Entity
|
||||
public class PlexServerContent : MediaServerContent
|
||||
{
|
||||
public string Title { get; set; }
|
||||
public string ReleaseYear { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public string TvDbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
public PlexMediaTypeEntity Type { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public ICollection<PlexEpisode> Episodes { get; set; }
|
||||
public ICollection<PlexSeasonsContent> Seasons { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Plex's internal ID for this item
|
||||
/// </summary>
|
||||
public int Key { get; set; }
|
||||
public DateTime AddedAt { get; set; }
|
||||
public string Quality { get; set; }
|
||||
|
||||
public int? RequestId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public bool HasImdb => !string.IsNullOrEmpty(ImdbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTvDb => !string.IsNullOrEmpty(TvDbId);
|
||||
|
||||
[NotMapped]
|
||||
public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId);
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Plex;
|
||||
}
|
||||
|
||||
[Table("PlexSeasonsContent")]
|
||||
|
@ -73,10 +56,4 @@ namespace Ombi.Store.Entities
|
|||
public int SeasonKey { get; set; }
|
||||
public int ParentKey { get; set; }
|
||||
}
|
||||
|
||||
public enum PlexMediaTypeEntity
|
||||
{
|
||||
Movie = 0,
|
||||
Show = 1
|
||||
}
|
||||
}
|
|
@ -35,17 +35,13 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public class EmbyContentRepository : ExternalRepository<EmbyContent>, IEmbyContentRepository
|
||||
public class EmbyContentRepository : MediaServerContentRepository<EmbyContent>, IEmbyContentRepository
|
||||
{
|
||||
|
||||
public EmbyContentRepository(ExternalContext db):base(db)
|
||||
{
|
||||
Db = db;
|
||||
}
|
||||
|
||||
private ExternalContext Db { get; }
|
||||
|
||||
|
||||
public async Task<EmbyContent> GetByImdbId(string imdbid)
|
||||
{
|
||||
return await Db.EmbyContent.FirstOrDefaultAsync(x => x.ImdbId == imdbid);
|
||||
|
@ -69,20 +65,20 @@ namespace Ombi.Store.Repository
|
|||
return await Db.EmbyContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.EmbyId == embyId);
|
||||
}
|
||||
|
||||
public async Task Update(EmbyContent existingContent)
|
||||
public override async Task Update(IMediaServerContent existingContent)
|
||||
{
|
||||
Db.EmbyContent.Update(existingContent);
|
||||
Db.EmbyContent.Update((EmbyContent)existingContent);
|
||||
await InternalSaveChanges();
|
||||
}
|
||||
|
||||
public IQueryable<EmbyEpisode> GetAllEpisodes()
|
||||
public override IQueryable<IMediaServerEpisode> GetAllEpisodes()
|
||||
{
|
||||
return Db.EmbyEpisode.AsQueryable();
|
||||
}
|
||||
|
||||
public async Task<EmbyEpisode> Add(EmbyEpisode content)
|
||||
public override async Task<IMediaServerEpisode> Add(IMediaServerEpisode content)
|
||||
{
|
||||
await Db.EmbyEpisode.AddAsync(content);
|
||||
await Db.EmbyEpisode.AddAsync((EmbyEpisode)content);
|
||||
await InternalSaveChanges();
|
||||
return content;
|
||||
}
|
||||
|
@ -91,16 +87,17 @@ namespace Ombi.Store.Repository
|
|||
return await Db.EmbyEpisode.FirstOrDefaultAsync(x => x.EmbyId == key);
|
||||
}
|
||||
|
||||
public async Task AddRange(IEnumerable<EmbyEpisode> content)
|
||||
public override async Task AddRange(IEnumerable<IMediaServerEpisode> content)
|
||||
{
|
||||
Db.EmbyEpisode.AddRange(content);
|
||||
Db.EmbyEpisode.AddRange((IEnumerable<EmbyEpisode>)content);
|
||||
await InternalSaveChanges();
|
||||
}
|
||||
|
||||
public void UpdateWithoutSave(EmbyContent existingContent)
|
||||
public override void UpdateWithoutSave(IMediaServerContent existingContent)
|
||||
{
|
||||
Db.EmbyContent.Update(existingContent);
|
||||
Db.EmbyContent.Update((EmbyContent)existingContent);
|
||||
}
|
||||
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Emby;
|
||||
}
|
||||
}
|
|
@ -6,19 +6,16 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public interface IEmbyContentRepository : IRepository<EmbyContent>
|
||||
public interface IEmbyContentRepository : IMediaServerContentRepository<EmbyContent>
|
||||
{
|
||||
Task<EmbyContent> GetByEmbyId(string embyId);
|
||||
Task<EmbyEpisode> GetEpisodeByEmbyId(string key);
|
||||
|
||||
// TODO: merge these with IJellyfinContentRepository
|
||||
IQueryable<EmbyContent> Get();
|
||||
Task<EmbyContent> GetByTheMovieDbId(string mov);
|
||||
Task<EmbyContent> GetByTvDbId(string tv);
|
||||
Task<EmbyContent> GetByImdbId(string imdbid);
|
||||
Task<EmbyContent> GetByEmbyId(string embyId);
|
||||
Task Update(EmbyContent existingContent);
|
||||
IQueryable<EmbyEpisode> GetAllEpisodes();
|
||||
Task<EmbyEpisode> Add(EmbyEpisode content);
|
||||
Task<EmbyEpisode> GetEpisodeByEmbyId(string key);
|
||||
Task AddRange(IEnumerable<EmbyEpisode> content);
|
||||
|
||||
void UpdateWithoutSave(EmbyContent existingContent);
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public interface IExternalRepository<T> where T : Entity
|
||||
public interface IExternalRepository<T> where T : IEntity
|
||||
{
|
||||
Task<T> Find(object key);
|
||||
IQueryable<T> GetAll();
|
||||
|
@ -25,6 +25,5 @@ namespace Ombi.Store.Repository
|
|||
where TEntity : class;
|
||||
|
||||
Task ExecuteSql(string sql);
|
||||
DbSet<T> _db { get; }
|
||||
}
|
||||
}
|
|
@ -6,19 +6,16 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public interface IJellyfinContentRepository : IRepository<JellyfinContent>
|
||||
public interface IJellyfinContentRepository : IMediaServerContentRepository<JellyfinContent>
|
||||
{
|
||||
Task<JellyfinContent> GetByJellyfinId(string jellyfinId);
|
||||
Task<JellyfinEpisode> GetEpisodeByJellyfinId(string key);
|
||||
|
||||
// TODO: merge these with IEmbyContentRepository
|
||||
IQueryable<JellyfinContent> Get();
|
||||
Task<JellyfinContent> GetByTheMovieDbId(string mov);
|
||||
Task<JellyfinContent> GetByTvDbId(string tv);
|
||||
Task<JellyfinContent> GetByImdbId(string imdbid);
|
||||
Task<JellyfinContent> GetByJellyfinId(string jellyfinId);
|
||||
Task Update(JellyfinContent existingContent);
|
||||
IQueryable<JellyfinEpisode> GetAllEpisodes();
|
||||
Task<JellyfinEpisode> Add(JellyfinEpisode content);
|
||||
Task<JellyfinEpisode> GetEpisodeByJellyfinId(string key);
|
||||
Task AddRange(IEnumerable<JellyfinEpisode> content);
|
||||
|
||||
void UpdateWithoutSave(JellyfinContent existingContent);
|
||||
}
|
||||
}
|
||||
|
|
18
src/Ombi.Store/Repository/IMediaServerContentRepository.cs
Normal file
18
src/Ombi.Store/Repository/IMediaServerContentRepository.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Store.Entities;
|
||||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public interface IMediaServerContentRepository<Content> : IExternalRepository<Content>
|
||||
where Content : IMediaServerContent
|
||||
{
|
||||
RecentlyAddedType RecentlyAddedType{ get; }
|
||||
Task Update(IMediaServerContent existingContent);
|
||||
IQueryable<IMediaServerEpisode> GetAllEpisodes();
|
||||
Task<IMediaServerEpisode> Add(IMediaServerEpisode content);
|
||||
Task AddRange(IEnumerable<IMediaServerEpisode> content);
|
||||
void UpdateWithoutSave(IMediaServerContent existingContent);
|
||||
}
|
||||
}
|
|
@ -8,23 +8,18 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public interface IPlexContentRepository : IExternalRepository<PlexServerContent>
|
||||
public interface IPlexContentRepository : IMediaServerContentRepository<PlexServerContent>
|
||||
{
|
||||
Task<bool> ContentExists(string providerId);
|
||||
Task<PlexServerContent> Get(string providerId, ProviderType type);
|
||||
Task<PlexServerContent> GetByType(string providerId, ProviderType type, PlexMediaTypeEntity plexType);
|
||||
Task<PlexServerContent> GetByType(string providerId, ProviderType type, MediaType mediaType);
|
||||
Task<PlexServerContent> GetByKey(int key);
|
||||
Task Update(PlexServerContent existingContent);
|
||||
IQueryable<PlexEpisode> GetAllEpisodes();
|
||||
Task<PlexEpisode> Add(PlexEpisode content);
|
||||
Task<PlexEpisode> GetEpisodeByKey(int key);
|
||||
Task AddRange(IEnumerable<PlexEpisode> content);
|
||||
IEnumerable<PlexServerContent> GetWhereContentByCustom(Expression<Func<PlexServerContent, bool>> predicate);
|
||||
Task<PlexServerContent> GetFirstContentByCustom(Expression<Func<PlexServerContent, bool>> predicate);
|
||||
Task DeleteEpisode(PlexEpisode content);
|
||||
void DeleteWithoutSave(PlexServerContent content);
|
||||
void DeleteWithoutSave(PlexEpisode content);
|
||||
Task UpdateRange(IEnumerable<PlexServerContent> existingContent);
|
||||
void UpdateWithoutSave(PlexServerContent existingContent);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public interface IRepository<T> where T : Entity
|
||||
public interface IRepository<T> where T : IEntity
|
||||
{
|
||||
Task<T> Find(object key);
|
||||
Task<T> Find(object key, CancellationToken cancellationToken);
|
||||
|
@ -27,6 +27,5 @@ namespace Ombi.Store.Repository
|
|||
where TEntity : class;
|
||||
|
||||
Task ExecuteSql(string sql);
|
||||
DbSet<T> _db { get; }
|
||||
}
|
||||
}
|
|
@ -35,17 +35,13 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public class JellyfinContentRepository : ExternalRepository<JellyfinContent>, IJellyfinContentRepository
|
||||
public class JellyfinContentRepository : MediaServerContentRepository<JellyfinContent>, IJellyfinContentRepository
|
||||
{
|
||||
|
||||
public JellyfinContentRepository(ExternalContext db):base(db)
|
||||
{
|
||||
Db = db;
|
||||
}
|
||||
|
||||
private ExternalContext Db { get; }
|
||||
|
||||
|
||||
public async Task<JellyfinContent> GetByImdbId(string imdbid)
|
||||
{
|
||||
return await Db.JellyfinContent.FirstOrDefaultAsync(x => x.ImdbId == imdbid);
|
||||
|
@ -69,20 +65,20 @@ namespace Ombi.Store.Repository
|
|||
return await Db.JellyfinContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.JellyfinId == jellyfinId);
|
||||
}
|
||||
|
||||
public async Task Update(JellyfinContent existingContent)
|
||||
public override async Task Update(IMediaServerContent existingContent)
|
||||
{
|
||||
Db.JellyfinContent.Update(existingContent);
|
||||
Db.JellyfinContent.Update((JellyfinContent)existingContent);
|
||||
await InternalSaveChanges();
|
||||
}
|
||||
|
||||
public IQueryable<JellyfinEpisode> GetAllEpisodes()
|
||||
public override IQueryable<IMediaServerEpisode> GetAllEpisodes()
|
||||
{
|
||||
return Db.JellyfinEpisode.AsQueryable();
|
||||
}
|
||||
|
||||
public async Task<JellyfinEpisode> Add(JellyfinEpisode content)
|
||||
public override async Task<IMediaServerEpisode> Add(IMediaServerEpisode content)
|
||||
{
|
||||
await Db.JellyfinEpisode.AddAsync(content);
|
||||
await Db.JellyfinEpisode.AddAsync((JellyfinEpisode)content);
|
||||
await InternalSaveChanges();
|
||||
return content;
|
||||
}
|
||||
|
@ -91,16 +87,17 @@ namespace Ombi.Store.Repository
|
|||
return await Db.JellyfinEpisode.FirstOrDefaultAsync(x => x.JellyfinId == key);
|
||||
}
|
||||
|
||||
public async Task AddRange(IEnumerable<JellyfinEpisode> content)
|
||||
public override async Task AddRange(IEnumerable<IMediaServerEpisode> content)
|
||||
{
|
||||
Db.JellyfinEpisode.AddRange(content);
|
||||
Db.JellyfinEpisode.AddRange((IEnumerable<JellyfinEpisode>)content);
|
||||
await InternalSaveChanges();
|
||||
}
|
||||
|
||||
public void UpdateWithoutSave(JellyfinContent existingContent)
|
||||
public override void UpdateWithoutSave(IMediaServerContent existingContent)
|
||||
{
|
||||
Db.JellyfinContent.Update(existingContent);
|
||||
Db.JellyfinContent.Update((JellyfinContent)existingContent);
|
||||
}
|
||||
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Jellyfin;
|
||||
}
|
||||
}
|
||||
|
|
25
src/Ombi.Store/Repository/MediaServerRepository.cs
Normal file
25
src/Ombi.Store/Repository/MediaServerRepository.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Store.Context;
|
||||
using Ombi.Store.Entities;
|
||||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public abstract class MediaServerContentRepository<T> : ExternalRepository<T>, IMediaServerContentRepository<T> where T : MediaServerContent
|
||||
{
|
||||
protected ExternalContext Db { get; }
|
||||
public abstract RecentlyAddedType RecentlyAddedType { get; }
|
||||
|
||||
public MediaServerContentRepository(ExternalContext db) : base(db)
|
||||
{
|
||||
Db = db;
|
||||
}
|
||||
|
||||
public abstract Task Update(IMediaServerContent existingContent);
|
||||
public abstract IQueryable<IMediaServerEpisode> GetAllEpisodes();
|
||||
public abstract Task<IMediaServerEpisode> Add(IMediaServerEpisode content);
|
||||
public abstract Task AddRange(IEnumerable<IMediaServerEpisode> content);
|
||||
public abstract void UpdateWithoutSave(IMediaServerContent existingContent);
|
||||
}
|
||||
}
|
|
@ -37,17 +37,13 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public class PlexServerContentRepository : ExternalRepository<PlexServerContent>, IPlexContentRepository
|
||||
public class PlexServerContentRepository : MediaServerContentRepository<PlexServerContent>, IPlexContentRepository
|
||||
{
|
||||
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Plex;
|
||||
public PlexServerContentRepository(ExternalContext db) : base(db)
|
||||
{
|
||||
Db = db;
|
||||
}
|
||||
|
||||
private ExternalContext Db { get; }
|
||||
|
||||
|
||||
public async Task<bool> ContentExists(string providerId)
|
||||
{
|
||||
var any = await Db.PlexServerContent.AnyAsync(x => x.ImdbId == providerId);
|
||||
|
@ -79,16 +75,16 @@ namespace Ombi.Store.Repository
|
|||
return null;
|
||||
}
|
||||
|
||||
public async Task<PlexServerContent> GetByType(string providerId, ProviderType type, PlexMediaTypeEntity plexType)
|
||||
public async Task<PlexServerContent> GetByType(string providerId, ProviderType type, MediaType mediaType)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ProviderType.ImdbId:
|
||||
return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.ImdbId == providerId && x.Type == plexType);
|
||||
return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.ImdbId == providerId && x.Type == mediaType);
|
||||
case ProviderType.TheMovieDbId:
|
||||
return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TheMovieDbId == providerId && x.Type == plexType);
|
||||
return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TheMovieDbId == providerId && x.Type == mediaType);
|
||||
case ProviderType.TvDbId:
|
||||
return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TvDbId == providerId && x.Type == plexType);
|
||||
return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TvDbId == providerId && x.Type == mediaType);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -114,14 +110,14 @@ namespace Ombi.Store.Repository
|
|||
.FirstOrDefaultAsync(predicate);
|
||||
}
|
||||
|
||||
public async Task Update(PlexServerContent existingContent)
|
||||
public override async Task Update(IMediaServerContent existingContent)
|
||||
{
|
||||
Db.PlexServerContent.Update(existingContent);
|
||||
Db.PlexServerContent.Update((PlexServerContent)existingContent);
|
||||
await InternalSaveChanges();
|
||||
}
|
||||
public void UpdateWithoutSave(PlexServerContent existingContent)
|
||||
public override void UpdateWithoutSave(IMediaServerContent existingContent)
|
||||
{
|
||||
Db.PlexServerContent.Update(existingContent);
|
||||
Db.PlexServerContent.Update((PlexServerContent)existingContent);
|
||||
}
|
||||
|
||||
public async Task UpdateRange(IEnumerable<PlexServerContent> existingContent)
|
||||
|
@ -130,7 +126,7 @@ namespace Ombi.Store.Repository
|
|||
await InternalSaveChanges();
|
||||
}
|
||||
|
||||
public IQueryable<PlexEpisode> GetAllEpisodes()
|
||||
public override IQueryable<IMediaServerEpisode> GetAllEpisodes()
|
||||
{
|
||||
return Db.PlexEpisode.Include(x => x.Series).AsQueryable();
|
||||
}
|
||||
|
@ -145,9 +141,9 @@ namespace Ombi.Store.Repository
|
|||
Db.PlexEpisode.Remove(content);
|
||||
}
|
||||
|
||||
public async Task<PlexEpisode> Add(PlexEpisode content)
|
||||
public override async Task<IMediaServerEpisode> Add(IMediaServerEpisode content)
|
||||
{
|
||||
await Db.PlexEpisode.AddAsync(content);
|
||||
await Db.PlexEpisode.AddAsync((PlexEpisode)content);
|
||||
await InternalSaveChanges();
|
||||
return content;
|
||||
}
|
||||
|
@ -162,10 +158,11 @@ namespace Ombi.Store.Repository
|
|||
{
|
||||
return await Db.PlexEpisode.FirstOrDefaultAsync(x => x.Key == key);
|
||||
}
|
||||
public async Task AddRange(IEnumerable<PlexEpisode> content)
|
||||
public override async Task AddRange(IEnumerable<IMediaServerEpisode> content)
|
||||
{
|
||||
Db.PlexEpisode.AddRange(content);
|
||||
Db.PlexEpisode.AddRange((IEnumerable<PlexEpisode>)content);
|
||||
await InternalSaveChanges();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue