From a1aacc1998d873f8e1746bf4a7aae36861b8b51b Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 11 Feb 2022 21:54:07 +0000 Subject: [PATCH] feat: Added migrations for media sever quality. Emby and Radarr Sync jobs now pull the quality --- .../Models/Media/EmbyMediastream.cs | 29 - .../Models/Media/Movie/EmbyMovie.cs | 1 + .../Models/V3/RadarrV3QualityProfile.cs | 1 - .../Jobs/Emby/EmbyContentSync.cs | 14 +- src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs | 7 +- src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs | 143 ++--- src/Ombi.Store/Entities/MediaServerContent.cs | 2 +- src/Ombi.Store/Entities/PlexServerContent.cs | 1 - src/Ombi.Store/Entities/RadarrCache.cs | 2 + ...211213229_MediaServerQualities.Designer.cs | 527 ++++++++++++++++++ .../20220211213229_MediaServerQualities.cs | 59 ++ .../ExternalMySqlContextModelSnapshot.cs | 18 +- ...211213347_MediaServerQualities.Designer.cs | 525 +++++++++++++++++ .../20220211213347_MediaServerQualities.cs | 57 ++ .../ExternalSqliteContextModelSnapshot.cs | 17 +- 15 files changed, 1290 insertions(+), 113 deletions(-) create mode 100644 src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs create mode 100644 src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.cs create mode 100644 src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs create mode 100644 src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.cs diff --git a/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs b/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs index 01032e0e7..f633f4ce0 100644 --- a/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs +++ b/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs @@ -2,35 +2,6 @@ namespace Ombi.Api.Emby.Models.Movie { public class EmbyMediastream { - 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.Emby/Models/Media/Movie/EmbyMovie.cs b/src/Ombi.Api.Emby/Models/Media/Movie/EmbyMovie.cs index a10ddaae6..e127f75f6 100644 --- a/src/Ombi.Api.Emby/Models/Media/Movie/EmbyMovie.cs +++ b/src/Ombi.Api.Emby/Models/Media/Movie/EmbyMovie.cs @@ -30,5 +30,6 @@ namespace Ombi.Api.Emby.Models.Movie public int CriticRating { get; set; } public string Overview { get; set; } public EmbyProviderids ProviderIds { get; set; } + public EmbyMediastream[] MediaStreams { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs b/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs index d985da358..6eca4af87 100644 --- a/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs +++ b/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs @@ -25,5 +25,4 @@ public int resolution { get; set; } public string modifier { get; set; } } - } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 646cbdee0..faff73752 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.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; @@ -86,10 +87,10 @@ namespace Ombi.Schedule.Jobs.Emby private async Task StartServerCache(EmbyServers server, bool recentlyAdded) { if (!ValidateSettings(server)) + { return; + } - //await _repo.ExecuteSql("DELETE FROM EmbyEpisode"); - //await _repo.ExecuteSql("DELETE FROM EmbyContent"); if (server.EmbySelectedLibraries.Any() && server.EmbySelectedLibraries.Any(x => x.Enabled)) { @@ -256,6 +257,12 @@ namespace Ombi.Schedule.Jobs.Emby 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"; + } + content.Add(new EmbyContent { ImdbId = movieInfo.ProviderIds.Imdb, @@ -264,7 +271,8 @@ namespace Ombi.Schedule.Jobs.Emby Type = MediaType.Movie, EmbyId = movieInfo.Id, Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), - AddedAt = DateTime.UtcNow + AddedAt = DateTime.UtcNow, + Quality = quality }); } else diff --git a/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs index 1fb191fd1..19178ca48 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs @@ -1,11 +1,6 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Ombi.Store.Entities; - -namespace Ombi.Schedule.Jobs.Radarr +namespace Ombi.Schedule.Jobs.Radarr { public interface IRadarrSync : IBaseJob { - Task> GetCachedContent(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs index 3cda06281..3f9816dbe 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -10,106 +9,114 @@ using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; +using Ombi.Store.Repository; using Quartz; -using Serilog; namespace Ombi.Schedule.Jobs.Radarr { public class RadarrSync : IRadarrSync { - public RadarrSync(ISettingsService radarr, IRadarrV3Api radarrApi, ILogger log, ExternalContext ctx) + public RadarrSync(ISettingsService radarr, ISettingsService radarr4k, IRadarrV3Api radarrApi, ILogger log, ExternalContext ctx, + IExternalRepository radarrRepo) { - RadarrSettings = radarr; - RadarrApi = radarrApi; - Logger = log; + _radarrSettings = radarr; + _radarr4kSettings = radarr4k; + _api = radarrApi; + _logger = log; _ctx = ctx; - RadarrSettings.ClearCache(); + _radarrRepo = radarrRepo; + _radarrSettings.ClearCache(); + _radarr4kSettings.ClearCache(); } - private ISettingsService RadarrSettings { get; } - private IRadarrV3Api RadarrApi { get; } - private ILogger Logger { get; } + private readonly ISettingsService _radarrSettings; + private readonly ISettingsService _radarr4kSettings; + private readonly IRadarrV3Api _api; + private readonly ILogger _logger; private readonly ExternalContext _ctx; - - private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1); + private readonly IExternalRepository _radarrRepo; public async Task Execute(IJobExecutionContext job) { - await SemaphoreSlim.WaitAsync(); try { - var settings = await RadarrSettings.GetSettingsAsync(); - if (settings.Enabled) + var strat = _ctx.Database.CreateExecutionStrategy(); + await strat.ExecuteAsync(async () => { - try - { - var movies = await RadarrApi.GetMovies(settings.ApiKey, settings.FullUri); - if (movies != null) - { - var strat = _ctx.Database.CreateExecutionStrategy(); - await strat.ExecuteAsync(async () => - { - // Let's remove the old cached data - using (var tran = await _ctx.Database.BeginTransactionAsync()) - { - await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM RadarrCache"); - tran.Commit(); - } - }); + // Let's remove the old cached data + using var tran = await _ctx.Database.BeginTransactionAsync(); + await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM RadarrCache"); + tran.Commit(); + }); - var movieIds = new List(); - foreach (var m in movies) + var radarrSettings = _radarrSettings.GetSettingsAsync(); + var radarr4kSettings = _radarr4kSettings.GetSettingsAsync(); + await Process(await radarrSettings); + await Process(await radarr4kSettings); + } + catch (Exception) + { + _logger.LogInformation(LoggingEvents.RadarrCacher, "Radarr is not setup, cannot cache episodes"); + } + } + + private async Task Process(RadarrSettings settings) + { + if (settings.Enabled) + { + try + { + var movies = await _api.GetMovies(settings.ApiKey, settings.FullUri); + var existingMovies = _radarrRepo.GetAll(); + if (movies != null) + { + var movieIds = new List(); + foreach (var m in movies) + { + if (m.monitored || m.hasFile) { - if (m.monitored || m.hasFile) + if (m.tmdbId > 0) { - if (m.tmdbId > 0) + var is4k = m.movieFile?.quality?.resolution >= 2160; + + // Do we have a cached movie for this already? + var existing = await existingMovies.FirstOrDefaultAsync(x => x.TheMovieDbId == m.tmdbId); + if (existing != null) + { + existing.Has4K = is4k; + existing.HasFile = m.hasFile; + } + else { movieIds.Add(new RadarrCache { TheMovieDbId = m.tmdbId, - HasFile = m.hasFile + HasFile = m.hasFile, + Has4K = is4k, + HasRegular = !is4k }); } - else - { - Logger.LogError("TMDBId is not > 0 for movie {0}", m.title); - } + } + else + { + _logger.LogError($"TMDBId is not > 0 for movie {m.title}"); } } - strat = _ctx.Database.CreateExecutionStrategy(); - await strat.ExecuteAsync(async () => - { - using (var tran = await _ctx.Database.BeginTransactionAsync()) - { - await _ctx.RadarrCache.AddRangeAsync(movieIds); - - await _ctx.SaveChangesAsync(); - tran.Commit(); - } - }); } - await OmbiQuartz.TriggerJob(nameof(IArrAvailabilityChecker), "DVR"); - } - catch (System.Exception ex) - { - Logger.LogError(LoggingEvents.Cacher, ex, "Failed caching queued items from Radarr"); + // Save from the updates made to the existing movies (they are in the EF Change Tracker) + await _radarrRepo.SaveChangesAsync(); + + await _radarrRepo.AddRange(movieIds); } + + await OmbiQuartz.TriggerJob(nameof(IArrAvailabilityChecker), "DVR"); + } + catch (System.Exception ex) + { + _logger.LogError(LoggingEvents.Cacher, ex, "Failed caching queued items from Radarr"); } } - catch (Exception) - { - Logger.LogInformation(LoggingEvents.RadarrCacher, "Radarr is not setup, cannot cache episodes"); - } - finally - { - SemaphoreSlim.Release(); - } - } - - public async Task> GetCachedContent() - { - return await _ctx.RadarrCache.ToListAsync(); } private bool _disposed; diff --git a/src/Ombi.Store/Entities/MediaServerContent.cs b/src/Ombi.Store/Entities/MediaServerContent.cs index df50efc86..7c059ddb9 100644 --- a/src/Ombi.Store/Entities/MediaServerContent.cs +++ b/src/Ombi.Store/Entities/MediaServerContent.cs @@ -12,7 +12,7 @@ namespace Ombi.Store.Entities public string TvDbId { get; set; } public string TheMovieDbId { get; set; } public MediaType Type { get; set; } - + public string Quality { get; set; } public string Url { get; set; } public ICollection Episodes { get; set; } diff --git a/src/Ombi.Store/Entities/PlexServerContent.cs b/src/Ombi.Store/Entities/PlexServerContent.cs index cba02c68c..f33ddb2f1 100644 --- a/src/Ombi.Store/Entities/PlexServerContent.cs +++ b/src/Ombi.Store/Entities/PlexServerContent.cs @@ -41,7 +41,6 @@ namespace Ombi.Store.Entities /// Plex's internal ID for this item /// public int Key { get; set; } - public string Quality { get; set; } public int? RequestId { get; set; } diff --git a/src/Ombi.Store/Entities/RadarrCache.cs b/src/Ombi.Store/Entities/RadarrCache.cs index 4b62412fc..553e84f2b 100644 --- a/src/Ombi.Store/Entities/RadarrCache.cs +++ b/src/Ombi.Store/Entities/RadarrCache.cs @@ -7,5 +7,7 @@ namespace Ombi.Store.Entities { public int TheMovieDbId { get; set; } public bool HasFile { get; set; } + public bool Has4K { get; set; } + public bool HasRegular { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs new file mode 100644 index 000000000..ab88ff30d --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs @@ -0,0 +1,527 @@ +// +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("20220211213229_MediaServerQualities")] + partial class MediaServerQualities + { + 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("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("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("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/20220211213229_MediaServerQualities.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.cs new file mode 100644 index 000000000..add7da05e --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.cs @@ -0,0 +1,59 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + public partial class MediaServerQualities : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "RadarrCache", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "HasRegular", + table: "RadarrCache", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Quality", + table: "JellyfinContent", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "Quality", + table: "EmbyContent", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "HasRegular", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs index dbdbe6f55..ad8c72d37 100644 --- a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Ombi.Store.Context.MySql; +#nullable disable + namespace Ombi.Store.Migrations.ExternalMySql { [DbContext(typeof(ExternalMySqlContext))] @@ -14,8 +16,8 @@ namespace Ombi.Store.Migrations.ExternalMySql { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Relational:MaxIdentifierLength", 64) - .HasAnnotation("ProductVersion", "5.0.1"); + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => { @@ -50,6 +52,9 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("ProviderId") .HasColumnType("longtext"); + b.Property("Quality") + .HasColumnType("longtext"); + b.Property("TheMovieDbId") .HasColumnType("longtext"); @@ -132,6 +137,9 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("ProviderId") .HasColumnType("longtext"); + b.Property("Quality") + .HasColumnType("longtext"); + b.Property("TheMovieDbId") .HasColumnType("longtext"); @@ -362,9 +370,15 @@ namespace Ombi.Store.Migrations.ExternalMySql .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"); diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs new file mode 100644 index 000000000..4ec8422d5 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs @@ -0,0 +1,525 @@ +// +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("20220211213347_MediaServerQualities")] + partial class MediaServerQualities + { + 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("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("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("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/20220211213347_MediaServerQualities.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.cs new file mode 100644 index 000000000..b194b7845 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.cs @@ -0,0 +1,57 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + public partial class MediaServerQualities : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "RadarrCache", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "HasRegular", + table: "RadarrCache", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Quality", + table: "JellyfinContent", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "Quality", + table: "EmbyContent", + type: "TEXT", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "HasRegular", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs index 00d4f44f4..ddc906d43 100644 --- a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Ombi.Store.Context.Sqlite; +#nullable disable + namespace Ombi.Store.Migrations.ExternalSqlite { [DbContext(typeof(ExternalSqliteContext))] @@ -13,8 +15,7 @@ namespace Ombi.Store.Migrations.ExternalSqlite protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "5.0.1"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => { @@ -49,6 +50,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("ProviderId") .HasColumnType("TEXT"); + b.Property("Quality") + .HasColumnType("TEXT"); + b.Property("TheMovieDbId") .HasColumnType("TEXT"); @@ -131,6 +135,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("ProviderId") .HasColumnType("TEXT"); + b.Property("Quality") + .HasColumnType("TEXT"); + b.Property("TheMovieDbId") .HasColumnType("TEXT"); @@ -361,9 +368,15 @@ namespace Ombi.Store.Migrations.ExternalSqlite .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("HasFile") .HasColumnType("INTEGER"); + b.Property("HasRegular") + .HasColumnType("INTEGER"); + b.Property("TheMovieDbId") .HasColumnType("INTEGER");