feat: Added migrations for media sever quality. Emby and Radarr Sync jobs now pull the quality

This commit is contained in:
tidusjar 2022-02-11 21:54:07 +00:00
commit a1aacc1998
15 changed files with 1290 additions and 113 deletions

View file

@ -2,35 +2,6 @@ namespace Ombi.Api.Emby.Models.Movie
{ {
public class EmbyMediastream 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 DisplayTitle { get; set; }
public string ChannelLayout { get; set; }
public int Channels { get; set; }
public int SampleRate { get; set; }
} }
} }

View file

@ -30,5 +30,6 @@ namespace Ombi.Api.Emby.Models.Movie
public int CriticRating { get; set; } public int CriticRating { get; set; }
public string Overview { get; set; } public string Overview { get; set; }
public EmbyProviderids ProviderIds { get; set; } public EmbyProviderids ProviderIds { get; set; }
public EmbyMediastream[] MediaStreams { get; set; }
} }
} }

View file

@ -25,5 +25,4 @@
public int resolution { get; set; } public int resolution { get; set; }
public string modifier { get; set; } public string modifier { get; set; }
} }
} }

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
@ -86,10 +87,10 @@ namespace Ombi.Schedule.Jobs.Emby
private async Task StartServerCache(EmbyServers server, bool recentlyAdded) private async Task StartServerCache(EmbyServers server, bool recentlyAdded)
{ {
if (!ValidateSettings(server)) if (!ValidateSettings(server))
{
return; return;
}
//await _repo.ExecuteSql("DELETE FROM EmbyEpisode");
//await _repo.ExecuteSql("DELETE FROM EmbyContent");
if (server.EmbySelectedLibraries.Any() && server.EmbySelectedLibraries.Any(x => x.Enabled)) if (server.EmbySelectedLibraries.Any() && server.EmbySelectedLibraries.Any(x => x.Enabled))
{ {
@ -256,6 +257,12 @@ namespace Ombi.Schedule.Jobs.Emby
return; return;
} }
_logger.LogDebug("Adding new movie {0}", movieInfo.Name); _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 content.Add(new EmbyContent
{ {
ImdbId = movieInfo.ProviderIds.Imdb, ImdbId = movieInfo.ProviderIds.Imdb,
@ -264,7 +271,8 @@ namespace Ombi.Schedule.Jobs.Emby
Type = MediaType.Movie, Type = MediaType.Movie,
EmbyId = movieInfo.Id, EmbyId = movieInfo.Id,
Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname),
AddedAt = DateTime.UtcNow AddedAt = DateTime.UtcNow,
Quality = quality
}); });
} }
else else

View file

@ -1,11 +1,6 @@
using System.Collections.Generic; namespace Ombi.Schedule.Jobs.Radarr
using System.Threading.Tasks;
using Ombi.Store.Entities;
namespace Ombi.Schedule.Jobs.Radarr
{ {
public interface IRadarrSync : IBaseJob public interface IRadarrSync : IBaseJob
{ {
Task<IEnumerable<RadarrCache>> GetCachedContent();
} }
} }

View file

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -10,106 +9,114 @@ using Ombi.Helpers;
using Ombi.Settings.Settings.Models.External; using Ombi.Settings.Settings.Models.External;
using Ombi.Store.Context; using Ombi.Store.Context;
using Ombi.Store.Entities; using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Quartz; using Quartz;
using Serilog;
namespace Ombi.Schedule.Jobs.Radarr namespace Ombi.Schedule.Jobs.Radarr
{ {
public class RadarrSync : IRadarrSync public class RadarrSync : IRadarrSync
{ {
public RadarrSync(ISettingsService<RadarrSettings> radarr, IRadarrV3Api radarrApi, ILogger<RadarrSync> log, ExternalContext ctx) public RadarrSync(ISettingsService<RadarrSettings> radarr, ISettingsService<Radarr4KSettings> radarr4k, IRadarrV3Api radarrApi, ILogger<RadarrSync> log, ExternalContext ctx,
IExternalRepository<RadarrCache> radarrRepo)
{ {
RadarrSettings = radarr; _radarrSettings = radarr;
RadarrApi = radarrApi; _radarr4kSettings = radarr4k;
Logger = log; _api = radarrApi;
_logger = log;
_ctx = ctx; _ctx = ctx;
RadarrSettings.ClearCache(); _radarrRepo = radarrRepo;
_radarrSettings.ClearCache();
_radarr4kSettings.ClearCache();
} }
private ISettingsService<RadarrSettings> RadarrSettings { get; } private readonly ISettingsService<RadarrSettings> _radarrSettings;
private IRadarrV3Api RadarrApi { get; } private readonly ISettingsService<Radarr4KSettings> _radarr4kSettings;
private ILogger<RadarrSync> Logger { get; } private readonly IRadarrV3Api _api;
private readonly ILogger<RadarrSync> _logger;
private readonly ExternalContext _ctx; private readonly ExternalContext _ctx;
private readonly IExternalRepository<RadarrCache> _radarrRepo;
private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1);
public async Task Execute(IJobExecutionContext job) public async Task Execute(IJobExecutionContext job)
{ {
await SemaphoreSlim.WaitAsync();
try try
{ {
var settings = await RadarrSettings.GetSettingsAsync(); var strat = _ctx.Database.CreateExecutionStrategy();
if (settings.Enabled) await strat.ExecuteAsync(async () =>
{ {
try // Let's remove the old cached data
{ using var tran = await _ctx.Database.BeginTransactionAsync();
var movies = await RadarrApi.GetMovies(settings.ApiKey, settings.FullUri); await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM RadarrCache");
if (movies != null) tran.Commit();
{ });
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();
}
});
var movieIds = new List<RadarrCache>(); var radarrSettings = _radarrSettings.GetSettingsAsync();
foreach (var m in movies) 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<RadarrCache>();
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 movieIds.Add(new RadarrCache
{ {
TheMovieDbId = m.tmdbId, TheMovieDbId = m.tmdbId,
HasFile = m.hasFile HasFile = m.hasFile,
Has4K = is4k,
HasRegular = !is4k
}); });
} }
else }
{ else
Logger.LogError("TMDBId is not > 0 for movie {0}", m.title); {
} _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"); // Save from the updates made to the existing movies (they are in the EF Change Tracker)
} await _radarrRepo.SaveChangesAsync();
catch (System.Exception ex)
{ await _radarrRepo.AddRange(movieIds);
Logger.LogError(LoggingEvents.Cacher, ex, "Failed caching queued items from Radarr");
} }
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<IEnumerable<RadarrCache>> GetCachedContent()
{
return await _ctx.RadarrCache.ToListAsync();
} }
private bool _disposed; private bool _disposed;

View file

@ -12,7 +12,7 @@ namespace Ombi.Store.Entities
public string TvDbId { get; set; } public string TvDbId { get; set; }
public string TheMovieDbId { get; set; } public string TheMovieDbId { get; set; }
public MediaType Type { get; set; } public MediaType Type { get; set; }
public string Quality { get; set; }
public string Url { get; set; } public string Url { get; set; }
public ICollection<IMediaServerEpisode> Episodes { get; set; } public ICollection<IMediaServerEpisode> Episodes { get; set; }

View file

@ -41,7 +41,6 @@ namespace Ombi.Store.Entities
/// Plex's internal ID for this item /// Plex's internal ID for this item
/// </summary> /// </summary>
public int Key { get; set; } public int Key { get; set; }
public string Quality { get; set; }
public int? RequestId { get; set; } public int? RequestId { get; set; }

View file

@ -7,5 +7,7 @@ namespace Ombi.Store.Entities
{ {
public int TheMovieDbId { get; set; } public int TheMovieDbId { get; set; }
public bool HasFile { get; set; } public bool HasFile { get; set; }
public bool Has4K { get; set; }
public bool HasRegular { get; set; }
} }
} }

View file

@ -0,0 +1,527 @@
// <auto-generated />
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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("TheMovieDbId")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("CouchPotatoCache");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime(6)");
b.Property<string>("EmbyId")
.IsRequired()
.HasColumnType("varchar(255)");
b.Property<string>("ImdbId")
.HasColumnType("longtext");
b.Property<string>("ProviderId")
.HasColumnType("longtext");
b.Property<string>("Quality")
.HasColumnType("longtext");
b.Property<string>("TheMovieDbId")
.HasColumnType("longtext");
b.Property<string>("Title")
.HasColumnType("longtext");
b.Property<string>("TvDbId")
.HasColumnType("longtext");
b.Property<int>("Type")
.HasColumnType("int");
b.Property<string>("Url")
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("EmbyContent");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime(6)");
b.Property<string>("EmbyId")
.HasColumnType("longtext");
b.Property<int>("EpisodeNumber")
.HasColumnType("int");
b.Property<string>("ImdbId")
.HasColumnType("longtext");
b.Property<string>("ParentId")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderId")
.HasColumnType("longtext");
b.Property<int>("SeasonNumber")
.HasColumnType("int");
b.Property<string>("TheMovieDbId")
.HasColumnType("longtext");
b.Property<string>("Title")
.HasColumnType("longtext");
b.Property<string>("TvDbId")
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("EmbyEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime(6)");
b.Property<string>("ImdbId")
.HasColumnType("longtext");
b.Property<string>("JellyfinId")
.IsRequired()
.HasColumnType("varchar(255)");
b.Property<string>("ProviderId")
.HasColumnType("longtext");
b.Property<string>("Quality")
.HasColumnType("longtext");
b.Property<string>("TheMovieDbId")
.HasColumnType("longtext");
b.Property<string>("Title")
.HasColumnType("longtext");
b.Property<string>("TvDbId")
.HasColumnType("longtext");
b.Property<int>("Type")
.HasColumnType("int");
b.Property<string>("Url")
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("JellyfinContent");
});
modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime(6)");
b.Property<int>("EpisodeNumber")
.HasColumnType("int");
b.Property<string>("ImdbId")
.HasColumnType("longtext");
b.Property<string>("JellyfinId")
.HasColumnType("longtext");
b.Property<string>("ParentId")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderId")
.HasColumnType("longtext");
b.Property<int>("SeasonNumber")
.HasColumnType("int");
b.Property<string>("TheMovieDbId")
.HasColumnType("longtext");
b.Property<string>("Title")
.HasColumnType("longtext");
b.Property<string>("TvDbId")
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("JellyfinEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime(6)");
b.Property<int>("ArtistId")
.HasColumnType("int");
b.Property<string>("ForeignAlbumId")
.HasColumnType("longtext");
b.Property<bool>("Monitored")
.HasColumnType("tinyint(1)");
b.Property<decimal>("PercentOfTracks")
.HasColumnType("decimal(65,30)");
b.Property<DateTime>("ReleaseDate")
.HasColumnType("datetime(6)");
b.Property<string>("Title")
.HasColumnType("longtext");
b.Property<int>("TrackCount")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("LidarrAlbumCache");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("ArtistId")
.HasColumnType("int");
b.Property<string>("ArtistName")
.HasColumnType("longtext");
b.Property<string>("ForeignArtistId")
.HasColumnType("longtext");
b.Property<bool>("Monitored")
.HasColumnType("tinyint(1)");
b.HasKey("Id");
b.ToTable("LidarrArtistCache");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("EpisodeNumber")
.HasColumnType("int");
b.Property<int>("GrandparentKey")
.HasColumnType("int");
b.Property<int>("Key")
.HasColumnType("int");
b.Property<int>("ParentKey")
.HasColumnType("int");
b.Property<int>("SeasonNumber")
.HasColumnType("int");
b.Property<string>("Title")
.HasColumnType("longtext");
b.HasKey("Id");
b.HasIndex("GrandparentKey");
b.ToTable("PlexEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("ParentKey")
.HasColumnType("int");
b.Property<int>("PlexContentId")
.HasColumnType("int");
b.Property<int?>("PlexServerContentId")
.HasColumnType("int");
b.Property<int>("SeasonKey")
.HasColumnType("int");
b.Property<int>("SeasonNumber")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("PlexServerContentId");
b.ToTable("PlexSeasonsContent");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<DateTime>("AddedAt")
.HasColumnType("datetime(6)");
b.Property<string>("ImdbId")
.HasColumnType("longtext");
b.Property<int>("Key")
.HasColumnType("int");
b.Property<string>("Quality")
.HasColumnType("longtext");
b.Property<string>("ReleaseYear")
.HasColumnType("longtext");
b.Property<int?>("RequestId")
.HasColumnType("int");
b.Property<string>("TheMovieDbId")
.HasColumnType("longtext");
b.Property<string>("Title")
.HasColumnType("longtext");
b.Property<string>("TvDbId")
.HasColumnType("longtext");
b.Property<int>("Type")
.HasColumnType("int");
b.Property<string>("Url")
.HasColumnType("longtext");
b.HasKey("Id");
b.ToTable("PlexServerContent");
});
modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<bool>("Has4K")
.HasColumnType("tinyint(1)");
b.Property<bool>("HasFile")
.HasColumnType("tinyint(1)");
b.Property<bool>("HasRegular")
.HasColumnType("tinyint(1)");
b.Property<int>("TheMovieDbId")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("RadarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("TvDbId")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("SickRageCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("EpisodeNumber")
.HasColumnType("int");
b.Property<int>("SeasonNumber")
.HasColumnType("int");
b.Property<int>("TvDbId")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("SickRageEpisodeCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("TheMovieDbId")
.HasColumnType("int");
b.Property<int>("TvDbId")
.HasColumnType("int");
b.HasKey("Id");
b.ToTable("SonarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("EpisodeNumber")
.HasColumnType("int");
b.Property<bool>("HasFile")
.HasColumnType("tinyint(1)");
b.Property<int>("MovieDbId")
.HasColumnType("int");
b.Property<int>("SeasonNumber")
.HasColumnType("int");
b.Property<int>("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
}
}
}

View file

@ -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<bool>(
name: "Has4K",
table: "RadarrCache",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "HasRegular",
table: "RadarrCache",
type: "tinyint(1)",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
name: "Quality",
table: "JellyfinContent",
type: "longtext",
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.AddColumn<string>(
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");
}
}
}

View file

@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Ombi.Store.Context.MySql; using Ombi.Store.Context.MySql;
#nullable disable
namespace Ombi.Store.Migrations.ExternalMySql namespace Ombi.Store.Migrations.ExternalMySql
{ {
[DbContext(typeof(ExternalMySqlContext))] [DbContext(typeof(ExternalMySqlContext))]
@ -14,8 +16,8 @@ namespace Ombi.Store.Migrations.ExternalMySql
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("Relational:MaxIdentifierLength", 64) .HasAnnotation("ProductVersion", "6.0.0")
.HasAnnotation("ProductVersion", "5.0.1"); .HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
{ {
@ -50,6 +52,9 @@ namespace Ombi.Store.Migrations.ExternalMySql
b.Property<string>("ProviderId") b.Property<string>("ProviderId")
.HasColumnType("longtext"); .HasColumnType("longtext");
b.Property<string>("Quality")
.HasColumnType("longtext");
b.Property<string>("TheMovieDbId") b.Property<string>("TheMovieDbId")
.HasColumnType("longtext"); .HasColumnType("longtext");
@ -132,6 +137,9 @@ namespace Ombi.Store.Migrations.ExternalMySql
b.Property<string>("ProviderId") b.Property<string>("ProviderId")
.HasColumnType("longtext"); .HasColumnType("longtext");
b.Property<string>("Quality")
.HasColumnType("longtext");
b.Property<string>("TheMovieDbId") b.Property<string>("TheMovieDbId")
.HasColumnType("longtext"); .HasColumnType("longtext");
@ -362,9 +370,15 @@ namespace Ombi.Store.Migrations.ExternalMySql
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("int"); .HasColumnType("int");
b.Property<bool>("Has4K")
.HasColumnType("tinyint(1)");
b.Property<bool>("HasFile") b.Property<bool>("HasFile")
.HasColumnType("tinyint(1)"); .HasColumnType("tinyint(1)");
b.Property<bool>("HasRegular")
.HasColumnType("tinyint(1)");
b.Property<int>("TheMovieDbId") b.Property<int>("TheMovieDbId")
.HasColumnType("int"); .HasColumnType("int");

View file

@ -0,0 +1,525 @@
// <auto-generated />
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<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("TheMovieDbId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("CouchPotatoCache");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("AddedAt")
.HasColumnType("TEXT");
b.Property<string>("EmbyId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ImdbId")
.HasColumnType("TEXT");
b.Property<string>("ProviderId")
.HasColumnType("TEXT");
b.Property<string>("Quality")
.HasColumnType("TEXT");
b.Property<string>("TheMovieDbId")
.HasColumnType("TEXT");
b.Property<string>("Title")
.HasColumnType("TEXT");
b.Property<string>("TvDbId")
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<string>("Url")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("EmbyContent");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("AddedAt")
.HasColumnType("TEXT");
b.Property<string>("EmbyId")
.HasColumnType("TEXT");
b.Property<int>("EpisodeNumber")
.HasColumnType("INTEGER");
b.Property<string>("ImdbId")
.HasColumnType("TEXT");
b.Property<string>("ParentId")
.HasColumnType("TEXT");
b.Property<string>("ProviderId")
.HasColumnType("TEXT");
b.Property<int>("SeasonNumber")
.HasColumnType("INTEGER");
b.Property<string>("TheMovieDbId")
.HasColumnType("TEXT");
b.Property<string>("Title")
.HasColumnType("TEXT");
b.Property<string>("TvDbId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("EmbyEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("AddedAt")
.HasColumnType("TEXT");
b.Property<string>("ImdbId")
.HasColumnType("TEXT");
b.Property<string>("JellyfinId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ProviderId")
.HasColumnType("TEXT");
b.Property<string>("Quality")
.HasColumnType("TEXT");
b.Property<string>("TheMovieDbId")
.HasColumnType("TEXT");
b.Property<string>("Title")
.HasColumnType("TEXT");
b.Property<string>("TvDbId")
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<string>("Url")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("JellyfinContent");
});
modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("AddedAt")
.HasColumnType("TEXT");
b.Property<int>("EpisodeNumber")
.HasColumnType("INTEGER");
b.Property<string>("ImdbId")
.HasColumnType("TEXT");
b.Property<string>("JellyfinId")
.HasColumnType("TEXT");
b.Property<string>("ParentId")
.HasColumnType("TEXT");
b.Property<string>("ProviderId")
.HasColumnType("TEXT");
b.Property<int>("SeasonNumber")
.HasColumnType("INTEGER");
b.Property<string>("TheMovieDbId")
.HasColumnType("TEXT");
b.Property<string>("Title")
.HasColumnType("TEXT");
b.Property<string>("TvDbId")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("JellyfinEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("AddedAt")
.HasColumnType("TEXT");
b.Property<int>("ArtistId")
.HasColumnType("INTEGER");
b.Property<string>("ForeignAlbumId")
.HasColumnType("TEXT");
b.Property<bool>("Monitored")
.HasColumnType("INTEGER");
b.Property<decimal>("PercentOfTracks")
.HasColumnType("TEXT");
b.Property<DateTime>("ReleaseDate")
.HasColumnType("TEXT");
b.Property<string>("Title")
.HasColumnType("TEXT");
b.Property<int>("TrackCount")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("LidarrAlbumCache");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ArtistId")
.HasColumnType("INTEGER");
b.Property<string>("ArtistName")
.HasColumnType("TEXT");
b.Property<string>("ForeignArtistId")
.HasColumnType("TEXT");
b.Property<bool>("Monitored")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("LidarrArtistCache");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("EpisodeNumber")
.HasColumnType("INTEGER");
b.Property<int>("GrandparentKey")
.HasColumnType("INTEGER");
b.Property<int>("Key")
.HasColumnType("INTEGER");
b.Property<int>("ParentKey")
.HasColumnType("INTEGER");
b.Property<int>("SeasonNumber")
.HasColumnType("INTEGER");
b.Property<string>("Title")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("GrandparentKey");
b.ToTable("PlexEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("ParentKey")
.HasColumnType("INTEGER");
b.Property<int>("PlexContentId")
.HasColumnType("INTEGER");
b.Property<int?>("PlexServerContentId")
.HasColumnType("INTEGER");
b.Property<int>("SeasonKey")
.HasColumnType("INTEGER");
b.Property<int>("SeasonNumber")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("PlexServerContentId");
b.ToTable("PlexSeasonsContent");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("AddedAt")
.HasColumnType("TEXT");
b.Property<string>("ImdbId")
.HasColumnType("TEXT");
b.Property<int>("Key")
.HasColumnType("INTEGER");
b.Property<string>("Quality")
.HasColumnType("TEXT");
b.Property<string>("ReleaseYear")
.HasColumnType("TEXT");
b.Property<int?>("RequestId")
.HasColumnType("INTEGER");
b.Property<string>("TheMovieDbId")
.HasColumnType("TEXT");
b.Property<string>("Title")
.HasColumnType("TEXT");
b.Property<string>("TvDbId")
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.Property<string>("Url")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("PlexServerContent");
});
modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool>("Has4K")
.HasColumnType("INTEGER");
b.Property<bool>("HasFile")
.HasColumnType("INTEGER");
b.Property<bool>("HasRegular")
.HasColumnType("INTEGER");
b.Property<int>("TheMovieDbId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("RadarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("TvDbId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("SickRageCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("EpisodeNumber")
.HasColumnType("INTEGER");
b.Property<int>("SeasonNumber")
.HasColumnType("INTEGER");
b.Property<int>("TvDbId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("SickRageEpisodeCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("TheMovieDbId")
.HasColumnType("INTEGER");
b.Property<int>("TvDbId")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("SonarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("EpisodeNumber")
.HasColumnType("INTEGER");
b.Property<bool>("HasFile")
.HasColumnType("INTEGER");
b.Property<int>("MovieDbId")
.HasColumnType("INTEGER");
b.Property<int>("SeasonNumber")
.HasColumnType("INTEGER");
b.Property<int>("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
}
}
}

View file

@ -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<bool>(
name: "Has4K",
table: "RadarrCache",
type: "INTEGER",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<bool>(
name: "HasRegular",
table: "RadarrCache",
type: "INTEGER",
nullable: false,
defaultValue: false);
migrationBuilder.AddColumn<string>(
name: "Quality",
table: "JellyfinContent",
type: "TEXT",
nullable: true);
migrationBuilder.AddColumn<string>(
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");
}
}
}

View file

@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Ombi.Store.Context.Sqlite; using Ombi.Store.Context.Sqlite;
#nullable disable
namespace Ombi.Store.Migrations.ExternalSqlite namespace Ombi.Store.Migrations.ExternalSqlite
{ {
[DbContext(typeof(ExternalSqliteContext))] [DbContext(typeof(ExternalSqliteContext))]
@ -13,8 +15,7 @@ namespace Ombi.Store.Migrations.ExternalSqlite
protected override void BuildModel(ModelBuilder modelBuilder) protected override void BuildModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder.HasAnnotation("ProductVersion", "6.0.0");
.HasAnnotation("ProductVersion", "5.0.1");
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
{ {
@ -49,6 +50,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite
b.Property<string>("ProviderId") b.Property<string>("ProviderId")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Quality")
.HasColumnType("TEXT");
b.Property<string>("TheMovieDbId") b.Property<string>("TheMovieDbId")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -131,6 +135,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite
b.Property<string>("ProviderId") b.Property<string>("ProviderId")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("Quality")
.HasColumnType("TEXT");
b.Property<string>("TheMovieDbId") b.Property<string>("TheMovieDbId")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -361,9 +368,15 @@ namespace Ombi.Store.Migrations.ExternalSqlite
.ValueGeneratedOnAdd() .ValueGeneratedOnAdd()
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<bool>("Has4K")
.HasColumnType("INTEGER");
b.Property<bool>("HasFile") b.Property<bool>("HasFile")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");
b.Property<bool>("HasRegular")
.HasColumnType("INTEGER");
b.Property<int>("TheMovieDbId") b.Property<int>("TheMovieDbId")
.HasColumnType("INTEGER"); .HasColumnType("INTEGER");