mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 08:16:05 -07:00
Added the ability to override root and quality options in Sonarr (#2049)
Added the ability to override the Root path and Qualities against a TV show for Sonarr
This commit is contained in:
parent
5f7ce5c175
commit
3fa6940a8b
20 changed files with 1165 additions and 59 deletions
|
@ -177,6 +177,13 @@ namespace Ombi.Core.Engine
|
|||
var allRequests = TvRepository.Get();
|
||||
var results = await allRequests.FirstOrDefaultAsync(x => x.Id == request.Id);
|
||||
|
||||
results.TvDbId = request.TvDbId;
|
||||
results.ImdbId = request.ImdbId;
|
||||
results.Overview = request.Overview;
|
||||
results.PosterPath = PosterPathHelper.FixPosterPath(request.PosterPath);
|
||||
results.QualityOverride = request.QualityOverride;
|
||||
results.RootFolder = request.RootFolder;
|
||||
|
||||
await TvRepository.Update(results);
|
||||
return results;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Net.Mail;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Ombi.Core.Helpers
|
||||
|
@ -31,12 +32,11 @@ namespace Ombi.Core.Helpers
|
|||
// Return true if strIn is in valid e-mail format.
|
||||
try
|
||||
{
|
||||
return Regex.IsMatch(strIn,
|
||||
@"^(?("")("".+?(?<!\\)""@)|(([0-9a-z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-z])@))" +
|
||||
@"(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-z][-\w]*[0-9a-z]*\.)+[a-z0-9][\-a-z0-9]{0,22}[a-z0-9]))$",
|
||||
RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
|
||||
// ReSharper disable once ObjectCreationAsStatement
|
||||
new MailAddress(strIn);
|
||||
return true;
|
||||
}
|
||||
catch (RegexMatchTimeoutException)
|
||||
catch (FormatException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -105,9 +105,8 @@ namespace Ombi.Core.Senders
|
|||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <param name="model"></param>
|
||||
/// <param name="qualityId">This is for any qualities overriden from the UI</param>
|
||||
/// <returns></returns>
|
||||
public async Task<NewSeries> SendToSonarr(ChildRequests model, string qualityId = null)
|
||||
public async Task<NewSeries> SendToSonarr(ChildRequests model)
|
||||
{
|
||||
var s = await SonarrSettings.GetSettingsAsync();
|
||||
if (!s.Enabled)
|
||||
|
@ -118,15 +117,12 @@ namespace Ombi.Core.Senders
|
|||
{
|
||||
return null;
|
||||
}
|
||||
var qualityProfile = 0;
|
||||
if (!string.IsNullOrEmpty(qualityId)) // try to parse the passed in quality, otherwise use the settings default quality
|
||||
{
|
||||
int.TryParse(qualityId, out qualityProfile);
|
||||
}
|
||||
|
||||
if (qualityProfile <= 0)
|
||||
int.TryParse(s.QualityProfile, out var qualityToUse);
|
||||
|
||||
if (model.ParentRequest.QualityOverride.HasValue)
|
||||
{
|
||||
int.TryParse(s.QualityProfile, out qualityProfile);
|
||||
qualityToUse = model.ParentRequest.QualityOverride.Value;
|
||||
}
|
||||
|
||||
// Get the root path from the rootfolder selected.
|
||||
|
@ -151,7 +147,7 @@ namespace Ombi.Core.Senders
|
|||
monitored = true,
|
||||
seasonFolder = s.SeasonFolders,
|
||||
rootFolderPath = rootFolderPath,
|
||||
qualityProfileId = qualityProfile,
|
||||
qualityProfileId = qualityToUse,
|
||||
titleSlug = model.ParentRequest.Title,
|
||||
addOptions = new AddOptions
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace Ombi.Notifications
|
|||
private List<INotification> NotificationAgents { get; }
|
||||
private ILogger<NotificationService> Log { get; }
|
||||
|
||||
/// <summary>
|
||||
/// <summary>^
|
||||
/// Sends a notification to the user. This one is used in normal notification scenarios
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Newtonsoft.Json;
|
||||
using Ombi.Helpers;
|
||||
|
||||
namespace Ombi.Store.Entities
|
||||
|
@ -35,5 +36,26 @@ namespace Ombi.Store.Entities
|
|||
|
||||
[NotMapped]
|
||||
public bool EmailLogin { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public override string PasswordHash
|
||||
{
|
||||
get => base.PasswordHash;
|
||||
set => base.PasswordHash = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override string SecurityStamp
|
||||
{
|
||||
get => base.SecurityStamp;
|
||||
set => base.SecurityStamp = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public override string ConcurrencyStamp
|
||||
{
|
||||
get => base.ConcurrencyStamp;
|
||||
set => base.ConcurrencyStamp = value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ namespace Ombi.Store.Entities.Requests
|
|||
{
|
||||
public int TvDbId { get; set; }
|
||||
public string ImdbId { get; set; }
|
||||
public int? QualityOverride { get; set; }
|
||||
public int? RootFolder { get; set; }
|
||||
public string Overview { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
|
1
src/Ombi.Store/Migration.txt
Normal file
1
src/Ombi.Store/Migration.txt
Normal file
|
@ -0,0 +1 @@
|
|||
dotnet ef migrations add Inital --context OmbiContext --startup-project ../Ombi/Ombi.csproj
|
918
src/Ombi.Store/Migrations/20180307131304_SonarrOverrides.Designer.cs
generated
Normal file
918
src/Ombi.Store/Migrations/20180307131304_SonarrOverrides.Designer.cs
generated
Normal file
|
@ -0,0 +1,918 @@
|
|||
// <auto-generated />
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.EntityFrameworkCore.Storage.Internal;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Context;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Entities.Requests;
|
||||
using System;
|
||||
|
||||
namespace Ombi.Store.Migrations
|
||||
{
|
||||
[DbContext(typeof(OmbiContext))]
|
||||
[Migration("20180307131304_SonarrOverrides")]
|
||||
partial class SonarrOverrides
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "2.0.0-rtm-26452");
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ClaimType");
|
||||
|
||||
b.Property<string>("ClaimValue");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("ProviderKey");
|
||||
|
||||
b.Property<string>("ProviderDisplayName");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired();
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("RoleId");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.Property<string>("LoginProvider");
|
||||
|
||||
b.Property<string>("Name");
|
||||
|
||||
b.Property<string>("Value");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Value");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ApplicationConfiguration");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("AuditArea");
|
||||
|
||||
b.Property<int>("AuditType");
|
||||
|
||||
b.Property<DateTime>("DateTime");
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<string>("User");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Audit");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("TheMovieDbId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("CouchPotatoCache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("AddedAt");
|
||||
|
||||
b.Property<string>("EmbyId")
|
||||
.IsRequired();
|
||||
|
||||
b.Property<string>("ProviderId");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("EmbyContent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("AddedAt");
|
||||
|
||||
b.Property<string>("EmbyId");
|
||||
|
||||
b.Property<int>("EpisodeNumber");
|
||||
|
||||
b.Property<string>("ParentId");
|
||||
|
||||
b.Property<string>("ProviderId");
|
||||
|
||||
b.Property<int>("SeasonNumber");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ParentId");
|
||||
|
||||
b.ToTable("EmbyEpisode");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Content");
|
||||
|
||||
b.Property<string>("SettingsName");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GlobalSettings");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("Agent");
|
||||
|
||||
b.Property<bool>("Enabled");
|
||||
|
||||
b.Property<string>("Message");
|
||||
|
||||
b.Property<int>("NotificationType");
|
||||
|
||||
b.Property<string>("Subject");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("NotificationTemplates");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("AddedAt");
|
||||
|
||||
b.Property<string>("PlayerId");
|
||||
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("NotificationUserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("AccessFailedCount");
|
||||
|
||||
b.Property<string>("Alias");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken();
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<bool>("EmailConfirmed");
|
||||
|
||||
b.Property<string>("EmbyConnectUserId");
|
||||
|
||||
b.Property<int?>("EpisodeRequestLimit");
|
||||
|
||||
b.Property<DateTime?>("LastLoggedIn");
|
||||
|
||||
b.Property<bool>("LockoutEnabled");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd");
|
||||
|
||||
b.Property<int?>("MovieRequestLimit");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<string>("PasswordHash");
|
||||
|
||||
b.Property<string>("PhoneNumber");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed");
|
||||
|
||||
b.Property<string>("ProviderUserId");
|
||||
|
||||
b.Property<string>("SecurityStamp");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled");
|
||||
|
||||
b.Property<string>("UserAccessToken");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256);
|
||||
|
||||
b.Property<int>("UserType");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("EpisodeNumber");
|
||||
|
||||
b.Property<int>("GrandparentKey");
|
||||
|
||||
b.Property<int>("Key");
|
||||
|
||||
b.Property<int>("ParentKey");
|
||||
|
||||
b.Property<int>("SeasonNumber");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GrandparentKey");
|
||||
|
||||
b.ToTable("PlexEpisode");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("ParentKey");
|
||||
|
||||
b.Property<int>("PlexContentId");
|
||||
|
||||
b.Property<int?>("PlexServerContentId");
|
||||
|
||||
b.Property<int>("SeasonKey");
|
||||
|
||||
b.Property<int>("SeasonNumber");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("PlexServerContentId");
|
||||
|
||||
b.ToTable("PlexSeasonsContent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("AddedAt");
|
||||
|
||||
b.Property<string>("ImdbId");
|
||||
|
||||
b.Property<int>("Key");
|
||||
|
||||
b.Property<string>("Quality");
|
||||
|
||||
b.Property<string>("ReleaseYear");
|
||||
|
||||
b.Property<string>("TheMovieDbId");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("TvDbId");
|
||||
|
||||
b.Property<int>("Type");
|
||||
|
||||
b.Property<string>("Url");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("PlexServerContent");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("HasFile");
|
||||
|
||||
b.Property<int>("TheMovieDbId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("RadarrCache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Approved");
|
||||
|
||||
b.Property<bool>("Available");
|
||||
|
||||
b.Property<bool?>("Denied");
|
||||
|
||||
b.Property<string>("DeniedReason");
|
||||
|
||||
b.Property<int?>("IssueId");
|
||||
|
||||
b.Property<int>("ParentRequestId");
|
||||
|
||||
b.Property<int>("RequestType");
|
||||
|
||||
b.Property<DateTime>("RequestedDate");
|
||||
|
||||
b.Property<string>("RequestedUserId");
|
||||
|
||||
b.Property<int>("SeriesType");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ParentRequestId");
|
||||
|
||||
b.HasIndex("RequestedUserId");
|
||||
|
||||
b.ToTable("ChildRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Value");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("IssueCategory");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Comment");
|
||||
|
||||
b.Property<DateTime>("Date");
|
||||
|
||||
b.Property<int?>("IssuesId");
|
||||
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IssuesId");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("IssueComments");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Description");
|
||||
|
||||
b.Property<int>("IssueCategoryId");
|
||||
|
||||
b.Property<int?>("IssueId");
|
||||
|
||||
b.Property<string>("ProviderId");
|
||||
|
||||
b.Property<int?>("RequestId");
|
||||
|
||||
b.Property<int>("RequestType");
|
||||
|
||||
b.Property<DateTime?>("ResovledDate");
|
||||
|
||||
b.Property<int>("Status");
|
||||
|
||||
b.Property<string>("Subject");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("UserReportedId");
|
||||
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<bool>("Approved");
|
||||
|
||||
b.Property<bool>("Available");
|
||||
|
||||
b.Property<string>("Background");
|
||||
|
||||
b.Property<bool?>("Denied");
|
||||
|
||||
b.Property<string>("DeniedReason");
|
||||
|
||||
b.Property<DateTime?>("DigitalReleaseDate");
|
||||
|
||||
b.Property<string>("ImdbId");
|
||||
|
||||
b.Property<int?>("IssueId");
|
||||
|
||||
b.Property<string>("Overview");
|
||||
|
||||
b.Property<string>("PosterPath");
|
||||
|
||||
b.Property<int>("QualityOverride");
|
||||
|
||||
b.Property<DateTime>("ReleaseDate");
|
||||
|
||||
b.Property<int>("RequestType");
|
||||
|
||||
b.Property<DateTime>("RequestedDate");
|
||||
|
||||
b.Property<string>("RequestedUserId");
|
||||
|
||||
b.Property<int>("RootPathOverride");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.Property<int>("TheMovieDbId");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RequestedUserId");
|
||||
|
||||
b.ToTable("MovieRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("EpisodeCount");
|
||||
|
||||
b.Property<DateTime>("RequestDate");
|
||||
|
||||
b.Property<int>("RequestId");
|
||||
|
||||
b.Property<int>("RequestType");
|
||||
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("RequestLog");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("ImdbId");
|
||||
|
||||
b.Property<string>("Overview");
|
||||
|
||||
b.Property<string>("PosterPath");
|
||||
|
||||
b.Property<int?>("QualityOverride");
|
||||
|
||||
b.Property<DateTime>("ReleaseDate");
|
||||
|
||||
b.Property<int?>("RootFolder");
|
||||
|
||||
b.Property<string>("Status");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<int>("TvDbId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("TvRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("TvDbId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SickRageCache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("EpisodeNumber");
|
||||
|
||||
b.Property<int>("SeasonNumber");
|
||||
|
||||
b.Property<int>("TvDbId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SickRageEpisodeCache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("TvDbId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SonarrCache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("EpisodeNumber");
|
||||
|
||||
b.Property<bool>("HasFile");
|
||||
|
||||
b.Property<int>("SeasonNumber");
|
||||
|
||||
b.Property<int>("TvDbId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("SonarrEpisodeCache");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<string>("Token");
|
||||
|
||||
b.Property<string>("UserId");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Tokens");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<DateTime>("AirDate");
|
||||
|
||||
b.Property<bool>("Approved");
|
||||
|
||||
b.Property<bool>("Available");
|
||||
|
||||
b.Property<int>("EpisodeNumber");
|
||||
|
||||
b.Property<bool>("Requested");
|
||||
|
||||
b.Property<int>("SeasonId");
|
||||
|
||||
b.Property<string>("Title");
|
||||
|
||||
b.Property<string>("Url");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("SeasonId");
|
||||
|
||||
b.ToTable("EpisodeRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd();
|
||||
|
||||
b.Property<int>("ChildRequestId");
|
||||
|
||||
b.Property<int>("SeasonNumber");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ChildRequestId");
|
||||
|
||||
b.ToTable("SeasonRequests");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.EmbyContent", "Series")
|
||||
.WithMany("Episodes")
|
||||
.HasForeignKey("ParentId")
|
||||
.HasPrincipalKey("EmbyId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany("NotificationUserIds")
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series")
|
||||
.WithMany("Episodes")
|
||||
.HasForeignKey("GrandparentKey")
|
||||
.HasPrincipalKey("Key")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.PlexServerContent")
|
||||
.WithMany("Seasons")
|
||||
.HasForeignKey("PlexServerContentId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest")
|
||||
.WithMany("ChildRequests")
|
||||
.HasForeignKey("ParentRequestId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("RequestedUserId");
|
||||
});
|
||||
|
||||
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");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory")
|
||||
.WithMany()
|
||||
.HasForeignKey("IssueCategoryId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
|
||||
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests")
|
||||
.WithMany("Issues")
|
||||
.HasForeignKey("IssueId");
|
||||
|
||||
b.HasOne("Ombi.Store.Entities.Requests.MovieRequests")
|
||||
.WithMany("Issues")
|
||||
.HasForeignKey("IssueId");
|
||||
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserReportedId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
|
||||
.WithMany()
|
||||
.HasForeignKey("RequestedUserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.OmbiUser", "User")
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season")
|
||||
.WithMany("Episodes")
|
||||
.HasForeignKey("SeasonId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
|
||||
{
|
||||
b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest")
|
||||
.WithMany("SeasonRequests")
|
||||
.HasForeignKey("ChildRequestId")
|
||||
.OnDelete(DeleteBehavior.Cascade);
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
25
src/Ombi.Store/Migrations/20180307131304_SonarrOverrides.cs
Normal file
25
src/Ombi.Store/Migrations/20180307131304_SonarrOverrides.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Ombi.Store.Migrations
|
||||
{
|
||||
public partial class SonarrOverrides : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "QualityOverride",
|
||||
table: "TvRequests",
|
||||
type: "INTEGER",
|
||||
nullable: true);
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "QualityOverride",
|
||||
table: "TvRequests");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -621,6 +621,8 @@ namespace Ombi.Store.Migrations
|
|||
|
||||
b.Property<string>("PosterPath");
|
||||
|
||||
b.Property<int?>("QualityOverride");
|
||||
|
||||
b.Property<DateTime>("ReleaseDate");
|
||||
|
||||
b.Property<int?>("RootFolder");
|
||||
|
|
|
@ -1,28 +1,5 @@
|
|||
import { IUser } from "./IUser";
|
||||
|
||||
export interface IMediaBase {
|
||||
imdbId: string;
|
||||
id: number;
|
||||
providerId: number;
|
||||
title: string;
|
||||
overview: string;
|
||||
posterPath: string;
|
||||
releaseDate: Date;
|
||||
status: string;
|
||||
requestedDate: Date;
|
||||
approved: boolean;
|
||||
type: RequestType;
|
||||
requested: boolean;
|
||||
available: boolean;
|
||||
otherMessage: string;
|
||||
adminNote: string;
|
||||
requestedUser: string;
|
||||
issueId: number;
|
||||
denied: boolean;
|
||||
deniedReason: string;
|
||||
released: boolean;
|
||||
}
|
||||
|
||||
export enum RequestType {
|
||||
movie = 1,
|
||||
tvShow = 2,
|
||||
|
@ -36,6 +13,7 @@ export interface IMovieRequests extends IFullBaseRequest {
|
|||
qualityOverride: number;
|
||||
digitalReleaseDate: Date;
|
||||
|
||||
// For the UI
|
||||
rootPathOverrideTitle: string;
|
||||
qualityOverrideTitle: string;
|
||||
}
|
||||
|
@ -85,6 +63,11 @@ export interface ITvRequests {
|
|||
releaseDate: Date;
|
||||
status: string;
|
||||
childRequests: IChildRequests[];
|
||||
qualityOverride: number;
|
||||
|
||||
// For UI display
|
||||
qualityOverrideTitle: string;
|
||||
rootPathOverrideTitle: string;
|
||||
}
|
||||
|
||||
export interface IChildRequests extends IBaseRequest {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Component, Input } from "@angular/core";
|
||||
// import { Component, Input } from "@angular/core";
|
||||
|
||||
import { IMediaBase } from "../interfaces";
|
||||
// import { IMediaBase } from "../interfaces";
|
||||
|
||||
@Component({
|
||||
selector: "request-card",
|
||||
templateUrl: "./request-card.component.html",
|
||||
})
|
||||
export class RequestCardComponent {
|
||||
@Input() public request: IMediaBase;
|
||||
}
|
||||
// @Component({
|
||||
// selector: "request-card",
|
||||
// templateUrl: "./request-card.component.html",
|
||||
// })
|
||||
// export class RequestCardComponent {
|
||||
// @Input() public request: IMediaBase;
|
||||
// }
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
<div class="input-group">
|
||||
<input type="text" id="search" class="form-control form-control-custom searchwidth" placeholder="Search" (keyup)="search($event)">
|
||||
<span class="input-group-btn">
|
||||
<button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = true" >
|
||||
<i class="fa fa-filter"></i> {{ 'Requests.Filter' | translate }}</button>
|
||||
<button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = !filterDisplay" >
|
||||
<i class="fa fa-filter"></i> {{ 'Requests.Filter' | translate }}</button>
|
||||
<!-- <button id="filterBtn" class="btn btn-sm btn-warning-outline" (click)="sortDisplay = !sortDisplay" >
|
||||
<i class="fa fa-sort"></i> {{ 'Requests.Sort' | translate }}</button> -->
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -36,6 +36,8 @@ export class MovieRequestsComponent implements OnInit {
|
|||
public filter: IFilter;
|
||||
public filterType = FilterType;
|
||||
|
||||
public sortDisplay: boolean;
|
||||
|
||||
private currentlyLoaded: number;
|
||||
private amountToLoad: number;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import { TvRequestsComponent } from "./tvrequests.component";
|
|||
|
||||
import { SidebarModule, TreeTableModule } from "primeng/primeng";
|
||||
|
||||
import { IdentityService, RadarrService, RequestService } from "../services";
|
||||
import { IdentityService, RadarrService, RequestService, SonarrService } from "../services";
|
||||
|
||||
import { AuthGuard } from "../auth/auth.guard";
|
||||
|
||||
|
@ -48,7 +48,8 @@ const routes: Routes = [
|
|||
IdentityService,
|
||||
RequestService,
|
||||
RadarrService,
|
||||
],
|
||||
SonarrService,
|
||||
],
|
||||
|
||||
})
|
||||
export class RequestsModule { }
|
||||
|
|
|
@ -51,17 +51,61 @@
|
|||
|
||||
|
||||
<div>Release Date: {{node.data.releaseDate | date}}</div>
|
||||
<div *ngIf="isAdmin">
|
||||
<div *ngIf="node.data.qualityOverrideTitle">{{ 'Requests.QualityOverride' | translate }}
|
||||
<span>{{node.data.qualityOverrideTitle}} </span>
|
||||
</div>
|
||||
<div *ngIf="node.data.rootPathOverrideTitle">{{ 'Requests.RootFolderOverride' | translate }}
|
||||
<span>{{node.data.rootPathOverrideTitle}} </span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
</div>
|
||||
<div class="col-sm-3 col-sm-push-3 small-padding">
|
||||
|
||||
<button style="text-align: right" class="btn btn-sm btn-success-outline" (click)="openClosestTab($event)"><i class="fa fa-plus"></i> View</button>
|
||||
<div *ngIf="isAdmin">
|
||||
<!--Sonarr Root Folder-->
|
||||
<div *ngIf="sonarrRootFolders" class="btn-group btn-split" id="rootFolderBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeRootFolder' | translate }}</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li *ngFor="let folder of sonarrRootFolders">
|
||||
<a href="#" (click)="selectRootFolder(node.data, folder, $event)">{{folder.path}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!--Sonarr Quality Profiles -->
|
||||
<div *ngIf="sonarrProfiles" class="btn-group btn-split" id="changeQualityBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeQualityProfile' | translate }}</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
<li *ngFor="let profile of sonarrProfiles">
|
||||
<a href="#" (click)="selectQualityProfile(node.data, profile, $event)">{{profile.name}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--This is the section that holds the child seasons if they want to specify specific episodes-->
|
||||
<div *ngIf="node.leaf">
|
||||
<tvrequests-children [childRequests]="node.data" [isAdmin] ="isAdmin" (requestDeleted)="childRequestDeleted($event)" [issueCategories]="issueCategories" [issuesEnabled]="issuesEnabled" [issueProviderId]="node.data.tvDbId" ></tvrequests-children>
|
||||
<tvrequests-children [childRequests]="node.data" [isAdmin] ="isAdmin"
|
||||
(requestDeleted)="childRequestDeleted($event)"
|
||||
[issueCategories]="issueCategories" [issuesEnabled]="issuesEnabled"
|
||||
[issueProviderId]="node.data.tvDbId"></tvrequests-children>
|
||||
</div>
|
||||
</ng-template>
|
||||
</p-column>
|
||||
|
|
|
@ -11,10 +11,10 @@ import "rxjs/add/operator/distinctUntilChanged";
|
|||
import "rxjs/add/operator/map";
|
||||
|
||||
import { AuthService } from "../auth/auth.service";
|
||||
import { RequestService } from "../services";
|
||||
import { NotificationService, RequestService, SonarrService } from "../services";
|
||||
|
||||
import { TreeNode } from "primeng/primeng";
|
||||
import { IIssueCategory, ITvRequests } from "../interfaces";
|
||||
import { IIssueCategory, ISonarrProfile, ISonarrRootFolder, ITvRequests } from "../interfaces";
|
||||
|
||||
@Component({
|
||||
selector: "tv-requests",
|
||||
|
@ -34,13 +34,18 @@ export class TvRequestsComponent implements OnInit {
|
|||
@Input() public issuesEnabled: boolean;
|
||||
public issueProviderId: string;
|
||||
|
||||
public sonarrProfiles: ISonarrProfile[] = [];
|
||||
public sonarrRootFolders: ISonarrRootFolder[] = [];
|
||||
|
||||
private currentlyLoaded: number;
|
||||
private amountToLoad: number;
|
||||
|
||||
constructor(private requestService: RequestService,
|
||||
private auth: AuthService,
|
||||
private sanitizer: DomSanitizer,
|
||||
private imageService: ImageService) {
|
||||
private imageService: ImageService,
|
||||
private sonarrService: SonarrService,
|
||||
private notificationService: NotificationService) {
|
||||
this.searchChanged
|
||||
.debounceTime(600) // Wait Xms after the last event before emitting last event
|
||||
.distinctUntilChanged() // only emit if value is different from previous value
|
||||
|
@ -54,9 +59,11 @@ export class TvRequestsComponent implements OnInit {
|
|||
.subscribe(m => {
|
||||
this.tvRequests = m;
|
||||
this.tvRequests.forEach((val) => this.loadBackdrop(val));
|
||||
this.tvRequests.forEach((val) => this.setOverride(val.data));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public openClosestTab(el: any) {
|
||||
const rowclass = "undefined ng-star-inserted";
|
||||
el = el.toElement || el.relatedTarget || el.target;
|
||||
|
@ -83,11 +90,18 @@ export class TvRequestsComponent implements OnInit {
|
|||
}
|
||||
|
||||
public ngOnInit() {
|
||||
|
||||
const profile = <ISonarrProfile>{name:"test",id:1 };
|
||||
const folder = <ISonarrRootFolder>{path:"testpath", id:1};
|
||||
|
||||
this.sonarrProfiles.push(profile);
|
||||
this.sonarrRootFolders.push(folder);
|
||||
this.amountToLoad = 1000;
|
||||
this.currentlyLoaded = 1000;
|
||||
this.tvRequests = [];
|
||||
this.loadInit();
|
||||
this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser");
|
||||
|
||||
this.loadInit();
|
||||
}
|
||||
|
||||
public loadMore() {
|
||||
|
@ -117,14 +131,72 @@ export class TvRequestsComponent implements OnInit {
|
|||
this.ngOnInit();
|
||||
}
|
||||
|
||||
public selectRootFolder(searchResult: ITvRequests, rootFolderSelected: ISonarrRootFolder, event: any) {
|
||||
event.preventDefault();
|
||||
searchResult.rootFolder = rootFolderSelected.id;
|
||||
this.setOverride(searchResult);
|
||||
this.updateRequest(searchResult);
|
||||
}
|
||||
|
||||
public selectQualityProfile(searchResult: ITvRequests, profileSelected: ISonarrProfile, event: any) {
|
||||
event.preventDefault();
|
||||
searchResult.qualityOverride = profileSelected.id;
|
||||
this.setOverride(searchResult);
|
||||
this.updateRequest(searchResult);
|
||||
}
|
||||
|
||||
private setOverride(req: ITvRequests): void {
|
||||
this.setQualityOverrides(req);
|
||||
this.setRootFolderOverrides(req);
|
||||
}
|
||||
|
||||
private updateRequest(request: ITvRequests) {
|
||||
this.requestService.updateTvRequest(request)
|
||||
.subscribe(x => {
|
||||
this.notificationService.success("Request Updated");
|
||||
this.setOverride(x);
|
||||
request = x;
|
||||
});
|
||||
}
|
||||
|
||||
private setQualityOverrides(req: ITvRequests): void {
|
||||
if (this.sonarrProfiles) {
|
||||
const profile = this.sonarrProfiles.filter((p) => {
|
||||
return p.id === req.qualityOverride;
|
||||
});
|
||||
if (profile.length > 0) {
|
||||
req.qualityOverrideTitle = profile[0].name;
|
||||
}
|
||||
}
|
||||
}
|
||||
private setRootFolderOverrides(req: ITvRequests): void {
|
||||
if (this.sonarrRootFolders) {
|
||||
const path = this.sonarrRootFolders.filter((folder) => {
|
||||
return folder.id === req.rootFolder;
|
||||
});
|
||||
if (path.length > 0) {
|
||||
req.rootPathOverrideTitle = path[0].path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private loadInit() {
|
||||
this.requestService.getTvRequestsTree(this.amountToLoad, 0)
|
||||
.subscribe(x => {
|
||||
this.tvRequests = x;
|
||||
this.tvRequests.forEach((val, index) => {
|
||||
this.loadBackdrop(val);
|
||||
this.setOverride(val.data);
|
||||
});
|
||||
});
|
||||
|
||||
if(this.isAdmin) {
|
||||
this.sonarrService.getQualityProfilesWithoutSettings()
|
||||
.subscribe(x => this.sonarrProfiles = x);
|
||||
|
||||
this.sonarrService.getRootFoldersWithoutSettings()
|
||||
.subscribe(x => this.sonarrRootFolders = x);
|
||||
}
|
||||
}
|
||||
|
||||
private resetSearch() {
|
||||
|
|
|
@ -20,4 +20,11 @@ export class SonarrService extends ServiceHelpers {
|
|||
public getQualityProfiles(settings: ISonarrSettings): Observable<ISonarrProfile[]> {
|
||||
return this.http.post<ISonarrProfile[]>(`${this.url}/Profiles/`, JSON.stringify(settings), {headers: this.headers});
|
||||
}
|
||||
|
||||
public getRootFoldersWithoutSettings(): Observable<ISonarrRootFolder[]> {
|
||||
return this.http.get<ISonarrRootFolder[]>(`${this.url}/RootFolders/`, {headers: this.headers});
|
||||
}
|
||||
public getQualityProfilesWithoutSettings(): Observable<ISonarrProfile[]> {
|
||||
return this.http.get<ISonarrProfile[]>(`${this.url}/Profiles/`, {headers: this.headers});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,5 +46,27 @@ namespace Ombi.Controllers.External
|
|||
{
|
||||
return await SonarrApi.GetRootFolders(settings.ApiKey, settings.FullUri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Sonarr profiles.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("Profiles")]
|
||||
public async Task<IEnumerable<SonarrProfile>> GetProfiles()
|
||||
{
|
||||
var settings = await SonarrSettings.GetSettingsAsync();
|
||||
return await SonarrApi.GetProfiles(settings.ApiKey, settings.FullUri);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Sonarr root folders.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("RootFolders")]
|
||||
public async Task<IEnumerable<SonarrRootFolder>> GetRootFolders()
|
||||
{
|
||||
var settings = await SonarrSettings.GetSettingsAsync();
|
||||
return await SonarrApi.GetRootFolders(settings.ApiKey, settings.FullUri);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -121,8 +121,8 @@
|
|||
"RequestDate": "Request Date:",
|
||||
"QualityOverride": "Quality Override:",
|
||||
"RootFolderOverride": "Root Folder Override:",
|
||||
"ChangeRootFolder":"Change Root Folder",
|
||||
"ChangeQualityProfile":"Change Quality Profile",
|
||||
"ChangeRootFolder":"Root Folder",
|
||||
"ChangeQualityProfile":"Quality Profile",
|
||||
"MarkUnavailable":"Mark Unavailable",
|
||||
"MarkAvailable":"Mark Available",
|
||||
"Remove":"Remove",
|
||||
|
@ -133,6 +133,7 @@
|
|||
"GridStatus":"Status",
|
||||
"ReportIssue":"Report Issue",
|
||||
"Filter":"Filter",
|
||||
"Sort":"Sort",
|
||||
"SeasonNumberHeading":"Season: {seasonNumber}"
|
||||
},
|
||||
"Issues":{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue