diff --git a/src/Ombi.Core.Tests/Services/PlexServiceTests.cs b/src/Ombi.Core.Tests/Services/PlexServiceTests.cs new file mode 100644 index 000000000..a61c86b2e --- /dev/null +++ b/src/Ombi.Core.Tests/Services/PlexServiceTests.cs @@ -0,0 +1,146 @@ +using MockQueryable.Moq; +using Moq.AutoMock; +using NUnit.Framework; +using Ombi.Core.Models; +using Ombi.Core.Services; +using Ombi.Store.Entities; +using Ombi.Store.Repository; +using Ombi.Test.Common; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using UserType = Ombi.Store.Entities.UserType; + +namespace Ombi.Core.Tests.Services +{ + public class PlexServiceTests + { + + private PlexService _subject; + private AutoMocker _mocker; + + [SetUp] + public void Setup() + { + _mocker = new AutoMocker(); + _subject = _mocker.CreateInstance(); + } + + [Test] + public async Task GetWatchListUsers_AllUsersSynced() + { + var userMock = MockHelper.MockUserManager(new List + { + new OmbiUser + { + MediaServerToken = "token", + Id = "1", + UserName = "user1", + UserType = UserType.PlexUser, + }, + new OmbiUser + { + MediaServerToken = "token", + Id = "2", + UserName = "user2", + UserType = UserType.PlexUser, + }, + new OmbiUser + { + MediaServerToken = "token", + Id = "2", + UserName = "user2", + UserType = UserType.LocalUser, + } + }); + + _mocker.Use(userMock.Object); + _subject = _mocker.CreateInstance(); + + _mocker.Setup, IQueryable>(x => x.GetAll()) + .Returns(new List().AsQueryable().BuildMock().Object); + + var result = await _subject.GetWatchlistUsers(CancellationToken.None); + + Assert.Multiple(() => + { + Assert.That(result.All(x => x.SyncStatus == WatchlistSyncStatus.Successful)); + Assert.That(result.Count, Is.EqualTo(2)); + }); + } + + [Test] + public async Task GetWatchListUsers_NotEnabled() + { + var userMock = MockHelper.MockUserManager(new List + { + new OmbiUser + { + MediaServerToken = "", + Id = "1", + UserName = "user1", + UserType = UserType.PlexUser, + }, + new OmbiUser + { + MediaServerToken = null, + Id = "2", + UserName = "user2", + UserType = UserType.PlexUser, + }, + }); + + _mocker.Use(userMock.Object); + _subject = _mocker.CreateInstance(); + + _mocker.Setup, IQueryable>(x => x.GetAll()) + .Returns(new List().AsQueryable().BuildMock().Object); + + var result = await _subject.GetWatchlistUsers(CancellationToken.None); + + Assert.Multiple(() => + { + Assert.That(result.All(x => x.SyncStatus == WatchlistSyncStatus.NotEnabled)); + Assert.That(result.Count, Is.EqualTo(2)); + }); + } + + + [Test] + public async Task GetWatchListUsers_Failed() + { + var userMock = MockHelper.MockUserManager(new List + { + new OmbiUser + { + MediaServerToken = "test", + Id = "1", + UserName = "user1", + UserType = UserType.PlexUser, + }, + }); + + _mocker.Use(userMock.Object); + _subject = _mocker.CreateInstance(); + + _mocker.Setup, IQueryable>(x => x.GetAll()) + .Returns(new List + { + new PlexWatchlistUserError + { + UserId = "1", + MediaServerToken = "test", + } + }.AsQueryable().BuildMock().Object); + + var result = await _subject.GetWatchlistUsers(CancellationToken.None); + + Assert.Multiple(() => + { + Assert.That(result.All(x => x.SyncStatus == WatchlistSyncStatus.Failed)); + Assert.That(result.Count, Is.EqualTo(1)); + }); + } + } +} diff --git a/src/Ombi.Core/Models/PlexUserWatchlistModel.cs b/src/Ombi.Core/Models/PlexUserWatchlistModel.cs new file mode 100644 index 000000000..83652b105 --- /dev/null +++ b/src/Ombi.Core/Models/PlexUserWatchlistModel.cs @@ -0,0 +1,16 @@ +namespace Ombi.Core.Models +{ + public class PlexUserWatchlistModel + { + public string UserId { get; set; } + public WatchlistSyncStatus SyncStatus { get; set; } + public string UserName { get; set; } + } + + public enum WatchlistSyncStatus + { + Successful, + Failed, + NotEnabled + } +} diff --git a/src/Ombi.Core/Services/IPlexService.cs b/src/Ombi.Core/Services/IPlexService.cs new file mode 100644 index 000000000..4cacdc4e5 --- /dev/null +++ b/src/Ombi.Core/Services/IPlexService.cs @@ -0,0 +1,12 @@ +using Ombi.Core.Models; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace Ombi.Core.Services +{ + public interface IPlexService + { + Task> GetWatchlistUsers(CancellationToken cancellationToken); + } +} diff --git a/src/Ombi.Core/Services/PlexService.cs b/src/Ombi.Core/Services/PlexService.cs new file mode 100644 index 000000000..4d3f41bda --- /dev/null +++ b/src/Ombi.Core/Services/PlexService.cs @@ -0,0 +1,55 @@ +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Authentication; +using Ombi.Core.Models; +using Ombi.Store.Entities; +using Ombi.Store.Repository; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using UserType = Ombi.Store.Entities.UserType; + +namespace Ombi.Core.Services +{ + public class PlexService : IPlexService + { + private readonly IRepository _watchlistUserErrors; + private readonly OmbiUserManager _userManager; + + public PlexService(IRepository watchlistUserErrors, OmbiUserManager userManager) + { + _watchlistUserErrors = watchlistUserErrors; + _userManager = userManager; + } + + public async Task> GetWatchlistUsers(CancellationToken cancellationToken) + { + var plexUsers = _userManager.Users.Where(x => x.UserType == UserType.PlexUser); + var userErrors = await _watchlistUserErrors.GetAll().ToListAsync(cancellationToken); + + var model = new List(); + + + foreach(var plexUser in plexUsers) + { + model.Add(new PlexUserWatchlistModel + { + UserId = plexUser.Id, + UserName = plexUser.UserName, + SyncStatus = GetWatchlistSyncStatus(plexUser, userErrors) + }); + } + + return model; + } + + private static WatchlistSyncStatus GetWatchlistSyncStatus(OmbiUser user, List userErrors) + { + if (string.IsNullOrWhiteSpace(user.MediaServerToken)) + { + return WatchlistSyncStatus.NotEnabled; + } + return userErrors.Any(x => x.UserId == user.Id) ? WatchlistSyncStatus.Failed : WatchlistSyncStatus.Successful; + } + } +} diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index c866f4442..9e47042de 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -229,6 +229,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddScoped(); services.AddTransient(); + services.AddTransient(); } public static void RegisterJobs(this IServiceCollection services) diff --git a/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs b/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs index 3de9f23e3..64794f010 100644 --- a/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs +++ b/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs @@ -97,7 +97,7 @@ namespace Ombi.Schedule.Tests [Test] public async Task FailedWatchListUser_NewToken_ShouldBeRemoved() { - _mocker.Setup, IQueryable>(x => x.GetAll()).Returns(new List + _mocker.Setup, IQueryable>(x => x.GetAll()).Returns(new List { new PlexWatchlistUserError { @@ -121,7 +121,7 @@ namespace Ombi.Schedule.Tests [Test] public async Task FailedWatchListUser_OldToken_ShouldSkip() { - _mocker.Setup, IQueryable>(x => x.GetAll()).Returns(new List + _mocker.Setup, IQueryable>(x => x.GetAll()).Returns(new List { new PlexWatchlistUserError { diff --git a/src/Ombi.Store/Entities/PlexWatchlistUserError.cs b/src/Ombi.Store/Entities/PlexWatchlistUserError.cs index 6a94c226f..8e5d2b41b 100644 --- a/src/Ombi.Store/Entities/PlexWatchlistUserError.cs +++ b/src/Ombi.Store/Entities/PlexWatchlistUserError.cs @@ -7,8 +7,5 @@ namespace Ombi.Store.Entities { public string UserId { get; set; } public string MediaServerToken { get; set; } - - [ForeignKey(nameof(UserId))] - public OmbiUser User { get; set; } } } diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220822204249_PlexWatchlistUserError.Designer.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220822204249_PlexWatchlistUserError.Designer.cs deleted file mode 100644 index 166acb5f9..000000000 --- a/src/Ombi.Store/Migrations/OmbiMySql/20220822204249_PlexWatchlistUserError.Designer.cs +++ /dev/null @@ -1,1313 +0,0 @@ -// -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("20220822204249_PlexWatchlistUserError")] - partial class PlexWatchlistUserError - { - 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.PlexWatchlistUserError", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("MediaServerToken") - .HasColumnType("longtext"); - - b.Property("UserId") - .HasColumnType("varchar(255)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("PlexWatchlistUserError"); - }); - - 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.PlexWatchlistUserError", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "User") - .WithMany() - .HasForeignKey("UserId"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") - .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/20220822204249_PlexWatchlistUserError.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220822204249_PlexWatchlistUserError.cs deleted file mode 100644 index cf0e28299..000000000 --- a/src/Ombi.Store/Migrations/OmbiMySql/20220822204249_PlexWatchlistUserError.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Ombi.Store.Migrations.OmbiMySql -{ - public partial class PlexWatchlistUserError : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "PlexWatchlistUserError", - columns: table => new - { - Id = table.Column(type: "int", nullable: false) - .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), - UserId = table.Column(type: "varchar(255)", nullable: true) - .Annotation("MySql:CharSet", "utf8mb4"), - MediaServerToken = table.Column(type: "longtext", nullable: true) - .Annotation("MySql:CharSet", "utf8mb4") - }, - constraints: table => - { - table.PrimaryKey("PK_PlexWatchlistUserError", x => x.Id); - table.ForeignKey( - name: "FK_PlexWatchlistUserError_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id"); - }) - .Annotation("MySql:CharSet", "utf8mb4"); - - migrationBuilder.CreateIndex( - name: "IX_PlexWatchlistUserError_UserId", - table: "PlexWatchlistUserError", - column: "UserId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "PlexWatchlistUserError"); - } - } -} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs index aeae9b66e..e66e29521 100644 --- a/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs @@ -350,25 +350,6 @@ namespace Ombi.Store.Migrations.OmbiMySql b.ToTable("AspNetUsers", (string)null); }); - modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistUserError", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("MediaServerToken") - .HasColumnType("longtext"); - - b.Property("UserId") - .HasColumnType("varchar(255)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("PlexWatchlistUserError"); - }); - modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => { b.Property("Id") @@ -1112,15 +1093,6 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Navigation("User"); }); - modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistUserError", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "User") - .WithMany() - .HasForeignKey("UserId"); - - b.Navigation("User"); - }); - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => { b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220822203722_PlexWatchlistUserError.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220822203722_PlexWatchlistUserError.Designer.cs deleted file mode 100644 index d38e7cf78..000000000 --- a/src/Ombi.Store/Migrations/OmbiSqlite/20220822203722_PlexWatchlistUserError.Designer.cs +++ /dev/null @@ -1,1311 +0,0 @@ -// -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("20220822203722_PlexWatchlistUserError")] - partial class PlexWatchlistUserError - { - 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.PlexWatchlistUserError", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("MediaServerToken") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("PlexWatchlistUserError"); - }); - - 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.PlexWatchlistUserError", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "User") - .WithMany() - .HasForeignKey("UserId"); - - b.Navigation("User"); - }); - - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") - .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/20220822203722_PlexWatchlistUserError.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220822203722_PlexWatchlistUserError.cs deleted file mode 100644 index 1e51d8cc7..000000000 --- a/src/Ombi.Store/Migrations/OmbiSqlite/20220822203722_PlexWatchlistUserError.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Ombi.Store.Migrations.OmbiSqlite -{ - public partial class PlexWatchlistUserError : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "PlexWatchlistUserError", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - UserId = table.Column(type: "TEXT", nullable: true), - MediaServerToken = table.Column(type: "TEXT", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PlexWatchlistUserError", x => x.Id); - table.ForeignKey( - name: "FK_PlexWatchlistUserError_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id"); - }); - - migrationBuilder.CreateIndex( - name: "IX_PlexWatchlistUserError_UserId", - table: "PlexWatchlistUserError", - column: "UserId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "PlexWatchlistUserError"); - } - } -} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs index 61132b642..f9ce86bae 100644 --- a/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs @@ -348,25 +348,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.ToTable("AspNetUsers", (string)null); }); - modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistUserError", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("MediaServerToken") - .HasColumnType("TEXT"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("PlexWatchlistUserError"); - }); - modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => { b.Property("Id") @@ -1110,15 +1091,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Navigation("User"); }); - modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistUserError", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "User") - .WithMany() - .HasForeignKey("UserId"); - - b.Navigation("User"); - }); - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => { b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") diff --git a/src/Ombi/ClientApp/src/app/interfaces/IPlex.ts b/src/Ombi/ClientApp/src/app/interfaces/IPlex.ts index 6afc13e21..0b5e6878b 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IPlex.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IPlex.ts @@ -107,3 +107,16 @@ export interface IPlexServerResponse { port: string; scheme: string; } + +export interface IPlexWatchlistUsers { + userId: string; + syncStatus: WatchlistSyncStatus; + userName: string; +} + +export enum WatchlistSyncStatus +{ + Successful, + Failed, + NotEnabled +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/services/applications/plex.service.ts b/src/Ombi/ClientApp/src/app/services/applications/plex.service.ts index 39bfea53e..83dd8fc7c 100644 --- a/src/Ombi/ClientApp/src/app/services/applications/plex.service.ts +++ b/src/Ombi/ClientApp/src/app/services/applications/plex.service.ts @@ -1,4 +1,4 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; +import { APP_BASE_HREF } from "@angular/common"; import { HttpClient } from "@angular/common/http"; import { Injectable, Inject } from "@angular/core"; @@ -6,7 +6,7 @@ import { Observable } from "rxjs"; import { ServiceHelpers } from "../service.helpers"; -import { IPlexAuthentication, IPlexLibResponse, IPlexLibSimpleResponse, IPlexOAuthViewModel, IPlexServer, IPlexServerAddViewModel, IPlexServerViewModel, IPlexUserAddResponse, IPlexUserViewModel, IUsersModel } from "../../interfaces"; +import { IPlexAuthentication, IPlexLibResponse, IPlexLibSimpleResponse, IPlexOAuthViewModel, IPlexServer, IPlexServerAddViewModel, IPlexServerViewModel, IPlexUserAddResponse, IPlexUserViewModel, IPlexWatchlistUsers, IUsersModel } from "../../interfaces"; @Injectable() export class PlexService extends ServiceHelpers { @@ -45,4 +45,8 @@ export class PlexService extends ServiceHelpers { public oAuth(wizard: IPlexOAuthViewModel): Observable { return this.http.post(`${this.url}oauth`, JSON.stringify(wizard), {headers: this.headers}); } + + public getWatchlistUsers(): Observable { + return this.http.get(`${this.url}WatchlistUsers`, {headers: this.headers}); + } } diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.html b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.html new file mode 100644 index 000000000..02eca3561 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.html @@ -0,0 +1,32 @@ +
+
+ Watchlist Errors + +

If the Sync fails, this is because of an authentication issue with Plex (Token has expired). If this happens the user needs to re-login to Ombi.

+

Key: +
+ +
+ +
+ +

+ + + + + + + + + + + + +
Username {{element.userName}} Watchlist Sync Result + + + +
+
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.scss b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.scss new file mode 100644 index 000000000..b940e9001 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.scss @@ -0,0 +1,9 @@ +@import "~styles/shared.scss"; +.small-middle-container { + margin: auto; + width: 95%; + margin-top: 10px; +} +.fieldset { + width: 100%; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.stories.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.stories.ts new file mode 100644 index 000000000..ee0472f58 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.stories.ts @@ -0,0 +1,68 @@ +// also exported from '@storybook/angular' if you can deal with breaking changes in 6.1 +import { APP_BASE_HREF, CommonModule } from '@angular/common'; +import { Story, Meta, moduleMetadata } from '@storybook/angular'; +import { Observable, of } from 'rxjs'; +import { IPlexWatchlistUsers, WatchlistSyncStatus } from '../../../../interfaces'; +import { PlexService } from '../../../../services'; +import { SharedModule } from '../../../../shared/shared.module'; +import { PlexWatchlistComponent } from './plex-watchlist.component'; + + +const mockUsers: IPlexWatchlistUsers[] = +[ + { + userName: "Success User", + userId: "a", + syncStatus: WatchlistSyncStatus.Successful + }, + { + userName: "Failed User", + userId: "2", + syncStatus: WatchlistSyncStatus.Failed + }, + { + userName: "Not Enabled", + userId: "2", + syncStatus: WatchlistSyncStatus.NotEnabled + }, +]; + +function plexServiveMock(): Partial { + return { + getWatchlistUsers: () : Observable => of(mockUsers), + }; +} + +// More on default export: https://storybook.js.org/docs/angular/writing-stories/introduction#default-export +export default { + title: 'Plex Watchlist Component', + component: PlexWatchlistComponent, + decorators: [ + moduleMetadata({ + providers: [ + { + provide: APP_BASE_HREF, + useValue: "" + }, + { + provide: PlexService, + useValue: plexServiveMock() + } + ], + imports: [ + CommonModule, + SharedModule + ] + }) + ] +} as Meta; + +// More on component templates: https://storybook.js.org/docs/angular/writing-stories/introduction#using-args +const Template: Story = (args: PlexWatchlistComponent) => ({ + props: args, +}); + +export const Default = Template.bind({}); +Default.args = { +}; + diff --git a/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.ts new file mode 100644 index 000000000..cf558943b --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/plex/components/watchlist/plex-watchlist.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from "@angular/core"; +import { MatTableDataSource } from "@angular/material/table"; +import { take } from "rxjs"; +import { IPlexWatchlistUsers, WatchlistSyncStatus } from "../../../../interfaces"; +import { PlexService } from "../../../../services"; + +@Component({ + templateUrl: "./plex-watchlist.component.html", + styleUrls: ["./plex-watchlist.component.scss"] +}) +export class PlexWatchlistComponent implements OnInit{ + + public dataSource: MatTableDataSource = new MatTableDataSource(); + public displayedColumns: string[] = ['userName','syncStatus']; + + public WatchlistSyncStatus = WatchlistSyncStatus; + + constructor(private plexService: PlexService) { } + + public ngOnInit() { + this.plexService.getWatchlistUsers().pipe(take(1)).subscribe((x: IPlexWatchlistUsers[]) => { + this.dataSource = new MatTableDataSource(x); + }); + } +} diff --git a/src/Ombi/Controllers/V1/External/PlexController.cs b/src/Ombi/Controllers/V1/External/PlexController.cs index c8b503dc0..7cc0cc824 100644 --- a/src/Ombi/Controllers/V1/External/PlexController.cs +++ b/src/Ombi/Controllers/V1/External/PlexController.cs @@ -9,6 +9,8 @@ using Ombi.Api.Plex; using Ombi.Api.Plex.Models; using Ombi.Attributes; using Ombi.Core.Authentication; +using Ombi.Core.Models; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; @@ -23,18 +25,20 @@ namespace Ombi.Controllers.V1.External public class PlexController : Controller { public PlexController(IPlexApi plexApi, ISettingsService plexSettings, - ILogger logger, IPlexOAuthManager manager) + ILogger logger, IPlexOAuthManager manager, IPlexService plexService) { PlexApi = plexApi; PlexSettings = plexSettings; _log = logger; _plexOAuthManager = manager; + _plexService = plexService; } private IPlexApi PlexApi { get; } private ISettingsService PlexSettings { get; } private readonly ILogger _log; private readonly IPlexOAuthManager _plexOAuthManager; + private readonly IPlexService _plexService; /// /// Signs into the Plex API. @@ -300,5 +304,9 @@ namespace Ombi.Controllers.V1.External return new JsonResult(new {url = url.ToString()}); } + + [Admin] + [HttpGet("WatchlistUsers")] + public async Task> GetPlexWatchlistUsers() => await _plexService.GetWatchlistUsers(HttpContext.RequestAborted); } }