mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 01:02:57 -07:00
feat(radarr): 4K Requests and Radarr 4K support
* feat: updated radarr settings API to support 4k * feat: refactored the radarr setting page to support the new model * feat: Added 4k radarr to the settings page * feat: Added the new Movie 4k Request * feat: Got some of the backend rules done * feat: Made a load of progress * Removed the csproj ref * feat: fixed the radarr ui * feat: fixed up all the movie requests page * feat: Hide the 4K buttons when the user does not have the 4k permission * fix: fixed the templateref issue * test: fixed up all the tests * feat: Added migrations for media sever quality. Emby and Radarr Sync jobs now pull the quality * feat: Done the media sync jobs * feat: plex availability checker * feat: Updated the jellyfin availability checker to check for 4k * feat: updated emby availbility checker to check for 4k * feat: almost got it all working now * feat: Added 4k approve to the request list options * feat: Added 4k to the requests list and bulk approve * feat: Added the features service * feat: added feature update to the frontend * feat: got the features page working * feat: Applied the feature service on the backend * feat: added the feature flag on the UI * feat: added 4k to the card
This commit is contained in:
parent
09f648515e
commit
ba88848866
153 changed files with 12438 additions and 784 deletions
|
@ -170,7 +170,7 @@ namespace Ombi.Api.Emby
|
|||
|
||||
request.AddQueryString("Recursive", true.ToString());
|
||||
request.AddQueryString("IncludeItemTypes", type);
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds");
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,MediaStreams,Overview" : "ProviderIds,MediaStreams ");
|
||||
request.AddQueryString("startIndex", startIndex.ToString());
|
||||
request.AddQueryString("limit", count.ToString());
|
||||
request.AddQueryString("sortBy", "DateCreated");
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -157,7 +157,7 @@ namespace Ombi.Api.Jellyfin
|
|||
|
||||
request.AddQueryString("Recursive", true.ToString());
|
||||
request.AddQueryString("IncludeItemTypes", type);
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview,ParentId" : "ProviderIds,ParentId");
|
||||
request.AddQueryString("Fields", includeOverview ? "ProviderIds,MediaStreams Overview,ParentId" : "ProviderIds,ParentId,MediaStreams");
|
||||
request.AddQueryString("startIndex", startIndex.ToString());
|
||||
request.AddQueryString("limit", count.ToString());
|
||||
if(!string.IsNullOrEmpty(parentIdFilder))
|
||||
|
|
|
@ -2,35 +2,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie
|
|||
{
|
||||
public class JellyfinMediastream
|
||||
{
|
||||
public string Codec { get; set; }
|
||||
public string Language { get; set; }
|
||||
public string TimeBase { get; set; }
|
||||
public string CodecTimeBase { get; set; }
|
||||
public string NalLengthSize { get; set; }
|
||||
public bool IsInterlaced { get; set; }
|
||||
public bool IsAVC { get; set; }
|
||||
public int BitRate { get; set; }
|
||||
public int BitDepth { get; set; }
|
||||
public int RefFrames { get; set; }
|
||||
public bool IsDefault { get; set; }
|
||||
public bool IsForced { get; set; }
|
||||
public int Height { get; set; }
|
||||
public int Width { get; set; }
|
||||
public float AverageFrameRate { get; set; }
|
||||
public float RealFrameRate { get; set; }
|
||||
public string Profile { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string AspectRatio { get; set; }
|
||||
public int Index { get; set; }
|
||||
public bool IsExternal { get; set; }
|
||||
public bool IsTextSubtitleStream { get; set; }
|
||||
public bool SupportsExternalStream { get; set; }
|
||||
public string PixelFormat { get; set; }
|
||||
public int Level { get; set; }
|
||||
public bool IsAnamorphic { get; set; }
|
||||
public string DisplayTitle { get; set; }
|
||||
public string ChannelLayout { get; set; }
|
||||
public int Channels { get; set; }
|
||||
public int SampleRate { get; set; }
|
||||
}
|
||||
}
|
|
@ -30,5 +30,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie
|
|||
public int CriticRating { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public JellyfinProviderids ProviderIds { get; set; }
|
||||
public JellyfinMediastream[] MediaStreams { get; set; }
|
||||
}
|
||||
}
|
|
@ -44,7 +44,10 @@ namespace Ombi.Api.Radarr.Models
|
|||
public int id { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class MovieQuality
|
||||
{
|
||||
public V3.Quality quality { get; set; }
|
||||
}
|
||||
public class Moviefile
|
||||
{
|
||||
public int movieId { get; set; }
|
||||
|
@ -54,7 +57,7 @@ namespace Ombi.Api.Radarr.Models
|
|||
public DateTime dateAdded { get; set; }
|
||||
public string sceneName { get; set; }
|
||||
public int indexerFlags { get; set; }
|
||||
public V3.Quality quality { get; set; }
|
||||
public MovieQuality quality { get; set; }
|
||||
public Mediainfo mediaInfo { get; set; }
|
||||
public string originalFilePath { get; set; }
|
||||
public bool qualityCutoffNotMet { get; set; }
|
||||
|
|
|
@ -25,5 +25,4 @@
|
|||
public int resolution { get; set; }
|
||||
public string modifier { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using Ombi.Api.TheMovieDb;
|
|||
using Ombi.Core.Engine;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
|
@ -43,8 +44,9 @@ namespace Ombi.Core.Tests.Engine.V2
|
|||
var ombiSettings = new Mock<ISettingsService<OmbiSettings>>();
|
||||
var requestSubs = new Mock<IRepository<RequestSubscription>>();
|
||||
var mediaCache = new Mock<IMediaCacheService>();
|
||||
var featureService = new Mock<IFeatureService>();
|
||||
_engine = new MovieRequestEngine(movieApi.Object, requestService.Object, user.Object, notificationHelper.Object, rules.Object, movieSender.Object,
|
||||
logger.Object, userManager.Object, requestLogRepo.Object, cache.Object, ombiSettings.Object, requestSubs.Object, mediaCache.Object);
|
||||
logger.Object, userManager.Object, requestLogRepo.Object, cache.Object, ombiSettings.Object, requestSubs.Object, mediaCache.Object, featureService.Object);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
Assert.That(result.Result, Is.True);
|
||||
VoteRepository.Verify(x => x.Add(It.Is<Votes>(c => c.UserId == "abc" && c.VoteType == type)), Times.Once);
|
||||
VoteRepository.Verify(x => x.Delete(It.IsAny<Votes>()), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never);
|
||||
}
|
||||
public static IEnumerable<TestCaseData> VoteData
|
||||
{
|
||||
|
@ -129,7 +129,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
|
||||
Assert.That(result.Result, Is.False);
|
||||
VoteRepository.Verify(x => x.Delete(It.IsAny<Votes>()), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never);
|
||||
}
|
||||
public static IEnumerable<TestCaseData> AttemptedTwiceData
|
||||
{
|
||||
|
@ -175,7 +175,7 @@ namespace Ombi.Core.Tests.Engine
|
|||
Assert.That(result.Result, Is.True);
|
||||
VoteRepository.Verify(x => x.Delete(It.IsAny<Votes>()), Times.Once);
|
||||
VoteRepository.Verify(x => x.Add(It.Is<Votes>(v => v.VoteType == type)), Times.Once);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never);
|
||||
MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never);
|
||||
}
|
||||
public static IEnumerable<TestCaseData> VoteConvertData
|
||||
{
|
||||
|
|
|
@ -10,6 +10,7 @@ using Ombi.Test.Common;
|
|||
using System.Collections.Generic;
|
||||
using Ombi.Store.Entities;
|
||||
using System;
|
||||
using Ombi.Core.Services;
|
||||
|
||||
namespace Ombi.Core.Tests.Rule.Request
|
||||
{
|
||||
|
@ -28,21 +29,23 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
|
||||
PrincipalMock = new Mock<IPrincipal>();
|
||||
PrincipalMock.Setup(x => x.Identity.Name).Returns("abc");
|
||||
FeatureService = new Mock<IFeatureService>();
|
||||
|
||||
UserManager = MockHelper.MockUserManager(_users);
|
||||
Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object);
|
||||
Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object, FeatureService.Object);
|
||||
}
|
||||
|
||||
|
||||
private AutoApproveRule Rule { get; set; }
|
||||
private Mock<IPrincipal> PrincipalMock { get; set; }
|
||||
private Mock<OmbiUserManager> UserManager { get; set; }
|
||||
private Mock<IFeatureService> FeatureService { get; set; }
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenAdminAndRequestMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Admin)).ReturnsAsync(true);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -64,7 +67,7 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public async Task Should_ReturnSuccess_WhenAutoApproveMovieAndRequestMovie()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(true);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -137,5 +140,17 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
Assert.True(result.Success);
|
||||
Assert.False(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnFail_When4kRequestAndFeatureNotEnabled()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), It.IsAny<string>())).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.False(request.Approved);
|
||||
Assert.False(request.Approved4K);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,42 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public async Task Should_ReturnSuccess_WhenRequestingMovieWithMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovie4KWithMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Request4KMovie)).ReturnsAsync(true);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnFailure_WhenRequestingMovie4KWithMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Request4KMovie)).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.False(result.Success);
|
||||
Assert.False(string.IsNullOrEmpty(result.Message));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnSuccess_WhenRequestingMovie4KWithAutoApprove()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(true);
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.Request4KMovie)).ReturnsAsync(false);
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
|
@ -52,7 +87,7 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public async Task Should_ReturnFail_WhenRequestingMovieWithoutMovieRole()
|
||||
{
|
||||
UserManager.Setup(x => x.IsInRoleAsync(It.IsAny<OmbiUser>(), OmbiRoles.RequestMovie)).ReturnsAsync(false);
|
||||
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.False(result.Success);
|
||||
|
|
|
@ -9,7 +9,9 @@ using NUnit.Framework;
|
|||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Rule.Rules;
|
||||
using Ombi.Core.Rule.Rules.Request;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
|
@ -24,12 +26,14 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
public void Setup()
|
||||
{
|
||||
ContextMock = new Mock<IMovieRequestRepository>();
|
||||
Rule = new ExistingMovieRequestRule(ContextMock.Object);
|
||||
FeatureService = new Mock<IFeatureService>();
|
||||
Rule = new ExistingMovieRequestRule(ContextMock.Object, FeatureService.Object);
|
||||
}
|
||||
|
||||
|
||||
private ExistingMovieRequestRule Rule { get; set; }
|
||||
private Mock<IMovieRequestRepository> ContextMock { get; set; }
|
||||
private Mock<IFeatureService> FeatureService { get; set; }
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_Has_Been_Requested_With_TheMovieDBId()
|
||||
|
@ -96,5 +100,82 @@ namespace Ombi.Core.Tests.Rule.Request
|
|||
Assert.That(result.Success, Is.True);
|
||||
Assert.That(result.Message, Is.Null.Or.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_HasAlready4K_Request()
|
||||
{
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "2",
|
||||
RequestType = RequestType.Movie,
|
||||
Is4kRequest = true
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
var o = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "1",
|
||||
Has4KRequest = true
|
||||
};
|
||||
var result = await Rule.Execute(o);
|
||||
|
||||
Assert.That(result.Success, Is.False);
|
||||
Assert.That(result.Message, Is.Not.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_4K_Request()
|
||||
{
|
||||
FeatureService.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true);
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "2",
|
||||
RequestType = RequestType.Movie,
|
||||
Is4kRequest = false
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
var o = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "1",
|
||||
Is4kRequest = true
|
||||
};
|
||||
var result = await Rule.Execute(o);
|
||||
|
||||
Assert.That(result.Success, Is.True);
|
||||
Assert.That(result.Message, Is.Null.Or.Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task ExistingRequestRule_Movie_4K_Request_FeatureNotEnabled()
|
||||
{
|
||||
FeatureService.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(false);
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(new List<MovieRequests>
|
||||
{
|
||||
new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "2",
|
||||
RequestType = RequestType.Movie,
|
||||
Is4kRequest = false
|
||||
}
|
||||
}.AsQueryable().BuildMock().Object);
|
||||
var o = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 2,
|
||||
ImdbId = "1",
|
||||
Is4kRequest = true
|
||||
};
|
||||
var result = await Rule.Execute(o);
|
||||
|
||||
Assert.That(result.Success, Is.False);
|
||||
Assert.That(result.Message, Is.Not.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
ProviderId = "123"
|
||||
TheMovieDbId = "123",
|
||||
Quality = "1"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
|
@ -47,6 +48,47 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
Assert.True(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInEmby_4K()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(search.Available4K);
|
||||
Assert.False(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInEmby_Both()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new EmbyContent
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true,
|
||||
Quality = "1"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(search.Available4K);
|
||||
Assert.True(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_NotAvailable_WhenNotFoundInEmby()
|
||||
{
|
||||
|
|
|
@ -30,13 +30,14 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
|
||||
|
||||
[Test]
|
||||
public async Task ShouldBe_Requested_WhenExisitngMovie()
|
||||
public async Task ShouldBe_Requested_WhenExistingMovie()
|
||||
{
|
||||
var list = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = 123,
|
||||
Approved = true,
|
||||
RequestType = RequestType.Movie
|
||||
RequestType = RequestType.Movie,
|
||||
RequestedDate = System.DateTime.Now,
|
||||
};
|
||||
|
||||
MovieMock.Setup(x => x.GetRequestAsync(123)).ReturnsAsync(list);
|
||||
|
|
|
@ -35,7 +35,8 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
ProviderId = "123"
|
||||
TheMovieDbId = "123",
|
||||
Quality = "1080"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
|
@ -47,6 +48,47 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
Assert.True(search.Available);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_4K()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.False(search.Available);
|
||||
Assert.True(search.Available4K);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_Both()
|
||||
{
|
||||
SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings());
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
Has4K = true,
|
||||
Quality = "1"
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
{
|
||||
TheMovieDbId = "123",
|
||||
};
|
||||
var result = await Rule.Execute(search);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(search.Available);
|
||||
Assert.True(search.Available4K);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Movie_Uses_Default_Url_When()
|
||||
{
|
||||
|
@ -66,7 +108,7 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
});
|
||||
ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny<string>())).ReturnsAsync(new JellyfinContent
|
||||
{
|
||||
ProviderId = "123",
|
||||
TheMovieDbId = "123",
|
||||
JellyfinId = 1.ToString()
|
||||
});
|
||||
var search = new SearchMovieViewModel()
|
||||
|
|
|
@ -28,7 +28,8 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
{
|
||||
var list = new List<RadarrCache>(){new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 123
|
||||
TheMovieDbId = 123,
|
||||
HasRegular = true
|
||||
}}.AsQueryable();
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
@ -40,13 +41,54 @@ namespace Ombi.Core.Tests.Rule.Search
|
|||
Assert.True(request.Approved);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnAvailabl_WhenMovieIsInRadarr_4K()
|
||||
{
|
||||
var list = new List<RadarrCache>(){new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 123,
|
||||
Has4K = true,
|
||||
HasFile = true
|
||||
}}.AsQueryable();
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
||||
var request = new SearchMovieViewModel { Id = 123 };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.False(request.Available);
|
||||
Assert.True(request.Available4K);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnAvailable_WhenMovieIsInRadarr_Both()
|
||||
{
|
||||
var list = new List<RadarrCache>(){new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 123,
|
||||
Has4K = true,
|
||||
HasRegular = true,
|
||||
HasFile = true
|
||||
}}.AsQueryable();
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
||||
var request = new SearchMovieViewModel { Id = 123 };
|
||||
var result = await Rule.Execute(request);
|
||||
|
||||
Assert.True(result.Success);
|
||||
Assert.True(request.Available);
|
||||
Assert.True(request.Available4K);
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Should_ReturnNotApproved_WhenMovieIsNotInRadarr()
|
||||
{
|
||||
var list = DbHelper.GetQueryableMockDbSet(new RadarrCache
|
||||
{
|
||||
TheMovieDbId = 000012
|
||||
TheMovieDbId = 000012,
|
||||
});
|
||||
|
||||
ContextMock.Setup(x => x.GetAll()).Returns(list);
|
||||
|
|
|
@ -18,9 +18,9 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
Task RemoveAllMovieRequests();
|
||||
Task<MovieRequests> GetRequest(int requestId);
|
||||
Task<MovieRequests> UpdateMovieRequest(MovieRequests request);
|
||||
Task<RequestEngineResult> ApproveMovie(MovieRequests request);
|
||||
Task<RequestEngineResult> ApproveMovieById(int requestId);
|
||||
Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason);
|
||||
Task<RequestEngineResult> ApproveMovie(MovieRequests request, bool is4K);
|
||||
Task<RequestEngineResult> ApproveMovieById(int requestId, bool is4K);
|
||||
Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason, bool is4K);
|
||||
Task<RequestsViewModel<MovieRequests>> GetRequests(int count, int position, string sortProperty, string sortOrder);
|
||||
|
||||
Task<RequestsViewModel<MovieRequests>> GetUnavailableRequests(int count, int position, string sortProperty,
|
||||
|
|
|
@ -19,11 +19,11 @@ namespace Ombi.Core.Engine.Interfaces
|
|||
Task<IEnumerable<T>> GetRequests();
|
||||
Task<bool> UserHasRequest(string userId);
|
||||
|
||||
Task<RequestEngineResult> MarkUnavailable(int modelId);
|
||||
Task<RequestEngineResult> MarkAvailable(int modelId);
|
||||
Task<RequestEngineResult> MarkUnavailable(int modelId, bool is4K);
|
||||
Task<RequestEngineResult> MarkAvailable(int modelId, bool is4K);
|
||||
Task<int> GetTotal();
|
||||
Task UnSubscribeRequest(int requestId, RequestType type);
|
||||
Task SubscribeToRequest(int requestId, RequestType type);
|
||||
Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken);
|
||||
Task<RequestEngineResult> ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ using Ombi.Store.Entities.Requests;
|
|||
using Ombi.Store.Repository;
|
||||
using Ombi.Core.Models;
|
||||
using System.Threading;
|
||||
using Ombi.Core.Services;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
|
@ -30,7 +31,8 @@ namespace Ombi.Core.Engine
|
|||
public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user,
|
||||
INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger<MovieRequestEngine> log,
|
||||
OmbiUserManager manager, IRepository<RequestLog> rl, ICacheService cache,
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService)
|
||||
ISettingsService<OmbiSettings> ombiSettings, IRepository<RequestSubscription> sub, IMediaCacheService mediaCacheService,
|
||||
IFeatureService featureService)
|
||||
: base(user, requestService, r, manager, cache, ombiSettings, sub)
|
||||
{
|
||||
MovieApi = movieApi;
|
||||
|
@ -39,6 +41,7 @@ namespace Ombi.Core.Engine
|
|||
Logger = log;
|
||||
_requestLog = rl;
|
||||
_mediaCacheService = mediaCacheService;
|
||||
_featureService = featureService;
|
||||
}
|
||||
|
||||
private IMovieDbApi MovieApi { get; }
|
||||
|
@ -47,6 +50,7 @@ namespace Ombi.Core.Engine
|
|||
private ILogger<MovieRequestEngine> Logger { get; }
|
||||
private readonly IRepository<RequestLog> _requestLog;
|
||||
private readonly IMediaCacheService _mediaCacheService;
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
/// <summary>
|
||||
/// Requests the movie.
|
||||
|
@ -72,7 +76,8 @@ namespace Ombi.Core.Engine
|
|||
var userDetails = await GetUser();
|
||||
var canRequestOnBehalf = model.RequestOnBehalf.HasValue();
|
||||
|
||||
var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin);
|
||||
var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser)
|
||||
|| await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin);
|
||||
if (canRequestOnBehalf && !isAdmin)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -93,7 +98,30 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
var requestModel = new MovieRequests
|
||||
var is4kFeatureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests);
|
||||
var is4kRequest = is4kFeatureEnabled && model.Is4kRequest;
|
||||
|
||||
MovieRequests requestModel;
|
||||
bool isExisting = false;
|
||||
// Do we already have a request? 4k or non 4k
|
||||
var existingRequest = await MovieRepository.GetRequestAsync(movieInfo.Id);
|
||||
if (existingRequest != null && is4kFeatureEnabled)
|
||||
{
|
||||
if (model.Is4kRequest)
|
||||
{
|
||||
existingRequest.Is4kRequest = true;
|
||||
existingRequest.RequestedDate4k = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
existingRequest.RequestedDate = DateTime.Now;
|
||||
}
|
||||
isExisting = true;
|
||||
requestModel = existingRequest;
|
||||
}
|
||||
else
|
||||
{
|
||||
requestModel = new MovieRequests
|
||||
{
|
||||
TheMovieDbId = movieInfo.Id,
|
||||
RequestType = RequestType.Movie,
|
||||
|
@ -105,15 +133,18 @@ namespace Ombi.Core.Engine
|
|||
? DateTime.Parse(movieInfo.ReleaseDate)
|
||||
: DateTime.MinValue,
|
||||
Status = movieInfo.Status,
|
||||
RequestedDate = DateTime.UtcNow,
|
||||
RequestedDate = model.Is4kRequest ? DateTime.MinValue : DateTime.Now,
|
||||
Approved = false,
|
||||
RequestedUserId = canRequestOnBehalf ? model.RequestOnBehalf : userDetails.Id,
|
||||
Background = movieInfo.BackdropPath,
|
||||
LangCode = model.LanguageCode,
|
||||
RequestedByAlias = model.RequestedByAlias,
|
||||
RootPathOverride = model.RootFolderOverride.GetValueOrDefault(),
|
||||
QualityOverride = model.QualityPathOverride.GetValueOrDefault()
|
||||
QualityOverride = model.QualityPathOverride.GetValueOrDefault(),
|
||||
RequestedDate4k = model.Is4kRequest ? DateTime.Now : DateTime.MinValue,
|
||||
Is4kRequest = model.Is4kRequest
|
||||
};
|
||||
}
|
||||
|
||||
var usDates = movieInfo.ReleaseDates?.Results?.FirstOrDefault(x => x.IsoCode == "US");
|
||||
requestModel.DigitalReleaseDate = usDates?.ReleaseDate
|
||||
|
@ -132,10 +163,10 @@ namespace Ombi.Core.Engine
|
|||
|
||||
if (requestModel.Approved) // The rules have auto approved this
|
||||
{
|
||||
var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf);
|
||||
var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf, isExisting, is4kRequest);
|
||||
if (requestEngineResult.Result)
|
||||
{
|
||||
var result = await ApproveMovie(requestModel);
|
||||
var result = await ApproveMovie(requestModel, model.Is4kRequest);
|
||||
if (result.IsError)
|
||||
{
|
||||
Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message);
|
||||
|
@ -153,7 +184,7 @@ namespace Ombi.Core.Engine
|
|||
// If there are no providers then it's successful but movie has not been sent
|
||||
}
|
||||
|
||||
return await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf);
|
||||
return await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf, isExisting, is4kRequest);
|
||||
}
|
||||
|
||||
|
||||
|
@ -508,13 +539,13 @@ namespace Ombi.Core.Engine
|
|||
return results;
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ApproveMovieById(int requestId)
|
||||
public async Task<RequestEngineResult> ApproveMovieById(int requestId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(requestId);
|
||||
return await ApproveMovie(request);
|
||||
return await ApproveMovie(request, is4K);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason)
|
||||
public async Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
|
@ -525,8 +556,16 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
if (is4K)
|
||||
{
|
||||
request.Denied4K = true;
|
||||
request.DeniedReason4K = denyReason;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Denied = true;
|
||||
request.DeniedReason = denyReason;
|
||||
}
|
||||
await MovieRepository.Update(request);
|
||||
await _mediaCacheService.Purge();
|
||||
|
||||
|
@ -540,7 +579,7 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ApproveMovie(MovieRequests request)
|
||||
public async Task<RequestEngineResult> ApproveMovie(MovieRequests request, bool is4K)
|
||||
{
|
||||
if (request == null)
|
||||
{
|
||||
|
@ -550,9 +589,18 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
if (is4K)
|
||||
{
|
||||
request.MarkedAsApproved4K = DateTime.Now;
|
||||
request.Approved4K = true;
|
||||
request.Denied4K = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.MarkedAsApproved = DateTime.Now;
|
||||
request.Approved = true;
|
||||
request.Denied = false;
|
||||
}
|
||||
await MovieRepository.Update(request);
|
||||
|
||||
var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification, string.Empty);
|
||||
|
@ -562,7 +610,7 @@ namespace Ombi.Core.Engine
|
|||
}
|
||||
await _mediaCacheService.Purge();
|
||||
|
||||
return await ProcessSendingMovie(request);
|
||||
return await ProcessSendingMovie(request, is4K);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> RequestCollection(int collectionId, CancellationToken cancellationToken)
|
||||
|
@ -590,11 +638,11 @@ namespace Ombi.Core.Engine
|
|||
return new RequestEngineResult { Result = true, Message = $"The collection {collections.name} has been successfully added!", RequestId = results.FirstOrDefault().RequestId };
|
||||
}
|
||||
|
||||
private async Task<RequestEngineResult> ProcessSendingMovie(MovieRequests request)
|
||||
private async Task<RequestEngineResult> ProcessSendingMovie(MovieRequests request, bool is4K)
|
||||
{
|
||||
if (request.Approved)
|
||||
{
|
||||
var result = await Sender.Send(request);
|
||||
var result = await Sender.Send(request, is4K);
|
||||
if (result.Success && result.Sent)
|
||||
{
|
||||
return new RequestEngineResult
|
||||
|
@ -683,7 +731,7 @@ namespace Ombi.Core.Engine
|
|||
return await MovieRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken)
|
||||
public async Task<RequestEngineResult> ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = await MovieRepository.Find(requestId);
|
||||
if (request == null)
|
||||
|
@ -695,10 +743,10 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
return await ProcessSendingMovie(request);
|
||||
return await ProcessSendingMovie(request, is4K);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> MarkUnavailable(int modelId)
|
||||
public async Task<RequestEngineResult> MarkUnavailable(int modelId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
|
@ -709,7 +757,14 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
if (is4K)
|
||||
{
|
||||
request.Available4K = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Available = false;
|
||||
}
|
||||
await MovieRepository.Update(request);
|
||||
await _mediaCacheService.Purge();
|
||||
|
||||
|
@ -720,7 +775,7 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> MarkAvailable(int modelId)
|
||||
public async Task<RequestEngineResult> MarkAvailable(int modelId, bool is4K)
|
||||
{
|
||||
var request = await MovieRepository.Find(modelId);
|
||||
if (request == null)
|
||||
|
@ -730,9 +785,16 @@ namespace Ombi.Core.Engine
|
|||
ErrorMessage = "Request does not exist"
|
||||
};
|
||||
}
|
||||
|
||||
if (!is4K)
|
||||
{
|
||||
request.Available = true;
|
||||
request.MarkedAsAvailable = DateTime.Now;
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Available4K = true;
|
||||
request.MarkedAsAvailable4K = DateTime.Now;
|
||||
}
|
||||
await NotificationHelper.Notify(request, NotificationType.RequestAvailable);
|
||||
await MovieRepository.Update(request);
|
||||
await _mediaCacheService.Purge();
|
||||
|
@ -744,9 +806,20 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
private async Task<RequestEngineResult> AddMovieRequest(MovieRequests model, string movieName, string requestOnBehalf)
|
||||
private async Task<RequestEngineResult> AddMovieRequest(MovieRequests model, string movieName, string requestOnBehalf, bool isExisting, bool is4k)
|
||||
{
|
||||
if (is4k)
|
||||
{
|
||||
model.Has4KRequest = true;
|
||||
}
|
||||
if (!isExisting)
|
||||
{
|
||||
await MovieRepository.Add(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
await MovieRepository.Update(model);
|
||||
}
|
||||
|
||||
var result = await RunSpecificRule(model, SpecificRules.CanSendNotification, requestOnBehalf);
|
||||
if (result.Success)
|
||||
|
|
|
@ -793,7 +793,7 @@ namespace Ombi.Core.Engine
|
|||
return await TvRepository.GetChild().AnyAsync(x => x.RequestedUserId == userId);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> MarkUnavailable(int modelId)
|
||||
public async Task<RequestEngineResult> MarkUnavailable(int modelId, bool is4K)
|
||||
{
|
||||
var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == modelId);
|
||||
if (request == null)
|
||||
|
@ -821,7 +821,7 @@ namespace Ombi.Core.Engine
|
|||
};
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> MarkAvailable(int modelId)
|
||||
public async Task<RequestEngineResult> MarkAvailable(int modelId, bool is4K)
|
||||
{
|
||||
ChildRequests request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == modelId);
|
||||
if (request == null)
|
||||
|
@ -918,7 +918,7 @@ namespace Ombi.Core.Engine
|
|||
return await AfterRequest(model.ChildRequests.FirstOrDefault(), requestOnBehalf);
|
||||
}
|
||||
|
||||
public async Task<RequestEngineResult> ReProcessRequest(int requestId, CancellationToken cancellationToken)
|
||||
public async Task<RequestEngineResult> ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == requestId, cancellationToken);
|
||||
if (request == null)
|
||||
|
|
|
@ -406,6 +406,13 @@ namespace Ombi.Core.Engine.V2
|
|||
mapped.Subscribed = viewMovie.Subscribed;
|
||||
mapped.ShowSubscribe = viewMovie.ShowSubscribe;
|
||||
mapped.DigitalReleaseDate = viewMovie.DigitalReleaseDate;
|
||||
mapped.RequestedDate4k = viewMovie.RequestedDate4k;
|
||||
mapped.Approved4K = viewMovie.Approved4K;
|
||||
mapped.Available4K = viewMovie.Available4K;
|
||||
mapped.Denied4K = viewMovie.Denied4K;
|
||||
mapped.DeniedReason4K = viewMovie.DeniedReason4K;
|
||||
mapped.Has4KRequest = viewMovie.Has4KRequest;
|
||||
|
||||
|
||||
return mapped;
|
||||
}
|
||||
|
|
|
@ -193,7 +193,7 @@ namespace Ombi.Core.Engine
|
|||
case RequestType.Movie:
|
||||
if (totalVotes >= voteSettings.MovieVoteMax)
|
||||
{
|
||||
result = await _movieRequestEngine.ApproveMovieById(requestId);
|
||||
result = await _movieRequestEngine.ApproveMovieById(requestId, false);
|
||||
}
|
||||
break;
|
||||
case RequestType.Album:
|
||||
|
|
|
@ -34,6 +34,8 @@ namespace Ombi.Core.Models.Requests
|
|||
public int TheMovieDbId { get; set; }
|
||||
public string LanguageCode { get; set; } = "en";
|
||||
|
||||
public bool Is4kRequest { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is only set from a HTTP Header
|
||||
/// </summary>
|
||||
|
|
|
@ -28,5 +28,14 @@ namespace Ombi.Core.Models.Search
|
|||
public override RequestType Type => RequestType.Movie;
|
||||
public ReleaseDatesDto ReleaseDates { get; set; }
|
||||
public DateTime? DigitalReleaseDate { get; set; }
|
||||
public bool Has4KRequest { get; set; }
|
||||
public bool Approved4K { get; set; }
|
||||
public DateTime MarkedAsApproved4K { get; set; }
|
||||
public DateTime RequestedDate4k { get; set; }
|
||||
public bool Available4K { get; set; }
|
||||
public DateTime? MarkedAsAvailable4K { get; set; }
|
||||
public bool? Denied4K { get; set; }
|
||||
public DateTime MarkedAsDenied4K { get; set; }
|
||||
public string DeniedReason4K { get; set; }
|
||||
}
|
||||
}
|
|
@ -41,6 +41,15 @@ namespace Ombi.Core.Models.Search.V2
|
|||
public Recommendations Recommendations { get; set; }
|
||||
public ExternalIds ExternalIds { get; set; }
|
||||
public Keywords Keywords { get; set; }
|
||||
public bool Has4KRequest { get; set; }
|
||||
public bool Approved4K { get; set; }
|
||||
public DateTime MarkedAsApproved4K { get; set; }
|
||||
public DateTime RequestedDate4k { get; set; }
|
||||
public bool Available4K { get; set; }
|
||||
public DateTime? MarkedAsAvailable4K { get; set; }
|
||||
public bool? Denied4K { get; set; }
|
||||
public DateTime MarkedAsDenied4K { get; set; }
|
||||
public string DeniedReason4K { get; set; }
|
||||
}
|
||||
public class Keywords
|
||||
{
|
||||
|
|
|
@ -5,7 +5,9 @@ using Microsoft.EntityFrameworkCore;
|
|||
using Ombi.Core.Authentication;
|
||||
using Ombi.Core.Models.Requests;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
|
||||
|
@ -13,32 +15,57 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
{
|
||||
public class AutoApproveRule : BaseRequestRule, IRules<BaseRequest>
|
||||
{
|
||||
public AutoApproveRule(IPrincipal principal, OmbiUserManager um)
|
||||
public AutoApproveRule(IPrincipal principal, OmbiUserManager um, IFeatureService featureService)
|
||||
{
|
||||
User = principal;
|
||||
_manager = um;
|
||||
_featureService = featureService;
|
||||
}
|
||||
|
||||
private IPrincipal User { get; }
|
||||
private readonly OmbiUserManager _manager;
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
public async Task<RuleResult> Execute(BaseRequest obj)
|
||||
{
|
||||
var username = User.Identity.Name.ToUpper();
|
||||
var user = await _manager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username);
|
||||
if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser)
|
||||
{
|
||||
if (obj is MovieRequests movie)
|
||||
{
|
||||
await Check4K(movie);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.Approved = true;
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
|
||||
if (obj.RequestType == RequestType.Movie && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie))
|
||||
obj.Approved = true;
|
||||
{
|
||||
var movie = (MovieRequests)obj;
|
||||
await Check4K(movie);
|
||||
}
|
||||
if (obj.RequestType == RequestType.TvShow && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveTv))
|
||||
obj.Approved = true;
|
||||
if (obj.RequestType == RequestType.Album && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMusic))
|
||||
obj.Approved = true;
|
||||
return Success(); // We don't really care, we just don't set the obj to approve
|
||||
}
|
||||
|
||||
private async Task Check4K(MovieRequests movie)
|
||||
{
|
||||
var featureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests);
|
||||
if (movie.Is4kRequest && featureEnabled)
|
||||
{
|
||||
movie.Approved4K = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
movie.Approved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,8 +33,23 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
|
||||
if (obj.RequestType == RequestType.Movie)
|
||||
{
|
||||
if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMovie) || await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie))
|
||||
var movie = (MovieRequests)obj;
|
||||
var hasAutoApprove = await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie);
|
||||
if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMovie) || hasAutoApprove)
|
||||
{
|
||||
if (movie.Is4kRequest && !hasAutoApprove)
|
||||
{
|
||||
var has4kPermission = await _manager.IsInRoleAsync(user, OmbiRoles.Request4KMovie);
|
||||
if (has4kPermission)
|
||||
{
|
||||
return Success();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Success();
|
||||
}
|
||||
}
|
||||
return Fail(ErrorCode.NoPermissionsRequestMovie, "You do not have permissions to Request a Movie");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,24 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Core.Rule.Interfaces;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Core.Engine;
|
||||
using Ombi.Store.Repository.Requests;
|
||||
using Ombi.Core.Services;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
|
||||
namespace Ombi.Core.Rule.Rules.Request
|
||||
{
|
||||
public class ExistingMovieRequestRule : BaseRequestRule, IRules<BaseRequest>
|
||||
{
|
||||
public ExistingMovieRequestRule(IMovieRequestRepository movie)
|
||||
private readonly IFeatureService _featureService;
|
||||
|
||||
public ExistingMovieRequestRule(IMovieRequestRepository movie, IFeatureService featureService)
|
||||
{
|
||||
Movie = movie;
|
||||
_featureService = featureService;
|
||||
}
|
||||
|
||||
private IMovieRequestRepository Movie { get; }
|
||||
|
@ -35,7 +38,7 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
var existing = await movieRequests.FirstOrDefaultAsync(x => x.TheMovieDbId == movie.TheMovieDbId);
|
||||
if (existing != null) // Do we already have a request for this?
|
||||
{
|
||||
found = true;
|
||||
found = await Check4KRequests(movie, existing);
|
||||
}
|
||||
|
||||
if (!found && movie.ImdbId.HasValue())
|
||||
|
@ -45,7 +48,7 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
x.ImdbId == movie.ImdbId);
|
||||
if (existing != null)
|
||||
{
|
||||
found = true;
|
||||
found = await Check4KRequests(movie, existing);
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
|
@ -55,5 +58,20 @@ namespace Ombi.Core.Rule.Rules.Request
|
|||
}
|
||||
return Success();
|
||||
}
|
||||
|
||||
private async Task<bool> Check4KRequests(MovieRequests movie, MovieRequests existing)
|
||||
{
|
||||
var featureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests);
|
||||
if (movie.Is4kRequest && existing.Has4KRequest && featureEnabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (!movie.Is4kRequest && !existing.Has4KRequest || !featureEnabled)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,9 +65,27 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
}
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
if (obj is SearchMovieViewModel movie)
|
||||
{
|
||||
if (item.Has4K)
|
||||
{
|
||||
movie.Available4K = true;
|
||||
obj.EmbyUrl = item.Url;
|
||||
}
|
||||
|
||||
if (item.Quality.HasValue())
|
||||
{
|
||||
obj.Available = true;
|
||||
obj.EmbyUrl = item.Url;
|
||||
obj.Quality = item.Quality;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.Available = true;
|
||||
obj.EmbyUrl = item.Url;
|
||||
}
|
||||
|
||||
if (obj.Type == RequestType.TvShow)
|
||||
{
|
||||
|
|
|
@ -26,17 +26,27 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
|
||||
public async Task<RuleResult> Execute(SearchViewModel obj)
|
||||
{
|
||||
if (obj.Type == RequestType.Movie)
|
||||
if (obj is SearchMovieViewModel movie)
|
||||
{
|
||||
var movieRequests = await Movie.GetRequestAsync(obj.Id);
|
||||
if (movieRequests != null) // Do we already have a request for this?
|
||||
{
|
||||
obj.Requested = true;
|
||||
obj.RequestId = movieRequests.Id;
|
||||
obj.Approved = movieRequests.Approved;
|
||||
obj.Denied = movieRequests.Denied ?? false;
|
||||
obj.DeniedReason = movieRequests.DeniedReason;
|
||||
obj.Available = movieRequests.Available;
|
||||
// If the RequestDate is a min value, that means there's only a 4k request
|
||||
movie.Requested = movieRequests.RequestedDate != DateTime.MinValue;
|
||||
movie.RequestId = movieRequests.Id;
|
||||
movie.Approved = movieRequests.Approved;
|
||||
movie.Denied = movieRequests.Denied ?? false;
|
||||
movie.DeniedReason = movieRequests.DeniedReason;
|
||||
movie.Available = movieRequests.Available;
|
||||
movie.Has4KRequest = movieRequests.Has4KRequest;
|
||||
movie.RequestedDate4k = movieRequests.RequestedDate4k;
|
||||
movie.Approved4K = movieRequests.Approved4K;
|
||||
movie.Available4K = movieRequests.Available4K;
|
||||
movie.Denied4K = movieRequests.Denied4K;
|
||||
movie.DeniedReason4K = movieRequests.DeniedReason4K;
|
||||
movie.MarkedAsApproved4K = movieRequests.MarkedAsApproved4K;
|
||||
movie.MarkedAsAvailable4K = movieRequests.MarkedAsAvailable4K;
|
||||
movie.MarkedAsDenied4K = movieRequests.MarkedAsDenied4K;
|
||||
|
||||
return Success();
|
||||
}
|
||||
|
|
|
@ -80,8 +80,26 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
obj.TheMovieDbId = obj.Id.ToString();
|
||||
useTheMovieDb = true;
|
||||
}
|
||||
if (obj is SearchMovieViewModel movie)
|
||||
{
|
||||
if (item.Has4K)
|
||||
{
|
||||
movie.Available4K = true;
|
||||
obj.JellyfinUrl = item.Url;
|
||||
}
|
||||
|
||||
if (item.Quality.HasValue())
|
||||
{
|
||||
obj.Available = true;
|
||||
obj.EmbyUrl = item.Url;
|
||||
obj.Quality = item.Quality;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.Available = true;
|
||||
obj.JellyfinUrl = item.Url;
|
||||
}
|
||||
|
||||
if (obj.Type == RequestType.TvShow)
|
||||
{
|
||||
|
|
|
@ -89,7 +89,25 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
obj.TheMovieDbId = obj.Id.ToString();
|
||||
useTheMovieDb = true;
|
||||
}
|
||||
|
||||
if (obj is SearchMovieViewModel movie)
|
||||
{
|
||||
if (item.Has4K)
|
||||
{
|
||||
movie.Available4K = true;
|
||||
}
|
||||
|
||||
if (item.Quality.HasValue())
|
||||
{
|
||||
obj.Available = true;
|
||||
obj.Quality = item.Quality;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
obj.Available = true;
|
||||
}
|
||||
|
||||
if (item.Url.StartsWith("http"))
|
||||
{
|
||||
obj.PlexUrl = item.Url;
|
||||
|
@ -99,11 +117,9 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
// legacy content
|
||||
obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host);
|
||||
}
|
||||
obj.Quality = item.Quality;
|
||||
|
||||
if (obj.Type == RequestType.TvShow)
|
||||
if (obj is SearchTvShowViewModel search)
|
||||
{
|
||||
var search = (SearchTvShowViewModel)obj;
|
||||
// Let's go through the episodes now
|
||||
if (search.SeasonRequests.Any())
|
||||
{
|
||||
|
|
|
@ -18,16 +18,23 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
|
||||
public Task<RuleResult> Execute(SearchViewModel obj)
|
||||
{
|
||||
if (obj.Type == RequestType.Movie)
|
||||
if (obj is SearchMovieViewModel movie)
|
||||
{
|
||||
// Check if it's in Radarr
|
||||
var result = _db.GetAll().FirstOrDefault(x => x.TheMovieDbId == obj.Id);
|
||||
if (result != null)
|
||||
{
|
||||
obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something?
|
||||
movie.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something?
|
||||
if (result.HasFile)
|
||||
{
|
||||
obj.Available = true;
|
||||
if (result.Has4K)
|
||||
{
|
||||
movie.Available4K = true;
|
||||
}
|
||||
if (result.HasRegular)
|
||||
{
|
||||
movie.Available = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,6 @@ namespace Ombi.Core
|
|||
{
|
||||
public interface IMovieSender
|
||||
{
|
||||
Task<SenderResult> Send(MovieRequests model);
|
||||
Task<SenderResult> Send(MovieRequests model, bool is4K);
|
||||
}
|
||||
}
|
|
@ -20,13 +20,12 @@ namespace Ombi.Core.Senders
|
|||
{
|
||||
public class MovieSender : IMovieSender
|
||||
{
|
||||
public MovieSender(ISettingsService<RadarrSettings> radarrSettings, IRadarrApi api, ILogger<MovieSender> log,
|
||||
public MovieSender(ISettingsService<RadarrSettings> radarrSettings, ISettingsService<Radarr4KSettings> radarr4kSettings, ILogger<MovieSender> log,
|
||||
ISettingsService<DogNzbSettings> dogSettings, IDogNzbApi dogApi, ISettingsService<CouchPotatoSettings> cpSettings,
|
||||
ICouchPotatoApi cpApi, IRepository<UserQualityProfiles> userProfiles, IRepository<RequestQueue> requestQueue, INotificationHelper notify,
|
||||
IRadarrV3Api radarrV3Api)
|
||||
{
|
||||
_radarrSettings = radarrSettings;
|
||||
_radarrV2Api = api;
|
||||
_log = log;
|
||||
_dogNzbSettings = dogSettings;
|
||||
_dogNzbApi = dogApi;
|
||||
|
@ -36,10 +35,11 @@ namespace Ombi.Core.Senders
|
|||
_requestQueuRepository = requestQueue;
|
||||
_notificationHelper = notify;
|
||||
_radarrV3Api = radarrV3Api;
|
||||
_radarr4KSettings = radarr4kSettings;
|
||||
}
|
||||
|
||||
private readonly ISettingsService<RadarrSettings> _radarrSettings;
|
||||
private readonly IRadarrApi _radarrV2Api;
|
||||
private readonly ISettingsService<Radarr4KSettings> _radarr4KSettings;
|
||||
private readonly ILogger<MovieSender> _log;
|
||||
private readonly IDogNzbApi _dogNzbApi;
|
||||
private readonly ISettingsService<DogNzbSettings> _dogNzbSettings;
|
||||
|
@ -50,16 +50,24 @@ namespace Ombi.Core.Senders
|
|||
private readonly INotificationHelper _notificationHelper;
|
||||
private readonly IRadarrV3Api _radarrV3Api;
|
||||
|
||||
public async Task<SenderResult> Send(MovieRequests model)
|
||||
public async Task<SenderResult> Send(MovieRequests model, bool is4K)
|
||||
{
|
||||
try
|
||||
{
|
||||
var cpSettings = await _couchPotatoSettings.GetSettingsAsync();
|
||||
//var watcherSettings = await WatcherSettings.GetSettingsAsync();
|
||||
var radarrSettings = await _radarrSettings.GetSettingsAsync();
|
||||
|
||||
RadarrSettings radarrSettings;
|
||||
if (is4K)
|
||||
{
|
||||
radarrSettings = await _radarr4KSettings.GetSettingsAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
radarrSettings = await _radarrSettings.GetSettingsAsync();
|
||||
}
|
||||
if (radarrSettings.Enabled)
|
||||
{
|
||||
return await SendToRadarr(model, radarrSettings);
|
||||
return await SendToRadarr(model, is4K, radarrSettings);
|
||||
}
|
||||
|
||||
var dogSettings = await _dogNzbSettings.GetSettingsAsync();
|
||||
|
@ -123,7 +131,7 @@ namespace Ombi.Core.Senders
|
|||
return await _dogNzbApi.AddMovie(settings.ApiKey, id);
|
||||
}
|
||||
|
||||
private async Task<SenderResult> SendToRadarr(MovieRequests model, RadarrSettings settings)
|
||||
private async Task<SenderResult> SendToRadarr(MovieRequests model, bool is4K, RadarrSettings settings)
|
||||
{
|
||||
var qualityToUse = int.Parse(settings.DefaultQualityProfile);
|
||||
|
||||
|
|
28
src/Ombi.Core/Services/FeatureService.cs
Normal file
28
src/Ombi.Core/Services/FeatureService.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using Ombi.Core.Settings;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Core.Services
|
||||
{
|
||||
public interface IFeatureService
|
||||
{
|
||||
Task<bool> FeatureEnabled(string featureName);
|
||||
}
|
||||
|
||||
public class FeatureService : IFeatureService
|
||||
{
|
||||
private readonly ISettingsService<FeatureSettings> _featureSettings;
|
||||
|
||||
public FeatureService(ISettingsService<FeatureSettings> featureSettings)
|
||||
{
|
||||
_featureSettings = featureSettings;
|
||||
}
|
||||
|
||||
public async Task<bool> FeatureEnabled(string featureName)
|
||||
{
|
||||
var settings = await _featureSettings.GetSettingsAsync();
|
||||
return settings.Features?.Where(x => x.Name.Equals(featureName, System.StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Enabled)?.FirstOrDefault() ?? false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -224,6 +224,7 @@ namespace Ombi.DependencyInjection
|
|||
services.AddTransient<ITelegramNotification, TelegramNotification>();
|
||||
services.AddTransient<ILegacyMobileNotification, LegacyMobileNotification>();
|
||||
services.AddTransient<IChangeLogProcessor, ChangeLogProcessor>();
|
||||
services.AddScoped<IFeatureService, FeatureService>();
|
||||
}
|
||||
|
||||
public static void RegisterJobs(this IServiceCollection services)
|
||||
|
|
|
@ -16,5 +16,6 @@
|
|||
public const string ReceivesNewsletter = nameof(ReceivesNewsletter);
|
||||
public const string ManageOwnRequests = nameof(ManageOwnRequests);
|
||||
public const string EditCustomPage = nameof(EditCustomPage);
|
||||
public const string Request4KMovie = nameof(Request4KMovie);
|
||||
}
|
||||
}
|
|
@ -140,5 +140,81 @@ namespace Ombi.Schedule.Tests
|
|||
|
||||
_mocker.Verify<IPlexApi>(x => x.GetMetadata(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<int>()), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task UpdatesExistingMovieWhen_WeFindAnotherQuality()
|
||||
{
|
||||
var content = new Mediacontainer
|
||||
{
|
||||
Metadata = new[]
|
||||
{
|
||||
new Metadata
|
||||
{
|
||||
ratingKey = 11,
|
||||
title = "test1",
|
||||
year = 2021,
|
||||
type = "movie",
|
||||
Media = new Medium[1]
|
||||
{
|
||||
new Medium
|
||||
{
|
||||
videoResolution = "4k"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
var contentToAdd = new HashSet<PlexServerContent>();
|
||||
var contentProcessed = new Dictionary<int, int>();
|
||||
_mocker.Setup<IPlexContentRepository>(x =>
|
||||
x.GetFirstContentByCustom(It.IsAny<Expression<Func<PlexServerContent, bool>>>()))
|
||||
.Returns(Task.FromResult(new PlexServerContent
|
||||
{
|
||||
Quality = "1080"
|
||||
}));
|
||||
|
||||
await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed);
|
||||
|
||||
Assert.That(contentToAdd, Is.Empty);
|
||||
_mocker.Verify<IPlexContentRepository>(x => x.Update(It.Is<PlexServerContent>(x => x.Quality == "1080" && x.Has4K)), Times.Once);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DoesNotUpdatesExistingMovieWhen_WeFindSameQuality()
|
||||
{
|
||||
var content = new Mediacontainer
|
||||
{
|
||||
Metadata = new[]
|
||||
{
|
||||
new Metadata
|
||||
{
|
||||
ratingKey = 11,
|
||||
title = "test1",
|
||||
year = 2021,
|
||||
type = "movie",
|
||||
Media = new Medium[1]
|
||||
{
|
||||
new Medium
|
||||
{
|
||||
videoResolution = "1080"
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
var contentToAdd = new HashSet<PlexServerContent>();
|
||||
var contentProcessed = new Dictionary<int, int>();
|
||||
_mocker.Setup<IPlexContentRepository>(x =>
|
||||
x.GetFirstContentByCustom(It.IsAny<Expression<Func<PlexServerContent, bool>>>()))
|
||||
.Returns(Task.FromResult(new PlexServerContent
|
||||
{
|
||||
Quality = "1080"
|
||||
}));
|
||||
|
||||
await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed);
|
||||
|
||||
Assert.That(contentToAdd, Is.Empty);
|
||||
_mocker.Verify<IPlexContentRepository>(x => x.Update(It.IsAny<PlexServerContent>()), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,10 +53,11 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
|
||||
private async Task ProcessMovies()
|
||||
{
|
||||
var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available);
|
||||
var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest));
|
||||
|
||||
foreach (var movie in movies)
|
||||
{
|
||||
var has4kRequest = movie.Has4KRequest;
|
||||
EmbyContent embyContent = null;
|
||||
if (movie.TheMovieDbId > 0)
|
||||
{
|
||||
|
@ -75,8 +76,18 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
|
||||
_log.LogInformation("We have found the request {0} on Emby, sending the notification", movie?.Title ?? string.Empty);
|
||||
|
||||
if (has4kRequest && embyContent.Has4K)
|
||||
{
|
||||
movie.Available4K = true;
|
||||
movie.MarkedAsAvailable4K = DateTime.Now;
|
||||
}
|
||||
|
||||
// If we have a non-4k versison then mark as available
|
||||
if (embyContent.Quality.HasValue())
|
||||
{
|
||||
movie.Available = true;
|
||||
movie.MarkedAsAvailable = DateTime.Now;
|
||||
}
|
||||
if (movie.Available)
|
||||
{
|
||||
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
@ -209,6 +210,7 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
var totalCount = movies.TotalRecordCount;
|
||||
var processed = 0;
|
||||
var mediaToAdd = new HashSet<EmbyContent>();
|
||||
var mediaToUpdate = new HashSet<EmbyContent>();
|
||||
while (processed < totalCount)
|
||||
{
|
||||
foreach (var movie in movies.Items)
|
||||
|
@ -219,13 +221,13 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri);
|
||||
foreach (var item in movieInfo.Items)
|
||||
{
|
||||
await ProcessMovies(item, mediaToAdd, server);
|
||||
await ProcessMovies(item, mediaToAdd, mediaToUpdate, server);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Regular movie
|
||||
await ProcessMovies(movie, mediaToAdd, server);
|
||||
await ProcessMovies(movie, mediaToAdd, mediaToUpdate, server);
|
||||
}
|
||||
|
||||
processed++;
|
||||
|
@ -238,24 +240,32 @@ namespace Ombi.Schedule.Jobs.Emby
|
|||
movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, AmountToTake, server.AdministratorId, server.FullUri);
|
||||
}
|
||||
await _repo.AddRange(mediaToAdd);
|
||||
await _repo.UpdateRange(mediaToUpdate);
|
||||
mediaToAdd.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessMovies(EmbyMovie movieInfo, ICollection<EmbyContent> content, EmbyServers server)
|
||||
private async Task ProcessMovies(EmbyMovie movieInfo, ICollection<EmbyContent> content, ICollection<EmbyContent> toUpdate, EmbyServers server)
|
||||
{
|
||||
var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty;
|
||||
var has4K = false;
|
||||
if (quality.Contains("4K", CompareOptions.IgnoreCase))
|
||||
{
|
||||
has4K = true;
|
||||
}
|
||||
|
||||
// Check if it exists
|
||||
var existingMovie = await _repo.GetByEmbyId(movieInfo.Id);
|
||||
var alreadyGoingToAdd = content.Any(x => x.EmbyId == movieInfo.Id);
|
||||
if (existingMovie == null && !alreadyGoingToAdd)
|
||||
{
|
||||
|
||||
if (!movieInfo.ProviderIds.Any())
|
||||
{
|
||||
_logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping.");
|
||||
return;
|
||||
}
|
||||
_logger.LogDebug("Adding new movie {0}", movieInfo.Name);
|
||||
_logger.LogDebug($"Adding new movie {movieInfo.Name}");
|
||||
|
||||
content.Add(new EmbyContent
|
||||
{
|
||||
ImdbId = movieInfo.ProviderIds.Imdb,
|
||||
|
@ -264,13 +274,26 @@ 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 = has4K ? null : quality,
|
||||
Has4K = has4K
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!existingMovie.Quality.Equals(quality, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
_logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'");
|
||||
existingMovie.Quality = has4K ? null : quality;
|
||||
existingMovie.Has4K = has4K;
|
||||
|
||||
toUpdate.Add(existingMovie);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have this
|
||||
_logger.LogDebug("We already have movie {0}", movieInfo.Name);
|
||||
_logger.LogDebug($"We already have movie {movieInfo.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,10 +80,11 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
|
||||
private async Task ProcessMovies()
|
||||
{
|
||||
var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available);
|
||||
var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest));
|
||||
|
||||
foreach (var movie in movies)
|
||||
{
|
||||
var has4kRequest = movie.Has4KRequest;
|
||||
JellyfinContent jellyfinContent = null;
|
||||
if (movie.TheMovieDbId > 0)
|
||||
{
|
||||
|
@ -102,8 +103,19 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
|
||||
_log.LogInformation("We have found the request {0} on Jellyfin, sending the notification", movie?.Title ?? string.Empty);
|
||||
|
||||
if (has4kRequest && jellyfinContent.Has4K)
|
||||
{
|
||||
movie.Available4K = true;
|
||||
movie.MarkedAsAvailable4K = DateTime.Now;
|
||||
}
|
||||
|
||||
// If we have a non-4k versison then mark as available
|
||||
if (jellyfinContent.Quality.HasValue())
|
||||
{
|
||||
movie.Available = true;
|
||||
movie.MarkedAsAvailable = DateTime.Now;
|
||||
}
|
||||
|
||||
if (movie.Available)
|
||||
{
|
||||
var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
|
@ -77,9 +78,6 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
return;
|
||||
}
|
||||
|
||||
//await _repo.ExecuteSql("DELETE FROM JellyfinEpisode");
|
||||
//await _repo.ExecuteSql("DELETE FROM JellyfinContent");
|
||||
|
||||
if (server.JellyfinSelectedLibraries.Any() && server.JellyfinSelectedLibraries.Any(x => x.Enabled))
|
||||
{
|
||||
var movieLibsToFilter = server.JellyfinSelectedLibraries.Where(x => x.Enabled && x.CollectionType == "movies");
|
||||
|
@ -179,6 +177,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
var totalCount = movies.TotalRecordCount;
|
||||
var processed = 0;
|
||||
var mediaToAdd = new HashSet<JellyfinContent>();
|
||||
var mediaToUpdate = new HashSet<JellyfinContent>();
|
||||
while (processed < totalCount)
|
||||
{
|
||||
foreach (var movie in movies.Items)
|
||||
|
@ -189,7 +188,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri);
|
||||
foreach (var item in movieInfo.Items)
|
||||
{
|
||||
await ProcessMovies(item, mediaToAdd, server);
|
||||
await ProcessMovies(item, mediaToAdd, mediaToUpdate, server);
|
||||
}
|
||||
|
||||
processed++;
|
||||
|
@ -198,20 +197,28 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
{
|
||||
processed++;
|
||||
// Regular movie
|
||||
await ProcessMovies(movie, mediaToAdd, server);
|
||||
await ProcessMovies(movie, mediaToAdd, mediaToUpdate, server);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next batch
|
||||
movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, 200, server.AdministratorId, server.FullUri);
|
||||
await _repo.AddRange(mediaToAdd);
|
||||
await _repo.UpdateRange(mediaToUpdate);
|
||||
mediaToAdd.Clear();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection<JellyfinContent> content, JellyfinServers server)
|
||||
private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection<JellyfinContent> content, ICollection<JellyfinContent> toUpdate, JellyfinServers server)
|
||||
{
|
||||
var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty;
|
||||
var has4K = false;
|
||||
if (quality.Contains("4K", CompareOptions.IgnoreCase))
|
||||
{
|
||||
has4K = true;
|
||||
}
|
||||
|
||||
// Check if it exists
|
||||
var existingMovie = await _repo.GetByJellyfinId(movieInfo.Id);
|
||||
var alreadyGoingToAdd = content.Any(x => x.JellyfinId == movieInfo.Id);
|
||||
|
@ -222,7 +229,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
_logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping.");
|
||||
return;
|
||||
}
|
||||
_logger.LogDebug("Adding new movie {0}", movieInfo.Name);
|
||||
_logger.LogDebug($"Adding new movie {movieInfo.Name}");
|
||||
content.Add(new JellyfinContent
|
||||
{
|
||||
ImdbId = movieInfo.ProviderIds.Imdb,
|
||||
|
@ -231,13 +238,26 @@ namespace Ombi.Schedule.Jobs.Jellyfin
|
|||
Type = MediaType.Movie,
|
||||
JellyfinId = movieInfo.Id,
|
||||
Url = JellyfinHelper.GetJellyfinMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname),
|
||||
AddedAt = DateTime.UtcNow
|
||||
AddedAt = DateTime.UtcNow,
|
||||
Quality = has4K ? null : quality,
|
||||
Has4K = has4K
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!existingMovie.Quality.Equals(quality, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
_logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'");
|
||||
existingMovie.Quality = has4K ? null : quality;
|
||||
existingMovie.Has4K = has4K;
|
||||
|
||||
toUpdate.Add(existingMovie);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have this
|
||||
_logger.LogDebug("We already have movie {0}", movieInfo.Name);
|
||||
_logger.LogDebug($"We already have movie {movieInfo.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
_ombiSettings = ombiSettings;
|
||||
_movieRequests = movieRequest;
|
||||
_tvRequestRepository = tvRequestRepository;
|
||||
_musicRequestRepository = _musicRequestRepository;
|
||||
_musicRequestRepository = musicRequestRepository;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,9 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
await _requestQueue.SaveChangesAsync();
|
||||
continue;
|
||||
}
|
||||
var result = await _movieSender.Send(movieRequest);
|
||||
|
||||
// TODO probably need to add something to the request queue to better idenitfy if it's a 4k request
|
||||
var result = await _movieSender.Send(movieRequest, movieRequest.Approved4K);
|
||||
if (result.Success)
|
||||
{
|
||||
request.Completed = DateTime.UtcNow;
|
||||
|
|
|
@ -180,16 +180,12 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
private async Task ProcessMovies()
|
||||
{
|
||||
// Get all non available
|
||||
var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available);
|
||||
var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest));
|
||||
var itemsForAvailbility = new List<AvailabilityModel>();
|
||||
|
||||
foreach (var movie in movies)
|
||||
{
|
||||
if (movie.Available)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var has4kRequest = movie.Has4KRequest;
|
||||
PlexServerContent item = null;
|
||||
if (movie.ImdbId.HasValue())
|
||||
{
|
||||
|
@ -208,9 +204,23 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
continue;
|
||||
}
|
||||
|
||||
_log.LogInformation("[PAC] - Movie request {0} is now available, sending notification", $"{movie.Title} - {movie.Id}");
|
||||
_log.LogInformation($"[PAC] - Movie request {movie.Title} - {movie.Id} is now available, sending notification");
|
||||
|
||||
if (has4kRequest && item.Has4K)
|
||||
{
|
||||
movie.Available4K = true;
|
||||
movie.Approved4K = true;
|
||||
movie.MarkedAsAvailable4K = DateTime.Now;
|
||||
}
|
||||
|
||||
// If we have a non-4k versison then mark as available
|
||||
if (item.Quality.HasValue())
|
||||
{
|
||||
movie.Available = true;
|
||||
movie.MarkedAsAvailable = DateTime.UtcNow;
|
||||
movie.Approved = true;
|
||||
movie.MarkedAsAvailable = DateTime.Now;
|
||||
}
|
||||
|
||||
itemsForAvailbility.Add(new AvailabilityModel
|
||||
{
|
||||
Id = movie.Id,
|
||||
|
@ -222,9 +232,9 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
{
|
||||
await _movieRepo.SaveChangesAsync();
|
||||
}
|
||||
foreach (var i in itemsForAvailbility)
|
||||
{
|
||||
|
||||
foreach (var i in itemsForAvailbility.DistinctBy(x => x.Id))
|
||||
{
|
||||
await _notificationService.Notify(new NotificationOptions
|
||||
{
|
||||
DateTime = DateTime.Now,
|
||||
|
@ -234,8 +244,6 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
Recipient = i.RequestedUser
|
||||
});
|
||||
}
|
||||
|
||||
//await _repo.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private bool _disposed;
|
||||
|
|
|
@ -293,7 +293,7 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
Dictionary<int, int> contentProcessed)
|
||||
{
|
||||
Logger.LogDebug("Processing Movies");
|
||||
foreach (var movie in content?.Metadata ?? new Metadata[] { })
|
||||
foreach (var movie in content?.Metadata ?? Array.Empty<Metadata>())
|
||||
{
|
||||
// Let's check if we have this movie
|
||||
|
||||
|
@ -302,11 +302,31 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title
|
||||
&& x.ReleaseYear == movie.year.ToString()
|
||||
&& x.Type == MediaType.Movie);
|
||||
// The rating key keeps changing
|
||||
//var existing = await Repo.GetByKey(movie.ratingKey);
|
||||
if (existing != null)
|
||||
{
|
||||
Logger.LogDebug("We already have movie {0}", movie.title);
|
||||
// We need to see if this is a different quality,
|
||||
// We want to know if this is a 4k content for example
|
||||
var foundQualities = movie.Media?.Select(x => x.videoResolution);
|
||||
|
||||
foreach (var quality in foundQualities)
|
||||
{
|
||||
if (quality.Equals(existing.Quality))
|
||||
{
|
||||
// We got it
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't have this quality
|
||||
if (quality.Equals("4k", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
Logger.LogDebug($"We already have movie {movie.title}, But found a 4K version!");
|
||||
existing.Has4K = true;
|
||||
await Repo.Update(existing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Logger.LogDebug($"We already have movie {movie.title}");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -349,6 +369,10 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
}
|
||||
var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray());
|
||||
|
||||
var qualities = movie.Media?.Select(x => x.videoResolution);
|
||||
var is4k = qualities != null && qualities.Any(x => x.Equals("4k", StringComparison.InvariantCultureIgnoreCase));
|
||||
var selectedQuality = is4k ? string.Empty : qualities?.OrderBy(x => x)?.FirstOrDefault() ?? string.Empty;
|
||||
|
||||
var item = new PlexServerContent
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
|
@ -358,7 +382,8 @@ namespace Ombi.Schedule.Jobs.Plex
|
|||
Title = movie.title,
|
||||
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey, servers.ServerHostname),
|
||||
Seasons = new List<PlexSeasonsContent>(),
|
||||
Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty
|
||||
Quality = selectedQuality,
|
||||
Has4K = is4k,
|
||||
};
|
||||
if (providerIds.ImdbId.HasValue())
|
||||
{
|
||||
|
|
|
@ -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<IEnumerable<RadarrCache>> GetCachedContent();
|
||||
}
|
||||
}
|
|
@ -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,53 +9,67 @@ 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<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;
|
||||
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> RadarrSettings { get; }
|
||||
private IRadarrV3Api RadarrApi { get; }
|
||||
private ILogger<RadarrSync> Logger { get; }
|
||||
private readonly ISettingsService<RadarrSettings> _radarrSettings;
|
||||
private readonly ISettingsService<Radarr4KSettings> _radarr4kSettings;
|
||||
private readonly IRadarrV3Api _api;
|
||||
private readonly ILogger<RadarrSync> _logger;
|
||||
private readonly ExternalContext _ctx;
|
||||
|
||||
private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1);
|
||||
private readonly IExternalRepository<RadarrCache> _radarrRepo;
|
||||
|
||||
public async Task Execute(IJobExecutionContext job)
|
||||
{
|
||||
await SemaphoreSlim.WaitAsync();
|
||||
try
|
||||
{
|
||||
var settings = await RadarrSettings.GetSettingsAsync();
|
||||
if (settings.Enabled)
|
||||
{
|
||||
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())
|
||||
{
|
||||
using var tran = await _ctx.Database.BeginTransactionAsync();
|
||||
await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM RadarrCache");
|
||||
tran.Commit();
|
||||
}
|
||||
});
|
||||
|
||||
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<RadarrCache>();
|
||||
foreach (var m in movies)
|
||||
{
|
||||
|
@ -64,53 +77,47 @@ namespace Ombi.Schedule.Jobs.Radarr
|
|||
{
|
||||
if (m.tmdbId > 0)
|
||||
{
|
||||
movieIds.Add(new RadarrCache
|
||||
var is4k = m.movieFile?.quality?.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)
|
||||
{
|
||||
TheMovieDbId = m.tmdbId,
|
||||
HasFile = m.hasFile
|
||||
});
|
||||
existing.Has4K = is4k;
|
||||
existing.HasFile = m.hasFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.LogError("TMDBId is not > 0 for movie {0}", m.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
strat = _ctx.Database.CreateExecutionStrategy();
|
||||
await strat.ExecuteAsync(async () =>
|
||||
movieIds.Add(new RadarrCache
|
||||
{
|
||||
using (var tran = await _ctx.Database.BeginTransactionAsync())
|
||||
{
|
||||
await _ctx.RadarrCache.AddRangeAsync(movieIds);
|
||||
|
||||
await _ctx.SaveChangesAsync();
|
||||
tran.Commit();
|
||||
}
|
||||
TheMovieDbId = m.tmdbId,
|
||||
HasFile = m.hasFile,
|
||||
Has4K = is4k,
|
||||
HasRegular = !is4k
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError($"TMDBId is not > 0 for movie {m.title}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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");
|
||||
_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;
|
||||
protected virtual void Dispose(bool disposing)
|
||||
|
|
|
@ -10,4 +10,15 @@
|
|||
public string MinimumAvailability { get; set; }
|
||||
public bool ScanForAvailability { get; set; }
|
||||
}
|
||||
|
||||
public class Radarr4KSettings : RadarrSettings
|
||||
{
|
||||
// no additional properties needed
|
||||
}
|
||||
|
||||
public class RadarrCombinedModel
|
||||
{
|
||||
public RadarrSettings Radarr { get; set; }
|
||||
public Radarr4KSettings Radarr4K { get; set; }
|
||||
}
|
||||
}
|
24
src/Ombi.Settings/Settings/Models/FeatureSettings.cs
Normal file
24
src/Ombi.Settings/Settings/Models/FeatureSettings.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Settings.Settings.Models
|
||||
{
|
||||
public class FeatureSettings : Settings
|
||||
{
|
||||
public List<FeatureEnablement> Features { get; set; }
|
||||
}
|
||||
|
||||
public class FeatureEnablement
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
|
||||
public static class FeatureNames
|
||||
{
|
||||
public const string Movie4KRequests = nameof(Movie4KRequests);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Ombi.Store.Entities;
|
||||
|
||||
namespace Ombi.Store.Context
|
||||
|
|
|
@ -12,7 +12,11 @@ namespace Ombi.Store.Entities
|
|||
public string TvDbId { get; set; }
|
||||
public string TheMovieDbId { get; set; }
|
||||
public MediaType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Only populated if it's not 4k
|
||||
/// </summary>
|
||||
public string Quality { get; set; }
|
||||
public bool Has4K { get; set; }
|
||||
public string Url { get; set; }
|
||||
|
||||
public ICollection<IMediaServerEpisode> Episodes { get; set; }
|
||||
|
|
|
@ -41,7 +41,6 @@ namespace Ombi.Store.Entities
|
|||
/// Plex's internal ID for this item
|
||||
/// </summary>
|
||||
public int Key { get; set; }
|
||||
public string Quality { get; set; }
|
||||
|
||||
public int? RequestId { get; set; }
|
||||
|
||||
|
|
|
@ -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; }
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Ombi.Store.Entities.Requests
|
||||
{
|
||||
|
@ -22,9 +23,28 @@ namespace Ombi.Store.Entities.Requests
|
|||
[NotMapped]
|
||||
public bool ShowSubscribe { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This is only used during the request process to identify if
|
||||
/// it's a regular request or a 4k
|
||||
/// </summary>
|
||||
[NotMapped]
|
||||
public bool Is4kRequest { get; set; }
|
||||
|
||||
public int RootPathOverride { get; set; }
|
||||
public int QualityOverride { get; set; }
|
||||
|
||||
public bool Has4KRequest { get; set; }
|
||||
|
||||
public bool Approved4K { get; set; }
|
||||
public DateTime MarkedAsApproved4K { get; set; }
|
||||
public DateTime RequestedDate4k { get; set; }
|
||||
public bool Available4K { get; set; }
|
||||
public DateTime? MarkedAsAvailable4K { get; set; }
|
||||
public bool? Denied4K { get; set; }
|
||||
public DateTime MarkedAsDenied4K { get; set; }
|
||||
public string DeniedReason4K { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Only Use for setting the Language Code, Use the LanguageCode property for reading
|
||||
/// </summary>
|
||||
|
|
24
src/Ombi.Store/MigrationHelper.cs
Normal file
24
src/Ombi.Store/MigrationHelper.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System;
|
||||
|
||||
namespace Ombi.Store
|
||||
{
|
||||
internal static class MigrationHelper
|
||||
{
|
||||
public static void InsertRole(this MigrationBuilder mb, string role)
|
||||
{
|
||||
mb.Sql($@"
|
||||
INSERT INTO AspnetRoles(Id, ConcurrencyStamp, Name, NormalizedName)
|
||||
SELECT '{Guid.NewGuid()}','{Guid.NewGuid()}','{role}', '{role.ToUpper()}'
|
||||
WHERE NOT EXISTS(SELECT 1 FROM AspnetRoles WHERE Name = '{role}');");
|
||||
}
|
||||
|
||||
public static void InsertRoleMySql(this MigrationBuilder mb, string role)
|
||||
{
|
||||
mb.Sql($@"
|
||||
INSERT INTO AspNetRoles(Id, ConcurrencyStamp, Name, NormalizedName)
|
||||
SELECT '{Guid.NewGuid()}','{Guid.NewGuid()}','{role}', '{role.ToUpper()}'
|
||||
WHERE NOT EXISTS(SELECT 1 FROM AspNetRoles WHERE Name = '{role}');");
|
||||
}
|
||||
}
|
||||
}
|
527
src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs
generated
Normal file
527
src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs
generated
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
536
src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs
generated
Normal file
536
src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs
generated
Normal file
|
@ -0,0 +1,536 @@
|
|||
// <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("20220212210902_MediaServer4k")]
|
||||
partial class MediaServer4k
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.0")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
|
||||
{
|
||||
b.Property<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<bool>("Has4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
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<bool>("Has4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
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<bool>("Has4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.ExternalMySql
|
||||
{
|
||||
public partial class MediaServer4k : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4K",
|
||||
table: "PlexServerContent",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4K",
|
||||
table: "JellyfinContent",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4K",
|
||||
table: "EmbyContent",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4K",
|
||||
table: "PlexServerContent");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4K",
|
||||
table: "JellyfinContent");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4K",
|
||||
table: "EmbyContent");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 =>
|
||||
{
|
||||
|
@ -44,12 +46,18 @@ namespace Ombi.Store.Migrations.ExternalMySql
|
|||
.IsRequired()
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.Property<bool>("Has4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("ProviderId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Quality")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TheMovieDbId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
|
@ -122,6 +130,9 @@ namespace Ombi.Store.Migrations.ExternalMySql
|
|||
b.Property<DateTime>("AddedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("Has4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
|
@ -132,6 +143,9 @@ namespace Ombi.Store.Migrations.ExternalMySql
|
|||
b.Property<string>("ProviderId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Quality")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TheMovieDbId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
|
@ -321,6 +335,9 @@ namespace Ombi.Store.Migrations.ExternalMySql
|
|||
b.Property<DateTime>("AddedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("Has4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
|
@ -362,9 +379,15 @@ namespace Ombi.Store.Migrations.ExternalMySql
|
|||
.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");
|
||||
|
||||
|
|
525
src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs
generated
Normal file
525
src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs
generated
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
534
src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs
generated
Normal file
534
src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs
generated
Normal file
|
@ -0,0 +1,534 @@
|
|||
// <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("20220212210807_MediaServer4k")]
|
||||
partial class MediaServer4k
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "6.0.0");
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
|
||||
{
|
||||
b.Property<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<bool>("Has4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
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<bool>("Has4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
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<bool>("Has4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.ExternalSqlite
|
||||
{
|
||||
public partial class MediaServer4k : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4K",
|
||||
table: "PlexServerContent",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4K",
|
||||
table: "JellyfinContent",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4K",
|
||||
table: "EmbyContent",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4K",
|
||||
table: "PlexServerContent");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4K",
|
||||
table: "JellyfinContent");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4K",
|
||||
table: "EmbyContent");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 =>
|
||||
{
|
||||
|
@ -43,12 +44,18 @@ namespace Ombi.Store.Migrations.ExternalSqlite
|
|||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Has4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("ProviderId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Quality")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TheMovieDbId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -121,6 +128,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite
|
|||
b.Property<DateTime>("AddedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Has4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -131,6 +141,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite
|
|||
b.Property<string>("ProviderId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Quality")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TheMovieDbId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -320,6 +333,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite
|
|||
b.Property<DateTime>("AddedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Has4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -361,9 +377,15 @@ namespace Ombi.Store.Migrations.ExternalSqlite
|
|||
.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");
|
||||
|
||||
|
|
1246
src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.Designer.cs
generated
Normal file
1246
src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Ombi.Helpers;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiMySql
|
||||
{
|
||||
public partial class Radarr4kRole : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.InsertRoleMySql(OmbiRoles.Request4KMovie);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
1249
src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.Designer.cs
generated
Normal file
1249
src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,26 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiMySql
|
||||
{
|
||||
public partial class MovieRequest4K : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4KRequest",
|
||||
table: "MovieRequests",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4KRequest",
|
||||
table: "MovieRequests");
|
||||
}
|
||||
}
|
||||
}
|
1273
src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.Designer.cs
generated
Normal file
1273
src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiMySql
|
||||
{
|
||||
public partial class _4kMovieProperties : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Approved4K",
|
||||
table: "MovieRequests",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Available4K",
|
||||
table: "MovieRequests",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Denied4K",
|
||||
table: "MovieRequests",
|
||||
type: "tinyint(1)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DeniedReason4K",
|
||||
table: "MovieRequests",
|
||||
type: "longtext",
|
||||
nullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "MarkedAsApproved4K",
|
||||
table: "MovieRequests",
|
||||
type: "datetime(6)",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "MarkedAsAvailable4K",
|
||||
table: "MovieRequests",
|
||||
type: "datetime(6)",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "MarkedAsDenied4K",
|
||||
table: "MovieRequests",
|
||||
type: "datetime(6)",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "RequestedDate4k",
|
||||
table: "MovieRequests",
|
||||
type: "datetime(6)",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Approved4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Available4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Denied4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DeniedReason4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MarkedAsApproved4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MarkedAsAvailable4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MarkedAsDenied4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "RequestedDate4k",
|
||||
table: "MovieRequests");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Ombi.Store.Context.MySql;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiMySql
|
||||
{
|
||||
[DbContext(typeof(OmbiMySqlContext))]
|
||||
|
@ -14,8 +16,8 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
{
|
||||
#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("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
|
@ -40,7 +42,7 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
|
@ -63,7 +65,7 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
|
@ -86,7 +88,7 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
|
@ -108,7 +110,7 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
|
@ -123,7 +125,7 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
|
@ -142,7 +144,7 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
|
||||
|
@ -342,7 +344,7 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b =>
|
||||
|
@ -406,28 +408,6 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
b.ToTable("RequestQueue");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("RequestId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("RequestType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("RequestSubscription");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -661,21 +641,36 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
b.Property<bool>("Approved")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("Approved4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("Available")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool>("Available4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("Background")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool?>("Denied")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<bool?>("Denied4K")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("DeniedReason")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("DeniedReason4K")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime?>("DigitalReleaseDate")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("Has4KRequest")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
|
@ -688,12 +683,21 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
b.Property<DateTime>("MarkedAsApproved")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime>("MarkedAsApproved4K")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime?>("MarkedAsAvailable")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime?>("MarkedAsAvailable4K")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime>("MarkedAsDenied")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime>("MarkedAsDenied4K")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Overview")
|
||||
.HasColumnType("longtext");
|
||||
|
||||
|
@ -715,6 +719,9 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
b.Property<DateTime>("RequestedDate")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<DateTime>("RequestedDate4k")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("RequestedUserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
|
@ -815,6 +822,28 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
b.ToTable("TvRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("RequestId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("RequestType")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("varchar(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("RequestSubscription");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -1052,15 +1081,6 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||
|
@ -1145,6 +1165,15 @@ namespace Ombi.Store.Migrations.OmbiMySql
|
|||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
|
|
1244
src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.Designer.cs
generated
Normal file
1244
src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,20 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Ombi.Helpers;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiSqlite
|
||||
{
|
||||
public partial class Radarr4kRole : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.InsertRole(OmbiRoles.Request4KMovie);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
1247
src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.Designer.cs
generated
Normal file
1247
src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,26 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiSqlite
|
||||
{
|
||||
public partial class MovieRequest4K : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Has4KRequest",
|
||||
table: "MovieRequests",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Has4KRequest",
|
||||
table: "MovieRequests");
|
||||
}
|
||||
}
|
||||
}
|
1271
src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.Designer.cs
generated
Normal file
1271
src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiSqlite
|
||||
{
|
||||
public partial class _4kMovieProperties : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Approved4K",
|
||||
table: "MovieRequests",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Available4K",
|
||||
table: "MovieRequests",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "Denied4K",
|
||||
table: "MovieRequests",
|
||||
type: "INTEGER",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "DeniedReason4K",
|
||||
table: "MovieRequests",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "MarkedAsApproved4K",
|
||||
table: "MovieRequests",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "MarkedAsAvailable4K",
|
||||
table: "MovieRequests",
|
||||
type: "TEXT",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "MarkedAsDenied4K",
|
||||
table: "MovieRequests",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "RequestedDate4k",
|
||||
table: "MovieRequests",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Approved4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Available4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "Denied4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "DeniedReason4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MarkedAsApproved4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MarkedAsAvailable4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "MarkedAsDenied4K",
|
||||
table: "MovieRequests");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "RequestedDate4k",
|
||||
table: "MovieRequests");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
|||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Ombi.Store.Context.Sqlite;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Ombi.Store.Migrations.OmbiSqlite
|
||||
{
|
||||
[DbContext(typeof(OmbiSqliteContext))]
|
||||
|
@ -13,8 +15,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
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("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
|
@ -39,7 +40,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
|
@ -62,7 +63,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
|
@ -85,7 +86,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
|
@ -107,7 +108,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
|
@ -122,7 +123,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
|
@ -141,7 +142,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
|
||||
|
@ -341,7 +342,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b =>
|
||||
|
@ -405,28 +406,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.ToTable("RequestQueue");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("RequestId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("RequestType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("RequestSubscription");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -660,21 +639,36 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Property<bool>("Approved")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Approved4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Available")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("Available4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Background")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool?>("Denied")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool?>("Denied4K")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("DeniedReason")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DeniedReason4K")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("DigitalReleaseDate")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Has4KRequest")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ImdbId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -687,12 +681,21 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Property<DateTime>("MarkedAsApproved")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("MarkedAsApproved4K")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("MarkedAsAvailable")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime?>("MarkedAsAvailable4K")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("MarkedAsDenied")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("MarkedAsDenied4K")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Overview")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -714,6 +717,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Property<DateTime>("RequestedDate")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("RequestedDate4k")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("RequestedUserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
|
@ -814,6 +820,28 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.ToTable("TvRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("RequestId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("RequestType")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("RequestSubscription");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
|
@ -1051,15 +1079,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||
|
@ -1144,6 +1163,15 @@ namespace Ombi.Store.Migrations.OmbiSqlite
|
|||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
|
||||
b.Navigation("User");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
// ************************************************************************/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
@ -37,7 +36,6 @@ namespace Ombi.Store.Repository
|
|||
{
|
||||
public class EmbyContentRepository : MediaServerContentRepository<EmbyContent>, IEmbyContentRepository
|
||||
{
|
||||
|
||||
public EmbyContentRepository(ExternalContext db):base(db)
|
||||
{
|
||||
}
|
||||
|
@ -98,6 +96,12 @@ namespace Ombi.Store.Repository
|
|||
Db.EmbyContent.Update((EmbyContent)existingContent);
|
||||
}
|
||||
|
||||
public override Task UpdateRange(IEnumerable<IMediaServerContent> existingContent)
|
||||
{
|
||||
Db.EmbyContent.UpdateRange((EmbyContent)existingContent);
|
||||
return InternalSaveChanges();
|
||||
}
|
||||
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Emby;
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ namespace Ombi.Store.Repository
|
|||
{
|
||||
RecentlyAddedType RecentlyAddedType{ get; }
|
||||
Task Update(IMediaServerContent existingContent);
|
||||
Task UpdateRange(IEnumerable<IMediaServerContent> existingContent);
|
||||
IQueryable<IMediaServerEpisode> GetAllEpisodes();
|
||||
Task<IMediaServerEpisode> Add(IMediaServerEpisode content);
|
||||
Task AddRange(IEnumerable<IMediaServerEpisode> content);
|
||||
|
|
|
@ -98,6 +98,12 @@ namespace Ombi.Store.Repository
|
|||
Db.JellyfinContent.Update((JellyfinContent)existingContent);
|
||||
}
|
||||
|
||||
public override Task UpdateRange(IEnumerable<IMediaServerContent> existingContent)
|
||||
{
|
||||
Db.JellyfinContent.UpdateRange((JellyfinContent)existingContent);
|
||||
return InternalSaveChanges();
|
||||
}
|
||||
|
||||
public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Jellyfin;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,5 +21,6 @@ namespace Ombi.Store.Repository
|
|||
public abstract Task<IMediaServerEpisode> Add(IMediaServerEpisode content);
|
||||
public abstract Task AddRange(IEnumerable<IMediaServerEpisode> content);
|
||||
public abstract void UpdateWithoutSave(IMediaServerContent existingContent);
|
||||
public abstract Task UpdateRange(IEnumerable<IMediaServerContent> existingContent);
|
||||
}
|
||||
}
|
|
@ -164,5 +164,10 @@ namespace Ombi.Store.Repository
|
|||
await InternalSaveChanges();
|
||||
}
|
||||
|
||||
public override Task UpdateRange(IEnumerable<IMediaServerContent> existingContent)
|
||||
{
|
||||
Db.PlexServerContent.UpdateRange((PlexServerContent)existingContent);
|
||||
return InternalSaveChanges();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -126,6 +126,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.RottenTomatoes", "
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.I18n", "Ombi.I18n\Ombi.I18n.csproj", "{6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.MediaServer", "Ombi.Api.MediaServer\Ombi.Api.MediaServer.csproj", "{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -439,6 +441,12 @@ Global
|
|||
{6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU
|
||||
{6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.NonUiBuild|Any CPU.ActiveCfg = NonUiBuild|Any CPU
|
||||
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU
|
||||
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -487,6 +495,7 @@ Global
|
|||
{E2186FDA-D827-4781-8663-130AC382F12C} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{5DE40A66-B369-469E-8626-ECE23D9D8034} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{8F19C701-7881-4BC7-8BBA-B068A6B954AD} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
{AFC0BA9B-E38D-479F-825A-2F94EE4D6120} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
||||
|
|
|
@ -21,6 +21,8 @@ import { CustomPageComponent } from "./custompage/custompage.component";
|
|||
import { CustomizationState } from "./state/customization/customization.state";
|
||||
import { DataViewModule } from "primeng/dataview";
|
||||
import { DialogModule } from "primeng/dialog";
|
||||
import { FEATURES_INITIALIZER } from "./state/features/features-initializer";
|
||||
import { FeatureState } from "./state/features";
|
||||
import { JwtModule } from "@auth0/angular-jwt";
|
||||
import { LandingPageComponent } from "./landingpage/landingpage.component";
|
||||
import { LandingPageService } from "./services";
|
||||
|
@ -38,6 +40,8 @@ import { MatInputModule } from "@angular/material/input";
|
|||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatMenuModule } from "@angular/material/menu";
|
||||
import { MatNativeDateModule } from '@angular/material/core';
|
||||
import { MatPaginatorI18n } from "./localization/MatPaginatorI18n";
|
||||
import { MatPaginatorIntl } from "@angular/material/paginator";
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatSlideToggleModule } from "@angular/material/slide-toggle";
|
||||
|
@ -63,11 +67,9 @@ import { StorageService } from "./shared/storage/storage-service";
|
|||
import { TokenResetPasswordComponent } from "./login/tokenresetpassword.component";
|
||||
import { TooltipModule } from "primeng/tooltip";
|
||||
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor";
|
||||
import { environment } from "../environments/environment";
|
||||
import { MatPaginatorIntl } from "@angular/material/paginator";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
import { MatPaginatorI18n } from "./localization/MatPaginatorI18n";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "*", component: PageNotFoundComponent },
|
||||
|
@ -162,7 +164,7 @@ export function JwtTokenGetter() {
|
|||
}),
|
||||
SidebarModule,
|
||||
MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, LayoutModule, MatSlideToggleModule,
|
||||
NgxsModule.forRoot([CustomizationState], {
|
||||
NgxsModule.forRoot([CustomizationState, FeatureState], {
|
||||
developmentMode: !environment.production,
|
||||
}),
|
||||
...environment.production ? [] :
|
||||
|
@ -205,6 +207,7 @@ export function JwtTokenGetter() {
|
|||
StorageService,
|
||||
RequestService,
|
||||
SignalRNotificationService,
|
||||
FEATURES_INITIALIZER,
|
||||
CUSTOMIZATION_INITIALIZER,
|
||||
{
|
||||
provide: APP_BASE_HREF,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</div>
|
||||
<div *ngIf="discoverResults" class="row full-height">
|
||||
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
|
||||
<discover-card [isAdmin]="isAdmin" [result]="result"></discover-card>
|
||||
<discover-card [isAdmin]="isAdmin" [result]="result" [is4kEnabled]="is4kEnabled"></discover-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,4 +1,4 @@
|
|||
import { Component } from "@angular/core";
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { SearchV2Service } from "../../../services";
|
||||
import { IActorCredits, IActorCast } from "../../../interfaces/ISearchTvResultV2";
|
||||
|
@ -6,30 +6,31 @@ import { IDiscoverCardResult } from "../../interfaces";
|
|||
import { RequestType } from "../../../interfaces";
|
||||
import { AuthService } from "../../../auth/auth.service";
|
||||
import { forkJoin } from "rxjs";
|
||||
import { isEqual } from "lodash";
|
||||
import { FeaturesFacade } from "../../../state/features/features.facade";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./discover-actor.component.html",
|
||||
styleUrls: ["./discover-actor.component.scss"],
|
||||
})
|
||||
export class DiscoverActorComponent {
|
||||
export class DiscoverActorComponent implements OnInit {
|
||||
public actorId: number;
|
||||
public loadingFlag: boolean;
|
||||
public isAdmin: boolean;
|
||||
public is4kEnabled = false;
|
||||
|
||||
public discoverResults: IDiscoverCardResult[] = [];
|
||||
|
||||
constructor(private searchService: SearchV2Service,
|
||||
private route: ActivatedRoute,
|
||||
private auth: AuthService) {
|
||||
private auth: AuthService,
|
||||
private featureService: FeaturesFacade) {
|
||||
this.route.params.subscribe((params: any) => {
|
||||
this.actorId = params.actorId;
|
||||
this.isAdmin = this.auth.isAdmin();
|
||||
this.search();
|
||||
});
|
||||
}
|
||||
|
||||
private search() {
|
||||
ngOnInit() {
|
||||
this.isAdmin = this.auth.isAdmin();
|
||||
this.is4kEnabled = this.featureService.is4kEnabled();
|
||||
this.discoverResults = [];
|
||||
this.loading();
|
||||
|
||||
|
|
|
@ -20,12 +20,24 @@
|
|||
</a>
|
||||
</div>
|
||||
<div [ngClass]="result.posterPath.includes('images/') ? 'button-request-container-show' : 'button-request-container'" class="row" *ngIf="!result.available && !result.approved && !result.requested">
|
||||
<div class="button-request poster-overlay">
|
||||
<button id="requestButton{{result.id}}{{result.type}}{{discoverType}}" *ngIf="requestable" mat-raised-button class="btn-ombi full-width poster-request-btn" (click)="request($event)">
|
||||
<div *ngIf="!is4kEnabled" class="button-request poster-overlay">
|
||||
<button id="requestButton{{result.id}}{{result.type}}{{discoverType}}" *ngIf="requestable" mat-raised-button class="btn-ombi full-width poster-request-btn" (click)="request($event, false)">
|
||||
<i *ngIf="!loading" class="fa-lg fas fa-cloud-download-alt"></i>
|
||||
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
||||
{{'Common.Request' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<div *ngIf="is4kEnabled && requestable" class="button-request poster-overlay">
|
||||
<button [matMenuTriggerFor]="menu" id="requestButton{{result.id}}{{result.type}}{{discoverType}}" mat-raised-button class="btn-ombi full-width poster-request-btn">
|
||||
<i *ngIf="!loading" class="fa-lg fas fa-cloud-download-alt"></i>
|
||||
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
||||
{{'Common.Request' | translate }}
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item class="btn-ombi full-width poster-request-btn" (click)="request($event, false)">{{'Common.Request' | translate }}</button>
|
||||
<button mat-menu-item class="btn-ombi full-width poster-request-btn" (click)="request($event, true)">{{'Common.Request4K' | translate }}</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -293,3 +293,7 @@ a.poster-overlay:hover{
|
|||
.btn-ombi{
|
||||
background-color:#293a4c;
|
||||
}
|
||||
|
||||
::ng-deep .mat-menu-panel {
|
||||
min-width: 190px !important;
|
||||
}
|
|
@ -21,6 +21,7 @@ export class DiscoverCardComponent implements OnInit {
|
|||
@Input() public discoverType: DiscoverType;
|
||||
@Input() public result: IDiscoverCardResult;
|
||||
@Input() public isAdmin: boolean;
|
||||
@Input() public is4kEnabled: boolean = false;
|
||||
public RequestType = RequestType;
|
||||
public hide: boolean;
|
||||
public fullyLoaded = false;
|
||||
|
@ -111,7 +112,7 @@ export class DiscoverCardComponent implements OnInit {
|
|||
return "";
|
||||
}
|
||||
|
||||
public request(event: any) {
|
||||
public request(event: any, is4k: boolean) {
|
||||
event.preventDefault();
|
||||
this.loading = true;
|
||||
switch (this.result.type) {
|
||||
|
@ -121,14 +122,15 @@ export class DiscoverCardComponent implements OnInit {
|
|||
return;
|
||||
case RequestType.movie:
|
||||
if (this.isAdmin) {
|
||||
const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.result.id }, panelClass: 'modal-panel' });
|
||||
const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.result.id, }, panelClass: 'modal-panel' });
|
||||
dialog.afterClosed().subscribe((result) => {
|
||||
if (result) {
|
||||
this.requestService.requestMovie({ theMovieDbId: +this.result.id,
|
||||
languageCode: this.translate.currentLang,
|
||||
qualityPathOverride: result.radarrPathId,
|
||||
requestOnBehalf: result.username?.id,
|
||||
rootFolderOverride: result.radarrFolderId, }).subscribe(x => {
|
||||
rootFolderOverride: result.radarrFolderId,
|
||||
is4KRequest: is4k }).subscribe(x => {
|
||||
if (x.result) {
|
||||
this.result.requested = true;
|
||||
this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.result.title }), "Ok");
|
||||
|
@ -139,7 +141,7 @@ export class DiscoverCardComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
} else {
|
||||
this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: this.translate.currentLang, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null }).subscribe(x => {
|
||||
this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: this.translate.currentLang, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null, is4KRequest: is4k }).subscribe(x => {
|
||||
if (x.result) {
|
||||
this.result.requested = true;
|
||||
this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.result.title }), "Ok");
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
|
||||
<p-carousel #carousel [numVisible]="10" [numScroll]="10" [page]="0" [value]="discoverResults" [responsiveOptions]="responsiveOptions" (onPage)="newPage()">
|
||||
<ng-template let-result pTemplate="item">
|
||||
<discover-card [discoverType]="discoverType" [isAdmin]="isAdmin" [result]="result"></discover-card>
|
||||
<discover-card [discoverType]="discoverType" [isAdmin]="isAdmin" [result]="result" [is4kEnabled]="is4kEnabled"></discover-card>
|
||||
</ng-template>
|
||||
</p-carousel>
|
|
@ -5,6 +5,7 @@ import { SearchV2Service } from "../../../services";
|
|||
import { StorageService } from "../../../shared/storage/storage-service";
|
||||
import { MatButtonToggleChange } from '@angular/material/button-toggle';
|
||||
import { Carousel } from 'primeng/carousel';
|
||||
import { FeaturesFacade } from "../../../state/features/features.facade";
|
||||
|
||||
export enum DiscoverType {
|
||||
Upcoming,
|
||||
|
@ -36,6 +37,7 @@ export class CarouselListComponent implements OnInit {
|
|||
public RequestType = RequestType;
|
||||
public loadingFlag: boolean;
|
||||
public DiscoverType = DiscoverType;
|
||||
public is4kEnabled = false;
|
||||
|
||||
get mediaTypeStorageKey() {
|
||||
return "DiscoverOptions" + this.discoverType.toString();
|
||||
|
@ -44,7 +46,8 @@ export class CarouselListComponent implements OnInit {
|
|||
private currentlyLoaded = 0;
|
||||
|
||||
constructor(private searchService: SearchV2Service,
|
||||
private storageService: StorageService) {
|
||||
private storageService: StorageService,
|
||||
private featureFacade: FeaturesFacade) {
|
||||
this.responsiveOptions = [
|
||||
{
|
||||
breakpoint: '4000px',
|
||||
|
@ -135,6 +138,7 @@ export class CarouselListComponent implements OnInit {
|
|||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
this.is4kEnabled = this.featureFacade.is4kEnabled();
|
||||
this.currentlyLoaded = 0;
|
||||
const localDiscoverOptions = +this.storageService.get(this.mediaTypeStorageKey);
|
||||
if (localDiscoverOptions) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
<div *ngIf="discoverResults" class="row full-height">
|
||||
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
|
||||
<discover-card [isAdmin]="isAdmins" [result]="result"></discover-card>
|
||||
<discover-card [isAdmin]="isAdmins" [result]="result" [is4kEnabled]="is4kEnabled"></discover-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -8,6 +8,7 @@ import { IDiscoverCardResult } from "../../interfaces";
|
|||
import { IMovieCollectionsViewModel } from "../../../interfaces/ISearchTvResultV2";
|
||||
import { RequestServiceV2 } from "../../../services/requestV2.service";
|
||||
import { RequestType } from "../../../interfaces";
|
||||
import { FeaturesFacade } from "../../../state/features/features.facade";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./discover-collections.component.html",
|
||||
|
@ -19,6 +20,7 @@ export class DiscoverCollectionsComponent implements OnInit {
|
|||
public collection: IMovieCollectionsViewModel;
|
||||
public loadingFlag: boolean;
|
||||
public isAdmin: boolean;
|
||||
public is4kEnabled = false;
|
||||
|
||||
public discoverResults: IDiscoverCardResult[] = [];
|
||||
|
||||
|
@ -27,13 +29,15 @@ export class DiscoverCollectionsComponent implements OnInit {
|
|||
private requestServiceV2: RequestServiceV2,
|
||||
private messageService: MessageService,
|
||||
private auth: AuthService,
|
||||
private translate: TranslateService) {
|
||||
private translate: TranslateService,
|
||||
private featureFacade: FeaturesFacade) {
|
||||
this.route.params.subscribe((params: any) => {
|
||||
this.collectionId = params.collectionId;
|
||||
});
|
||||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
this.is4kEnabled = this.featureFacade.is4kEnabled();
|
||||
this.loadingFlag = true;
|
||||
this.isAdmin = this.auth.isAdmin();
|
||||
this.collection = await this.searchService.getMovieCollections(this.collectionId);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
</div>
|
||||
<div *ngIf="discoverResults.length > 0" class="row full-height discoverResults col" >
|
||||
<div id="searchResults" class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults" data-test="searchResultsCount" attr.search-count="{{discoverResults.length}}">
|
||||
<discover-card [isAdmin]="isAdmin" [result]="result"></discover-card>
|
||||
<discover-card [isAdmin]="isAdmin" [result]="result" [is4kEnabled]="is4kEnabled"></discover-card>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="!loadingFlag && discoverResults.length === 0">
|
||||
|
|
|
@ -10,6 +10,7 @@ import { SearchFilter } from "../../../my-nav/SearchFilter";
|
|||
import { SearchV2Service } from "../../../services";
|
||||
import { StorageService } from "../../../shared/storage/storage-service";
|
||||
import { isEqual } from "lodash";
|
||||
import { FeaturesFacade } from "../../../state/features/features.facade";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./search-results.component.html",
|
||||
|
@ -21,6 +22,7 @@ export class DiscoverSearchResultsComponent implements OnInit {
|
|||
public searchTerm: string;
|
||||
public results: IMultiSearchResult[];
|
||||
public isAdmin: boolean;
|
||||
public is4kEnabled = false;
|
||||
|
||||
public discoverResults: IDiscoverCardResult[] = [];
|
||||
|
||||
|
@ -34,7 +36,8 @@ export class DiscoverSearchResultsComponent implements OnInit {
|
|||
private router: Router,
|
||||
private advancedDataService: AdvancedSearchDialogDataService,
|
||||
private store: StorageService,
|
||||
private authService: AuthService) {
|
||||
private authService: AuthService,
|
||||
private featureFacade: FeaturesFacade) {
|
||||
this.route.params.subscribe((params: any) => {
|
||||
this.isAdvancedSearch = this.router.url === '/discover/advanced/search';
|
||||
if (this.isAdvancedSearch) {
|
||||
|
@ -53,6 +56,7 @@ export class DiscoverSearchResultsComponent implements OnInit {
|
|||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
this.is4kEnabled = this.featureFacade.is4kEnabled();
|
||||
this.isAdmin = this.authService.isAdmin();
|
||||
this.filterService.onFilterChange.subscribe(async x => {
|
||||
if (!isEqual(this.filter, x)) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue