Improvements to the UI and also finished the availability checker #865 #1464

pull/1510/head
Jamie.Rees 7 years ago
parent 385d206287
commit 3cc45b3022

@ -5,10 +5,10 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="Moq" Version="4.7.10" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.3.0-beta4-build3742" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta4-build3742" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.0-beta4-build3742" />
</ItemGroup>
<ItemGroup>

@ -26,8 +26,8 @@ namespace Ombi.Core.Tests.Rule.Request
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
var result = await Rule.Execute(request);
Assert.Equal(result.Success, true);
Assert.Equal(request.Approved, true);
Assert.True(result.Success);
Assert.True(request.Approved);
}
[Fact]
@ -37,8 +37,8 @@ namespace Ombi.Core.Tests.Rule.Request
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow };
var result = await Rule.Execute(request);
Assert.Equal(result.Success, true);
Assert.Equal(request.Approved, true);
Assert.True(result.Success);
Assert.True(request.Approved);
}
[Fact]
@ -48,8 +48,8 @@ namespace Ombi.Core.Tests.Rule.Request
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
var result = await Rule.Execute(request);
Assert.Equal(result.Success, true);
Assert.Equal(request.Approved, true);
Assert.True(result.Success);
Assert.True(request.Approved);
}
[Fact]
@ -59,8 +59,8 @@ namespace Ombi.Core.Tests.Rule.Request
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow };
var result = await Rule.Execute(request);
Assert.Equal(result.Success, true);
Assert.Equal(request.Approved, true);
Assert.True(result.Success);
Assert.True(request.Approved);
}
[Fact]
@ -69,8 +69,8 @@ namespace Ombi.Core.Tests.Rule.Request
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie };
var result = await Rule.Execute(request);
Assert.Equal(result.Success, true);
Assert.Equal(request.Approved, false);
Assert.True(result.Success);
Assert.False(request.Approved);
}
[Fact]
@ -79,8 +79,8 @@ namespace Ombi.Core.Tests.Rule.Request
var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow };
var result = await Rule.Execute(request);
Assert.Equal(result.Success, true);
Assert.Equal(request.Approved, false);
Assert.True(result.Success);
Assert.False(request.Approved);
}
}
}

@ -33,7 +33,7 @@ namespace Ombi.Core.Tests.Rule.Search
Approved = true
};
MovieMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list);
MovieMock.Setup(x => x.GetRequest(123)).Returns(list);
var search = new SearchMovieViewModel
{
Id = 123,
@ -42,7 +42,7 @@ namespace Ombi.Core.Tests.Rule.Search
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.Equal(search.Approved, true);
Assert.False(search.Approved);
}
[Fact]
@ -54,7 +54,7 @@ namespace Ombi.Core.Tests.Rule.Search
Approved = true
};
MovieMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list);
MovieMock.Setup(x => x.GetRequest(123)).Returns(list);
var search = new SearchMovieViewModel
{
Id = 999,
@ -63,7 +63,7 @@ namespace Ombi.Core.Tests.Rule.Search
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.Equal(search.Approved, false);
Assert.False(search.Approved);
}
[Fact]
@ -82,7 +82,7 @@ namespace Ombi.Core.Tests.Rule.Search
}
};
TvMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list);
TvMock.Setup(x => x.GetRequest(123)).Returns(list);
var search = new SearchTvShowViewModel
{
Id = 123,
@ -91,7 +91,7 @@ namespace Ombi.Core.Tests.Rule.Search
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.Equal(search.Approved, true);
Assert.True(search.Approved);
}
[Fact]
@ -111,7 +111,7 @@ namespace Ombi.Core.Tests.Rule.Search
};
TvMock.Setup(x => x.GetRequest(123)).ReturnsAsync(list);
TvMock.Setup(x => x.GetRequest(123)).Returns(list);
var search = new SearchTvShowViewModel()
{
Id = 999,
@ -120,7 +120,7 @@ namespace Ombi.Core.Tests.Rule.Search
var result = await Rule.Execute(search);
Assert.True(result.Success);
Assert.Equal(search.Approved, false);
Assert.False(search.Approved);
}

@ -148,10 +148,18 @@ namespace Ombi.Core.Engine
{
var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id);
viewMovie.Id = showInfo.Id; // TheMovieDbId
viewMovie.ImdbId = showInfo.ImdbId;
}
// So when we run the rule to check if it's available in Plex we need the ImdbId
// But we only pass down the SearchViewModel that doesn't contain this
// So set the ImdbId to viewMovie.Id and then set it back afterwards
var oldId = viewMovie.Id;
viewMovie.CustomId = viewMovie.ImdbId ?? string.Empty;
await RunSearchRules(viewMovie);
viewMovie.Id = oldId;
return viewMovie;
}

@ -1,4 +1,6 @@
namespace Ombi.Core.Models.Search
using System.ComponentModel.DataAnnotations.Schema;
namespace Ombi.Core.Models.Search
{
public class SearchViewModel
{
@ -7,5 +9,16 @@
public bool Requested { get; set; }
public bool Available { get; set; }
public string PlexUrl { get; set; }
public string Quality { get; set; }
/// <summary>
/// This is used for the PlexAvailabilityCheck rule
/// </summary>
/// <value>
/// The custom identifier.
/// </value>
[NotMapped]
public string CustomId { get; set; }
}
}

@ -19,9 +19,9 @@ namespace Ombi.Core.Rule.Rules.Search
private IMovieRequestRepository Movie { get; }
private ITvRequestRepository Tv { get; }
public async Task<RuleResult> Execute(SearchViewModel obj)
public Task<RuleResult> Execute(SearchViewModel obj)
{
var movieRequests = await Movie.GetRequest(obj.Id);
var movieRequests = Movie.GetRequest(obj.Id);
if (movieRequests != null) // Do we already have a request for this?
{
@ -29,10 +29,10 @@ namespace Ombi.Core.Rule.Rules.Search
obj.Approved = movieRequests.Approved;
obj.Available = movieRequests.Available;
return Success();
return Task.FromResult(Success());
}
var tvRequests = await Tv.GetRequest(obj.Id);
var tvRequests = Tv.GetRequest(obj.Id);
if (tvRequests != null) // Do we already have a request for this?
{
@ -40,9 +40,9 @@ namespace Ombi.Core.Rule.Rules.Search
obj.Approved = tvRequests.ChildRequests.Any(x => x.Approved);
obj.Available = tvRequests.ChildRequests.Any(x => x.Available);
return Success();
return Task.FromResult(Success());
}
return Success();
return Task.FromResult(Success());
}
}
}

@ -16,11 +16,12 @@ namespace Ombi.Core.Rule.Rules.Search
public async Task<RuleResult> Execute(SearchViewModel obj)
{
var item = await PlexContentRepository.Get(obj.Id.ToString());
var item = await PlexContentRepository.Get(obj.CustomId);
if (item != null)
{
obj.Available = true;
obj.PlexUrl = item.Url;
obj.Quality = item.Quality;
}
return Success();
}

@ -1,5 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Context;
@ -15,16 +16,16 @@ namespace Ombi.Core.Rule.Rules.Search
private readonly IOmbiContext _ctx;
public Task<RuleResult> Execute(SearchViewModel obj)
public async Task<RuleResult> Execute(SearchViewModel obj)
{
// Check if it's in Radarr
var result = _ctx.RadarrCache.FirstOrDefault(x => x.TheMovieDbId == obj.Id);
var result = await _ctx.RadarrCache.FirstOrDefaultAsync(x => x.TheMovieDbId == obj.Id);
if (result != null)
{
obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something?
}
return Task.FromResult(Success());
return Success();
}
}
}

@ -1,6 +1,7 @@
using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Ombi.Api.Discord;
@ -89,18 +90,18 @@ namespace Ombi.DependencyInjection
{
services.AddEntityFrameworkSqlite().AddDbContext<OmbiContext>();
services.AddScoped<IOmbiContext, OmbiContext>();
services.AddScoped<ISettingsRepository, SettingsJsonRepository>();
services.AddScoped<ISettingsResolver, SettingsResolver>();
services.AddScoped<IPlexContentRepository, PlexContentRepository>();
services.AddScoped<INotificationTemplatesRepository, NotificationTemplatesRepository>();
services.AddScoped<IOmbiContext, OmbiContext>(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6
services.AddTransient<ISettingsRepository, SettingsJsonRepository>();
services.AddTransient<ISettingsResolver, SettingsResolver>();
services.AddTransient<IPlexContentRepository, PlexContentRepository>();
services.AddTransient<INotificationTemplatesRepository, NotificationTemplatesRepository>();
services.AddScoped<ITvRequestRepository, TvRequestRepository>();
services.AddScoped<IMovieRequestRepository, MovieRequestRepository>();
services.AddScoped<IAuditRepository, AuditRepository>();
services.AddScoped<IApplicationConfigRepository, ApplicationConfigRepository>();
services.AddScoped<ITokenRepository, TokenRepository>();
services.AddScoped(typeof(ISettingsService<>), typeof(SettingsService<>));
services.AddTransient<ITvRequestRepository, TvRequestRepository>();
services.AddTransient<IMovieRequestRepository, MovieRequestRepository>();
services.AddTransient<IAuditRepository, AuditRepository>();
services.AddTransient<IApplicationConfigRepository, ApplicationConfigRepository>();
services.AddTransient<ITokenRepository, TokenRepository>();
services.AddTransient(typeof(ISettingsService<>), typeof(SettingsService<>));
}
public static void RegisterServices(this IServiceCollection services)
{

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
<PackageReference Include="Moq" Version="4.7.99" />
<PackageReference Include="Nunit" Version="3.7.1" />
<PackageReference Include="NUnit.ConsoleRunner" Version="3.7.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.8.0" />
<packagereference Include="Microsoft.NET.Test.Sdk" Version="15.0.0"></packagereference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Ombi.Schedule\Ombi.Schedule.csproj" />
</ItemGroup>
</Project>

@ -0,0 +1,110 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Castle.Components.DictionaryAdapter;
using Moq;
using NUnit.Framework;
using Ombi.Schedule.Jobs.Plex;
using Ombi.Store.Entities;
using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;
namespace Ombi.Schedule.Tests
{
[TestFixture]
public class PlexAvailabilityCheckerTests
{
public PlexAvailabilityCheckerTests()
{
_repo = new Mock<IPlexContentRepository>();
_tv = new Mock<ITvRequestRepository>();
_movie = new Mock<IMovieRequestRepository>();
Checker = new PlexAvailabilityChecker(_repo.Object, _tv.Object, _movie.Object);
}
private readonly Mock<IPlexContentRepository> _repo;
private readonly Mock<ITvRequestRepository> _tv;
private readonly Mock<IMovieRequestRepository> _movie;
private PlexAvailabilityChecker Checker { get; }
[Test]
public async Task ProcessMovies_ShouldMarkAvailable_WhenInPlex()
{
var request = new MovieRequests
{
ImdbId = "test"
};
_movie.Setup(x => x.Get()).Returns(new List<MovieRequests> { request }.AsQueryable());
_repo.Setup(x => x.Get("test")).ReturnsAsync(new PlexContent());
await Checker.Start();
_movie.Verify(x => x.Save(), Times.Once);
Assert.True(request.Available);
}
[Test]
public async Task ProcessMovies_ShouldNotBeAvailable_WhenInNotPlex()
{
var request = new MovieRequests
{
ImdbId = "test"
};
_movie.Setup(x => x.Get()).Returns(new List<MovieRequests> { request }.AsQueryable());
await Checker.Start();
_movie.Verify(x => x.Save(), Times.Once);
Assert.False(request.Available);
}
[Test]
[Ignore("EF IAsyncQueryProvider")]
public async Task ProcessTv_ShouldMark_Episode_Available_WhenInPlex()
{
var request = new ChildRequests
{
ParentRequest = new TvRequests {TvDbId = 1},
SeasonRequests = new EditableList<SeasonRequests>
{
new SeasonRequests
{
Episodes = new EditableList<EpisodeRequests>
{
new EpisodeRequests
{
EpisodeNumber = 1,
Season = new SeasonRequests
{
SeasonNumber = 2
}
}
}
}
}
};
_tv.Setup(x => x.GetChild()).Returns(new List<ChildRequests> { request }.AsQueryable());
_repo.Setup(x => x.GetAllEpisodes()).Returns(new List<PlexEpisode>
{
new PlexEpisode
{
Series = new PlexContent
{
ProviderId = 1.ToString(),
},
EpisodeNumber = 1,
SeasonNumber = 2
}
}.AsQueryable);
await Checker.Start();
_tv.Verify(x => x.Save(), Times.Once);
Assert.True(request.SeasonRequests[0].Episodes[0].Available);
}
}
}

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:62604/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"Ombi.Schedule.Tests": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:62605/"
}
}
}

@ -27,7 +27,7 @@ namespace Ombi.Schedule.Jobs.Plex
private async Task ProcessTv()
{
var tv = _tvRepo.GetChild();
var tv = _tvRepo.GetChild().Where(x => !x.Available);
var plexEpisodes = _repo.GetAllEpisodes().Include(x => x.Series);
foreach (var child in tv)

@ -187,7 +187,8 @@ namespace Ombi.Schedule.Jobs.Plex
Type = PlexMediaTypeEntity.Movie,
Title = movie.title,
Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey),
Seasons = new List<PlexSeasonsContent>()
Seasons = new List<PlexSeasonsContent>(),
Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty
};
contentToAdd.Add(item);

@ -102,24 +102,24 @@ namespace Ombi.Schedule.Jobs.Plex
var currentPosition = 0;
var ResultCount = 50;
var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, ResultCount);
var currentData = _repo.GetAllEpisodes();
_log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}");
await ProcessEpsiodes(episodes);
await ProcessEpsiodes(episodes, currentData);
currentPosition += ResultCount;
while (currentPosition < episodes.MediaContainer.totalSize)
{
var ep = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition,
ResultCount);
await ProcessEpsiodes(ep);
await ProcessEpsiodes(ep, currentData);
_log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Processed {ResultCount} more episodes. Total Remaining {currentPosition - episodes.MediaContainer.totalSize}");
currentPosition += ResultCount;
}
}
private async Task ProcessEpsiodes(PlexContainer episodes)
private async Task ProcessEpsiodes(PlexContainer episodes, IQueryable<PlexEpisode> currentEpisodes)
{
var ep = new HashSet<PlexEpisode>();
foreach (var episode in episodes.MediaContainer.Metadata)
@ -128,6 +128,13 @@ namespace Ombi.Schedule.Jobs.Plex
// We have the parent and grandparent rating keys to link up to the season and series
//var metadata = _api.GetEpisodeMetaData(server.PlexAuthToken, server.FullUri, episode.ratingKey);
var epExists = currentEpisodes.Any(x => episode.ratingKey == x.Key &&
episode.grandparentRatingKey == x.GrandparentKey);
if (epExists)
{
continue;
}
ep.Add(new PlexEpisode
{
EpisodeNumber = episode.index,

@ -53,6 +53,7 @@ namespace Ombi.Store.Entities
/// </summary>
public int Key { get; set; }
public DateTime AddedAt { get; set; }
public string Quality { get; set; }
}
[Table("PlexSeasonsContent")]

@ -10,7 +10,7 @@ using Ombi.Helpers;
namespace Ombi.Store.Migrations
{
[DbContext(typeof(OmbiContext))]
[Migration("20170824133349_Inital")]
[Migration("20170825114646_Inital")]
partial class Inital
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@ -258,6 +258,8 @@ namespace Ombi.Store.Migrations
b.Property<string>("ProviderId");
b.Property<string>("Quality");
b.Property<string>("ReleaseYear");
b.Property<string>("Title");

@ -134,6 +134,7 @@ namespace Ombi.Store.Migrations
AddedAt = table.Column<DateTime>(nullable: false),
Key = table.Column<int>(nullable: false),
ProviderId = table.Column<string>(nullable: true),
Quality = table.Column<string>(nullable: true),
ReleaseYear = table.Column<string>(nullable: true),
Title = table.Column<string>(nullable: true),
Type = table.Column<int>(nullable: false),

@ -257,6 +257,8 @@ namespace Ombi.Store.Migrations
b.Property<string>("ProviderId");
b.Property<string>("Quality");
b.Property<string>("ReleaseYear");
b.Property<string>("Title");

@ -9,7 +9,8 @@ namespace Ombi.Store.Repository
Task<MovieRequests> Add(MovieRequests request);
Task Delete(MovieRequests request);
IQueryable<MovieRequests> Get();
Task<MovieRequests> GetRequest(int theMovieDbId);
Task<MovieRequests> GetRequestAsync(int theMovieDbId);
MovieRequests GetRequest(int theMovieDbId);
Task Update(MovieRequests request);
Task Save();
}

@ -11,7 +11,8 @@ namespace Ombi.Store.Repository.Requests
Task Delete(TvRequests request);
Task DeleteChild(ChildRequests request);
IQueryable<TvRequests> Get();
Task<TvRequests> GetRequest(int tvDbId);
Task<TvRequests> GetRequestAsync(int tvDbId);
TvRequests GetRequest(int tvDbId);
Task Update(TvRequests request);
Task UpdateChild(ChildRequests request);
IQueryable<ChildRequests> GetChild();

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
@ -16,11 +17,27 @@ namespace Ombi.Store.Repository.Requests
private IOmbiContext Db { get; }
public async Task<MovieRequests> GetRequest(int theMovieDbId)
public async Task<MovieRequests> GetRequestAsync(int theMovieDbId)
{
return await Db.MovieRequests.Where(x => x.TheMovieDbId == theMovieDbId)
try
{
return await Db.MovieRequests.Where(x => x.TheMovieDbId == theMovieDbId)
.Include(x => x.RequestedUser)
.FirstOrDefaultAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public MovieRequests GetRequest(int theMovieDbId)
{
return Db.MovieRequests.Where(x => x.TheMovieDbId == theMovieDbId)
.Include(x => x.RequestedUser)
.FirstOrDefaultAsync();
.FirstOrDefault();
}
public IQueryable<MovieRequests> Get()

@ -15,17 +15,28 @@ namespace Ombi.Store.Repository.Requests
private IOmbiContext Db { get; }
public async Task<TvRequests> GetRequest(int tvDbId)
public async Task<TvRequests> GetRequestAsync(int tvDbId)
{
return await Db.TvRequests.Where(x => x.TvDbId == tvDbId)
.Include(x => x.ChildRequests)
.ThenInclude(x => x.RequestedUser)
.ThenInclude(x => x.RequestedUser)
.Include(x => x.ChildRequests)
.ThenInclude(x => x.SeasonRequests)
.ThenInclude(x => x.Episodes)
.FirstOrDefaultAsync();
}
public TvRequests GetRequest(int tvDbId)
{
return Db.TvRequests.Where(x => x.TvDbId == tvDbId)
.Include(x => x.ChildRequests)
.ThenInclude(x => x.RequestedUser)
.Include(x => x.ChildRequests)
.ThenInclude(x => x.SeasonRequests)
.ThenInclude(x => x.Episodes)
.FirstOrDefault();
}
public IQueryable<TvRequests> Get()
{
return Db.TvRequests
@ -40,6 +51,7 @@ namespace Ombi.Store.Repository.Requests
{
return Db.ChildRequests
.Include(x => x.RequestedUser)
.Include(x => x.ParentRequest)
.Include(x => x.SeasonRequests)
.ThenInclude(x => x.Episodes)
.AsQueryable();

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26730.8
VisualStudioVersion = 15.0.26730.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}"
EndProject
@ -76,9 +76,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Pushbullet", "Ombi
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Slack", "Ombi.Api.Slack\Ombi.Api.Slack.csproj", "{71708256-9152-4E81-9FCA-E3181A185806}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Mattermost", "Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj", "{737B2620-FE5A-4135-A017-79C269A7D36C}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Mattermost", "Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj", "{737B2620-FE5A-4135-A017-79C269A7D36C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Pushover", "Ombi.Api.Pushover\Ombi.Api.Pushover.csproj", "{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Pushover", "Ombi.Api.Pushover\Ombi.Api.Pushover.csproj", "{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Schedule.Tests", "Ombi.Schedule.Tests\Ombi.Schedule.Tests.csproj", "{BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -198,6 +200,10 @@ Global
{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Release|Any CPU.Build.0 = Release|Any CPU
{BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -225,6 +231,7 @@ Global
{71708256-9152-4E81-9FCA-E3181A185806} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{737B2620-FE5A-4135-A017-79C269A7D36C} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{CA55DD4F-4EFF-4906-A848-35FCC7BD5654} = {9293CA11-360A-4C20-A674-B9E794431BF5}
{BDD8B924-016E-4CDA-9FFA-50B0A34BCD3C} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}

@ -20,5 +20,6 @@
approved: boolean,
requested: boolean,
available: boolean,
plexUrl: string
plexUrl: string,
quality:string
}

@ -43,15 +43,7 @@
<span class="label label-success">{{node.data.status}}</span>
</div>
<div>
<span>Request status: </span>
<span *ngIf="node.data.available" class="label label-success">Available</span>
<span *ngIf="node.data.approved && !node.data.available" class="label label-info">Processing Request</span>
<span *ngIf="node.data.denied" class="label label-danger">Request Denied</span>
<span *ngIf="node.data.deniedReason" title="{{node.data.deniedReason}}"><i class="fa fa-info-circle"></i></span>
<span *ngIf="!node.data.approved && !node.data.availble && !node.data.denied" class="label label-warning">Pending Approval</span>
</div>
<div>Release Date: {{node.data.releaseDate | date}}</div>
<br />
</div>

@ -214,6 +214,7 @@ export class TvRequestsComponent implements OnInit, OnDestroy {
this.requestService.getTvRequests(this.amountToLoad, 0)
.takeUntil(this.subscriptions)
.subscribe(x => {
debugger;
this.tvRequests = this.transformData(x);
});
this.isAdmin = this.identityService.hasRole("Admin");

@ -46,7 +46,11 @@
<span *ngIf="result.releaseDate" class="label label-info" target="_blank">Release Date: {{result.releaseDate | date: 'dd/MM/yyyy'}}</span>
<a *ngIf="result.homepage" href="{{result.homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
<a *ngIf="result.trailer" href="{{result.trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
<span *ngIf="result.available" class="label label-success">Available</span>
<span *ngIf="result.quality" class="label label-success">{{result.quality}}p</span>
<span *ngIf="result.approved && !result.available" class="label label-info">Processing Request</span>
<div *ngIf="result.requested && !result.available; then requested else notRequested"></div>
<ng-template #requested>
@ -58,11 +62,7 @@
</ng-template>
<span id="{{id}}netflixTab"></span>
<a *ngIf="result.homepage" href="{{result.homepage}}" target="_blank"><span class="label label-info">HomePage</span></a>
<a *ngIf="result.trailer" href="{{result.trailer}}" target="_blank"><span class="label label-info">Trailer</span></a>
<br/>
@ -132,11 +132,12 @@
<br/>
<div *ngIf="result.available">
<input name="providerId" type="text" value="{{id}}" hidden="hidden"/>
<a *ngIf="result.plexUrl" style="text-align: right" class="btn btn-sm btn-success-outline" href="{{result.plexUrl}}" target="_blank"><i class="fa fa-eye"></i> View On Plex</a>
<!--<input name="providerId" type="text" value="{{id}}" hidden="hidden"/>
<input name="type" type="text" value="{{type}}" hidden="hidden"/>
<div class="dropdown">
<button class="btn btn-sm btn-danger-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-exclamation"></i> @UI.Search_ReportIssue
<i class="fa fa-exclamation"></i> Report Issue
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
@ -146,7 +147,7 @@
<li><a issue-select="3" class="dropdownIssue" href="#">Playback</a></li>
<li><a issue-select="4" class="dropdownIssue" href="#" data-toggle="modal" data-target="#issuesModal">Other</a></li>
</ul>
</div>
</div>-->
</div>
</div>

@ -9,21 +9,10 @@
<li role="presentation" class="active">
<a id="movieTabButton" href="#MoviesTab" aria-controls="home" role="tab" data-toggle="tab" (click)="selectTab()"><i class="fa fa-film"></i> Movies</a>
</li>
<!--<li role="presentation">
<a id="actorTabButton" href="#ActorsTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-users"></i> Actors</a>
</li>-->
<li role="presentation">
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectTab()"><i class="fa fa-television"></i> TV Shows</a>
</li>
<!--
<li role="presentation">
<a href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab"><i class="fa fa-music"></i> Albums</a>
</li>-->
</ul>
<!-- Tab panes -->
@ -33,28 +22,8 @@
<movie-search></movie-search>
</div>
<!--
<div role="tabpanel" class="tab-pane" id="ActorsTab">
<div class="input-group">
<input id="actorSearchContent" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons">
<div class="input-group-addon">
<i id="actorSearchButton" class="fa fa-search"></i>
</div>
</div>
<div class="checkbox">
<input type="checkbox" id="actorsSearchNew" name="actorsSearchNew"><label for="actorsSearchNew">@UI.Search_NewOnly</label>
</div>
<br />
<br />
<div id="actorMovieList">
</div>
</div>-->
<div [hidden]="!showTv">
<tv-search></tv-search>
</div>
</div>

@ -44,7 +44,7 @@
<div>
<a href="http://www.imdb.com/title/{{result.imdbId}}/" target="_blank">
<h4>{{result.title}} ({{result.firstAired}})</h4>
<h4>{{result.title}} ({{result.firstAired | date: 'yyyy'}})</h4>
</a>
@ -85,16 +85,7 @@
<div class="col-sm-2">
<input name="{{type}}Id" type="text" value="{{result.id}}" hidden="hidden"/>
<div *ngIf="result.available">
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i> Available</button>
<div *ngIf="result.url">
<br/>
<br/>
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{result.url}}" target="_blank"><i class="fa fa-eye"></i> View In Plex</a>
</div>
</div>
<!--<div *ngIf="result.requested; then requestedBtn else notRequestedBtn"></div>
<template #requestedBtn>
<button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button>
@ -134,11 +125,13 @@
<br/>
<div *ngIf="result.available">
<input name="providerId" type="text" value="{{id}}" hidden="hidden"/>
<a *ngIf="result.plexUrl" style="text-align: right" class="btn btn-sm btn-success-outline" href="{{result.plexUrl}}" target="_blank"><i class="fa fa-eye"></i> View On Plex</a>
<!--<input name="providerId" type="text" value="{{id}}" hidden="hidden"/>
<input name="type" type="text" value="{{type}}" hidden="hidden"/>
<div class="dropdown">
<button class="btn btn-sm btn-danger-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
<i class="fa fa-exclamation"></i> @UI.Search_ReportIssue
<i class="fa fa-exclamation"></i> Report Issue
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
@ -148,7 +141,7 @@
<li><a issue-select="3" class="dropdownIssue" href="#">Playback</a></li>
<li><a issue-select="4" class="dropdownIssue" href="#" data-toggle="modal" data-target="#issuesModal">Other</a></li>
</ul>
</div>
</div>-->
</div>
</div>

Loading…
Cancel
Save