diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs
index ef3638741..da64e99b6 100644
--- a/src/Ombi.Core/Engine/MovieSearchEngine.cs
+++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs
@@ -10,9 +10,7 @@ using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Ombi.Core.Rule.Interfaces;
-using StackExchange.Profiling;
using Microsoft.Extensions.Caching.Memory;
-using Ombi.Api.Trakt;
using Ombi.Core.Authentication;
using Ombi.Helpers;
@@ -55,22 +53,14 @@ namespace Ombi.Core.Engine
///
public async Task> Search(string search)
{
- using (MiniProfiler.Current.Step("Starting Movie Search Engine"))
- using (MiniProfiler.Current.Step("Searching Movie"))
+ var result = await MovieApi.SearchMovie(search);
+
+ if (result != null)
{
- var result = await MovieApi.SearchMovie(search);
-
- using (MiniProfiler.Current.Step("Fin API, Transforming"))
- {
- if (result != null)
- {
- Logger.LogDebug("Search Result: {result}", result);
- return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
- }
- }
-
- return null;
+ Logger.LogDebug("Search Result: {result}", result);
+ return await TransformMovieResultsToResponse(result.Take(10)); // Take 10 to stop us overloading the API
}
+ return null;
}
///
@@ -174,7 +164,7 @@ namespace Ombi.Core.Engine
// 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;
diff --git a/src/Ombi.Core/Engine/TvSearchEngine.cs b/src/Ombi.Core/Engine/TvSearchEngine.cs
index cf5d1ef3c..8cfae9506 100644
--- a/src/Ombi.Core/Engine/TvSearchEngine.cs
+++ b/src/Ombi.Core/Engine/TvSearchEngine.cs
@@ -15,11 +15,7 @@ using System.Linq;
using System.Security.Principal;
using System.Threading.Tasks;
using Ombi.Core.Rule.Interfaces;
-using Ombi.Store.Entities.Requests;
using Ombi.Store.Repository.Requests;
-using Ombi.Store.Entities;
-using Microsoft.AspNetCore.Identity;
-using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Ombi.Core.Authentication;
using Ombi.Helpers;
@@ -117,11 +113,7 @@ namespace Ombi.Core.Engine
});
}
}
-
- var existingRequests = await GetTvRequests();
- var plexSettings = await PlexSettings.GetSettingsAsync();
- var embySettings = await EmbySettings.GetSettingsAsync();
- return await ProcessResult(mapped, existingRequests, plexSettings, embySettings);
+ return await ProcessResult(mapped);
}
public async Task> GetShowInformationTreeNode(int tvdbid)
@@ -189,127 +181,21 @@ namespace Ombi.Core.Engine
};
}
-
private async Task> ProcessResults(IEnumerable items)
{
- var existingRequests = await GetTvRequests();
-
- var plexSettings = await PlexSettings.GetSettingsAsync();
- var embySettings = await EmbySettings.GetSettingsAsync();
-
var retVal = new List();
foreach (var tvMazeSearch in items)
{
var viewT = Mapper.Map(tvMazeSearch);
- retVal.Add(await ProcessResult(viewT, existingRequests, plexSettings, embySettings));
+ retVal.Add(await ProcessResult(viewT));
}
return retVal;
}
- private async Task ProcessResult(SearchTvShowViewModel item, Dictionary existingRequests, PlexSettings plexSettings, EmbySettings embySettings)
+ private async Task ProcessResult(SearchTvShowViewModel item)
{
- if (embySettings.Enable)
- {
- var content = await EmbyContentRepo.Get(item.Id.ToString());
-
- if (content != null)
- {
- item.Available = true;
- }
-
- // Let's go through the episodes now
- if (item.SeasonRequests.Any())
- {
- var allEpisodes = EmbyContentRepo.GetAllEpisodes().Include(x => x.Series);
- foreach (var season in item.SeasonRequests)
- {
- foreach (var episode in season.Episodes)
- {
- var epExists = await allEpisodes.FirstOrDefaultAsync(x =>
- x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && item.Id.ToString() == x.Series.ProviderId);
- if (epExists != null)
- {
- episode.Available = true;
- }
- }
- }
- }
- }
- if (plexSettings.Enable)
- {
- var content = await PlexContentRepo.Get(item.Id.ToString());
-
- if (content != null)
- {
- item.Available = true;
- item.PlexUrl = content.Url;
- }
- // Let's go through the episodes now
- if (item.SeasonRequests.Any())
- {
- var allEpisodes = PlexContentRepo.GetAllEpisodes();
- foreach (var season in item.SeasonRequests)
- {
- foreach (var episode in season.Episodes)
- {
- var epExists = await allEpisodes.FirstOrDefaultAsync(x =>
- x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && x.Series.ProviderId == item.Id.ToString());
- if (epExists != null)
- {
- episode.Available = true;
- }
- }
- }
- }
- }
-
- if (item.SeasonRequests.Any() && item.SeasonRequests.All(x => x.Episodes.All(e => e.Approved)))
- {
- item.FullyAvailable = true;
- }
-
- if (item.Id > 0)
- {
- var tvdbid = item.Id;
- if (existingRequests.ContainsKey(tvdbid))
- {
- var existingRequest = existingRequests[tvdbid];
-
- item.Requested = true;
- item.Approved = existingRequest.ChildRequests.Any(x => x.Approved);
-
- // Let's modify the seasonsrequested to reflect what we have requested...
- foreach (var season in item.SeasonRequests)
- {
- foreach (var existingRequestChildRequest in existingRequest.ChildRequests)
- {
- // Find the existing request season
- var existingSeason =
- existingRequestChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber);
- if (existingSeason == null) continue;
-
- foreach (var ep in existingSeason.Episodes)
- {
- // Find the episode from what we are searching
- var episodeSearching = season.Episodes.FirstOrDefault(x => x.EpisodeNumber == ep.EpisodeNumber);
- if (episodeSearching == null)
- {
- continue;
- }
- episodeSearching.Requested = true;
- episodeSearching.Available = ep.Available;
- episodeSearching.Approved = ep.Season.ChildRequest.Approved;
- }
- }
- }
- }
- // TODO CHECK SONARR/RADARR
- //if (sonarrCached.Select(x => x.TvdbId).Contains(tvdbid) || sickRageCache.Contains(tvdbid))
- // // compare to the sonarr/sickrage db
- //{
- // item.Requested = true;
- //}
- }
+ item.CustomId = item.Id.ToString();
+ await RunSearchRules(item);
return item;
}
diff --git a/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs b/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs
index 73732b4b5..42952cd73 100644
--- a/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs
+++ b/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using Ombi.Store.Entities;
namespace Ombi.Core.Models.Search
{
@@ -22,5 +23,8 @@ namespace Ombi.Core.Models.Search
public string Trailer { get; set; }
public string Homepage { get; set; }
public string ImdbId { get; set; }
+ public int RootPathOverride { get; set; }
+ public int QualityOverride { get; set; }
+ public override RequestType Type => RequestType.Movie;
}
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs b/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs
index c7bbac246..90f32eda6 100644
--- a/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs
+++ b/src/Ombi.Core/Models/Search/SearchTvShowViewModel.cs
@@ -1,6 +1,7 @@
using Ombi.Core.Models.Requests;
using Ombi.Store.Repository.Requests;
using System.Collections.Generic;
+using Ombi.Store.Entities;
namespace Ombi.Core.Models.Search
{
@@ -54,5 +55,7 @@ namespace Ombi.Core.Models.Search
/// This is where we have EVERY Episode for that series
///
public bool FullyAvailable { get; set; }
+
+ public override RequestType Type => RequestType.TvShow;
}
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Models/Search/SearchViewModel.cs b/src/Ombi.Core/Models/Search/SearchViewModel.cs
index fec2af075..2771d1be8 100644
--- a/src/Ombi.Core/Models/Search/SearchViewModel.cs
+++ b/src/Ombi.Core/Models/Search/SearchViewModel.cs
@@ -1,8 +1,9 @@
using System.ComponentModel.DataAnnotations.Schema;
+using Ombi.Store.Entities;
namespace Ombi.Core.Models.Search
{
- public class SearchViewModel
+ public abstract class SearchViewModel
{
public int Id { get; set; }
public bool Approved { get; set; }
@@ -10,6 +11,7 @@ namespace Ombi.Core.Models.Search
public bool Available { get; set; }
public string PlexUrl { get; set; }
public string Quality { get; set; }
+ public abstract RequestType Type { get; }
///
diff --git a/src/Ombi.Core/Rule/Interfaces/IRules.cs b/src/Ombi.Core/Rule/Interfaces/IRules.cs
index a46749cd1..020991502 100644
--- a/src/Ombi.Core/Rule/Interfaces/IRules.cs
+++ b/src/Ombi.Core/Rule/Interfaces/IRules.cs
@@ -1,9 +1,8 @@
using System.Threading.Tasks;
-using Ombi.Core.Models.Requests;
namespace Ombi.Core.Rule.Interfaces
{
- public interface IRules where T : new()
+ public interface IRules
{
Task Execute(T obj);
}
diff --git a/src/Ombi.Core/Rule/RuleEvaluator.cs b/src/Ombi.Core/Rule/RuleEvaluator.cs
index 2f3b96b2a..a0c272c00 100644
--- a/src/Ombi.Core/Rule/RuleEvaluator.cs
+++ b/src/Ombi.Core/Rule/RuleEvaluator.cs
@@ -73,7 +73,7 @@ namespace Ombi.Core.Rule
}
- private void GetTypes(IServiceProvider provider, Assembly ass, string baseSearchType, List> ruleList) where T : new()
+ private void GetTypes(IServiceProvider provider, Assembly ass, string baseSearchType, List> ruleList)
{
foreach (var ti in ass.DefinedTypes)
{
diff --git a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs
index 44670e7f8..20ad75b19 100644
--- a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs
@@ -1,6 +1,9 @@
-using System.Threading.Tasks;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
+using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.Rule.Rules.Search
@@ -20,6 +23,28 @@ namespace Ombi.Core.Rule.Rules.Search
if (item != null)
{
obj.Available = true;
+
+ if (obj.Type == RequestType.TvShow)
+ {
+ var searchResult = (SearchTvShowViewModel)obj;
+ // Let's go through the episodes now
+ if (searchResult.SeasonRequests.Any())
+ {
+ var allEpisodes = EmbyContentRepository.GetAllEpisodes().Include(x => x.Series);
+ foreach (var season in searchResult.SeasonRequests)
+ {
+ foreach (var episode in season.Episodes)
+ {
+ var epExists = await allEpisodes.FirstOrDefaultAsync(x =>
+ x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && item.ProviderId.ToString() == x.Series.ProviderId);
+ if (epExists != null)
+ {
+ episode.Available = true;
+ }
+ }
+ }
+ }
+ }
}
return Success();
}
diff --git a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs
index b84f9c652..4a5faad6b 100644
--- a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
+using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Ombi.Store.Repository.Requests;
@@ -21,28 +22,75 @@ namespace Ombi.Core.Rule.Rules.Search
public Task Execute(SearchViewModel obj)
{
- var movieRequests = Movie.GetRequest(obj.Id);
- if (movieRequests != null) // Do we already have a request for this?
+ if (obj.Type == RequestType.Movie)
{
+ var movieRequests = Movie.GetRequest(obj.Id);
+ if (movieRequests != null) // Do we already have a request for this?
+ {
- obj.Requested = true;
- obj.Approved = movieRequests.Approved;
- obj.Available = movieRequests.Available;
+ obj.Requested = true;
+ obj.Approved = movieRequests.Approved;
+ obj.Available = movieRequests.Available;
+ return Task.FromResult(Success());
+ }
return Task.FromResult(Success());
}
-
- var tvRequests = Tv.GetRequest(obj.Id);
- if (tvRequests != null) // Do we already have a request for this?
+ else
{
+ //var tvRequests = Tv.GetRequest(obj.Id);
+ //if (tvRequests != null) // Do we already have a request for this?
+ //{
+
+ // obj.Requested = true;
+ // obj.Approved = tvRequests.ChildRequests.Any(x => x.Approved);
+ // obj.Available = tvRequests.ChildRequests.Any(x => x.Available);
+
+ // return Task.FromResult(Success());
+ //}
+
+ var request = (SearchTvShowViewModel) obj;
+ var tvRequests = Tv.GetRequest(obj.Id);
+ if (tvRequests != null) // Do we already have a request for this?
+ {
+
+ request.Requested = true;
+ request.Approved = tvRequests.ChildRequests.Any(x => x.Approved);
+
+ // Let's modify the seasonsrequested to reflect what we have requested...
+ foreach (var season in request.SeasonRequests)
+ {
+ foreach (var existingRequestChildRequest in tvRequests.ChildRequests)
+ {
+ // Find the existing request season
+ var existingSeason =
+ existingRequestChildRequest.SeasonRequests.FirstOrDefault(x => x.SeasonNumber == season.SeasonNumber);
+ if (existingSeason == null) continue;
+
+ foreach (var ep in existingSeason.Episodes)
+ {
+ // Find the episode from what we are searching
+ var episodeSearching = season.Episodes.FirstOrDefault(x => x.EpisodeNumber == ep.EpisodeNumber);
+ if (episodeSearching == null)
+ {
+ continue;
+ }
+ episodeSearching.Requested = true;
+ episodeSearching.Available = ep.Available;
+ episodeSearching.Approved = ep.Season.ChildRequest.Approved;
+ }
+ }
+ }
+ }
+
+ if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.All(e => e.Approved)))
+ {
+ request.FullyAvailable = true;
+ }
- obj.Requested = true;
- obj.Approved = tvRequests.ChildRequests.Any(x => x.Approved);
- obj.Available = tvRequests.ChildRequests.Any(x => x.Available);
return Task.FromResult(Success());
}
- return Task.FromResult(Success());
}
}
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs
index c293e00be..1b406cc93 100644
--- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs
@@ -1,6 +1,9 @@
-using System.Threading.Tasks;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
+using Ombi.Store.Entities;
using Ombi.Store.Repository;
namespace Ombi.Core.Rule.Rules.Search
@@ -22,6 +25,29 @@ namespace Ombi.Core.Rule.Rules.Search
obj.Available = true;
obj.PlexUrl = item.Url;
obj.Quality = item.Quality;
+
+ if (obj.Type == RequestType.TvShow)
+ {
+ var search = (SearchTvShowViewModel)obj;
+ // Let's go through the episodes now
+ if (search.SeasonRequests.Any())
+ {
+ var allEpisodes = PlexContentRepository.GetAllEpisodes();
+ foreach (var season in search.SeasonRequests)
+ {
+ foreach (var episode in season.Episodes)
+ {
+ var epExists = await allEpisodes.FirstOrDefaultAsync(x =>
+ x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber &&
+ x.Series.ProviderId == item.ProviderId.ToString());
+ if (epExists != null)
+ {
+ episode.Available = true;
+ }
+ }
+ }
+ }
+ }
}
return Success();
}
diff --git a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs
index b2187e206..1c936012a 100644
--- a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs
+++ b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs
@@ -4,6 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Ombi.Core.Models.Search;
using Ombi.Core.Rule.Interfaces;
using Ombi.Store.Context;
+using Ombi.Store.Entities;
namespace Ombi.Core.Rule.Rules.Search
{
@@ -18,13 +19,16 @@ namespace Ombi.Core.Rule.Rules.Search
public async Task Execute(SearchViewModel obj)
{
- // Check if it's in Radarr
- var result = await _ctx.RadarrCache.FirstOrDefaultAsync(x => x.TheMovieDbId == obj.Id);
- if (result != null)
+ if (obj.Type == RequestType.Movie)
{
- obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something?
+ // Check if it's in Radarr
+ 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 Success();
}
}
diff --git a/src/Ombi.Core/Rule/Rules/Search/SonarrCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/SonarrCacheRule.cs
new file mode 100644
index 000000000..d444222cf
--- /dev/null
+++ b/src/Ombi.Core/Rule/Rules/Search/SonarrCacheRule.cs
@@ -0,0 +1,34 @@
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Ombi.Core.Models.Search;
+using Ombi.Core.Rule.Interfaces;
+using Ombi.Store.Context;
+using Ombi.Store.Entities;
+
+namespace Ombi.Core.Rule.Rules.Search
+{
+ public class SonarrCacheRule : BaseSearchRule, IRules
+ {
+ public SonarrCacheRule(IOmbiContext ctx)
+ {
+ _ctx = ctx;
+ }
+
+ private readonly IOmbiContext _ctx;
+
+ public async Task Execute(SearchViewModel obj)
+ {
+ if (obj.Type == RequestType.TvShow)
+ {
+ // Check if it's in Radarr
+ var result = await _ctx.SonarrCache.FirstOrDefaultAsync(x => x.TvDbId == 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 Success();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Ombi.Core/Senders/IMovieSender.cs b/src/Ombi.Core/Senders/IMovieSender.cs
index 4ed06b429..28e29cab0 100644
--- a/src/Ombi.Core/Senders/IMovieSender.cs
+++ b/src/Ombi.Core/Senders/IMovieSender.cs
@@ -5,6 +5,6 @@ namespace Ombi.Core
{
public interface IMovieSender
{
- Task Send(MovieRequests model, string qualityId = "");
+ Task Send(MovieRequests model);
}
}
\ No newline at end of file
diff --git a/src/Ombi.Core/Senders/MovieSender.cs b/src/Ombi.Core/Senders/MovieSender.cs
index 051081df2..25795b5ee 100644
--- a/src/Ombi.Core/Senders/MovieSender.cs
+++ b/src/Ombi.Core/Senders/MovieSender.cs
@@ -1,4 +1,5 @@
-using Ombi.Core.Settings;
+using System.Linq;
+using Ombi.Core.Settings;
using Ombi.Settings.Settings.Models.External;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@@ -21,7 +22,7 @@ namespace Ombi.Core
private IRadarrApi RadarrApi { get; }
private ILogger Log { get; }
- public async Task Send(MovieRequests model, string qualityId = "")
+ public async Task Send(MovieRequests model)
{
//var cpSettings = await CouchPotatoSettings.GetSettingsAsync();
//var watcherSettings = await WatcherSettings.GetSettingsAsync();
@@ -39,7 +40,7 @@ namespace Ombi.Core
if (radarrSettings.Enabled)
{
- return await SendToRadarr(model, radarrSettings, qualityId);
+ return await SendToRadarr(model, radarrSettings);
}
return new MovieSenderResult
@@ -49,22 +50,16 @@ namespace Ombi.Core
};
}
- private async Task SendToRadarr(MovieRequests model, RadarrSettings settings, string qualityId)
+ private async Task SendToRadarr(MovieRequests model, RadarrSettings settings)
{
- var qualityProfile = 0;
- if (!string.IsNullOrEmpty(qualityId)) // try to parse the passed in quality, otherwise use the settings default quality
+ var qualityToUse = int.Parse(settings.DefaultQualityProfile);
+ if (model.QualityOverride <= 0)
{
- int.TryParse(qualityId, out qualityProfile);
+ qualityToUse = model.QualityOverride;
}
- if (qualityProfile <= 0)
- {
- int.TryParse(settings.DefaultQualityProfile, out qualityProfile);
- }
-
- //var rootFolderPath = model.RootFolderSelected <= 0 ? settings.FullRootPath : GetRootPath(model.RootFolderSelected, settings);
- var rootFolderPath = settings.DefaultRootPath; // TODO Allow changing in the UI
- var result = await RadarrApi.AddMovie(model.TheMovieDbId, model.Title, model.ReleaseDate.Year, qualityProfile, rootFolderPath, settings.ApiKey, settings.FullUri, !settings.AddOnly, settings.MinimumAvailability);
+ var rootFolderPath = model.RootPathOverride <= 0 ? settings.DefaultRootPath : await RadarrRootPath(model.RootPathOverride, settings);
+ var result = await RadarrApi.AddMovie(model.TheMovieDbId, model.Title, model.ReleaseDate.Year, qualityToUse, rootFolderPath, settings.ApiKey, settings.FullUri, !settings.AddOnly, settings.MinimumAvailability);
if (!string.IsNullOrEmpty(result.Error?.message))
{
@@ -77,5 +72,12 @@ namespace Ombi.Core
}
return new MovieSenderResult { Success = true, MovieSent = false };
}
+
+ private async Task RadarrRootPath(int overrideId, RadarrSettings settings)
+ {
+ var paths = await RadarrApi.GetRootFolders(settings.ApiKey, settings.FullUri);
+ var selectedPath = paths.FirstOrDefault(x => x.id == overrideId);
+ return selectedPath.path;
+ }
}
}
\ No newline at end of file
diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs
index 1be7d1dc5..1e0ba1d80 100644
--- a/src/Ombi.DependencyInjection/IocExtensions.cs
+++ b/src/Ombi.DependencyInjection/IocExtensions.cs
@@ -42,6 +42,7 @@ using Ombi.Core.Senders;
using Ombi.Schedule.Jobs.Emby;
using Ombi.Schedule.Jobs.Ombi;
using Ombi.Schedule.Jobs.Plex;
+using Ombi.Schedule.Jobs.Sonarr;
using Ombi.Schedule.Ombi;
using Ombi.Store.Repository.Requests;
using PlexContentCacher = Ombi.Schedule.Jobs.Plex.PlexContentCacher;
@@ -142,6 +143,7 @@ namespace Ombi.DependencyInjection
services.AddTransient();
services.AddTransient();
services.AddTransient();
+ services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
diff --git a/src/Ombi.Helpers/CacheKeys.cs b/src/Ombi.Helpers/CacheKeys.cs
index f1c64fa38..db66d4e13 100644
--- a/src/Ombi.Helpers/CacheKeys.cs
+++ b/src/Ombi.Helpers/CacheKeys.cs
@@ -16,5 +16,7 @@ namespace Ombi.Helpers
public const string TopRatedMovies = nameof(TopRatedMovies);
public const string UpcomingMovies = nameof(UpcomingMovies);
public const string NowPlayingMovies = nameof(NowPlayingMovies);
+ public const string RadarrRootProfiles = nameof(RadarrRootProfiles);
+ public const string RadarrQualityProfiles = nameof(RadarrQualityProfiles);
}
}
diff --git a/src/Ombi.Helpers/LoggingEvents.cs b/src/Ombi.Helpers/LoggingEvents.cs
index e4a349049..5d6b17aa5 100644
--- a/src/Ombi.Helpers/LoggingEvents.cs
+++ b/src/Ombi.Helpers/LoggingEvents.cs
@@ -11,10 +11,11 @@ namespace Ombi.Helpers
public static EventId Cacher => new EventId(2000);
public static EventId RadarrCacher => new EventId(2001);
- public static EventId PlexEpisodeCacher => new EventId(2001);
- public static EventId EmbyContentCacher => new EventId(2002);
- public static EventId PlexUserImporter => new EventId(2003);
- public static EventId EmbyUserImporter => new EventId(2004);
+ public static EventId PlexEpisodeCacher => new EventId(2002);
+ public static EventId EmbyContentCacher => new EventId(2003);
+ public static EventId PlexUserImporter => new EventId(2004);
+ public static EventId EmbyUserImporter => new EventId(2005);
+ public static EventId SonarrCacher => new EventId(2006);
public static EventId MovieSender => new EventId(3000);
diff --git a/src/Ombi.Schedule/JobSetup.cs b/src/Ombi.Schedule/JobSetup.cs
index 6b13a10bb..c0fb6d5f8 100644
--- a/src/Ombi.Schedule/JobSetup.cs
+++ b/src/Ombi.Schedule/JobSetup.cs
@@ -3,6 +3,7 @@ using Ombi.Schedule.Jobs;
using Ombi.Schedule.Jobs.Emby;
using Ombi.Schedule.Jobs.Plex;
using Ombi.Schedule.Jobs.Radarr;
+using Ombi.Schedule.Jobs.Sonarr;
using Ombi.Schedule.Ombi;
namespace Ombi.Schedule
@@ -11,7 +12,7 @@ namespace Ombi.Schedule
{
public JobSetup(IPlexContentCacher plexContentCacher, IRadarrCacher radarrCacher,
IOmbiAutomaticUpdater updater, IEmbyContentCacher embyCacher, IPlexUserImporter userImporter,
- IEmbyUserImporter embyUserImporter)
+ IEmbyUserImporter embyUserImporter, ISonarrCacher cache)
{
PlexContentCacher = plexContentCacher;
RadarrCacher = radarrCacher;
@@ -19,6 +20,7 @@ namespace Ombi.Schedule
EmbyContentCacher = embyCacher;
PlexUserImporter = userImporter;
EmbyUserImporter = embyUserImporter;
+ SonarrCacher = cache;
}
private IPlexContentCacher PlexContentCacher { get; }
@@ -27,17 +29,17 @@ namespace Ombi.Schedule
private IPlexUserImporter PlexUserImporter { get; }
private IEmbyContentCacher EmbyContentCacher { get; }
private IEmbyUserImporter EmbyUserImporter { get; }
+ private ISonarrCacher SonarrCacher { get; }
public void Setup()
{
RecurringJob.AddOrUpdate(() => PlexContentCacher.CacheContent(), Cron.Hourly(20));
RecurringJob.AddOrUpdate(() => EmbyContentCacher.Start(), Cron.Hourly(5));
RecurringJob.AddOrUpdate(() => RadarrCacher.CacheContent(), Cron.Hourly(10));
- RecurringJob.AddOrUpdate(() => PlexUserImporter.Start(), Cron.Daily(1));
+ RecurringJob.AddOrUpdate(() => RadarrCacher.CacheContent(), Cron.Hourly(15));
+ RecurringJob.AddOrUpdate(() => PlexUserImporter.Start(), Cron.Daily(5));
RecurringJob.AddOrUpdate(() => EmbyUserImporter.Start(), Cron.Daily);
- RecurringJob.AddOrUpdate(() => Updater.Update(null), Cron.Daily(3));
-
- //BackgroundJob.Enqueue(() => PlexUserImporter.Start());
+ RecurringJob.AddOrUpdate(() => Updater.Update(null), Cron.HourInterval(6));
}
}
}
diff --git a/src/Ombi.Schedule/Jobs/Radarr/RadarrCacher.cs b/src/Ombi.Schedule/Jobs/Radarr/RadarrCacher.cs
index fb42be325..9667af648 100644
--- a/src/Ombi.Schedule/Jobs/Radarr/RadarrCacher.cs
+++ b/src/Ombi.Schedule/Jobs/Radarr/RadarrCacher.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
@@ -28,8 +29,11 @@ namespace Ombi.Schedule.Jobs.Radarr
private ILogger Logger { get; }
private readonly IOmbiContext _ctx;
+ private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1);
+
public async Task CacheContent()
{
+ await SemaphoreSlim.WaitAsync();
try
{
var settings = RadarrSettings.GetSettings();
@@ -48,7 +52,7 @@ namespace Ombi.Schedule.Jobs.Radarr
{
if (m.tmdbId > 0)
{
- movieIds.Add(new RadarrCache { TheMovieDbId = m.tmdbId });
+ movieIds.Add(new RadarrCache {TheMovieDbId = m.tmdbId});
}
else
{
@@ -70,6 +74,10 @@ namespace Ombi.Schedule.Jobs.Radarr
{
Logger.LogInformation(LoggingEvents.RadarrCacher, "Radarr is not setup, cannot cache episodes");
}
+ finally
+ {
+ SemaphoreSlim.Release();
+ }
}
public async Task> GetCachedContent()
diff --git a/src/Ombi.Schedule/Jobs/Sonarr/ISonarrCacher.cs b/src/Ombi.Schedule/Jobs/Sonarr/ISonarrCacher.cs
new file mode 100644
index 000000000..e3b968784
--- /dev/null
+++ b/src/Ombi.Schedule/Jobs/Sonarr/ISonarrCacher.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace Ombi.Schedule.Jobs.Sonarr
+{
+ public interface ISonarrCacher
+ {
+ Task Start();
+ }
+}
\ No newline at end of file
diff --git a/src/Ombi.Schedule/Jobs/Sonarr/SonarrCacher.cs b/src/Ombi.Schedule/Jobs/Sonarr/SonarrCacher.cs
new file mode 100644
index 000000000..591f02747
--- /dev/null
+++ b/src/Ombi.Schedule/Jobs/Sonarr/SonarrCacher.cs
@@ -0,0 +1,116 @@
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
+using Ombi.Api.Sonarr;
+using Ombi.Core.Settings;
+using Ombi.Core.Settings.Models.External;
+using Ombi.Helpers;
+using Ombi.Store.Context;
+using Ombi.Store.Entities;
+
+namespace Ombi.Schedule.Jobs.Sonarr
+{
+ public class SonarrCacher : ISonarrCacher
+ {
+ public SonarrCacher(ISettingsService s, ISonarrApi api, ILogger l, IOmbiContext ctx)
+ {
+ _settings = s;
+ _api = api;
+ _log = l;
+ }
+
+ private readonly ISettingsService _settings;
+ private readonly ISonarrApi _api;
+ private readonly ILogger _log;
+ private readonly IOmbiContext _ctx;
+
+ private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1);
+ public async Task Start()
+ {
+ await SemaphoreSlim.WaitAsync();
+ try
+ {
+ var settings = await _settings.GetSettingsAsync();
+ if (!settings.Enabled)
+ {
+ return;
+ }
+ var series = await _api.GetSeries(settings.ApiKey, settings.FullUri);
+ if (series != null)
+ {
+ var ids = series.Select(x => x.tvdbId);
+
+ await _ctx.Database.ExecuteSqlCommandAsync("DELETE FROM SonarrCache");
+ var entites = ids.Select(id => new SonarrCache {TvDbId = id}).ToList();
+
+ await _ctx.SonarrCache.AddRangeAsync(entites);
+ await _ctx.SaveChangesAsync();
+ }
+ }
+ catch (Exception e)
+ {
+ _log.LogError(LoggingEvents.SonarrCacher, e, "Exception when trying to cache Sonarr");
+ }
+ finally
+ {
+ SemaphoreSlim.Release();
+ }
+ }
+
+
+ //public void Queued()
+ //{
+ // var settings = SonarrSettings.GetSettings();
+ // if (settings.Enabled)
+ // {
+ // Job.SetRunning(true, JobNames.SonarrCacher);
+ // try
+ // {
+ // var series = SonarrApi.GetSeries(settings.ApiKey, settings.FullUri);
+ // if (series != null)
+ // {
+ // Cache.Set(CacheKeys.SonarrQueued, series, CacheKeys.TimeFrameMinutes.SchedulerCaching);
+ // }
+ // }
+ // catch (System.Exception ex)
+ // {
+ // Log.Error(ex, "Failed caching queued items from Sonarr");
+ // }
+ // finally
+ // {
+ // Job.Record(JobNames.SonarrCacher);
+ // Job.SetRunning(false, JobNames.SonarrCacher);
+ // }
+ // }
+ //}
+
+ //// we do not want to set here...
+ //public IEnumerable QueuedIds()
+ //{
+ // var result = new List();
+
+ // var series = Cache.Get>(CacheKeys.SonarrQueued);
+ // if (series != null)
+ // {
+ // foreach (var s in series)
+ // {
+ // var cached = new SonarrCachedResult { TvdbId = s.tvdbId };
+ // foreach (var season in s.seasons)
+ // {
+ // cached.Seasons.Add(new SonarrSeasons
+ // {
+ // SeasonNumber = season.seasonNumber,
+ // Monitored = season.monitored
+ // });
+ // }
+
+ // result.Add(cached);
+ // }
+ // }
+ // return result;
+ //}
+ }
+}
\ No newline at end of file
diff --git a/src/Ombi.Schedule/Ombi.Schedule.csproj b/src/Ombi.Schedule/Ombi.Schedule.csproj
index 328194252..04106e767 100644
--- a/src/Ombi.Schedule/Ombi.Schedule.csproj
+++ b/src/Ombi.Schedule/Ombi.Schedule.csproj
@@ -23,6 +23,7 @@
+
diff --git a/src/Ombi.Store/Context/IOmbiContext.cs b/src/Ombi.Store/Context/IOmbiContext.cs
index f4a7910e1..63612ea8c 100644
--- a/src/Ombi.Store/Context/IOmbiContext.cs
+++ b/src/Ombi.Store/Context/IOmbiContext.cs
@@ -33,6 +33,7 @@ namespace Ombi.Store.Context
DbSet MovieIssues { get; set; }
DbSet TvIssues { get; set; }
DbSet Tokens { get; set; }
+ DbSet SonarrCache { get; set; }
EntityEntry Update(object entity);
EntityEntry Update(TEntity entity) where TEntity : class;
}
diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs
index 257e6a3c8..ebbab4b21 100644
--- a/src/Ombi.Store/Context/OmbiContext.cs
+++ b/src/Ombi.Store/Context/OmbiContext.cs
@@ -38,6 +38,7 @@ namespace Ombi.Store.Context
public DbSet Audit { get; set; }
public DbSet Tokens { get; set; }
+ public DbSet SonarrCache { get; set; }
public DbSet ApplicationConfigurations { get; set; }
diff --git a/src/Ombi.Store/Entities/Requests/MovieRequests.cs b/src/Ombi.Store/Entities/Requests/MovieRequests.cs
index 11b12c7f6..680a1c8bb 100644
--- a/src/Ombi.Store/Entities/Requests/MovieRequests.cs
+++ b/src/Ombi.Store/Entities/Requests/MovieRequests.cs
@@ -11,5 +11,8 @@ namespace Ombi.Store.Entities.Requests
public int? IssueId { get; set; }
[ForeignKey(nameof(IssueId))]
public List Issues { get; set; }
+
+ public int RootPathOverride { get; set; }
+ public int QualityOverride { get; set; }
}
}
diff --git a/src/Ombi.Store/Entities/SonarrCache.cs b/src/Ombi.Store/Entities/SonarrCache.cs
new file mode 100644
index 000000000..33e06f7d9
--- /dev/null
+++ b/src/Ombi.Store/Entities/SonarrCache.cs
@@ -0,0 +1,10 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Ombi.Store.Entities
+{
+ [Table("SonarrCache")]
+ public class SonarrCache : Entity
+ {
+ public int TvDbId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Ombi.Store/Migrations/20171002113357_SonarrCacher.Designer.cs b/src/Ombi.Store/Migrations/20171002113357_SonarrCacher.Designer.cs
new file mode 100644
index 000000000..9ea6c0745
--- /dev/null
+++ b/src/Ombi.Store/Migrations/20171002113357_SonarrCacher.Designer.cs
@@ -0,0 +1,747 @@
+//
+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 System;
+
+namespace Ombi.Store.Migrations
+{
+ [DbContext(typeof(OmbiContext))]
+ [Migration("20171002113357_SonarrCacher")]
+ partial class SonarrCacher
+ {
+ 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("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Name")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedName")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasName("RoleNameIndex");
+
+ b.ToTable("AspNetRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("RoleId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetRoleClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ClaimType");
+
+ b.Property("ClaimValue");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserClaims");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider");
+
+ b.Property("ProviderKey");
+
+ b.Property("ProviderDisplayName");
+
+ b.Property("UserId")
+ .IsRequired();
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AspNetUserLogins");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("RoleId");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("AspNetUserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId");
+
+ b.Property("LoginProvider");
+
+ b.Property("Name");
+
+ b.Property("Value");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("AspNetUserTokens");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Type");
+
+ b.Property("Value");
+
+ b.HasKey("Id");
+
+ b.ToTable("ApplicationConfiguration");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Audit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AuditArea");
+
+ b.Property("AuditType");
+
+ b.Property("DateTime");
+
+ b.Property("Description");
+
+ b.Property("User");
+
+ b.HasKey("Id");
+
+ b.ToTable("Audit");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AddedAt");
+
+ b.Property("EmbyId")
+ .IsRequired();
+
+ b.Property("ProviderId");
+
+ b.Property("Title");
+
+ b.Property("Type");
+
+ b.HasKey("Id");
+
+ b.ToTable("EmbyContent");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AddedAt");
+
+ b.Property("EmbyId");
+
+ b.Property("EpisodeNumber");
+
+ b.Property("ParentId");
+
+ b.Property("ProviderId");
+
+ b.Property("SeasonNumber");
+
+ b.Property("Title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ParentId");
+
+ b.ToTable("EmbyEpisode");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.GlobalSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Content");
+
+ b.Property("SettingsName");
+
+ b.HasKey("Id");
+
+ b.ToTable("GlobalSettings");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Agent");
+
+ b.Property("Enabled");
+
+ b.Property("Message");
+
+ b.Property("NotificationType");
+
+ b.Property("Subject");
+
+ b.HasKey("Id");
+
+ b.ToTable("NotificationTemplates");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AccessFailedCount");
+
+ b.Property("Alias");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken();
+
+ b.Property("Email")
+ .HasMaxLength(256);
+
+ b.Property("EmailConfirmed");
+
+ b.Property("LastLoggedIn");
+
+ b.Property("LockoutEnabled");
+
+ b.Property("LockoutEnd");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedUserName")
+ .HasMaxLength(256);
+
+ b.Property("PasswordHash");
+
+ b.Property("PhoneNumber");
+
+ b.Property("PhoneNumberConfirmed");
+
+ b.Property("ProviderUserId");
+
+ b.Property("SecurityStamp");
+
+ b.Property("TwoFactorEnabled");
+
+ b.Property("UserName")
+ .HasMaxLength(256);
+
+ b.Property("UserType");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedEmail")
+ .HasName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasName("UserNameIndex");
+
+ b.ToTable("AspNetUsers");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.PlexContent", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AddedAt");
+
+ b.Property("Key");
+
+ b.Property("ProviderId");
+
+ b.Property("Quality");
+
+ b.Property("ReleaseYear");
+
+ b.Property("Title");
+
+ b.Property("Type");
+
+ b.Property("Url");
+
+ b.HasKey("Id");
+
+ b.ToTable("PlexContent");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("EpisodeNumber");
+
+ b.Property("GrandparentKey");
+
+ b.Property("Key");
+
+ b.Property("ParentKey");
+
+ b.Property("SeasonNumber");
+
+ b.Property("Title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GrandparentKey");
+
+ b.ToTable("PlexEpisode");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ParentKey");
+
+ b.Property("PlexContentId");
+
+ b.Property("SeasonKey");
+
+ b.Property("SeasonNumber");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PlexContentId");
+
+ b.ToTable("PlexSeasonsContent");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("TheMovieDbId");
+
+ b.HasKey("Id");
+
+ b.ToTable("RadarrCache");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Approved");
+
+ b.Property("Available");
+
+ b.Property("Denied");
+
+ b.Property("DeniedReason");
+
+ b.Property("IssueId");
+
+ b.Property("ParentRequestId");
+
+ b.Property("RequestType");
+
+ b.Property("RequestedDate");
+
+ b.Property("RequestedUserId");
+
+ b.Property("Title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ParentRequestId");
+
+ b.HasIndex("RequestedUserId");
+
+ b.ToTable("ChildRequests");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieIssues", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Description");
+
+ b.Property("IssueId");
+
+ b.Property("MovieId");
+
+ b.Property("Subect");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IssueId");
+
+ b.HasIndex("MovieId");
+
+ b.ToTable("MovieIssues");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Approved");
+
+ b.Property("Available");
+
+ b.Property("Denied");
+
+ b.Property("DeniedReason");
+
+ b.Property("ImdbId");
+
+ b.Property("IssueId");
+
+ b.Property("Overview");
+
+ b.Property("PosterPath");
+
+ b.Property("QualityOverride");
+
+ b.Property("ReleaseDate");
+
+ b.Property("RequestType");
+
+ b.Property("RequestedDate");
+
+ b.Property("RequestedUserId");
+
+ b.Property("RootPathOverride");
+
+ b.Property("Status");
+
+ b.Property("TheMovieDbId");
+
+ b.Property("Title");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RequestedUserId");
+
+ b.ToTable("MovieRequests");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Requests.TvIssues", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Description");
+
+ b.Property("IssueId");
+
+ b.Property("Subect");
+
+ b.Property("TvId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IssueId");
+
+ b.HasIndex("TvId");
+
+ b.ToTable("TvIssues");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ImdbId");
+
+ b.Property("Overview");
+
+ b.Property("PosterPath");
+
+ b.Property("ReleaseDate");
+
+ b.Property("RootFolder");
+
+ b.Property("Status");
+
+ b.Property("Title");
+
+ b.Property("TvDbId");
+
+ b.HasKey("Id");
+
+ b.ToTable("TvRequests");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("TvDbId");
+
+ b.HasKey("Id");
+
+ b.ToTable("SonarrCache");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("Token");
+
+ b.Property("UserId");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Tokens");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("AirDate");
+
+ b.Property("Approved");
+
+ b.Property("Available");
+
+ b.Property("EpisodeNumber");
+
+ b.Property("Requested");
+
+ b.Property("SeasonId");
+
+ b.Property("Title");
+
+ b.Property("Url");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SeasonId");
+
+ b.ToTable("EpisodeRequests");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("ChildRequestId");
+
+ b.Property("SeasonNumber");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChildRequestId");
+
+ b.ToTable("SeasonRequests");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("Ombi.Store.Entities.OmbiUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("Ombi.Store.Entities.OmbiUser")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", 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", 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.PlexEpisode", b =>
+ {
+ b.HasOne("Ombi.Store.Entities.PlexContent", "Series")
+ .WithMany("Episodes")
+ .HasForeignKey("GrandparentKey")
+ .HasPrincipalKey("Key")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
+ {
+ b.HasOne("Ombi.Store.Entities.PlexContent")
+ .WithMany("Seasons")
+ .HasForeignKey("PlexContentId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ 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.MovieIssues", b =>
+ {
+ b.HasOne("Ombi.Store.Entities.Requests.MovieRequests")
+ .WithMany("Issues")
+ .HasForeignKey("IssueId");
+
+ b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", "Movie")
+ .WithMany()
+ .HasForeignKey("MovieId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b =>
+ {
+ b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser")
+ .WithMany()
+ .HasForeignKey("RequestedUserId");
+ });
+
+ modelBuilder.Entity("Ombi.Store.Entities.Requests.TvIssues", b =>
+ {
+ b.HasOne("Ombi.Store.Entities.Requests.ChildRequests")
+ .WithMany("Issues")
+ .HasForeignKey("IssueId");
+
+ b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "Child")
+ .WithMany()
+ .HasForeignKey("TvId")
+ .OnDelete(DeleteBehavior.Cascade);
+ });
+
+ 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
+ }
+ }
+}
diff --git a/src/Ombi.Store/Migrations/20171002113357_SonarrCacher.cs b/src/Ombi.Store/Migrations/20171002113357_SonarrCacher.cs
new file mode 100644
index 000000000..36bdbca20
--- /dev/null
+++ b/src/Ombi.Store/Migrations/20171002113357_SonarrCacher.cs
@@ -0,0 +1,53 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+using System;
+using System.Collections.Generic;
+
+namespace Ombi.Store.Migrations
+{
+ public partial class SonarrCacher : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "QualityOverride",
+ table: "MovieRequests",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.AddColumn(
+ name: "RootPathOverride",
+ table: "MovieRequests",
+ type: "INTEGER",
+ nullable: false,
+ defaultValue: 0);
+
+ migrationBuilder.CreateTable(
+ name: "SonarrCache",
+ columns: table => new
+ {
+ Id = table.Column(type: "INTEGER", nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ TvDbId = table.Column(type: "INTEGER", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_SonarrCache", x => x.Id);
+ });
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "SonarrCache");
+
+ migrationBuilder.DropColumn(
+ name: "QualityOverride",
+ table: "MovieRequests");
+
+ migrationBuilder.DropColumn(
+ name: "RootPathOverride",
+ table: "MovieRequests");
+ }
+ }
+}
diff --git a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs
index 1a46eb954..e744a7fd6 100644
--- a/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs
+++ b/src/Ombi.Store/Migrations/OmbiContextModelSnapshot.cs
@@ -460,6 +460,8 @@ namespace Ombi.Store.Migrations
b.Property("PosterPath");
+ b.Property("QualityOverride");
+
b.Property("ReleaseDate");
b.Property("RequestType");
@@ -468,6 +470,8 @@ namespace Ombi.Store.Migrations
b.Property("RequestedUserId");
+ b.Property("RootPathOverride");
+
b.Property("Status");
b.Property("TheMovieDbId");
@@ -529,6 +533,18 @@ namespace Ombi.Store.Migrations
b.ToTable("TvRequests");
});
+ modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd();
+
+ b.Property("TvDbId");
+
+ b.HasKey("Id");
+
+ b.ToTable("SonarrCache");
+ });
+
modelBuilder.Entity("Ombi.Store.Entities.Tokens", b =>
{
b.Property("Id")
diff --git a/src/Ombi.TheMovieDbApi/Models/MovieResponse.cs b/src/Ombi.TheMovieDbApi/Models/MovieResponse.cs
index f619f647a..17aceca5d 100644
--- a/src/Ombi.TheMovieDbApi/Models/MovieResponse.cs
+++ b/src/Ombi.TheMovieDbApi/Models/MovieResponse.cs
@@ -45,8 +45,8 @@ namespace Ombi.TheMovieDbApi.Models
public ProductionCompanies[] production_companies { get; set; }
public ProductionCountries[] production_countries { get; set; }
public string release_date { get; set; }
- public int revenue { get; set; }
- public int runtime { get; set; }
+ public float revenue { get; set; }
+ public float runtime { get; set; }
public SpokenLanguages[] spoken_languages { get; set; }
public string status { get; set; }
public string tagline { get; set; }
diff --git a/src/Ombi.TheMovieDbApi/Models/MovieResponseDTO.cs b/src/Ombi.TheMovieDbApi/Models/MovieResponseDTO.cs
index b679ba5cf..0fd27a23f 100644
--- a/src/Ombi.TheMovieDbApi/Models/MovieResponseDTO.cs
+++ b/src/Ombi.TheMovieDbApi/Models/MovieResponseDTO.cs
@@ -15,8 +15,8 @@
public float Popularity { get; set; }
public string PosterPath { get; set; }
public string ReleaseDate { get; set; }
- public int Revenue { get; set; }
- public int Runtime { get; set; }
+ public float Revenue { get; set; }
+ public float Runtime { get; set; }
public string Status { get; set; }
public string Tagline { get; set; }
public string Title { get; set; }
diff --git a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts
index 70aeed4b9..e67c63ed0 100644
--- a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts
+++ b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts
@@ -79,6 +79,8 @@ export interface IRequestGrid {
export interface IMovieRequests extends IFullBaseRequest {
theMovieDbId: number;
+ rootPathOverride: number;
+ qualityOverride: number;
}
export interface IFullBaseRequest extends IBaseRequest {
diff --git a/src/Ombi/ClientApp/app/landingpage/landingpage.component.html b/src/Ombi/ClientApp/app/landingpage/landingpage.component.html
index 2678f4bb9..4372394c3 100644
--- a/src/Ombi/ClientApp/app/landingpage/landingpage.component.html
+++ b/src/Ombi/ClientApp/app/landingpage/landingpage.component.html
@@ -41,7 +41,7 @@
-
+
diff --git a/src/Ombi/ClientApp/app/login/resetpassword.component.html b/src/Ombi/ClientApp/app/login/resetpassword.component.html
index cd109ddff..c990da5dc 100644
--- a/src/Ombi/ClientApp/app/login/resetpassword.component.html
+++ b/src/Ombi/ClientApp/app/login/resetpassword.component.html
@@ -7,7 +7,7 @@ include the remember me checkbox