diff --git a/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj b/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj +++ b/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj b/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj index 4945a2fb2..70032d638 100644 --- a/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj +++ b/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj b/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj +++ b/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj b/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj index b524c9ce4..f60971192 100644 --- a/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj +++ b/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj b/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj index 4945a2fb2..70032d638 100644 --- a/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj +++ b/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Github/Ombi.Api.Github.csproj b/src/Ombi.Api.Github/Ombi.Api.Github.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.Github/Ombi.Api.Github.csproj +++ b/src/Ombi.Api.Github/Ombi.Api.Github.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj b/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj index 1285c073c..be32916f8 100644 --- a/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj +++ b/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj b/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj +++ b/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj b/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj index dfdb5a93f..0c745556e 100644 --- a/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj +++ b/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj b/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj +++ b/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj b/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj index a25024b6c..16c3a8558 100644 --- a/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj +++ b/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj b/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj index f167146af..a1b98b765 100644 --- a/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj +++ b/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj b/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj index 584b980ce..c8a78e491 100644 --- a/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj +++ b/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj b/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj index f84a8add6..6406ef9de 100644 --- a/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj +++ b/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Plex/IPlexApi.cs b/src/Ombi.Api.Plex/IPlexApi.cs index a4597765e..746c85b77 100644 --- a/src/Ombi.Api.Plex/IPlexApi.cs +++ b/src/Ombi.Api.Plex/IPlexApi.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using Ombi.Api.Plex.Models; using Ombi.Api.Plex.Models.Friends; @@ -16,9 +17,9 @@ namespace Ombi.Api.Plex Task GetServer(string authToken); Task GetLibrarySections(string authToken, string plexFullHost); Task GetLibrary(string authToken, string plexFullHost, string libraryId); - Task GetEpisodeMetaData(string authToken, string host, int ratingKey); - Task GetMetadata(string authToken, string plexFullHost, int itemId); - Task GetSeasons(string authToken, string plexFullHost, int ratingKey); + Task GetEpisodeMetaData(string authToken, string host, string ratingKey); + Task GetMetadata(string authToken, string plexFullHost, string itemId); + Task GetSeasons(string authToken, string plexFullHost, string ratingKey); Task GetAllEpisodes(string authToken, string host, string section, int start, int retCount); Task GetUsers(string authToken); Task GetAccount(string authToken); @@ -26,5 +27,7 @@ namespace Ombi.Api.Plex Task GetPin(int pinId); Task GetOAuthUrl(string code, string applicationUrl); Task AddUser(string emailAddress, string serverId, string authToken, int[] libs); + Task GetWatchlist(string plexToken, CancellationToken cancellationToken); + Task GetWatchlistMetadata(string ratingKey, string plexToken, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/Metadata.cs b/src/Ombi.Api.Plex/Models/Metadata.cs index 65cb21e95..3481e9b57 100644 --- a/src/Ombi.Api.Plex/Models/Metadata.cs +++ b/src/Ombi.Api.Plex/Models/Metadata.cs @@ -4,7 +4,7 @@ namespace Ombi.Api.Plex.Models { public class Metadata { - public int ratingKey { get; set; } + public string ratingKey { get; set; } public string key { get; set; } public string studio { get; set; } public string type { get; set; } @@ -22,8 +22,8 @@ namespace Ombi.Api.Plex.Models public int childCount { get; set; } public Genre[] Genre { get; set; } public string primaryExtraKey { get; set; } - public int parentRatingKey { get; set; } - public int grandparentRatingKey { get; set; } + public string parentRatingKey { get; set; } + public string grandparentRatingKey { get; set; } public string guid { get; set; } public int librarySectionID { get; set; } public string librarySectionKey { get; set; } diff --git a/src/Ombi.Api.Plex/Models/PlexWatchlist.cs b/src/Ombi.Api.Plex/Models/PlexWatchlist.cs new file mode 100644 index 000000000..52ca82cf9 --- /dev/null +++ b/src/Ombi.Api.Plex/Models/PlexWatchlist.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Ombi.Api.Plex.Models +{ + public class PlexWatchlist + { + public string librarySectionID { get; set; } + public string librarySectionTitle { get; set; } + public int offset { get; set; } + public int totalSize { get; set; } + public int size { get; set; } + public List Metadata { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs b/src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs new file mode 100644 index 000000000..b208c189f --- /dev/null +++ b/src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Ombi.Api.Plex.Models +{ + public class PlexWatchlistContainer + { + public PlexWatchlist MediaContainer { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs b/src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs new file mode 100644 index 000000000..b582ca4e1 --- /dev/null +++ b/src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace Ombi.Api.Plex.Models +{ + public class PlexWatchlistMetadataContainer + { + public PlexWatchlistMetadata MediaContainer { get; set; } + } + + + public class PlexWatchlistMetadata + { + public int offset { get; set; } + public int totalSize { get; set; } + public string identifier { get; set; } + public int size { get; set; } + public WatchlistMetadata[] Metadata { get; set; } + } + + public class WatchlistMetadata + { + public string guid { get; set; } + public string key { get; set; } + public string primaryExtraKey { get; set; } + public string ratingKey { get; set; } + public string type { get; set; } + public string slug { get; set; } + public string title { get; set; } + public List Guid { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj b/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj index 4945a2fb2..70032d638 100644 --- a/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj +++ b/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Plex/PlexApi.cs b/src/Ombi.Api.Plex/PlexApi.cs index 176af31ec..9f91c540c 100644 --- a/src/Ombi.Api.Plex/PlexApi.cs +++ b/src/Ombi.Api.Plex/PlexApi.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using Ombi.Api.Plex.Models; @@ -66,6 +67,7 @@ namespace Ombi.Api.Plex private const string FriendsUri = "https://plex.tv/pms/friends/all"; private const string GetAccountUri = "https://plex.tv/users/account.json"; private const string ServerUri = "https://plex.tv/pms/servers.xml"; + private const string WatchlistUri = "https://metadata.provider.plex.tv/"; /// /// Sign into the Plex API @@ -145,21 +147,21 @@ namespace Ombi.Api.Plex /// /// /// - public async Task GetEpisodeMetaData(string authToken, string plexFullHost, int ratingKey) + public async Task GetEpisodeMetaData(string authToken, string plexFullHost, string ratingKey) { var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get); await AddHeaders(request, authToken); return await Api.Request(request); } - public async Task GetMetadata(string authToken, string plexFullHost, int itemId) + public async Task GetMetadata(string authToken, string plexFullHost, string itemId) { var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get); await AddHeaders(request, authToken); return await Api.Request(request); } - public async Task GetSeasons(string authToken, string plexFullHost, int ratingKey) + public async Task GetSeasons(string authToken, string plexFullHost, string ratingKey) { var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get); await AddHeaders(request, authToken); @@ -288,6 +290,26 @@ namespace Ombi.Api.Plex } } + public async Task GetWatchlist(string plexToken, CancellationToken cancellationToken) + { + var request = new Request("library/sections/watchlist/all", WatchlistUri, HttpMethod.Get); + await AddHeaders(request, plexToken); + + var result = await Api.Request(request, cancellationToken); + + return result; + } + + public async Task GetWatchlistMetadata(string ratingKey, string plexToken, CancellationToken cancellationToken) + { + var request = new Request($"library/metadata/{ratingKey}", WatchlistUri, HttpMethod.Get); + await AddHeaders(request, plexToken); + + var result = await Api.Request(request, cancellationToken); + + return result; + } + /// /// Adds the required headers and also the authorization header diff --git a/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj b/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj index 4945a2fb2..70032d638 100644 --- a/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj +++ b/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj b/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj index 1285c073c..be32916f8 100644 --- a/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj +++ b/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj b/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj index f14df4f5f..889aa0ea6 100644 --- a/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj +++ b/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj b/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj +++ b/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Service/Ombi.Api.Service.csproj b/src/Ombi.Api.Service/Ombi.Api.Service.csproj index a344de142..38bcd678a 100644 --- a/src/Ombi.Api.Service/Ombi.Api.Service.csproj +++ b/src/Ombi.Api.Service/Ombi.Api.Service.csproj @@ -8,7 +8,7 @@ Ombi.Api.Service Ombi.Api.Service - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj b/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj +++ b/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj b/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj index 4945a2fb2..70032d638 100644 --- a/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj +++ b/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj b/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj index 4945a2fb2..70032d638 100644 --- a/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj +++ b/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj b/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj index 6353f4bf9..89c47d251 100644 --- a/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj +++ b/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj b/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj index e07f40c60..fd9632e56 100644 --- a/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj +++ b/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj b/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj index f167146af..a1b98b765 100644 --- a/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj +++ b/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api/Ombi.Api.csproj b/src/Ombi.Api/Ombi.Api.csproj index 83c3ee62e..7670d4d14 100644 --- a/src/Ombi.Api/Ombi.Api.csproj +++ b/src/Ombi.Api/Ombi.Api.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs b/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs index b922a21c0..0a85fd058 100644 --- a/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs @@ -10,6 +10,7 @@ using Ombi.Core.Authentication; using Ombi.Core.Engine.V2; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository.Requests; +using Ombi.Core.Helpers; namespace Ombi.Core.Tests.Engine { @@ -25,7 +26,7 @@ namespace Ombi.Core.Tests.Engine { MovieRepo = new Mock(); TvRepo = new Mock(); - var principle = new Mock(); + var principle = new Mock(); var identity = new Mock(); identity.Setup(x => x.Name).Returns("UnitTest"); principle.Setup(x => x.Identity).Returns(identity.Object); diff --git a/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs b/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs index 8c37aaa9a..f8ced161f 100644 --- a/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs @@ -4,6 +4,7 @@ using Moq.AutoMock; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; @@ -35,12 +36,17 @@ namespace Ombi.Core.Tests.Engine var identity = new Mock(); identity.Setup(x => x.Name).Returns("Test"); principle.Setup(x => x.Identity).Returns(identity.Object); + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identity.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { NormalizedUserName = "TEST", Id = "a" }); _repoMock = new Mock(); var requestServiceMock = new Mock(); requestServiceMock.Setup(x => x.MovieRequestService).Returns(_repoMock.Object); _mocker.Use(principle.Object); + _mocker.Use(currentUser.Object); _mocker.Use(userManager.Object); _mocker.Use(requestServiceMock); diff --git a/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs b/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs index f1af160d6..88e1c75d2 100644 --- a/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs +++ b/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs @@ -4,6 +4,7 @@ using Moq.AutoMock; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Services; using Ombi.Helpers; @@ -36,6 +37,13 @@ namespace Ombi.Core.Tests.Engine var identityMock = new Mock(); identityMock.SetupGet(x => x.Name).Returns("Test"); principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object); + + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identityMock.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" }); + + _mocker.Use(currentUser.Object); _mocker.Use(principleMock.Object); _subject = _mocker.CreateInstance(); diff --git a/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs b/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs index f7291409b..93dd5050d 100644 --- a/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs +++ b/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs @@ -4,6 +4,7 @@ using Moq.AutoMock; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Services; using Ombi.Helpers; @@ -36,7 +37,12 @@ namespace Ombi.Core.Tests.Engine var identityMock = new Mock(); identityMock.SetupGet(x => x.Name).Returns("Test"); principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object); + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identityMock.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" }); _mocker.Use(principleMock.Object); + _mocker.Use(currentUser.Object); _subject = _mocker.CreateInstance(); } diff --git a/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs b/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs index e601ab84d..ba383da6c 100644 --- a/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs +++ b/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs @@ -4,6 +4,7 @@ using Moq.AutoMock; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Services; using Ombi.Helpers; @@ -33,7 +34,12 @@ namespace Ombi.Core.Tests.Engine var identityMock = new Mock(); identityMock.SetupGet(x => x.Name).Returns("Test"); principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object); + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identityMock.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" }); _mocker.Use(principleMock.Object); + _mocker.Use(currentUser.Object); _subject = _mocker.CreateInstance(); } diff --git a/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs b/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs index d9f5b11be..16b7cb811 100644 --- a/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs @@ -7,6 +7,7 @@ using Moq; using NUnit.Framework; using Ombi.Api.TheMovieDb; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Rule.Interfaces; using Ombi.Core.Services; @@ -33,7 +34,7 @@ namespace Ombi.Core.Tests.Engine.V2 var requestService = new Mock(); _movieRequestRepository = new Mock(); requestService.Setup(x => x.MovieRequestService).Returns(_movieRequestRepository.Object); - var user = new Mock(); + var user = new Mock(); var notificationHelper = new Mock(); var rules = new Mock(); var movieSender = new Mock(); diff --git a/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs b/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs index 50ab63346..1b773f060 100644 --- a/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs +++ b/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs @@ -23,6 +23,7 @@ using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Test.Common; using Artist = Hqub.MusicBrainz.API.Entities.Artist; +using Ombi.Core.Helpers; namespace Ombi.Core.Tests.Engine.V2 { @@ -45,7 +46,7 @@ namespace Ombi.Core.Tests.Engine.V2 .ForEach(b => F.Behaviors.Remove(b)); F.Behaviors.Add(new OmitOnRecursionBehavior()); - var principle = new Mock(); + var principle = new Mock(); var requestService = new Mock(); var ruleEval = new Mock(); var um = MockHelper.MockUserManager(new List()); diff --git a/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs b/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs index 1269cd2bc..4194ae0ea 100644 --- a/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs @@ -9,6 +9,7 @@ using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Rule.Interfaces; using Ombi.Core.Settings; @@ -32,8 +33,9 @@ namespace Ombi.Core.Tests.Engine TvRequestEngine = new Mock(); MovieRequestEngine = new Mock(); MovieRequestEngine = new Mock(); - User = new Mock(); - User.Setup(x => x.Identity.Name).Returns("abc"); + User = new Mock(); + User.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "abc" }); + UserManager = MockHelper.MockUserManager(new List { new OmbiUser { Id = "abc", UserName = "abc", NormalizedUserName = "ABC" } }); Rule = new Mock(); Engine = new VoteEngine(VoteRepository.Object, User.Object, UserManager.Object, Rule.Object, VoteSettings.Object, MusicRequestEngine.Object, @@ -48,7 +50,7 @@ namespace Ombi.Core.Tests.Engine public Fixture F { get; set; } public VoteEngine Engine { get; set; } - public Mock User { get; set; } + public Mock User { get; set; } public Mock UserManager { get; set; } public Mock Rule { get; set; } public Mock> VoteRepository { get; set; } diff --git a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs index 9633249d4..c73237097 100644 --- a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using Ombi.Store.Entities; using System; using Ombi.Core.Services; +using Ombi.Core.Helpers; namespace Ombi.Core.Tests.Rule.Request { @@ -27,17 +28,18 @@ namespace Ombi.Core.Tests.Rule.Request public void Setup() { - PrincipalMock = new Mock(); - PrincipalMock.Setup(x => x.Identity.Name).Returns("abc"); FeatureService = new Mock(); + PrincipalMock = new Mock(); + PrincipalMock.Setup(x => x.Username).Returns("abc"); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" }); + UserManager = MockHelper.MockUserManager(_users); Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object, FeatureService.Object); } - private AutoApproveRule Rule { get; set; } - private Mock PrincipalMock { get; set; } + private Mock PrincipalMock { get; set; } private Mock UserManager { get; set; } private Mock FeatureService { get; set; } @@ -99,7 +101,8 @@ namespace Ombi.Core.Tests.Rule.Request [Test] public async Task Should_ReturnSuccess_WhenSystemUserAndRequestTV() { - PrincipalMock.Setup(x => x.Identity.Name).Returns("sys"); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" }); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.AutoApproveTv)).ReturnsAsync(false); var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow }; var result = await Rule.Execute(request); diff --git a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs index f601689dc..9d8db25d1 100644 --- a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Moq; using NUnit.Framework; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Rule.Rules; using Ombi.Core.Rule.Rules.Request; using Ombi.Helpers; @@ -26,8 +27,9 @@ namespace Ombi.Core.Tests.Rule.Request public void Setup() { - PrincipalMock = new Mock(); - PrincipalMock.Setup(x => x.Identity.Name).Returns("abc"); + PrincipalMock = new Mock(); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" }); + UserManager = MockHelper.MockUserManager(_users); Rule = new CanRequestRule(PrincipalMock.Object, UserManager.Object); @@ -35,7 +37,7 @@ namespace Ombi.Core.Tests.Rule.Request private CanRequestRule Rule { get; set; } - private Mock PrincipalMock { get; set; } + private Mock PrincipalMock { get; set; } private Mock UserManager { get; set; } [Test] @@ -107,7 +109,8 @@ namespace Ombi.Core.Tests.Rule.Request [Test] public async Task Should_ReturnSuccess_WhenRequestingMovieWithSystemRole() { - PrincipalMock.Setup(x => x.Identity.Name).Returns("sys"); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" }); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.Admin)).ReturnsAsync(false); var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); diff --git a/src/Ombi.Core/Authentication/OmbiUserManager.cs b/src/Ombi.Core/Authentication/OmbiUserManager.cs index 87f82c1de..124ff1aeb 100644 --- a/src/Ombi.Core/Authentication/OmbiUserManager.cs +++ b/src/Ombi.Core/Authentication/OmbiUserManager.cs @@ -116,16 +116,25 @@ namespace Ombi.Core.Authentication public async Task GetOmbiUserFromPlexToken(string plexToken) { var plexAccount = await _plexApi.GetAccount(plexToken); - + // Check for a ombi user - if (plexAccount?.user != null) + if (plexAccount?.user == null) + { + return null; + } + + var potentialOmbiUser = await Users.FirstOrDefaultAsync(x => + x.ProviderUserId == plexAccount.user.id); + // Update ombi user with the token + + if (potentialOmbiUser != null) { - var potentialOmbiUser = await Users.FirstOrDefaultAsync(x => - x.ProviderUserId == plexAccount.user.id); - return potentialOmbiUser; + potentialOmbiUser.MediaServerToken = plexAccount.user.authentication_token; + await UpdateAsync(potentialOmbiUser); } - return null; + return potentialOmbiUser; + } @@ -142,6 +151,10 @@ namespace Ombi.Core.Authentication var result = await _plexApi.SignIn(new UserRequest { password = password, login = login }); if (result.user?.authentication_token != null) { + // Update ombi user with the token + user.MediaServerToken = result.user?.authentication_token; + await UpdateAsync(user); + return true; } return false; diff --git a/src/Ombi.Core/Engine/BaseMediaEngine.cs b/src/Ombi.Core/Engine/BaseMediaEngine.cs index 277144ab1..ee1ce55a8 100644 --- a/src/Ombi.Core/Engine/BaseMediaEngine.cs +++ b/src/Ombi.Core/Engine/BaseMediaEngine.cs @@ -26,7 +26,7 @@ namespace Ombi.Core.Engine private Dictionary _dbMovies; private Dictionary _dbTv; - protected BaseMediaEngine(IPrincipal identity, IRequestServiceMain requestService, + protected BaseMediaEngine(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService ombiSettings, IRepository sub) : base(identity, um, rules) { RequestService = requestService; diff --git a/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs b/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs index f392bf7ad..af88813d9 100644 --- a/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs @@ -11,6 +11,7 @@ using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Config; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; @@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo { public class DemoMovieSearchEngine : MovieSearchEngine, IDemoMovieSearchEngine { - public DemoMovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, + public DemoMovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub, IOptions lists) : base(identity, service, movApi, mapper, logger, r, um, mem, s, sub) diff --git a/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs index 2c91a458f..706a5337d 100644 --- a/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs +++ b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs @@ -4,6 +4,7 @@ using Ombi.Api.Trakt; using Ombi.Api.TvMaze; using Ombi.Config; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; @@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo public class DemoTvSearchEngine : TvSearchEngine, IDemoTvSearchEngine { - public DemoTvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, + public DemoTvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService s, IRepository sub, IOptions lists, IImageService imageService, ISettingsService custom) diff --git a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs index 42aff9a61..2c68ea371 100644 --- a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs @@ -1,42 +1,35 @@ using System; using Ombi.Core.Rule; using System.Collections.Generic; -using System.Security.Principal; using System.Threading.Tasks; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; using Ombi.Store.Entities.Requests; using Ombi.Store.Entities; -using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; -using Ombi.Helpers; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine.Interfaces { public abstract class BaseEngine { - protected BaseEngine(IPrincipal user, OmbiUserManager um, IRuleEvaluator rules) + protected BaseEngine(ICurrentUser user, OmbiUserManager um, IRuleEvaluator rules) { - UserPrinciple = user; + CurrentUser = user; Rules = rules; UserManager = um; } - protected IPrincipal UserPrinciple { get; } + protected ICurrentUser CurrentUser { get; } protected IRuleEvaluator Rules { get; } - protected OmbiUserManager UserManager { get; } - protected string Username => UserPrinciple.Identity.Name; + protected OmbiUserManager UserManager { get; } + protected string Username => CurrentUser.Username; + protected Task GetUser() => CurrentUser.GetUser(); - private OmbiUser _user; - protected async Task GetUser() - { - if(!Username.HasValue()) - { - return null; - } - var username = Username.ToUpper(); - return _user ??= await UserManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); - } + /// + /// Only used for background tasks + /// + public void SetUser(OmbiUser user) => CurrentUser.SetUser(user); protected async Task UserAlias() { @@ -52,7 +45,7 @@ namespace Ombi.Core.Engine.Interfaces var user = await GetUser(); return await UserManager.IsInRoleAsync(user, roleName); } - + public async Task> RunRequestRules(BaseRequest model) { var ruleResults = await Rules.StartRequestRules(model); diff --git a/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs index d0fc04b10..01300287e 100644 --- a/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs @@ -25,5 +25,6 @@ namespace Ombi.Core.Engine.Interfaces Task UnSubscribeRequest(int requestId, RequestType type); Task SubscribeToRequest(int requestId, RequestType type); Task ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken); + void SetUser(OmbiUser user); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index 498cf3e0b..6e81e3e73 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -23,12 +23,13 @@ using Ombi.Store.Repository; using Ombi.Core.Models; using System.Threading; using Ombi.Core.Services; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine { public class MovieRequestEngine : BaseMediaEngine, IMovieRequestEngine { - public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user, + public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, ICurrentUser user, INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger log, OmbiUserManager manager, IRepository rl, ICacheService cache, ISettingsService ombiSettings, IRepository sub, IMediaCacheService mediaCacheService, @@ -142,7 +143,8 @@ namespace Ombi.Core.Engine RootPathOverride = model.RootFolderOverride.GetValueOrDefault(), QualityOverride = model.QualityPathOverride.GetValueOrDefault(), RequestedDate4k = model.Is4kRequest ? DateTime.Now : DateTime.MinValue, - Is4kRequest = model.Is4kRequest + Is4kRequest = model.Is4kRequest, + Source = model.Source }; } diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs index 7d84a0b40..682a999eb 100644 --- a/src/Ombi.Core/Engine/MovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging; using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; @@ -22,7 +23,7 @@ namespace Ombi.Core.Engine { public class MovieSearchEngine : BaseMediaEngine, IMovieEngine { - public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, + public MovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub) : base(identity, service, r, um, mem, s, sub) { diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs index b9aa183d2..640d2ade3 100644 --- a/src/Ombi.Core/Engine/MusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs @@ -24,12 +24,13 @@ using Ombi.Settings.Settings.Models.External; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using System.ComponentModel; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine { public class MusicRequestEngine : BaseMediaEngine, IMusicRequestEngine { - public MusicRequestEngine(IRequestServiceMain requestService, IPrincipal user, + public MusicRequestEngine(IRequestServiceMain requestService, ICurrentUser user, INotificationHelper helper, IRuleEvaluator r, ILogger log, OmbiUserManager manager, IRepository rl, ICacheService cache, ISettingsService ombiSettings, IRepository sub, ILidarrApi lidarr, diff --git a/src/Ombi.Core/Engine/MusicSearchEngine.cs b/src/Ombi.Core/Engine/MusicSearchEngine.cs index 89bae7069..2602bf71e 100644 --- a/src/Ombi.Core/Engine/MusicSearchEngine.cs +++ b/src/Ombi.Core/Engine/MusicSearchEngine.cs @@ -27,7 +27,7 @@ namespace Ombi.Core.Engine { public class MusicSearchEngine : BaseMediaEngine, IMusicSearchEngine { - public MusicSearchEngine(IPrincipal identity, IRequestServiceMain service, ILidarrApi lidarrApi, IMapper mapper, + public MusicSearchEngine(ICurrentUser identity, IRequestServiceMain service, ILidarrApi lidarrApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub, ISettingsService lidarrSettings) : base(identity, service, r, um, mem, s, sub) diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index 4b46e8151..5664d276f 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -32,7 +32,7 @@ namespace Ombi.Core.Engine { public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine { - public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, IPrincipal user, + public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, ICurrentUser user, INotificationHelper helper, IRuleEvaluator rule, OmbiUserManager manager, ILogger logger, ITvSender sender, IRepository rl, ISettingsService settings, ICacheService cache, IRepository sub, IMediaCacheService mediaCacheService) : base(user, requestService, rule, manager, cache, settings, sub) @@ -188,7 +188,7 @@ namespace Ombi.Core.Engine (await tvBuilder .GetShowInfo(tv.TheMovieDbId, tv.languageCode)) .CreateTvList(tv) - .CreateChild(tv, canRequestOnBehalf ? tv.RequestOnBehalf : user.Id); + .CreateChild(tv, canRequestOnBehalf ? tv.RequestOnBehalf : user.Id, tv.Source); await tvBuilder.BuildEpisodes(tv); diff --git a/src/Ombi.Core/Engine/TvSearchEngine.cs b/src/Ombi.Core/Engine/TvSearchEngine.cs index 518b97720..2747f262a 100644 --- a/src/Ombi.Core/Engine/TvSearchEngine.cs +++ b/src/Ombi.Core/Engine/TvSearchEngine.cs @@ -23,6 +23,7 @@ using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using System.Threading; using TraktSharp.Entities; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine { @@ -32,7 +33,7 @@ namespace Ombi.Core.Engine private readonly IImageService _imageService; private readonly IMovieDbApi _theMovieDbApi; - public TvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, + public TvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ISettingsService customizationSettings, ICacheService memCache, ISettingsService s, IRepository sub, IImageService imageService, IMovieDbApi theMovieDbApi) diff --git a/src/Ombi.Core/Engine/V2/CalendarEngine.cs b/src/Ombi.Core/Engine/V2/CalendarEngine.cs index b7ecc8ec6..8347141bb 100644 --- a/src/Ombi.Core/Engine/V2/CalendarEngine.cs +++ b/src/Ombi.Core/Engine/V2/CalendarEngine.cs @@ -5,6 +5,7 @@ using System.Security.Principal; using System.Threading.Tasks; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models.Search.V2; using Ombi.Core.Rule.Interfaces; using Ombi.Store.Entities; @@ -17,7 +18,7 @@ namespace Ombi.Core.Engine.V2 { public DateTime DaysAgo => DateTime.Now.AddDays(-90); public DateTime DaysAhead => DateTime.Now.AddDays(90); - public CalendarEngine(IPrincipal user, OmbiUserManager um, IRuleEvaluator rules, IMovieRequestRepository movieRepo, + public CalendarEngine(ICurrentUser user, OmbiUserManager um, IRuleEvaluator rules, IMovieRequestRepository movieRepo, ITvRequestRepository tvRequestRepo) : base(user, um, rules) { _movieRepo = movieRepo; diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index 576b511fa..3acd7d1f0 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -5,6 +5,7 @@ using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Models.Search.V2; @@ -28,7 +29,7 @@ namespace Ombi.Core.Engine.V2 { public class MovieSearchEngineV2 : BaseMediaEngine, IMovieEngineV2 { - public MovieSearchEngineV2(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, + public MovieSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub, ISettingsService customizationSettings, IMovieRequestEngine movieRequestEngine, IHttpClientFactory httpClientFactory) : base(identity, service, r, um, mem, s, sub) diff --git a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs index 44f792415..362a79e43 100644 --- a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs +++ b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs @@ -7,6 +7,7 @@ using Ombi.Api.MusicBrainz; using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search.V2; using Ombi.Core.Rule.Interfaces; @@ -25,7 +26,7 @@ namespace Ombi.Core.Engine.V2 { public class MultiSearchEngine : BaseMediaEngine, IMultiSearchEngine { - public MultiSearchEngine(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules, + public MultiSearchEngine(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService ombiSettings, IRepository sub, IMovieDbApi movieDbApi, ISettingsService lidarrSettings, IMusicBrainzApi musicApi) : base(identity, requestService, rules, um, cache, ombiSettings, sub) diff --git a/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs index b7d9575db..fc3fcf40e 100644 --- a/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs @@ -11,6 +11,7 @@ using Ombi.Api.Lidarr.Models; using Ombi.Api.MusicBrainz; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search.V2.Music; using Ombi.Core.Rule.Interfaces; @@ -31,7 +32,7 @@ namespace Ombi.Core.Engine.V2 private readonly ISettingsService _lidarrSettings; private readonly ILidarrApi _lidarrApi; - public MusicSearchEngineV2(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules, + public MusicSearchEngineV2(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService ombiSettings, IRepository sub, IMusicBrainzApi musicBrainzApi, ISettingsService lidarrSettings, ILidarrApi lidarrApi) diff --git a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs index 07f8ce981..46cd44bf1 100644 --- a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs @@ -25,6 +25,7 @@ using Ombi.Api.TheMovieDb.Models; using System.Diagnostics; using Ombi.Core.Engine.Interfaces; using Ombi.Core.Models.UI; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine.V2 { @@ -37,7 +38,7 @@ namespace Ombi.Core.Engine.V2 private readonly ISettingsService _customization; private readonly ITvRequestEngine _requestEngine; - public TvSearchEngineV2(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, + public TvSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService s, IRepository sub, IMovieDbApi movieApi, ISettingsService customization, ITvRequestEngine requestEngine) : base(identity, service, r, um, memCache, s, sub) diff --git a/src/Ombi.Core/Engine/VoteEngine.cs b/src/Ombi.Core/Engine/VoteEngine.cs index a63ba1604..3e7f6f542 100644 --- a/src/Ombi.Core/Engine/VoteEngine.cs +++ b/src/Ombi.Core/Engine/VoteEngine.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Models.UI; using Ombi.Core.Rule.Interfaces; @@ -20,7 +21,7 @@ namespace Ombi.Core.Engine { public class VoteEngine : BaseEngine, IVoteEngine { - public VoteEngine(IRepository votes, IPrincipal user, OmbiUserManager um, IRuleEvaluator r, ISettingsService voteSettings, + public VoteEngine(IRepository votes, ICurrentUser user, OmbiUserManager um, IRuleEvaluator r, ISettingsService voteSettings, IMusicRequestEngine musicRequestEngine, ITvRequestEngine tvRequestEngine, IMovieRequestEngine movieRequestEngine) : base(user, um, r) { _voteRepository = votes; diff --git a/src/Ombi.Core/Helpers/CurrentUser.cs b/src/Ombi.Core/Helpers/CurrentUser.cs new file mode 100644 index 000000000..974d59cd6 --- /dev/null +++ b/src/Ombi.Core/Helpers/CurrentUser.cs @@ -0,0 +1,47 @@ +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Authentication; +using Ombi.Helpers; +using Ombi.Store.Entities; +using System.Security.Principal; +using System.Threading.Tasks; + +namespace Ombi.Core.Helpers +{ + public class CurrentUser : ICurrentUser + { + private readonly IPrincipal _principle; + private readonly OmbiUserManager _userManager; + private OmbiUser _user; + public IIdentity Identity { get; set; } + + public CurrentUser(IPrincipal principle, OmbiUserManager userManager) + { + _principle = principle; + _userManager = userManager; + Identity = _principle?.Identity ?? null; + } + + public void SetUser(OmbiUser user) + { + _user = user; + } + + public string Username => Identity?.Name ?? _user?.UserName; + public async Task GetUser() + { + if (!Username.HasValue() && _user == null) + { + return null; + } + + if (_user != null) + { + return _user; + } + + var username = Username.ToUpper(); + return _user ??= await _userManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); + } + + } +} diff --git a/src/Ombi.Core/Helpers/ICurrentUser.cs b/src/Ombi.Core/Helpers/ICurrentUser.cs new file mode 100644 index 000000000..1cce973f3 --- /dev/null +++ b/src/Ombi.Core/Helpers/ICurrentUser.cs @@ -0,0 +1,15 @@ +using Ombi.Store.Entities; +using System.Security.Principal; +using System.Threading.Tasks; + +namespace Ombi.Core.Helpers +{ + public interface ICurrentUser + { + string Username { get; } + + Task GetUser(); + void SetUser(OmbiUser user); + IIdentity Identity { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs b/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs index 6843332c0..4053109da 100644 --- a/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs +++ b/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs @@ -53,7 +53,7 @@ namespace Ombi.Core.Helpers return this; } - public TvShowRequestBuilderV2 CreateChild(TvRequestViewModelV2 model, string userId) + public TvShowRequestBuilderV2 CreateChild(TvRequestViewModelV2 model, string userId, RequestSource source) { var animationGenre = TheMovieDbRecord.genres?.Any(s => s.name.Equals("Animation", StringComparison.InvariantCultureIgnoreCase)) ?? false; var animeKeyword = TheMovieDbRecord.Keywords?.KeywordsValue?.Any(s => s.Name.Equals("Anime", StringComparison.InvariantCultureIgnoreCase)) ?? false; @@ -68,7 +68,8 @@ namespace Ombi.Core.Helpers Title = TheMovieDbRecord.name, ReleaseYear = FirstAir, RequestedByAlias = model.RequestedByAlias, - SeriesType = animationGenre && animeKeyword ? SeriesType.Anime : SeriesType.Standard + SeriesType = animationGenre && animeKeyword ? SeriesType.Anime : SeriesType.Standard, + Source = source }; return this; diff --git a/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs b/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs index 39a5b6c2a..18125ed71 100644 --- a/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs +++ b/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs @@ -1,31 +1,5 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2018 Jamie Rees -// File: MovieRequestViewModel.cs -// Created By: Jamie Rees -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// ************************************************************************/ -#endregion - -using Newtonsoft.Json; +using Newtonsoft.Json; +using Ombi.Store.Entities.Requests; namespace Ombi.Core.Models.Requests { @@ -41,5 +15,11 @@ namespace Ombi.Core.Models.Requests /// [JsonIgnore] public string RequestedByAlias { get; set; } + + /// + /// Only set via list imports + /// + [JsonIgnore] + public RequestSource Source { get; set; } = RequestSource.Ombi; } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs b/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs index a9742fb32..e1df9553f 100644 --- a/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs +++ b/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Newtonsoft.Json; +using Ombi.Store.Entities.Requests; namespace Ombi.Core.Models.Requests { @@ -7,5 +8,6 @@ namespace Ombi.Core.Models.Requests { public int TheMovieDbId { get; set; } public string languageCode { get; set; } = "en"; + public RequestSource Source { get; set; } = RequestSource.Ombi; } } \ No newline at end of file diff --git a/src/Ombi.Core/Ombi.Core.csproj b/src/Ombi.Core/Ombi.Core.csproj index 0f7ca6845..67ecdbe13 100644 --- a/src/Ombi.Core/Ombi.Core.csproj +++ b/src/Ombi.Core/Ombi.Core.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs index 92c1b11a7..23d26625b 100644 --- a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs @@ -3,6 +3,7 @@ using System.Security.Principal; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Rule.Interfaces; using Ombi.Core.Services; @@ -15,20 +16,21 @@ namespace Ombi.Core.Rule.Rules.Request { public class AutoApproveRule : BaseRequestRule, IRules { - public AutoApproveRule(IPrincipal principal, OmbiUserManager um, IFeatureService featureService) + public AutoApproveRule(ICurrentUser principal, OmbiUserManager um, IFeatureService featureService) { User = principal; _manager = um; _featureService = featureService; } - private IPrincipal User { get; } + private ICurrentUser User { get; } private readonly OmbiUserManager _manager; private readonly IFeatureService _featureService; public async Task Execute(BaseRequest obj) { - var username = User.Identity.Name.ToUpper(); + var currentUser = await User.GetUser(); + var username = currentUser.UserName.ToUpper(); var user = await _manager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser) { diff --git a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs index 2546e1f29..e2e81e612 100644 --- a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs @@ -10,23 +10,25 @@ using Ombi.Core.Engine; using Ombi.Core.Rule.Interfaces; using Ombi.Helpers; using Ombi.Store.Entities.Requests; +using Ombi.Core.Helpers; namespace Ombi.Core.Rule.Rules.Request { public class CanRequestRule : BaseRequestRule, IRules { - public CanRequestRule(IPrincipal principal, OmbiUserManager manager) + public CanRequestRule(ICurrentUser principal, OmbiUserManager manager) { User = principal; _manager = manager; } - private IPrincipal User { get; } + private ICurrentUser User { get; } private readonly OmbiUserManager _manager; public async Task Execute(BaseRequest obj) { - var username = User.Identity.Name.ToUpper(); + var currentUser = await User.GetUser(); + var username = currentUser.UserName.ToUpper(); var user = await _manager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser) return Success(); diff --git a/src/Ombi.Core/Services/RequestLimitService.cs b/src/Ombi.Core/Services/RequestLimitService.cs index 83a87c7e7..d90e0d77c 100644 --- a/src/Ombi.Core/Services/RequestLimitService.cs +++ b/src/Ombi.Core/Services/RequestLimitService.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Helpers; using Ombi.Store.Entities; @@ -20,11 +21,11 @@ namespace Ombi.Core.Services } public class RequestLimitService : IRequestLimitService { - private readonly IPrincipal _user; + private readonly ICurrentUser _user; private readonly OmbiUserManager _userManager; private readonly IRepository _requestLog; - public RequestLimitService(IPrincipal user, OmbiUserManager userManager, IRepository rl) + public RequestLimitService(ICurrentUser user, OmbiUserManager userManager, IRepository rl) { _user = user; _userManager = userManager; @@ -141,7 +142,8 @@ namespace Ombi.Core.Services private async Task GetUser() { - var username = _user.Identity.Name.ToUpper(); + var currentUser = await _user.GetUser(); + var username = currentUser.UserName.ToUpper(); return await _userManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); } diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 3fb5cd643..691aca237 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -70,6 +70,7 @@ using Ombi.Api.RottenTomatoes; using System.Net.Http; using Microsoft.Extensions.Logging; using Ombi.Core.Services; +using Ombi.Core.Helpers; namespace Ombi.DependencyInjection { @@ -124,6 +125,8 @@ namespace Ombi.DependencyInjection var runtimeVersion = AssemblyHelper.GetRuntimeVersion(); services.AddSingleton(); services.AddScoped(sp => sp.GetService().HttpContext.User); + // HttpContext User is null for background jobs + services.AddScoped(sp => new CurrentUser(sp.GetService()?.HttpContext?.User ?? null, sp.GetService())); services.AddHttpClient("OmbiClient", client => { client.DefaultRequestHeaders.Add("User-Agent", $"Ombi/{runtimeVersion} (https://ombi.io/)"); @@ -233,6 +236,7 @@ namespace Ombi.DependencyInjection services.AddSingleton(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj index e65f2d5a2..93b839c07 100644 --- a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj +++ b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Helpers/Ombi.Helpers.csproj b/src/Ombi.Helpers/Ombi.Helpers.csproj index afc881d94..2098fa51f 100644 --- a/src/Ombi.Helpers/Ombi.Helpers.csproj +++ b/src/Ombi.Helpers/Ombi.Helpers.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Helpers/PlexHelper.cs b/src/Ombi.Helpers/PlexHelper.cs index 7951a7edf..4ae39f6ce 100644 --- a/src/Ombi.Helpers/PlexHelper.cs +++ b/src/Ombi.Helpers/PlexHelper.cs @@ -104,7 +104,7 @@ namespace Ombi.Helpers return new ProviderId(); } - public static string GetPlexMediaUrl(string machineId, int mediaId, string plexHost) + public static string GetPlexMediaUrl(string machineId, string mediaId, string plexHost) { var url = $"web/#!/server/{machineId}/details?key=%2flibrary%2Fmetadata%2F{mediaId}"; diff --git a/src/Ombi.Hubs/Ombi.Hubs.csproj b/src/Ombi.Hubs/Ombi.Hubs.csproj index fc65e2dc2..f6bee2eb1 100644 --- a/src/Ombi.Hubs/Ombi.Hubs.csproj +++ b/src/Ombi.Hubs/Ombi.Hubs.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.I18n/Ombi.I18n.csproj b/src/Ombi.I18n/Ombi.I18n.csproj index f44037974..a3387cdea 100644 --- a/src/Ombi.I18n/Ombi.I18n.csproj +++ b/src/Ombi.I18n/Ombi.I18n.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Mapping/Ombi.Mapping.csproj b/src/Ombi.Mapping/Ombi.Mapping.csproj index 9ad1f1135..322942cf2 100644 --- a/src/Ombi.Mapping/Ombi.Mapping.csproj +++ b/src/Ombi.Mapping/Ombi.Mapping.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj b/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj index 87a876caa..99e7509b4 100644 --- a/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj +++ b/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Notifications/Ombi.Notifications.csproj b/src/Ombi.Notifications/Ombi.Notifications.csproj index 6b497c23e..41fd3ae17 100644 --- a/src/Ombi.Notifications/Ombi.Notifications.csproj +++ b/src/Ombi.Notifications/Ombi.Notifications.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj b/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj index fd23ee60b..d8e698d0e 100644 --- a/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj +++ b/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj @@ -19,6 +19,7 @@ + diff --git a/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs b/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs index da128794c..8540f0037 100644 --- a/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs +++ b/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs @@ -47,7 +47,7 @@ namespace Ombi.Schedule.Tests } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); _mocker.Setup(x => x.GetFirstContentByCustom(It.IsAny>>())) .Returns(Task.FromResult(new PlexServerContent())); @@ -76,18 +76,18 @@ namespace Ombi.Schedule.Tests Id = "imdb://tt0322259" } }, - ratingKey = 1 + ratingKey = "1" }, } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed); var first = contentToAdd.First(); Assert.That(first.ImdbId, Is.EqualTo("tt0322259")); - _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(),It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(),It.IsAny()), Times.Never); } [Test] @@ -99,7 +99,7 @@ namespace Ombi.Schedule.Tests { new Metadata { - ratingKey = 11, + ratingKey = "11", title = "test1", year = 2021, type = "movie", @@ -107,8 +107,8 @@ namespace Ombi.Schedule.Tests } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); - _mocker.Setup(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny())) + var contentProcessed = new Dictionary(); + _mocker.Setup(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.FromResult(new PlexMetadata { MediaContainer = new Mediacontainer @@ -117,7 +117,7 @@ namespace Ombi.Schedule.Tests { new Metadata { - ratingKey = 11, + ratingKey = "11", title = "test1", year = 2021, type = "movie", @@ -138,7 +138,7 @@ namespace Ombi.Schedule.Tests var first = contentToAdd.First(); Assert.That(first.ImdbId, Is.EqualTo("tt0322259")); - _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); } [Test] @@ -150,7 +150,7 @@ namespace Ombi.Schedule.Tests { new Metadata { - ratingKey = 11, + ratingKey = "11", title = "test1", year = 2021, type = "movie", @@ -165,7 +165,7 @@ namespace Ombi.Schedule.Tests } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); _mocker.Setup(x => x.GetFirstContentByCustom(It.IsAny>>())) .Returns(Task.FromResult(new PlexServerContent @@ -188,7 +188,7 @@ namespace Ombi.Schedule.Tests { new Metadata { - ratingKey = 11, + ratingKey = "11", title = "test1", year = 2021, type = "movie", @@ -203,7 +203,7 @@ namespace Ombi.Schedule.Tests } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); _mocker.Setup(x => x.GetFirstContentByCustom(It.IsAny>>())) .Returns(Task.FromResult(new PlexServerContent diff --git a/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs b/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs new file mode 100644 index 000000000..b4759e280 --- /dev/null +++ b/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs @@ -0,0 +1,375 @@ +using Moq; +using Moq.AutoMock; +using NUnit.Framework; +using Ombi.Api.Plex; +using Ombi.Api.Plex.Models; +using Ombi.Core.Engine; +using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Models.Requests; +using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; +using Ombi.Schedule.Jobs.Plex; +using Ombi.Store.Entities; +using Ombi.Test.Common; +using Quartz; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Ombi.Schedule.Tests +{ + [TestFixture] + public class PlexWatchlistImportTests + { + + private PlexWatchlistImport _subject; + private AutoMocker _mocker; + private Mock _context; + + [SetUp] + public void Setup() + { + _mocker = new AutoMocker(); + var um = MockHelper.MockUserManager(new List { new OmbiUser { Id = "abc", UserType = UserType.PlexUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" } }); + _mocker.Use(um); + _context = _mocker.GetMock(); + _context.Setup(x => x.CancellationToken).Returns(CancellationToken.None); + _subject = _mocker.CreateInstance(); + } + + [Test] + public async Task TerminatesWhenPlexIsNotEnabled() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = false, EnableWatchlistImport = true }); + await _subject.Execute(null); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Never); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + } + [Test] + public async Task TerminatesWhenWatchlistIsNotEnabled() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = false }); + await _subject.Execute(null); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Never); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + } + + [Test] + public async Task EmptyWatchList() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer()); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + } + + [Test] + public async Task NoPlexUsersWithToken() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + var um = MockHelper.MockUserManager(new List + { + new OmbiUser { Id = "abc", UserType = UserType.EmbyUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.LocalUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.SystemUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.JellyfinUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.EmbyConnectUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.PlexUser, UserName = "abc", NormalizedUserName = "ABC" }, + }); + _mocker.Use(um); + _subject = _mocker.CreateInstance(); + + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Never); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + } + + + [Test] + public async Task MovieRequestFromWatchList_NoGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestMovie(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.Is(x => x.TheMovieDbId == 123)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + } + + + [Test] + public async Task TvRequestFromWatchList_NoGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "show", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestTvShow(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestTvShow(It.Is(x => x.TheMovieDbId == 123)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + } + + [Test] + public async Task MovieRequestFromWatchList_AlreadyRequested() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestMovie(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { ErrorCode = ErrorCode.AlreadyRequested, ErrorMessage = "Requested" }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.Is(x => x.TheMovieDbId == 123)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + } + + [Test] + public async Task TvRequestFromWatchList_AlreadyRequested() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "show", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestTvShow(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { ErrorCode = ErrorCode.AlreadyRequested, ErrorMessage = "Requested" }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestTvShow(It.Is(x => x.TheMovieDbId == 123)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + } + + [Test] + public async Task MovieRequestFromWatchList_NoTmdbGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "imdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestMovie(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Never); + } + + [Test] + public async Task TvRequestFromWatchList_NoTmdbGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "imdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestTvShow(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestTvShow(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Never); + } + } +} diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexWatchlistImport.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexWatchlistImport.cs new file mode 100644 index 000000000..2dd6d46e4 --- /dev/null +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexWatchlistImport.cs @@ -0,0 +1,6 @@ +namespace Ombi.Schedule.Jobs.Plex +{ + public interface IPlexWatchlistImport : IBaseJob + { + } +} \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs b/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs index fc46e88b7..84748c1f7 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs @@ -5,7 +5,7 @@ namespace Ombi.Schedule.Jobs.Plex.Models { public class ProcessedContent { - public IEnumerable Content { get; set; } + public IEnumerable Content { get; set; } public IEnumerable Episodes { get; set; } public bool HasProcessedContent => Content?.Any() ?? false; diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index 62d0fb1b9..170f6b943 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -167,7 +167,7 @@ namespace Ombi.Schedule.Jobs.Plex private async Task ProcessServer(PlexServers servers, bool recentlyAddedSearch) { var retVal = new ProcessedContent(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); var episodesProcessed = new List(); Logger.LogDebug("Getting all content from server {0}", servers.Name); var allContent = await GetAllContent(servers, recentlyAddedSearch); @@ -290,7 +290,7 @@ namespace Ombi.Schedule.Jobs.Plex } public async Task MovieLoop(PlexServers servers, Mediacontainer content, HashSet contentToAdd, - Dictionary contentProcessed) + Dictionary contentProcessed) { Logger.LogDebug("Processing Movies"); foreach (var movie in content?.Metadata ?? Array.Empty()) @@ -437,7 +437,7 @@ namespace Ombi.Schedule.Jobs.Plex } } - private async Task ProcessTvShow(PlexServers servers, Metadata show, HashSet contentToAdd, Dictionary contentProcessed) + private async Task ProcessTvShow(PlexServers servers, Metadata show, HashSet contentToAdd, Dictionary contentProcessed) { var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, show.ratingKey); diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs b/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs new file mode 100644 index 000000000..10e34bf20 --- /dev/null +++ b/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs @@ -0,0 +1,149 @@ +using Microsoft.Extensions.Logging; +using Ombi.Api.Plex; +using Ombi.Api.Plex.Models; +using Ombi.Core.Authentication; +using Ombi.Core.Engine; +using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Models.Requests; +using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; +using Ombi.Helpers; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Quartz; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Ombi.Schedule.Jobs.Plex +{ + public class PlexWatchlistImport : IPlexWatchlistImport + { + private readonly IPlexApi _plexApi; + private readonly ISettingsService _settings; + private readonly OmbiUserManager _ombiUserManager; + private readonly IMovieRequestEngine _movieRequestEngine; + private readonly ITvRequestEngine _tvRequestEngine; + private readonly ILogger _logger; + + public PlexWatchlistImport(IPlexApi plexApi, ISettingsService settings, OmbiUserManager ombiUserManager, + IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine, + ILogger logger) + { + _plexApi = plexApi; + _settings = settings; + _ombiUserManager = ombiUserManager; + _movieRequestEngine = movieRequestEngine; + _tvRequestEngine = tvRequestEngine; + _logger = logger; + } + + public async Task Execute(IJobExecutionContext context) + { + var settings = await _settings.GetSettingsAsync(); + if (!settings.Enable || !settings.EnableWatchlistImport) + { + return; + } + + var plexUsersWithTokens = _ombiUserManager.Users.Where(x => x.UserType == UserType.PlexUser && x.MediaServerToken != null).ToList(); + foreach (var user in plexUsersWithTokens) + { + var watchlist = await _plexApi.GetWatchlist(user.MediaServerToken, context?.CancellationToken ?? CancellationToken.None); + if (watchlist == null || !(watchlist.MediaContainer?.Metadata?.Any() ?? false)) + { + return; + } + + var items = watchlist.MediaContainer.Metadata; + foreach (var item in items) + { + var providerIds = await GetProviderIds(user.MediaServerToken, item, context?.CancellationToken ?? CancellationToken.None); + if (!providerIds.TheMovieDb.HasValue()) + { + // We need a MovieDbId to support this; + return; + } + switch (item.type) + { + case "show": + await ProcessShow(int.Parse(providerIds.TheMovieDb), user, context?.CancellationToken ?? CancellationToken.None); + break; + case "movie": + await ProcessMovie(int.Parse(providerIds.TheMovieDb), user, context?.CancellationToken ?? CancellationToken.None); + break; + } + } + } + } + + private async Task ProcessMovie(int theMovieDbId, OmbiUser user, CancellationToken cancellationToken) + { + _movieRequestEngine.SetUser(user); + var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist}); + if (response.IsError) + { + if (response.ErrorCode == ErrorCode.AlreadyRequested) + { + return; + } + _logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'"); + } + else + { + _logger.LogInformation($"Added title from PlexWatchlist for user '{user.UserName}'. {response.Message}"); + } + } + + + private async Task ProcessShow(int theMovieDbId, OmbiUser user, CancellationToken cancellationToken) + { + _tvRequestEngine.SetUser(user); + var response = await _tvRequestEngine.RequestTvShow(new TvRequestViewModelV2 { RequestAll = true, TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist }); + if (response.IsError) + { + if (response.ErrorCode == ErrorCode.AlreadyRequested) + { + return; + } + _logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'"); + } + else + { + _logger.LogInformation($"Added title from PlexWatchlist for user '{user.UserName}'. {response.Message}"); + } + } + + private async Task GetProviderIds(string authToken, Metadata movie, CancellationToken cancellationToken) + { + var guids = new List(); + if (!movie.Guid.Any()) + { + var metaData = await _plexApi.GetWatchlistMetadata(movie.ratingKey, authToken, cancellationToken); + + var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); + guids.Add(meta.guid); + if (meta.Guid != null) + { + foreach (var g in meta.Guid) + { + guids.Add(g.Id); + } + } + } + else + { + // Currently a Plex Pass feature only + foreach (var g in movie.Guid) + { + guids.Add(g.Id); + } + } + var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); + return providerIds; + } + + public void Dispose() { } + } +} diff --git a/src/Ombi.Schedule/Ombi.Schedule.csproj b/src/Ombi.Schedule/Ombi.Schedule.csproj index ed1a7d9a1..a972aa6bb 100644 --- a/src/Ombi.Schedule/Ombi.Schedule.csproj +++ b/src/Ombi.Schedule/Ombi.Schedule.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Schedule/OmbiScheduler.cs b/src/Ombi.Schedule/OmbiScheduler.cs index 8e45be57c..41602f641 100644 --- a/src/Ombi.Schedule/OmbiScheduler.cs +++ b/src/Ombi.Schedule/OmbiScheduler.cs @@ -91,6 +91,7 @@ namespace Ombi.Schedule await OmbiQuartz.Instance.AddJob(nameof(IPlexUserImporter), "Plex", JobSettingsHelper.UserImporter(s)); await OmbiQuartz.Instance.AddJob(nameof(IPlexEpisodeSync), "Plex", null); await OmbiQuartz.Instance.AddJob(nameof(IPlexAvailabilityChecker), "Plex", null); + await OmbiQuartz.Instance.AddJob(nameof(IPlexWatchlistImport), "Plex", JobSettingsHelper.PlexWatchlistImport(s)); } private static async Task AddEmby(JobSettings s) diff --git a/src/Ombi.Settings/Ombi.Settings.csproj b/src/Ombi.Settings/Ombi.Settings.csproj index 4b3aa4c60..3821892f0 100644 --- a/src/Ombi.Settings/Ombi.Settings.csproj +++ b/src/Ombi.Settings/Ombi.Settings.csproj @@ -6,7 +6,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs b/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs index 6cf021f7c..5917e2592 100644 --- a/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs @@ -7,6 +7,7 @@ namespace Ombi.Core.Settings.Models.External public sealed class PlexSettings : Ombi.Settings.Settings.Models.Settings { public bool Enable { get; set; } + public bool EnableWatchlistImport { get; set; } /// /// This is the ClientId for OAuth /// diff --git a/src/Ombi.Settings/Settings/Models/JobSettings.cs b/src/Ombi.Settings/Settings/Models/JobSettings.cs index ac7ab3bdc..cc4ed2e23 100644 --- a/src/Ombi.Settings/Settings/Models/JobSettings.cs +++ b/src/Ombi.Settings/Settings/Models/JobSettings.cs @@ -19,5 +19,6 @@ public string RetryRequests { get; set; } public string MediaDatabaseRefresh { get; set; } public string AutoDeleteRequests { get; set; } + public string PlexWatchlistImport { get; set; } } } diff --git a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs index e580e1977..b0839cce6 100644 --- a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs +++ b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs @@ -54,6 +54,11 @@ namespace Ombi.Settings.Settings.Models { return ValidateCron(Get(s.UserImporter, Cron.Daily())); } + + public static string PlexWatchlistImport(JobSettings s) + { + return ValidateCron(Get(s.PlexWatchlistImport, Cron.Daily())); + } public static string Newsletter(JobSettings s) { diff --git a/src/Ombi.Store/Entities/OmbiUser.cs b/src/Ombi.Store/Entities/OmbiUser.cs index 1b7ea6f7c..376db28f7 100644 --- a/src/Ombi.Store/Entities/OmbiUser.cs +++ b/src/Ombi.Store/Entities/OmbiUser.cs @@ -36,6 +36,7 @@ namespace Ombi.Store.Entities public RequestLimitType? MusicRequestLimitType { get; set; } public string UserAccessToken { get; set; } + public string MediaServerToken { get; set; } public List NotificationUserIds { get; set; } public List UserNotificationPreferences { get; set; } diff --git a/src/Ombi.Store/Entities/PlexEpisode.cs b/src/Ombi.Store/Entities/PlexEpisode.cs index 02cfc8a07..a9628a13d 100644 --- a/src/Ombi.Store/Entities/PlexEpisode.cs +++ b/src/Ombi.Store/Entities/PlexEpisode.cs @@ -7,15 +7,15 @@ namespace Ombi.Store.Entities [Table("PlexEpisode")] public class PlexEpisode : MediaServerEpisode { - public int Key { get; set; } // RatingKey + public string Key { get; set; } // RatingKey /// /// The parent key. /// - public int ParentKey { get; set; } + public string ParentKey { get; set; } /// /// The grandparent key. /// - public int GrandparentKey { get; set; } + public string GrandparentKey { get; set; } [NotMapped] public PlexServerContent PlexSeries { diff --git a/src/Ombi.Store/Entities/PlexServerContent.cs b/src/Ombi.Store/Entities/PlexServerContent.cs index f33ddb2f1..8af5e250e 100644 --- a/src/Ombi.Store/Entities/PlexServerContent.cs +++ b/src/Ombi.Store/Entities/PlexServerContent.cs @@ -40,7 +40,7 @@ namespace Ombi.Store.Entities /// /// Plex's internal ID for this item /// - public int Key { get; set; } + public string Key { get; set; } public int? RequestId { get; set; } @@ -50,9 +50,9 @@ namespace Ombi.Store.Entities [Table("PlexSeasonsContent")] public class PlexSeasonsContent : Entity { - public int PlexContentId { get; set; } + public string PlexContentId { get; set; } public int SeasonNumber { get; set; } - public int SeasonKey { get; set; } - public int ParentKey { get; set; } + public string SeasonKey { get; set; } + public string ParentKey { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/Requests/BaseRequest.cs b/src/Ombi.Store/Entities/Requests/BaseRequest.cs index f26bcc8ba..9c564376b 100644 --- a/src/Ombi.Store/Entities/Requests/BaseRequest.cs +++ b/src/Ombi.Store/Entities/Requests/BaseRequest.cs @@ -22,6 +22,8 @@ namespace Ombi.Store.Entities.Requests [ForeignKey(nameof(RequestedUserId))] public OmbiUser RequestedUser { get; set; } + public RequestSource Source { get; set; } = RequestSource.Ombi; + [NotMapped] public virtual bool CanApprove => !Approved && !Available; diff --git a/src/Ombi.Store/Entities/Requests/RequestSource.cs b/src/Ombi.Store/Entities/Requests/RequestSource.cs new file mode 100644 index 000000000..44ccc20d8 --- /dev/null +++ b/src/Ombi.Store/Entities/Requests/RequestSource.cs @@ -0,0 +1,8 @@ +namespace Ombi.Store.Entities.Requests +{ + public enum RequestSource + { + Ombi = 0, + PlexWatchlist = 1 + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.Designer.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.Designer.cs new file mode 100644 index 000000000..e0ca84108 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.Designer.cs @@ -0,0 +1,535 @@ +// +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("20220407114744_PlexIds")] + partial class PlexIds + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .HasColumnType("longtext"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.Property("PercentOfTracks") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TrackCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("GrandparentKey") + .HasColumnType("varchar(255)"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("ParentKey") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("longtext"); + + b.Property("PlexContentId") + .HasColumnType("longtext"); + + b.Property("PlexServerContentId") + .HasColumnType("int"); + + b.Property("SeasonKey") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("ReleaseYear") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("HasRegular") + .HasColumnType("tinyint(1)"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("MovieDbId") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.cs new file mode 100644 index 000000000..826260c93 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.cs @@ -0,0 +1,176 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + public partial class PlexIds : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "varchar(255)", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "varchar(255)", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "int", + nullable: false, + oldClrType: typeof(string), + oldType: "varchar(255)") + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "varchar(255)", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs index b75c45665..f55793b72 100644 --- a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs @@ -276,14 +276,14 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("EpisodeNumber") .HasColumnType("int"); - b.Property("GrandparentKey") - .HasColumnType("int"); + b.Property("GrandparentKey") + .HasColumnType("varchar(255)"); - b.Property("Key") - .HasColumnType("int"); + b.Property("Key") + .HasColumnType("longtext"); - b.Property("ParentKey") - .HasColumnType("int"); + b.Property("ParentKey") + .HasColumnType("longtext"); b.Property("SeasonNumber") .HasColumnType("int"); @@ -304,17 +304,17 @@ namespace Ombi.Store.Migrations.ExternalMySql .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("ParentKey") - .HasColumnType("int"); + b.Property("ParentKey") + .HasColumnType("longtext"); - b.Property("PlexContentId") - .HasColumnType("int"); + b.Property("PlexContentId") + .HasColumnType("longtext"); b.Property("PlexServerContentId") .HasColumnType("int"); - b.Property("SeasonKey") - .HasColumnType("int"); + b.Property("SeasonKey") + .HasColumnType("longtext"); b.Property("SeasonNumber") .HasColumnType("int"); @@ -341,8 +341,9 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("ImdbId") .HasColumnType("longtext"); - b.Property("Key") - .HasColumnType("int"); + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(255)"); b.Property("Quality") .HasColumnType("longtext"); @@ -498,9 +499,7 @@ namespace Ombi.Store.Migrations.ExternalMySql b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") .WithMany("Episodes") .HasForeignKey("GrandparentKey") - .HasPrincipalKey("Key") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasPrincipalKey("Key"); b.Navigation("Series"); }); diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.Designer.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.Designer.cs new file mode 100644 index 000000000..eb5a07394 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.Designer.cs @@ -0,0 +1,533 @@ +// +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("20220406212825_PlexIds")] + partial class PlexIds + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.Property("PercentOfTracks") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackCount") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("GrandparentKey") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("ParentKey") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("TEXT"); + + b.Property("PlexContentId") + .HasColumnType("TEXT"); + + b.Property("PlexServerContentId") + .HasColumnType("INTEGER"); + + b.Property("SeasonKey") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("ReleaseYear") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("HasRegular") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("MovieDbId") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.cs new file mode 100644 index 000000000..4f3d92ece --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.cs @@ -0,0 +1,162 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + public partial class PlexIds : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "INTEGER", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs index 302f5f537..ca7ba7a96 100644 --- a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs @@ -274,14 +274,14 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("EpisodeNumber") .HasColumnType("INTEGER"); - b.Property("GrandparentKey") - .HasColumnType("INTEGER"); + b.Property("GrandparentKey") + .HasColumnType("TEXT"); - b.Property("Key") - .HasColumnType("INTEGER"); + b.Property("Key") + .HasColumnType("TEXT"); - b.Property("ParentKey") - .HasColumnType("INTEGER"); + b.Property("ParentKey") + .HasColumnType("TEXT"); b.Property("SeasonNumber") .HasColumnType("INTEGER"); @@ -302,17 +302,17 @@ namespace Ombi.Store.Migrations.ExternalSqlite .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("ParentKey") - .HasColumnType("INTEGER"); + b.Property("ParentKey") + .HasColumnType("TEXT"); - b.Property("PlexContentId") - .HasColumnType("INTEGER"); + b.Property("PlexContentId") + .HasColumnType("TEXT"); b.Property("PlexServerContentId") .HasColumnType("INTEGER"); - b.Property("SeasonKey") - .HasColumnType("INTEGER"); + b.Property("SeasonKey") + .HasColumnType("TEXT"); b.Property("SeasonNumber") .HasColumnType("INTEGER"); @@ -339,8 +339,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("ImdbId") .HasColumnType("TEXT"); - b.Property("Key") - .HasColumnType("INTEGER"); + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); b.Property("Quality") .HasColumnType("TEXT"); @@ -496,9 +497,7 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") .WithMany("Episodes") .HasForeignKey("GrandparentKey") - .HasPrincipalKey("Key") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasPrincipalKey("Key"); b.Navigation("Series"); }); diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.Designer.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.Designer.cs new file mode 100644 index 000000000..c4d1fd2f1 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.Designer.cs @@ -0,0 +1,1285 @@ +// +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.OmbiMySql +{ + [DbContext(typeof(OmbiMySqlContext))] + [Migration("20220407114619_RequestSource")] + partial class RequestSource + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AuditArea") + .HasColumnType("int"); + + b.Property("AuditType") + .HasColumnType("int"); + + b.Property("DateTime") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("User") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("PlayerId") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Alias") + .HasColumnType("longtext"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("int"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("int"); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("LastLoggedIn") + .HasColumnType("datetime(6)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("MediaServerToken") + .HasColumnType("longtext"); + + b.Property("MovieRequestLimit") + .HasColumnType("int"); + + b.Property("MovieRequestLimitType") + .HasColumnType("int"); + + b.Property("MusicRequestLimit") + .HasColumnType("int"); + + b.Property("MusicRequestLimitType") + .HasColumnType("int"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("ProviderUserId") + .HasColumnType("longtext"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserAccessToken") + .HasColumnType("longtext"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("UserType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("AlbumId") + .HasColumnType("longtext"); + + b.Property("ContentId") + .HasColumnType("int"); + + b.Property("ContentType") + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Completed") + .HasColumnType("datetime(6)"); + + b.Property("Dts") + .HasColumnType("datetime(6)"); + + b.Property("Error") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Cover") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("Disk") + .HasColumnType("longtext"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("Rating") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("ParentRequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("SeriesType") + .HasColumnType("int"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("IssuesId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDate") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IssueCategoryId") + .HasColumnType("int"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("ResovledDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("UserReportedId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Approved4K") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Available4K") + .HasColumnType("tinyint(1)"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("Denied4K") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("DeniedReason4K") + .HasColumnType("longtext"); + + b.Property("DigitalReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Has4KRequest") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("LangCode") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("datetime(6)"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedDate4k") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("RootPathOverride") + .HasColumnType("int"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeCount") + .HasColumnType("int"); + + b.Property("RequestDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("ExternalProviderId") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("LanguageProfile") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RootFolder") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TotalSeasons") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RadarrQualityProfile") + .HasColumnType("int"); + + b.Property("RadarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrQualityProfile") + .HasColumnType("int"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("int"); + + b.Property("SonarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("tinyint(1)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("VoteType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AirDate") + .HasColumnType("datetime(6)"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("Requested") + .HasColumnType("tinyint(1)"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ChildRequestId") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + 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") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.cs new file mode 100644 index 000000000..1020b4d63 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.cs @@ -0,0 +1,59 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + public partial class RequestSource : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Source", + table: "MovieRequests", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "Source", + table: "ChildRequests", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "MediaServerToken", + table: "AspNetUsers", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "Source", + table: "AlbumRequests", + type: "int", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Source", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Source", + table: "ChildRequests"); + + migrationBuilder.DropColumn( + name: "MediaServerToken", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "Source", + table: "AlbumRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs index 5a5c28b40..e66e29521 100644 --- a/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs @@ -283,6 +283,9 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("LockoutEnd") .HasColumnType("datetime(6)"); + b.Property("MediaServerToken") + .HasColumnType("longtext"); + b.Property("MovieRequestLimit") .HasColumnType("int"); @@ -468,6 +471,9 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("RequestedUserId") .HasColumnType("varchar(255)"); + b.Property("Source") + .HasColumnType("int"); + b.Property("Title") .HasColumnType("longtext"); @@ -526,6 +532,9 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("SeriesType") .HasColumnType("int"); + b.Property("Source") + .HasColumnType("int"); + b.Property("Title") .HasColumnType("longtext"); @@ -728,6 +737,9 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("RootPathOverride") .HasColumnType("int"); + b.Property("Source") + .HasColumnType("int"); + b.Property("Status") .HasColumnType("longtext"); diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.Designer.cs new file mode 100644 index 000000000..2d3d8c76c --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.Designer.cs @@ -0,0 +1,1274 @@ +// +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.OmbiSqlite +{ + [DbContext(typeof(OmbiSqliteContext))] + [Migration("20220406213123_PlexIds")] + partial class PlexIds + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuditArea") + .HasColumnType("INTEGER"); + + b.Property("AuditType") + .HasColumnType("INTEGER"); + + b.Property("DateTime") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("PlayerId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Alias") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("LastLoggedIn") + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("MediaServerToken") + .HasColumnType("TEXT"); + + b.Property("MovieRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MovieRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("ProviderUserId") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserAccessToken") + .HasColumnType("TEXT"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("AlbumId") + .HasColumnType("TEXT"); + + b.Property("ContentId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("Dts") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Cover") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("Disk") + .HasColumnType("TEXT"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Rating") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("ParentRequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("SeriesType") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("IssuesId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDate") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IssueCategoryId") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("ResovledDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("UserReportedId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Approved4K") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Available4K") + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("Denied4K") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("DeniedReason4K") + .HasColumnType("TEXT"); + + b.Property("DigitalReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Has4KRequest") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("LangCode") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedDate4k") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("RootPathOverride") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeCount") + .HasColumnType("INTEGER"); + + b.Property("RequestDate") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("ExternalProviderId") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("LanguageProfile") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RootFolder") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TotalSeasons") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RadarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("RadarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VoteType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AirDate") + .HasColumnType("TEXT"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Requested") + .HasColumnType("INTEGER"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChildRequestId") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + 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") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.cs new file mode 100644 index 000000000..b83d441a0 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + public partial class PlexIds : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "MediaServerToken", + table: "AspNetUsers", + type: "TEXT", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "MediaServerToken", + table: "AspNetUsers"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs new file mode 100644 index 000000000..32f92ff6c --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs @@ -0,0 +1,1283 @@ +// +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.OmbiSqlite +{ + [DbContext(typeof(OmbiSqliteContext))] + [Migration("20220407072656_RequestSource")] + partial class RequestSource + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuditArea") + .HasColumnType("INTEGER"); + + b.Property("AuditType") + .HasColumnType("INTEGER"); + + b.Property("DateTime") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("PlayerId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Alias") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("LastLoggedIn") + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("MediaServerToken") + .HasColumnType("TEXT"); + + b.Property("MovieRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MovieRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("ProviderUserId") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserAccessToken") + .HasColumnType("TEXT"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("AlbumId") + .HasColumnType("TEXT"); + + b.Property("ContentId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("Dts") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Cover") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("Disk") + .HasColumnType("TEXT"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Rating") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("Source") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("ParentRequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("SeriesType") + .HasColumnType("INTEGER"); + + b.Property("Source") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("IssuesId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDate") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IssueCategoryId") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("ResovledDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("UserReportedId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Approved4K") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Available4K") + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("Denied4K") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("DeniedReason4K") + .HasColumnType("TEXT"); + + b.Property("DigitalReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Has4KRequest") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("LangCode") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedDate4k") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("RootPathOverride") + .HasColumnType("INTEGER"); + + b.Property("Source") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeCount") + .HasColumnType("INTEGER"); + + b.Property("RequestDate") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("ExternalProviderId") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("LanguageProfile") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RootFolder") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TotalSeasons") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RadarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("RadarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VoteType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AirDate") + .HasColumnType("TEXT"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Requested") + .HasColumnType("INTEGER"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChildRequestId") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + 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") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.cs new file mode 100644 index 000000000..c1a2400d0 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + public partial class RequestSource : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Source", + table: "MovieRequests", + type: "INTEGER", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "Source", + table: "ChildRequests", + type: "INTEGER", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "Source", + table: "AlbumRequests", + type: "INTEGER", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Source", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Source", + table: "ChildRequests"); + + migrationBuilder.DropColumn( + name: "Source", + table: "AlbumRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs index 528989d02..f9ce86bae 100644 --- a/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs @@ -281,6 +281,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("LockoutEnd") .HasColumnType("TEXT"); + b.Property("MediaServerToken") + .HasColumnType("TEXT"); + b.Property("MovieRequestLimit") .HasColumnType("INTEGER"); @@ -466,6 +469,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("RequestedUserId") .HasColumnType("TEXT"); + b.Property("Source") + .HasColumnType("INTEGER"); + b.Property("Title") .HasColumnType("TEXT"); @@ -524,6 +530,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("SeriesType") .HasColumnType("INTEGER"); + b.Property("Source") + .HasColumnType("INTEGER"); + b.Property("Title") .HasColumnType("TEXT"); @@ -726,6 +735,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("RootPathOverride") .HasColumnType("INTEGER"); + b.Property("Source") + .HasColumnType("INTEGER"); + b.Property("Status") .HasColumnType("TEXT"); diff --git a/src/Ombi.Store/Ombi.Store.csproj b/src/Ombi.Store/Ombi.Store.csproj index f35da548f..1c145f55a 100644 --- a/src/Ombi.Store/Ombi.Store.csproj +++ b/src/Ombi.Store/Ombi.Store.csproj @@ -7,7 +7,7 @@ true - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Store/Repository/IPlexContentRepository.cs b/src/Ombi.Store/Repository/IPlexContentRepository.cs index f3c6d0ae2..aeb4aae0a 100644 --- a/src/Ombi.Store/Repository/IPlexContentRepository.cs +++ b/src/Ombi.Store/Repository/IPlexContentRepository.cs @@ -13,8 +13,8 @@ namespace Ombi.Store.Repository Task ContentExists(string providerId); Task Get(string providerId, ProviderType type); Task GetByType(string providerId, ProviderType type, MediaType mediaType); - Task GetByKey(int key); - Task GetEpisodeByKey(int key); + Task GetByKey(string key); + Task GetEpisodeByKey(string key); IEnumerable GetWhereContentByCustom(Expression> predicate); Task GetFirstContentByCustom(Expression> predicate); Task DeleteEpisode(PlexEpisode content); diff --git a/src/Ombi.Store/Repository/PlexContentRepository.cs b/src/Ombi.Store/Repository/PlexContentRepository.cs index 9ae5adce8..96dfbe8e1 100644 --- a/src/Ombi.Store/Repository/PlexContentRepository.cs +++ b/src/Ombi.Store/Repository/PlexContentRepository.cs @@ -92,7 +92,7 @@ namespace Ombi.Store.Repository return null; } - public async Task GetByKey(int key) + public async Task GetByKey(string key) { return await Db.PlexServerContent.Include(x => x.Seasons).FirstOrDefaultAsync(x => x.Key == key); } @@ -154,7 +154,7 @@ namespace Ombi.Store.Repository await InternalSaveChanges(); } - public async Task GetEpisodeByKey(int key) + public async Task GetEpisodeByKey(string key) { return await Db.PlexEpisode.FirstOrDefaultAsync(x => x.Key == key); } diff --git a/src/Ombi.Test.Common/Ombi.Test.Common.csproj b/src/Ombi.Test.Common/Ombi.Test.Common.csproj index 71b05f59c..512055143 100644 --- a/src/Ombi.Test.Common/Ombi.Test.Common.csproj +++ b/src/Ombi.Test.Common/Ombi.Test.Common.csproj @@ -2,7 +2,7 @@ net6.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj b/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj index 41ac19686..ddab7e3f8 100644 --- a/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj +++ b/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj @@ -7,7 +7,7 @@ 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts b/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts index 130a97c1c..36b75adb6 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts @@ -104,6 +104,13 @@ export interface IBaseRequest { canApprove: boolean; title: string; requestedByAlias: string; + source: RequestSource; +} + +export enum RequestSource +{ + Ombi = 0, + PlexWatchlist = 1 } export interface ITvRequests { diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts index 1dc94f261..95b1fba00 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts @@ -112,6 +112,7 @@ export interface IPublicInfo { export interface IPlexSettings extends ISettings { enable: boolean; + enableWatchlistImport: boolean; servers: IPlexServer[]; } @@ -219,6 +220,7 @@ export interface IJobSettings { mediaDatabaseRefresh: string; autoDeleteRequests: string; embyRecentlyAddedSync: string; + plexWatchlistImport: string; } export interface IIssueSettings extends ISettings { diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html index a288b76be..7fd3ce0ea 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html @@ -54,6 +54,11 @@ {{request.requestedDate | amUserLocale | amDateFormat: 'LL'}} +
+ {{'MediaDetails.RequestSource' | translate }} + {{RequestSource[request.source]}} +
+
{{'MediaDetails.DeniedReason' | translate }} {{request.deniedReason}} diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts index c11a0f61c..ade256a82 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts @@ -1,6 +1,6 @@ import { Component, ViewEncapsulation, Input, OnInit, Inject } from "@angular/core"; import { ISearchMovieResultV2 } from "../../../../interfaces/ISearchMovieResultV2"; -import { IMovieRequests } from "../../../../interfaces"; +import { IMovieRequests, RequestSource } from "../../../../interfaces"; import { SearchV2Service } from "../../../../services/searchV2.service"; import { IMovieRatings } from "../../../../interfaces/IRatings"; import { APP_BASE_HREF } from "@angular/common"; @@ -21,6 +21,7 @@ export class MovieInformationPanelComponent implements OnInit { public ratings: IMovieRatings; public streams: IStreamingData[]; + public RequestSource = RequestSource; public baseUrl: string; diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html index 4098bb748..ea34849d0 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.html @@ -9,6 +9,7 @@ user: request.requestedUser.userAlias, date: request.requestedDate | amLocal | amUserLocale | amDateFormat: 'LL' } }} - {{request.deniedReason}} +  {{'MediaDetails.RequestSource' | translate }} {{RequestSource[request.source]}} diff --git a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts index 2de85814c..e397e60ea 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/tv/panels/tv-requests/tv-requests-panel.component.ts @@ -1,5 +1,5 @@ import { Component, Input } from "@angular/core"; -import { IChildRequests, RequestType } from "../../../../../interfaces"; +import { IChildRequests, RequestSource, RequestType } from "../../../../../interfaces"; import { DenyDialogComponent } from "../../../shared/deny-dialog/deny-dialog.component"; import { MatDialog } from "@angular/material/dialog"; @@ -17,6 +17,8 @@ export class TvRequestsPanelComponent { @Input() public isAdmin: boolean; @Input() public manageOwnRequests: boolean; + public RequestSource = RequestSource; + public displayedColumns: string[] = ['number', 'title', 'airDate', 'status']; constructor(private requestService: RequestService, diff --git a/src/Ombi/ClientApp/src/app/services/job.service.ts b/src/Ombi/ClientApp/src/app/services/job.service.ts index 8bd08c4f5..6cece68d9 100644 --- a/src/Ombi/ClientApp/src/app/services/job.service.ts +++ b/src/Ombi/ClientApp/src/app/services/job.service.ts @@ -27,6 +27,10 @@ export class JobService extends ServiceHelpers { return this.http.post(`${this.url}plexUserImporter/`, {headers: this.headers}); } + public runPlexWatchlistImport(): Observable { + return this.http.post(`${this.url}plexwatchlist/`, {headers: this.headers}); + } + public runEmbyImporter(): Observable { return this.http.post(`${this.url}embyUserImporter/`, {headers: this.headers}); } diff --git a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html index e15a88b7f..47e7ef1cd 100644 --- a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html +++ b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html @@ -77,6 +77,13 @@ The Plex Sync is required
+
+ + Plex Watchlist Import + + The Plex Watchlist Import is required + +
diff --git a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts index 47d05776b..89131bc42 100644 --- a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts @@ -37,6 +37,7 @@ export class JobsComponent implements OnInit { mediaDatabaseRefresh: [x.mediaDatabaseRefresh, Validators.required], autoDeleteRequests: [x.autoDeleteRequests, Validators.required], embyRecentlyAddedSync: [x.embyRecentlyAddedSync, Validators.required], + plexWatchlistImport: [x.plexWatchlistImport, Validators.required], }); }); } diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html index f84395043..858a94358 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html @@ -9,6 +9,12 @@ Enable
+
+ Enable User Watchlist Requests + +

When a Plex User adds something to their watchlist in Plex, it will turn up in Ombi as a Request if enabled. This only applies to users that are logging in with their Plex Account

+

Request limits if set are all still applied etc.

+
Advanced
@@ -183,6 +189,12 @@ Clear Data And Resync +
+ +
diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts index 8d42419fe..d7c977b7b 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts @@ -172,6 +172,14 @@ export class PlexComponent implements OnInit, OnDestroy { }); } + public runWatchlistImport(): void { + this.jobService.runPlexWatchlistImport().subscribe(x => { + if (x) { + this.notificationService.success("Triggered the Watchlist Import"); + } + }); + } + public ngOnDestroy() { this.subscriptions.next(); this.subscriptions.complete(); diff --git a/src/Ombi/Controllers/V1/JobController.cs b/src/Ombi/Controllers/V1/JobController.cs index 442866762..57ec060a2 100644 --- a/src/Ombi/Controllers/V1/JobController.cs +++ b/src/Ombi/Controllers/V1/JobController.cs @@ -91,6 +91,17 @@ namespace Ombi.Controllers.V1 return true; } + /// + /// Runs the Plex Watchlist Importer + /// + /// + [HttpPost("plexwatchlist")] + public async Task PlexWatchlistImport() + { + await OmbiQuartz.TriggerJob(nameof(IPlexWatchlistImport), "Plex"); + return true; + } + /// /// Runs the Emby User importer /// diff --git a/src/Ombi/Controllers/V1/SettingsController.cs b/src/Ombi/Controllers/V1/SettingsController.cs index ff4dea913..0892b1dda 100644 --- a/src/Ombi/Controllers/V1/SettingsController.cs +++ b/src/Ombi/Controllers/V1/SettingsController.cs @@ -626,6 +626,7 @@ namespace Ombi.Controllers.V1 j.MediaDatabaseRefresh = j.MediaDatabaseRefresh.HasValue() ? j.MediaDatabaseRefresh : JobSettingsHelper.MediaDatabaseRefresh(j); j.AutoDeleteRequests = j.AutoDeleteRequests.HasValue() ? j.AutoDeleteRequests : JobSettingsHelper.AutoDeleteRequests(j); j.EmbyRecentlyAddedSync = j.EmbyRecentlyAddedSync.HasValue() ? j.EmbyRecentlyAddedSync : JobSettingsHelper.EmbyRecentlyAddedSync(j); + j.PlexWatchlistImport = j.PlexWatchlistImport.HasValue() ? j.PlexWatchlistImport : JobSettingsHelper.PlexWatchlistImport(j); return j; } diff --git a/src/Ombi/Controllers/V1/TokenController.cs b/src/Ombi/Controllers/V1/TokenController.cs index 3a409c206..588c4f606 100644 --- a/src/Ombi/Controllers/V1/TokenController.cs +++ b/src/Ombi/Controllers/V1/TokenController.cs @@ -6,14 +6,12 @@ using System.Security.Claims; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using Ombi.Core.Authentication; using Ombi.Helpers; using Ombi.Models; using Ombi.Models.External; -using Ombi.Models.Identity; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Core.Settings; @@ -26,18 +24,16 @@ namespace Ombi.Controllers.V1 [ApiController] public class TokenController : ControllerBase { - public TokenController(OmbiUserManager um, IOptions ta, ITokenRepository token, + public TokenController(OmbiUserManager um, ITokenRepository token, IPlexOAuthManager oAuthManager, ILogger logger, ISettingsService auth) { _userManager = um; - _tokenAuthenticationOptions = ta.Value; _token = token; _plexOAuthManager = oAuthManager; _log = logger; _authSettings = auth; } - private readonly TokenAuthentication _tokenAuthenticationOptions; private readonly ITokenRepository _token; private readonly OmbiUserManager _userManager; private readonly IPlexOAuthManager _plexOAuthManager; @@ -117,6 +113,7 @@ namespace Ombi.Controllers.V1 { return Unauthorized(); } + return await CreateToken(true, user); } diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index d0e282dce..ad4aeaae2 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -379,7 +379,8 @@ "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource":"Source:" }, "Discovery": { "PopularTab": "Popular", diff --git a/tests/cypress/tests/requests/requests.spec.ts b/tests/cypress/tests/requests/requests.spec.ts index fc1a7489c..c161d0645 100644 --- a/tests/cypress/tests/requests/requests.spec.ts +++ b/tests/cypress/tests/requests/requests.spec.ts @@ -9,22 +9,27 @@ describe("Requests Tests", () => { cy.intercept("token").as("login"); cy.login(); - cy.requestAllTv(60735); // The Flash + const dbID = 60735; // The Flash + cy.requestAllTv(dbID); Page.visit(); Page.tvTab.click(); - const row = Page.tv.getGridRow(60735); + cy.waitUntil(() => { + const row = Page.tv.getGridRow(dbID); + return row.detailsButton.should("be.visible"); + }); + const row = Page.tv.getGridRow(dbID); row.detailsButton.click(); - cy.location("pathname").should("contains", "/details/tv/60735"); + cy.location("pathname").should("contains", "/details/tv/" + dbID); TvPage.title.contains("The Flash"); }); it("Deleting TV requests, removes from grid", () => { cy.intercept("POST", "request/tv").as("tvRequest"); cy.intercept("token").as("login"); - cy.intercept('DELETE', 'Request/tv/child/60735').as('deleteRequest'); + cy.intercept('DELETE','api/v1/Request/tv/child/60735').as('deleteRequest'); cy.login(); // cy.wait('@login');