From dec4f317b27445042ebc4ea5cbf2558a4605b5e9 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sat, 12 Feb 2022 21:16:09 +0000 Subject: [PATCH] feat: Done the media sync jobs --- src/Ombi.Api.Emby/EmbyApi.cs | 2 +- src/Ombi.Api.Jellyfin/JellyfinApi.cs | 2 +- .../Models/Media/JellyfinMediastream.cs | 29 - .../Models/Media/Movie/JellyfinMovie.cs | 1 + src/Ombi.Api.Plex/Models/Metadata.cs | 1 - .../Rule/Search/EmbyAvailabilityRuleTests.cs | 2 +- .../PlexContentSyncTests.cs | 78 ++- .../Jobs/Emby/EmbyContentSync.cs | 41 +- .../Jobs/Jellyfin/JellyfinContentSync.cs | 40 +- .../Jobs/Ombi/AutoDeleteRequests.cs | 2 +- .../Jobs/Plex/PlexContentSync.cs | 35 +- src/Ombi.Store/Entities/MediaServerContent.cs | 4 + .../20220212210902_MediaServer4k.Designer.cs | 536 ++++++++++++++++++ .../20220212210902_MediaServer4k.cs | 48 ++ .../ExternalMySqlContextModelSnapshot.cs | 9 + .../20220212210807_MediaServer4k.Designer.cs | 534 +++++++++++++++++ .../20220212210807_MediaServer4k.cs | 48 ++ .../ExternalSqliteContextModelSnapshot.cs | 9 + .../Repository/EmbyContentRepository.cs | 10 +- .../IMediaServerContentRepository.cs | 1 + .../Repository/JellyfinContentRepository.cs | 6 + .../Repository/MediaServerRepository.cs | 1 + .../Repository/PlexContentRepository.cs | 5 + 23 files changed, 1378 insertions(+), 66 deletions(-) create mode 100644 src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs create mode 100644 src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.cs create mode 100644 src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs create mode 100644 src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.cs diff --git a/src/Ombi.Api.Emby/EmbyApi.cs b/src/Ombi.Api.Emby/EmbyApi.cs index d911ca212..c12cdb716 100644 --- a/src/Ombi.Api.Emby/EmbyApi.cs +++ b/src/Ombi.Api.Emby/EmbyApi.cs @@ -170,7 +170,7 @@ namespace Ombi.Api.Emby request.AddQueryString("Recursive", true.ToString()); request.AddQueryString("IncludeItemTypes", type); - request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); + request.AddQueryString("Fields", includeOverview ? "ProviderIds,MediaStreams,Overview" : "ProviderIds,MediaStreams "); request.AddQueryString("startIndex", startIndex.ToString()); request.AddQueryString("limit", count.ToString()); request.AddQueryString("sortBy", "DateCreated"); diff --git a/src/Ombi.Api.Jellyfin/JellyfinApi.cs b/src/Ombi.Api.Jellyfin/JellyfinApi.cs index 2fafbfd86..f6afb7912 100644 --- a/src/Ombi.Api.Jellyfin/JellyfinApi.cs +++ b/src/Ombi.Api.Jellyfin/JellyfinApi.cs @@ -157,7 +157,7 @@ namespace Ombi.Api.Jellyfin request.AddQueryString("Recursive", true.ToString()); request.AddQueryString("IncludeItemTypes", type); - request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview,ParentId" : "ProviderIds,ParentId"); + request.AddQueryString("Fields", includeOverview ? "ProviderIds,MediaStreams Overview,ParentId" : "ProviderIds,ParentId,MediaStreams"); request.AddQueryString("startIndex", startIndex.ToString()); request.AddQueryString("limit", count.ToString()); if(!string.IsNullOrEmpty(parentIdFilder)) diff --git a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs index 89da2651a..e15a21e7b 100644 --- a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs +++ b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs @@ -2,35 +2,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie { public class JellyfinMediastream { - public string Codec { get; set; } - public string Language { get; set; } - public string TimeBase { get; set; } - public string CodecTimeBase { get; set; } - public string NalLengthSize { get; set; } - public bool IsInterlaced { get; set; } - public bool IsAVC { get; set; } - public int BitRate { get; set; } - public int BitDepth { get; set; } - public int RefFrames { get; set; } - public bool IsDefault { get; set; } - public bool IsForced { get; set; } - public int Height { get; set; } - public int Width { get; set; } - public float AverageFrameRate { get; set; } - public float RealFrameRate { get; set; } - public string Profile { get; set; } - public string Type { get; set; } - public string AspectRatio { get; set; } - public int Index { get; set; } - public bool IsExternal { get; set; } - public bool IsTextSubtitleStream { get; set; } - public bool SupportsExternalStream { get; set; } - public string PixelFormat { get; set; } - public int Level { get; set; } - public bool IsAnamorphic { get; set; } public string DisplayTitle { get; set; } - public string ChannelLayout { get; set; } - public int Channels { get; set; } - public int SampleRate { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs b/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs index d86bf5047..a83e1f087 100644 --- a/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs +++ b/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs @@ -30,5 +30,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie public int CriticRating { get; set; } public string Overview { get; set; } public JellyfinProviderids ProviderIds { get; set; } + public JellyfinMediastream[] MediaStreams { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/Metadata.cs b/src/Ombi.Api.Plex/Models/Metadata.cs index d0bb227ad..d505e5fb4 100644 --- a/src/Ombi.Api.Plex/Models/Metadata.cs +++ b/src/Ombi.Api.Plex/Models/Metadata.cs @@ -12,7 +12,6 @@ namespace Ombi.Api.Plex.Models public string contentRating { get; set; } public string summary { get; set; } public int index { get; set; } - public float rating { get; set; } //public int viewCount { get; set; } //public int lastViewedAt { get; set; } public int year { get; set; } diff --git a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs index 0e455418a..966dfe4e3 100644 --- a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs @@ -35,7 +35,7 @@ namespace Ombi.Core.Tests.Rule.Search SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings()); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new EmbyContent { - ProviderId = "123" + TheMovieDbId = "123" }); var search = new SearchMovieViewModel() { diff --git a/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs b/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs index 3b9fa33b0..da128794c 100644 --- a/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs +++ b/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs @@ -133,12 +133,88 @@ namespace Ombi.Schedule.Tests } })); - await _subject.MovieLoop(new PlexServers { Ip = "http://test.com/", Port = 80}, content, contentToAdd, contentProcessed); + await _subject.MovieLoop(new PlexServers { Ip = "http://test.com/", Port = 80 }, content, contentToAdd, contentProcessed); var first = contentToAdd.First(); Assert.That(first.ImdbId, Is.EqualTo("tt0322259")); _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); } + + [Test] + public async Task UpdatesExistingMovieWhen_WeFindAnotherQuality() + { + var content = new Mediacontainer + { + Metadata = new[] + { + new Metadata + { + ratingKey = 11, + title = "test1", + year = 2021, + type = "movie", + Media = new Medium[1] + { + new Medium + { + videoResolution = "4k" + } + } + }, + } + }; + var contentToAdd = new HashSet(); + var contentProcessed = new Dictionary(); + _mocker.Setup(x => + x.GetFirstContentByCustom(It.IsAny>>())) + .Returns(Task.FromResult(new PlexServerContent + { + Quality = "1080" + })); + + await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed); + + Assert.That(contentToAdd, Is.Empty); + _mocker.Verify(x => x.Update(It.Is(x => x.Quality == "1080" && x.Has4K)), Times.Once); + } + + [Test] + public async Task DoesNotUpdatesExistingMovieWhen_WeFindSameQuality() + { + var content = new Mediacontainer + { + Metadata = new[] + { + new Metadata + { + ratingKey = 11, + title = "test1", + year = 2021, + type = "movie", + Media = new Medium[1] + { + new Medium + { + videoResolution = "1080" + } + } + }, + } + }; + var contentToAdd = new HashSet(); + var contentProcessed = new Dictionary(); + _mocker.Setup(x => + x.GetFirstContentByCustom(It.IsAny>>())) + .Returns(Task.FromResult(new PlexServerContent + { + Quality = "1080" + })); + + await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed); + + Assert.That(contentToAdd, Is.Empty); + _mocker.Verify(x => x.Update(It.IsAny()), Times.Never); + } } } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index faff73752..89baa7e9d 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -210,6 +210,7 @@ namespace Ombi.Schedule.Jobs.Emby var totalCount = movies.TotalRecordCount; var processed = 0; var mediaToAdd = new HashSet(); + var mediaToUpdate = new HashSet(); while (processed < totalCount) { foreach (var movie in movies.Items) @@ -220,13 +221,13 @@ namespace Ombi.Schedule.Jobs.Emby await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri); foreach (var item in movieInfo.Items) { - await ProcessMovies(item, mediaToAdd, server); + await ProcessMovies(item, mediaToAdd, mediaToUpdate, server); } } else { // Regular movie - await ProcessMovies(movie, mediaToAdd, server); + await ProcessMovies(movie, mediaToAdd, mediaToUpdate, server); } processed++; @@ -239,29 +240,31 @@ namespace Ombi.Schedule.Jobs.Emby movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, AmountToTake, server.AdministratorId, server.FullUri); } await _repo.AddRange(mediaToAdd); + await _repo.UpdateRange(mediaToUpdate); mediaToAdd.Clear(); } } - private async Task ProcessMovies(EmbyMovie movieInfo, ICollection content, EmbyServers server) + private async Task ProcessMovies(EmbyMovie movieInfo, ICollection content, ICollection toUpdate, EmbyServers server) { + var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty; + var has4K = false; + if (quality.Contains("4K", CompareOptions.IgnoreCase)) + { + has4K = true; + } + // Check if it exists var existingMovie = await _repo.GetByEmbyId(movieInfo.Id); var alreadyGoingToAdd = content.Any(x => x.EmbyId == movieInfo.Id); if (existingMovie == null && !alreadyGoingToAdd) { - if (!movieInfo.ProviderIds.Any()) { _logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping."); return; } - _logger.LogDebug("Adding new movie {0}", movieInfo.Name); - var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty; - if (quality.Contains("4K", CompareOptions.IgnoreCase)) - { - quality = "4K"; - } + _logger.LogDebug($"Adding new movie {movieInfo.Name}"); content.Add(new EmbyContent { @@ -272,13 +275,25 @@ namespace Ombi.Schedule.Jobs.Emby EmbyId = movieInfo.Id, Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), AddedAt = DateTime.UtcNow, - Quality = quality + Quality = has4K ? null : quality, + Has4K = has4K }); } else { - // we have this - _logger.LogDebug("We already have movie {0}", movieInfo.Name); + if (!existingMovie.Quality.Equals(quality, StringComparison.InvariantCultureIgnoreCase)) + { + _logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'"); + existingMovie.Quality = has4K ? null : quality; + existingMovie.Has4K = has4K; + + toUpdate.Add(existingMovie); + } + else + { + // we have this + _logger.LogDebug($"We already have movie {movieInfo.Name}"); + } } } diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs index fec5ca0ce..10a6ae98c 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; @@ -77,9 +78,6 @@ namespace Ombi.Schedule.Jobs.Jellyfin return; } - //await _repo.ExecuteSql("DELETE FROM JellyfinEpisode"); - //await _repo.ExecuteSql("DELETE FROM JellyfinContent"); - if (server.JellyfinSelectedLibraries.Any() && server.JellyfinSelectedLibraries.Any(x => x.Enabled)) { var movieLibsToFilter = server.JellyfinSelectedLibraries.Where(x => x.Enabled && x.CollectionType == "movies"); @@ -179,6 +177,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin var totalCount = movies.TotalRecordCount; var processed = 0; var mediaToAdd = new HashSet(); + var mediaToUpdate = new HashSet(); while (processed < totalCount) { foreach (var movie in movies.Items) @@ -189,7 +188,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri); foreach (var item in movieInfo.Items) { - await ProcessMovies(item, mediaToAdd, server); + await ProcessMovies(item, mediaToAdd, mediaToUpdate, server); } processed++; @@ -198,20 +197,28 @@ namespace Ombi.Schedule.Jobs.Jellyfin { processed++; // Regular movie - await ProcessMovies(movie, mediaToAdd, server); + await ProcessMovies(movie, mediaToAdd, mediaToUpdate, server); } } // Get the next batch movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, 200, server.AdministratorId, server.FullUri); await _repo.AddRange(mediaToAdd); + await _repo.UpdateRange(mediaToUpdate); mediaToAdd.Clear(); } } - private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection content, JellyfinServers server) + private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection content, ICollection toUpdate, JellyfinServers server) { + var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty; + var has4K = false; + if (quality.Contains("4K", CompareOptions.IgnoreCase)) + { + has4K = true; + } + // Check if it exists var existingMovie = await _repo.GetByJellyfinId(movieInfo.Id); var alreadyGoingToAdd = content.Any(x => x.JellyfinId == movieInfo.Id); @@ -222,7 +229,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin _logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping."); return; } - _logger.LogDebug("Adding new movie {0}", movieInfo.Name); + _logger.LogDebug($"Adding new movie {movieInfo.Name}"); content.Add(new JellyfinContent { ImdbId = movieInfo.ProviderIds.Imdb, @@ -231,13 +238,26 @@ namespace Ombi.Schedule.Jobs.Jellyfin Type = MediaType.Movie, JellyfinId = movieInfo.Id, Url = JellyfinHelper.GetJellyfinMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), - AddedAt = DateTime.UtcNow + AddedAt = DateTime.UtcNow, + Quality = has4K ? null : quality, + Has4K = has4K }); } else { - // we have this - _logger.LogDebug("We already have movie {0}", movieInfo.Name); + if (!existingMovie.Quality.Equals(quality, StringComparison.InvariantCultureIgnoreCase)) + { + _logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'"); + existingMovie.Quality = has4K ? null : quality; + existingMovie.Has4K = has4K; + + toUpdate.Add(existingMovie); + } + else + { + // we have this + _logger.LogDebug($"We already have movie {movieInfo.Name}"); + } } } diff --git a/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs b/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs index a2a7e4ed1..eba3c4998 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs @@ -25,7 +25,7 @@ namespace Ombi.Schedule.Jobs.Ombi _ombiSettings = ombiSettings; _movieRequests = movieRequest; _tvRequestRepository = tvRequestRepository; - _musicRequestRepository = _musicRequestRepository; + _musicRequestRepository = musicRequestRepository; _logger = logger; } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index bdb7e70bc..04b28d6e7 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -293,7 +293,7 @@ namespace Ombi.Schedule.Jobs.Plex Dictionary contentProcessed) { Logger.LogDebug("Processing Movies"); - foreach (var movie in content?.Metadata ?? new Metadata[] { }) + foreach (var movie in content?.Metadata ?? Array.Empty()) { // Let's check if we have this movie @@ -302,11 +302,31 @@ namespace Ombi.Schedule.Jobs.Plex var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title && x.ReleaseYear == movie.year.ToString() && x.Type == MediaType.Movie); - // The rating key keeps changing - //var existing = await Repo.GetByKey(movie.ratingKey); if (existing != null) { - Logger.LogDebug("We already have movie {0}", movie.title); + // We need to see if this is a different quality, + // We want to know if this is a 4k content for example + var foundQualities = movie.Media?.Select(x => x.videoResolution); + + foreach (var quality in foundQualities) + { + if (quality.Equals(existing.Quality)) + { + // We got it + continue; + } + + // We don't have this quality + if (quality.Equals("4k", StringComparison.InvariantCultureIgnoreCase)) + { + Logger.LogDebug($"We already have movie {movie.title}, But found a 4K version!"); + existing.Has4K = true; + await Repo.Update(existing); + } + } + + + Logger.LogDebug($"We already have movie {movie.title}"); continue; } @@ -349,6 +369,10 @@ namespace Ombi.Schedule.Jobs.Plex } var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); + var qualities = movie.Media?.Select(x => x.videoResolution); + var is4k = qualities != null && qualities.Any(x => x.Equals("4k", StringComparison.InvariantCultureIgnoreCase)); + var selectedQuality = is4k ? string.Empty : qualities?.OrderBy(x => x)?.FirstOrDefault() ?? string.Empty; + var item = new PlexServerContent { AddedAt = DateTime.Now, @@ -358,7 +382,8 @@ namespace Ombi.Schedule.Jobs.Plex Title = movie.title, Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey, servers.ServerHostname), Seasons = new List(), - Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty + Quality = selectedQuality, + Has4K = is4k, }; if (providerIds.ImdbId.HasValue()) { diff --git a/src/Ombi.Store/Entities/MediaServerContent.cs b/src/Ombi.Store/Entities/MediaServerContent.cs index 7c059ddb9..4f086060b 100644 --- a/src/Ombi.Store/Entities/MediaServerContent.cs +++ b/src/Ombi.Store/Entities/MediaServerContent.cs @@ -12,7 +12,11 @@ namespace Ombi.Store.Entities public string TvDbId { get; set; } public string TheMovieDbId { get; set; } public MediaType Type { get; set; } + /// + /// Only populated if it's not 4k + /// public string Quality { get; set; } + public bool Has4K { get; set; } public string Url { get; set; } public ICollection Episodes { get; set; } diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs new file mode 100644 index 000000000..fbdc63e32 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs @@ -0,0 +1,536 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + [DbContext(typeof(ExternalMySqlContext))] + [Migration("20220212210902_MediaServer4k")] + partial class MediaServer4k + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .HasColumnType("longtext"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.Property("PercentOfTracks") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TrackCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("GrandparentKey") + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("int"); + + b.Property("PlexContentId") + .HasColumnType("int"); + + b.Property("PlexServerContentId") + .HasColumnType("int"); + + b.Property("SeasonKey") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("int"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("ReleaseYear") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("HasRegular") + .HasColumnType("tinyint(1)"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("MovieDbId") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.cs new file mode 100644 index 000000000..c7e1888a6 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + public partial class MediaServer4k : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "PlexServerContent", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "JellyfinContent", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "EmbyContent", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "PlexServerContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs index ad8c72d37..b75c45665 100644 --- a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs @@ -46,6 +46,9 @@ namespace Ombi.Store.Migrations.ExternalMySql .IsRequired() .HasColumnType("varchar(255)"); + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + b.Property("ImdbId") .HasColumnType("longtext"); @@ -127,6 +130,9 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("AddedAt") .HasColumnType("datetime(6)"); + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + b.Property("ImdbId") .HasColumnType("longtext"); @@ -329,6 +335,9 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("AddedAt") .HasColumnType("datetime(6)"); + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + b.Property("ImdbId") .HasColumnType("longtext"); diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs new file mode 100644 index 000000000..70cd280e9 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs @@ -0,0 +1,534 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + [DbContext(typeof(ExternalSqliteContext))] + [Migration("20220212210807_MediaServer4k")] + partial class MediaServer4k + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.Property("PercentOfTracks") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackCount") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("GrandparentKey") + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("INTEGER"); + + b.Property("PlexContentId") + .HasColumnType("INTEGER"); + + b.Property("PlexServerContentId") + .HasColumnType("INTEGER"); + + b.Property("SeasonKey") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("INTEGER"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("ReleaseYear") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("HasRegular") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("MovieDbId") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.cs new file mode 100644 index 000000000..593465c0a --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + public partial class MediaServer4k : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "PlexServerContent", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "JellyfinContent", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "EmbyContent", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "PlexServerContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs index ddc906d43..302f5f537 100644 --- a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs @@ -44,6 +44,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite .IsRequired() .HasColumnType("TEXT"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("ImdbId") .HasColumnType("TEXT"); @@ -125,6 +128,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("AddedAt") .HasColumnType("TEXT"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("ImdbId") .HasColumnType("TEXT"); @@ -327,6 +333,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("AddedAt") .HasColumnType("TEXT"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("ImdbId") .HasColumnType("TEXT"); diff --git a/src/Ombi.Store/Repository/EmbyContentRepository.cs b/src/Ombi.Store/Repository/EmbyContentRepository.cs index 19bab7f76..ddec14025 100644 --- a/src/Ombi.Store/Repository/EmbyContentRepository.cs +++ b/src/Ombi.Store/Repository/EmbyContentRepository.cs @@ -25,7 +25,6 @@ // ************************************************************************/ #endregion -using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -37,7 +36,6 @@ namespace Ombi.Store.Repository { public class EmbyContentRepository : MediaServerContentRepository, IEmbyContentRepository { - public EmbyContentRepository(ExternalContext db):base(db) { } @@ -97,7 +95,13 @@ namespace Ombi.Store.Repository { Db.EmbyContent.Update((EmbyContent)existingContent); } - + + public override Task UpdateRange(IEnumerable existingContent) + { + Db.EmbyContent.UpdateRange((EmbyContent)existingContent); + return InternalSaveChanges(); + } + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Emby; } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IMediaServerContentRepository.cs b/src/Ombi.Store/Repository/IMediaServerContentRepository.cs index 73cc00fde..db4835a16 100644 --- a/src/Ombi.Store/Repository/IMediaServerContentRepository.cs +++ b/src/Ombi.Store/Repository/IMediaServerContentRepository.cs @@ -10,6 +10,7 @@ namespace Ombi.Store.Repository { RecentlyAddedType RecentlyAddedType{ get; } Task Update(IMediaServerContent existingContent); + Task UpdateRange(IEnumerable existingContent); IQueryable GetAllEpisodes(); Task Add(IMediaServerEpisode content); Task AddRange(IEnumerable content); diff --git a/src/Ombi.Store/Repository/JellyfinContentRepository.cs b/src/Ombi.Store/Repository/JellyfinContentRepository.cs index 28cdcfae8..02acee5b0 100644 --- a/src/Ombi.Store/Repository/JellyfinContentRepository.cs +++ b/src/Ombi.Store/Repository/JellyfinContentRepository.cs @@ -98,6 +98,12 @@ namespace Ombi.Store.Repository Db.JellyfinContent.Update((JellyfinContent)existingContent); } + public override Task UpdateRange(IEnumerable existingContent) + { + Db.JellyfinContent.UpdateRange((JellyfinContent)existingContent); + return InternalSaveChanges(); + } + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Jellyfin; } } diff --git a/src/Ombi.Store/Repository/MediaServerRepository.cs b/src/Ombi.Store/Repository/MediaServerRepository.cs index 0f458ee2b..c1c7d4ec8 100644 --- a/src/Ombi.Store/Repository/MediaServerRepository.cs +++ b/src/Ombi.Store/Repository/MediaServerRepository.cs @@ -21,5 +21,6 @@ namespace Ombi.Store.Repository public abstract Task Add(IMediaServerEpisode content); public abstract Task AddRange(IEnumerable content); public abstract void UpdateWithoutSave(IMediaServerContent existingContent); + public abstract Task UpdateRange(IEnumerable existingContent); } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/PlexContentRepository.cs b/src/Ombi.Store/Repository/PlexContentRepository.cs index b99ba157f..be79d1a29 100644 --- a/src/Ombi.Store/Repository/PlexContentRepository.cs +++ b/src/Ombi.Store/Repository/PlexContentRepository.cs @@ -164,5 +164,10 @@ namespace Ombi.Store.Repository await InternalSaveChanges(); } + public override Task UpdateRange(IEnumerable existingContent) + { + Db.PlexServerContent.UpdateRange((PlexServerContent)existingContent); + return InternalSaveChanges(); + } } } \ No newline at end of file