We no longer block you from Requesting all seasons if we already have Season 1 Available/Requested. We will just request the delta now! For example if we request Season 1 and we have the first 3 episodes requested, we will skip those and request the remaining #2709

pull/4235/head v4.0.1423
tidusjar 3 years ago
parent ac3f1941bc
commit 11527e332c

@ -0,0 +1,209 @@
using MockQueryable.Moq;
using Moq;
using NUnit.Framework;
using Ombi.Core.Rule.Rules.Request;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ombi.Core.Tests.Rule.Request
{
[TestFixture]
public class ExistingPlexRequestRuleTests
{
private ExistingPlexRequestRule Rule;
private Mock<IPlexContentRepository> PlexContentRepo;
[SetUp]
public void SetUp()
{
PlexContentRepo = new Mock<IPlexContentRepository>();
Rule = new ExistingPlexRequestRule(PlexContentRepo.Object);
}
[Test]
public async Task RequestShow_DoesNotExistAtAll_IsSuccessful()
{
PlexContentRepo.Setup(x => x.GetAll()).Returns(new List<PlexServerContent>().AsQueryable().BuildMock().Object);
var req = new ChildRequests
{
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
}
},
SeasonNumber = 1
}
}
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.True);
}
[Test]
public async Task RequestShow_AllEpisodesAreaRequested_IsNotSuccessful()
{
SetupMockData();
var req = new ChildRequests
{
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
},
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 2,
},
},
SeasonNumber = 1
}
},
Id = 1,
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.False);
}
[Test]
public async Task RequestShow_SomeEpisodesAreaRequested_IsSuccessful()
{
SetupMockData();
var req = new ChildRequests
{
RequestType = RequestType.TvShow,
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
},
new EpisodeRequests
{
Id = 2,
EpisodeNumber = 2,
},
new EpisodeRequests
{
Id = 3,
EpisodeNumber = 3,
},
},
SeasonNumber = 1
}
},
Id = 1,
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.True);
var episodes = req.SeasonRequests.SelectMany(x => x.Episodes);
Assert.That(episodes.Count() == 1, "We didn't remove the episodes that have already been requested!");
Assert.That(episodes.First().EpisodeNumber == 3, "We removed the wrong episode");
}
[Test]
public async Task RequestShow_NewSeasonRequest_IsSuccessful()
{
SetupMockData();
var req = new ChildRequests
{
RequestType = RequestType.TvShow,
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
},
new EpisodeRequests
{
Id = 2,
EpisodeNumber = 2,
},
new EpisodeRequests
{
Id = 3,
EpisodeNumber = 3,
},
},
SeasonNumber = 2
}
},
Id = 1,
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.True);
}
private void SetupMockData()
{
var childRequests = new List<PlexServerContent>
{
new PlexServerContent
{
Type = PlexMediaTypeEntity.Show,
TheMovieDbId = "1",
Title = "Test",
ReleaseYear = "2001",
Episodes = new List<PlexEpisode>
{
new PlexEpisode
{
EpisodeNumber = 1,
Id = 1,
SeasonNumber = 1,
},
new PlexEpisode
{
EpisodeNumber = 2,
Id = 2,
SeasonNumber = 1,
},
}
}
};
PlexContentRepo.Setup(x => x.GetAll()).Returns(childRequests.AsQueryable().BuildMock().Object);
}
}
}

@ -0,0 +1,215 @@
using MockQueryable.Moq;
using Moq;
using NUnit.Framework;
using Ombi.Core.Rule.Rules.Request;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository.Requests;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Ombi.Core.Tests.Rule.Request
{
[TestFixture]
public class ExistingTvRequestRuleTests
{
private ExistingTvRequestRule Rule;
private Mock<ITvRequestRepository> TvRequestRepo;
[SetUp]
public void SetUp()
{
TvRequestRepo = new Mock<ITvRequestRepository>();
Rule = new ExistingTvRequestRule(TvRequestRepo.Object);
}
[Test]
public async Task RequestShow_DoesNotExistAtAll_IsSuccessful()
{
TvRequestRepo.Setup(x => x.GetChild()).Returns(new List<ChildRequests>().AsQueryable().BuildMock().Object);
var req = new ChildRequests
{
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
}
},
SeasonNumber = 1
}
}
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.True);
}
[Test]
public async Task RequestShow_AllEpisodesAreaRequested_IsNotSuccessful()
{
SetupMockData();
var req = new ChildRequests
{
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
},
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 2,
},
},
SeasonNumber = 1
}
},
Id = 1,
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.False);
}
[Test]
public async Task RequestShow_SomeEpisodesAreaRequested_IsSuccessful()
{
SetupMockData();
var req = new ChildRequests
{
RequestType = RequestType.TvShow,
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
},
new EpisodeRequests
{
Id = 2,
EpisodeNumber = 2,
},
new EpisodeRequests
{
Id = 3,
EpisodeNumber = 3,
},
},
SeasonNumber = 1
}
},
Id = 1,
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.True);
var episodes = req.SeasonRequests.SelectMany(x => x.Episodes);
Assert.That(episodes.Count() == 1, "We didn't remove the episodes that have already been requested!");
Assert.That(episodes.First().EpisodeNumber == 3, "We removed the wrong episode");
}
[Test]
public async Task RequestShow_NewSeasonRequest_IsSuccessful()
{
SetupMockData();
var req = new ChildRequests
{
RequestType = RequestType.TvShow,
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
},
new EpisodeRequests
{
Id = 2,
EpisodeNumber = 2,
},
new EpisodeRequests
{
Id = 3,
EpisodeNumber = 3,
},
},
SeasonNumber = 2
}
},
Id = 1,
};
var result = await Rule.Execute(req);
Assert.That(result.Success, Is.True);
}
private void SetupMockData()
{
var childRequests = new List<ChildRequests>
{
new ChildRequests
{
ParentRequest = new TvRequests
{
Id = 1,
ExternalProviderId = 1,
},
SeasonRequests = new List<SeasonRequests>
{
new SeasonRequests
{
Id = 1,
SeasonNumber = 1,
Episodes = new List<EpisodeRequests>
{
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 1,
},
new EpisodeRequests
{
Id = 1,
EpisodeNumber = 2,
}
}
}
}
}
};
TvRequestRepo.Setup(x => x.GetChild()).Returns(childRequests.AsQueryable().BuildMock().Object);
}
}
}

@ -7,6 +7,7 @@ using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;
namespace Ombi.Core.Rule.Rules.Request
{
@ -60,6 +61,7 @@ namespace Ombi.Core.Rule.Rules.Request
{
foreach (var season in child.SeasonRequests)
{
var episodesToRemove = new List<EpisodeRequests>();
var currentSeasonRequest =
content.Episodes.Where(x => x.SeasonNumber == season.SeasonNumber).ToList();
if (!currentSeasonRequest.Any())
@ -68,12 +70,24 @@ namespace Ombi.Core.Rule.Rules.Request
}
foreach (var e in season.Episodes)
{
var hasEpisode = currentSeasonRequest.Any(x => x.EpisodeNumber == e.EpisodeNumber);
if (hasEpisode)
var existingEpRequest = currentSeasonRequest.FirstOrDefault(x => x.EpisodeNumber == e.EpisodeNumber);
if (existingEpRequest != null)
{
return Fail($"We already have episodes requested from series {child.Title}");
episodesToRemove.Add(e);
}
}
episodesToRemove.ForEach(x =>
{
season.Episodes.Remove(x);
});
}
var anyEpisodes = child.SeasonRequests.SelectMany(x => x.Episodes).Any();
if (!anyEpisodes)
{
return Fail($"We already have episodes requested from series {child.Title}");
}
return Success();

@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Rule.Interfaces;
@ -41,15 +42,30 @@ namespace Ombi.Core.Rule.Rules.Request
{
continue;
}
var episodesToRemove = new List<EpisodeRequests>();
foreach (var e in season.Episodes)
{
var hasEpisode = currentSeasonRequest.Episodes.Any(x => x.EpisodeNumber == e.EpisodeNumber);
if (hasEpisode)
var existingEpRequest = currentSeasonRequest.Episodes.FirstOrDefault(x => x.EpisodeNumber == e.EpisodeNumber);
if (existingEpRequest != null)
{
return Fail($"We already have episodes requested from series {tv.Title}");
episodesToRemove.Add(e);
}
}
episodesToRemove.ForEach(x =>
{
season.Episodes.Remove(x);
});
}
var anyEpisodes = tv.SeasonRequests.SelectMany(x => x.Episodes).Any();
if (!anyEpisodes)
{
return Fail($"We already have episodes requested from series {tv.Title}");
}
}
return Success();
}

@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Models.Search;
@ -6,6 +7,7 @@ using Ombi.Helpers;
using Ombi.Store.Context;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository.Requests;
namespace Ombi.Core.Rule.Rules
{
@ -23,7 +25,7 @@ namespace Ombi.Core.Rule.Rules
if (obj.RequestType == RequestType.TvShow)
{
var vm = (ChildRequests) obj;
var result = await _ctx.SonarrCache.FirstOrDefaultAsync(x => x.TvDbId == vm.Id); // TODO lookup the external provider in the sonarr sync to use themoviedb
var result = await _ctx.SonarrCache.FirstOrDefaultAsync(x => x.TheMovieDbId == vm.Id);
if (result != null)
{
if (vm.SeasonRequests.Any())
@ -31,17 +33,30 @@ namespace Ombi.Core.Rule.Rules
var sonarrEpisodes = _ctx.SonarrEpisodeCache;
foreach (var season in vm.SeasonRequests)
{
var toRemove = new List<EpisodeRequests>();
foreach (var ep in season.Episodes)
{
// Check if we have it
var monitoredInSonarr = sonarrEpisodes.Any(x =>
var monitoredInSonarr = sonarrEpisodes.FirstOrDefault(x =>
x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == season.SeasonNumber
&& x.TvDbId == vm.Id);
if (monitoredInSonarr)
&& x.MovieDbId == vm.Id);
if (monitoredInSonarr != null)
{
return new RuleResult{Message = "We already have this request, please choose the \"Select...\" option to refine your request"};
}
toRemove.Add(ep);
}
}
toRemove.ForEach(x =>
{
season.Episodes.Remove(x);
});
}
var anyEpisodes = vm.SeasonRequests.SelectMany(x => x.Episodes).Any();
if (!anyEpisodes)
{
return new RuleResult { Message = $"We already have episodes requested from series {vm.Title}" };
}
}
}

@ -9,6 +9,8 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Api.Sonarr;
using Ombi.Api.Sonarr.Models;
using Ombi.Api.TheMovieDb;
using Ombi.Api.TheMovieDb.Models;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Schedule.Jobs.Radarr;
@ -21,12 +23,14 @@ namespace Ombi.Schedule.Jobs.Sonarr
{
public class SonarrSync : ISonarrSync
{
public SonarrSync(ISettingsService<SonarrSettings> s, ISonarrApi api, ILogger<SonarrSync> l, ExternalContext ctx)
public SonarrSync(ISettingsService<SonarrSettings> s, ISonarrApi api, ILogger<SonarrSync> l, ExternalContext ctx,
IMovieDbApi movieDbApi)
{
_settings = s;
_api = api;
_log = l;
_ctx = ctx;
_movieDbApi = movieDbApi;
_settings.ClearCache();
}
@ -34,6 +38,7 @@ namespace Ombi.Schedule.Jobs.Sonarr
private readonly ISonarrApi _api;
private readonly ILogger<SonarrSync> _log;
private readonly ExternalContext _ctx;
private readonly IMovieDbApi _movieDbApi;
public async Task Execute(IJobExecutionContext job)
{
@ -48,7 +53,17 @@ namespace Ombi.Schedule.Jobs.Sonarr
if (series != null)
{
var sonarrSeries = series as ImmutableHashSet<SonarrSeries> ?? series.ToImmutableHashSet();
var ids = sonarrSeries.Select(x => x.tvdbId);
var ids = sonarrSeries.Select(x => new SonarrDto
{
TvDbId = x.tvdbId,
ImdbId = x.imdbId,
Title = x.title,
MovieDbId = 0,
Id = x.id,
Monitored = x.monitored,
EpisodeFileCount = x.episodeFileCount
}).ToHashSet();
var strat = _ctx.Database.CreateExecutionStrategy();
await strat.ExecuteAsync(async () =>
{
@ -60,12 +75,27 @@ namespace Ombi.Schedule.Jobs.Sonarr
});
var existingSeries = await _ctx.SonarrCache.Select(x => x.TvDbId).ToListAsync();
//var entites = ids.Except(existingSeries).Select(id => new SonarrCache { TvDbId = id }).ToImmutableHashSet();
var entites = ids.Select(id => new SonarrCache { TvDbId = id }).ToImmutableHashSet();
await _ctx.SonarrCache.AddRangeAsync(entites);
entites.Clear();
var sonarrCacheToSave = new HashSet<SonarrCache>();
foreach (var id in ids)
{
var cache = new SonarrCache
{
TvDbId = id.TvDbId
};
var findResult = await _movieDbApi.Find(id.TvDbId.ToString(), ExternalSource.tvdb_id);
if (findResult.tv_results.Any())
{
cache.TheMovieDbId = findResult.tv_results.FirstOrDefault()?.id ?? -1;
id.MovieDbId = cache.TheMovieDbId;
}
sonarrCacheToSave.Add(cache);
}
await _ctx.SonarrCache.AddRangeAsync(sonarrCacheToSave);
await _ctx.SaveChangesAsync();
sonarrCacheToSave.Clear();
strat = _ctx.Database.CreateExecutionStrategy();
await strat.ExecuteAsync(async () =>
{
@ -76,15 +106,15 @@ namespace Ombi.Schedule.Jobs.Sonarr
}
});
foreach (var s in sonarrSeries)
foreach (var s in ids)
{
if (!s.monitored || s.episodeFileCount == 0) // We have files
if (!s.Monitored || s.EpisodeFileCount == 0) // We have files
{
continue;
}
_log.LogDebug("Syncing series: {0}", s.title);
var episodes = await _api.GetEpisodes(s.id, settings.ApiKey, settings.FullUri);
_log.LogDebug("Syncing series: {0}", s.Title);
var episodes = await _api.GetEpisodes(s.Id, settings.ApiKey, settings.FullUri);
var monitoredEpisodes = episodes.Where(x => x.monitored || x.hasFile);
//var allExistingEpisodes = await _ctx.SonarrEpisodeCache.Where(x => x.TvDbId == s.tvdbId).ToListAsync();
@ -95,7 +125,8 @@ namespace Ombi.Schedule.Jobs.Sonarr
{
EpisodeNumber = episode.episodeNumber,
SeasonNumber = episode.seasonNumber,
TvDbId = s.tvdbId,
TvDbId = s.TvDbId,
MovieDbId = s.MovieDbId,
HasFile = episode.hasFile
});
//var episodesToAdd = new List<SonarrEpisodeCache>();
@ -166,5 +197,16 @@ namespace Ombi.Schedule.Jobs.Sonarr
Dispose(true);
GC.SuppressFinalize(this);
}
private class SonarrDto
{
public int TvDbId { get; set; }
public string ImdbId { get; set; }
public string Title { get; set; }
public int MovieDbId { get; set; }
public int Id { get; set; }
public bool Monitored { get; set; }
public int EpisodeFileCount { get; set; }
}
}
}

@ -6,5 +6,6 @@ namespace Ombi.Store.Entities
public class SonarrCache : Entity
{
public int TvDbId { get; set; }
public int TheMovieDbId { get; set; }
}
}

@ -8,6 +8,7 @@ namespace Ombi.Store.Entities
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
public int TvDbId { get; set; }
public int MovieDbId { get; set; }
public bool HasFile { get; set; }
}
}

@ -0,0 +1,513 @@
// <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;
namespace Ombi.Store.Migrations.ExternalMySql
{
[DbContext(typeof(ExternalMySqlContext))]
[Migration("20210615152049_SonarrSyncMovieDbData")]
partial class SonarrSyncMovieDbData
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Relational:MaxIdentifierLength", 64)
.HasAnnotation("ProductVersion", "5.0.1");
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>("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>("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>("HasFile")
.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
}
}
}

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ombi.Store.Migrations.ExternalMySql
{
public partial class SonarrSyncMovieDbData : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "MovieDbId",
table: "SonarrEpisodeCache",
type: "int",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "TheMovieDbId",
table: "SonarrCache",
type: "int",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "MovieDbId",
table: "SonarrEpisodeCache");
migrationBuilder.DropColumn(
name: "TheMovieDbId",
table: "SonarrCache");
}
}
}

@ -413,6 +413,9 @@ namespace Ombi.Store.Migrations.ExternalMySql
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<int>("TheMovieDbId")
.HasColumnType("int");
b.Property<int>("TvDbId")
.HasColumnType("int");
@ -433,6 +436,9 @@ namespace Ombi.Store.Migrations.ExternalMySql
b.Property<bool>("HasFile")
.HasColumnType("tinyint(1)");
b.Property<int>("MovieDbId")
.HasColumnType("int");
b.Property<int>("SeasonNumber")
.HasColumnType("int");

@ -0,0 +1,512 @@
// <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;
namespace Ombi.Store.Migrations.ExternalSqlite
{
[DbContext(typeof(ExternalSqliteContext))]
[Migration("20210615145321_SonarrSyncMovieDbData")]
partial class SonarrSyncMovieDbData
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "5.0.1");
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>("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>("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>("HasFile")
.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
}
}
}

@ -0,0 +1,35 @@
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ombi.Store.Migrations.ExternalSqlite
{
public partial class SonarrSyncMovieDbData : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<int>(
name: "MovieDbId",
table: "SonarrEpisodeCache",
type: "INTEGER",
nullable: false,
defaultValue: 0);
migrationBuilder.AddColumn<int>(
name: "TheMovieDbId",
table: "SonarrCache",
type: "INTEGER",
nullable: false,
defaultValue: 0);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "MovieDbId",
table: "SonarrEpisodeCache");
migrationBuilder.DropColumn(
name: "TheMovieDbId",
table: "SonarrCache");
}
}
}

@ -412,6 +412,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("TheMovieDbId")
.HasColumnType("INTEGER");
b.Property<int>("TvDbId")
.HasColumnType("INTEGER");
@ -432,6 +435,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite
b.Property<bool>("HasFile")
.HasColumnType("INTEGER");
b.Property<int>("MovieDbId")
.HasColumnType("INTEGER");
b.Property<int>("SeasonNumber")
.HasColumnType("INTEGER");

Loading…
Cancel
Save