From 9ce0b9e70e2c8ac5ee18fd8b485847af6bbe05e7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 2 Oct 2018 21:34:16 +0100 Subject: [PATCH 01/58] Converted the Plex Jobs to use Quartz --- src/Ombi.DependencyInjection/IocExtensions.cs | 4 +- src/Ombi.Schedule/IocJobFactory.cs | 26 +++++++ src/Ombi.Schedule/JobSetup.cs | 5 +- .../Jobs/Plex/Interfaces/IPlexContentSync.cs | 4 +- .../Jobs/Plex/PlexContentSync.cs | 6 +- .../Jobs/Plex/PlexRecentlyAddedSync.cs | 68 +++++++++--------- src/Ombi.Schedule/Ombi.Schedule.csproj | 1 + src/Ombi.Schedule/OmbiQuartz.cs | 70 +++++++++++++++++++ src/Ombi.Schedule/OmbiScheduler.cs | 49 +++++++++++++ src/Ombi/Controllers/JobController.cs | 7 +- src/Ombi/Startup.cs | 2 + 11 files changed, 199 insertions(+), 43 deletions(-) create mode 100644 src/Ombi.Schedule/IocJobFactory.cs create mode 100644 src/Ombi.Schedule/OmbiQuartz.cs create mode 100644 src/Ombi.Schedule/OmbiScheduler.cs diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 3af06b476..c42621281 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -59,6 +59,7 @@ using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Schedule.Jobs.SickRage; using Ombi.Schedule.Processor; using Ombi.Store.Entities; +using Quartz.Spi; namespace Ombi.DependencyInjection { @@ -167,6 +168,7 @@ namespace Ombi.DependencyInjection public static void RegisterJobs(this IServiceCollection services) { + services.AddTransient(provider => new IoCJobFactory(provider)); services.AddTransient(); services.AddTransient(); @@ -187,7 +189,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + //services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.Schedule/IocJobFactory.cs b/src/Ombi.Schedule/IocJobFactory.cs new file mode 100644 index 000000000..d9a300eee --- /dev/null +++ b/src/Ombi.Schedule/IocJobFactory.cs @@ -0,0 +1,26 @@ +using System; +using Quartz; +using Quartz.Spi; + +namespace Ombi.Schedule +{ + public class IoCJobFactory : IJobFactory + { + private readonly IServiceProvider _factory; + + public IoCJobFactory(IServiceProvider factory) + { + _factory = factory; + } + public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) + { + return _factory.GetService(bundle.JobDetail.JobType) as IJob; + } + + public void ReturnJob(IJob job) + { + var disposable = job as IDisposable; + disposable?.Dispose(); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Schedule/JobSetup.cs b/src/Ombi.Schedule/JobSetup.cs index 7ce32de04..502d7b726 100644 --- a/src/Ombi.Schedule/JobSetup.cs +++ b/src/Ombi.Schedule/JobSetup.cs @@ -63,8 +63,8 @@ namespace Ombi.Schedule RecurringJob.AddOrUpdate(() => _embyContentSync.Start(), JobSettingsHelper.EmbyContent(s)); RecurringJob.AddOrUpdate(() => _sonarrSync.Start(), JobSettingsHelper.Sonarr(s)); RecurringJob.AddOrUpdate(() => _radarrSync.CacheContent(), JobSettingsHelper.Radarr(s)); - RecurringJob.AddOrUpdate(() => _plexContentSync.CacheContent(false), JobSettingsHelper.PlexContent(s)); - RecurringJob.AddOrUpdate(() => _plexRecentlyAddedSync.Start(), JobSettingsHelper.PlexRecentlyAdded(s)); + //RecurringJob.AddOrUpdate(() => _plexContentSync.Execute(null), JobSettingsHelper.PlexContent(s)); + //RecurringJob.AddOrUpdate(() => _plexRecentlyAddedSync.Start(), JobSettingsHelper.PlexRecentlyAdded(s)); RecurringJob.AddOrUpdate(() => _cpCache.Start(), JobSettingsHelper.CouchPotato(s)); RecurringJob.AddOrUpdate(() => _srSync.Start(), JobSettingsHelper.SickRageSync(s)); RecurringJob.AddOrUpdate(() => _refreshMetadata.Start(), JobSettingsHelper.RefreshMetadata(s)); @@ -87,7 +87,6 @@ namespace Ombi.Schedule if (disposing) { - _plexContentSync?.Dispose(); _radarrSync?.Dispose(); _updater?.Dispose(); _plexUserImporter?.Dispose(); diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs index 17a8bbb4f..9d2752d85 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexContentSync.cs @@ -1,9 +1,9 @@ using System.Threading.Tasks; +using Quartz; namespace Ombi.Schedule.Jobs { - public interface IPlexContentSync : IBaseJob + public interface IPlexContentSync : IJob { - Task CacheContent(bool recentlyAddedSearch = false); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index c39b80c1f..3b855740a 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -42,6 +42,7 @@ using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Schedule.Jobs.Plex.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Quartz; namespace Ombi.Schedule.Jobs.Plex { @@ -68,8 +69,11 @@ namespace Ombi.Schedule.Jobs.Plex private IRefreshMetadata Metadata { get; } private IPlexAvailabilityChecker Checker { get; } - public async Task CacheContent(bool recentlyAddedSearch = false) + public async Task Execute(IJobExecutionContext context) { + JobDataMap dataMap = context.JobDetail.JobDataMap; + var recentlyAddedSearch = dataMap.GetBooleanValueFromString("recentlyAddedSearch"); + var plexSettings = await Plex.GetSettingsAsync(); if (!plexSettings.Enable) { diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexRecentlyAddedSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexRecentlyAddedSync.cs index 51596f891..e26f07ba6 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexRecentlyAddedSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexRecentlyAddedSync.cs @@ -1,40 +1,40 @@ -using System; -using System.Threading.Tasks; -using Hangfire; +//using System; +//using System.Threading.Tasks; +//using Hangfire; -namespace Ombi.Schedule.Jobs.Plex -{ - public class PlexRecentlyAddedSync : IPlexRecentlyAddedSync - { - public PlexRecentlyAddedSync(IPlexContentSync sync) - { - _sync = sync; - } +//namespace Ombi.Schedule.Jobs.Plex +//{ +// public class PlexRecentlyAddedSync : IPlexRecentlyAddedSync +// { +// public PlexRecentlyAddedSync(IPlexContentSync sync) +// { +// _sync = sync; +// } - private readonly IPlexContentSync _sync; +// private readonly IPlexContentSync _sync; - public void Start() - { - BackgroundJob.Enqueue(() => _sync.CacheContent(true)); - } +// public void Start() +// { +// BackgroundJob.Enqueue(() => _sync.CacheContent(true)); +// } - private bool _disposed; - protected virtual void Dispose(bool disposing) - { - if (_disposed) - return; +// private bool _disposed; +// protected virtual void Dispose(bool disposing) +// { +// if (_disposed) +// return; - if (disposing) - { - _sync?.Dispose(); - } - _disposed = true; - } +// if (disposing) +// { +// _sync?.Dispose(); +// } +// _disposed = true; +// } - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - } -} \ No newline at end of file +// public void Dispose() +// { +// Dispose(true); +// GC.SuppressFinalize(this); +// } +// } +//} \ No newline at end of file diff --git a/src/Ombi.Schedule/Ombi.Schedule.csproj b/src/Ombi.Schedule/Ombi.Schedule.csproj index 06cc2bb49..fa4c389d3 100644 --- a/src/Ombi.Schedule/Ombi.Schedule.csproj +++ b/src/Ombi.Schedule/Ombi.Schedule.csproj @@ -16,6 +16,7 @@ + diff --git a/src/Ombi.Schedule/OmbiQuartz.cs b/src/Ombi.Schedule/OmbiQuartz.cs new file mode 100644 index 000000000..20c12bf23 --- /dev/null +++ b/src/Ombi.Schedule/OmbiQuartz.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using Quartz; +using Quartz.Impl; +using Quartz.Spi; + +namespace Ombi.Schedule +{ + public class OmbiQuartz + { + private IScheduler _scheduler; + + public static IScheduler Scheduler => Instance._scheduler; + + // Singleton + private static OmbiQuartz _instance; + + /// + /// Singleton + /// + public static OmbiQuartz Instance => _instance ?? (_instance = new OmbiQuartz()); + + private OmbiQuartz() + { + Init(); + } + + private async void Init() + { + _scheduler = await new StdSchedulerFactory().GetScheduler(); + } + + public IScheduler UseJobFactory(IJobFactory jobFactory) + { + Scheduler.JobFactory = jobFactory; + return Scheduler; + } + + + public async void AddJob(string name, string group, string cronExpression, Dictionary jobData = null) + where T : IJob + { + var jobBuilder = JobBuilder.Create() + .WithIdentity(name, group); + if (jobData != null) + { + foreach (var o in jobData) + { + jobBuilder.UsingJobData(o.Key, o.Value); + } + } + + var job = jobBuilder.Build(); + + + + ITrigger jobTrigger = TriggerBuilder.Create() + .WithIdentity(name + "Trigger", group) + .StartNow() + .WithCronSchedule(cronExpression) + .Build(); + + await Scheduler.ScheduleJob(job, jobTrigger); + } + + public static async void Start() + { + await Scheduler.Start(); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Schedule/OmbiScheduler.cs b/src/Ombi.Schedule/OmbiScheduler.cs new file mode 100644 index 000000000..f728a9ba4 --- /dev/null +++ b/src/Ombi.Schedule/OmbiScheduler.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using Microsoft.AspNetCore.Builder; +using Ombi.Core.Settings; +using Ombi.Schedule.Jobs.Plex; +using Ombi.Settings.Settings.Models; +using Quartz; +using Quartz.Spi; + +namespace Ombi.Schedule +{ + public static class OmbiScheduler + { + //public void Setup() + //{ + // CreateJobDefinitions(); + //} + + //public void CreateJobDefinitions() + //{ + // var contentSync = JobBuilder.Create() + // .UsingJobData("recentlyAddedSearch", false) + // .WithIdentity(nameof(PlexContentSync), "Plex") + // .Build(); + + // var recentlyAdded = JobBuilder.Create() + // .UsingJobData("recentlyAddedSearch", true) + // .WithIdentity("PlexRecentlyAdded", "Plex") + // .Build(); + //} + + public static void UseQuartz(this IApplicationBuilder app) + { + // Job Factory through IOC container + var jobFactory = (IJobFactory)app.ApplicationServices.GetService(typeof(IJobFactory)); + var service = (ISettingsService)app.ApplicationServices.GetService(typeof(ISettingsService)); + var s = service.GetSettings(); + // Set job factory + OmbiQuartz.Instance.UseJobFactory(jobFactory); + + // Run configuration + OmbiQuartz.Instance.AddJob(nameof(PlexContentSync), "Plex", JobSettingsHelper.PlexContent(s), new Dictionary{{ "recentlyAddedSearch", "false" } }); + OmbiQuartz.Instance.AddJob(nameof(PlexContentSync), "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "true" } }); + + // Run Quartz + OmbiQuartz.Start(); + } + } +} \ No newline at end of file diff --git a/src/Ombi/Controllers/JobController.cs b/src/Ombi/Controllers/JobController.cs index a89346250..3b1b65f3e 100644 --- a/src/Ombi/Controllers/JobController.cs +++ b/src/Ombi/Controllers/JobController.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using Hangfire; using Microsoft.AspNetCore.Mvc; @@ -6,10 +7,12 @@ using Microsoft.Extensions.Caching.Memory; using Ombi.Api.Service; using Ombi.Attributes; using Ombi.Helpers; +using Ombi.Schedule; using Ombi.Schedule.Jobs; using Ombi.Schedule.Jobs.Emby; using Ombi.Schedule.Jobs.Ombi; using Ombi.Schedule.Jobs.Plex; +using Quartz; namespace Ombi.Controllers { @@ -117,7 +120,7 @@ namespace Ombi.Controllers [HttpPost("plexcontentcacher")] public bool StartPlexContentCacher() { - BackgroundJob.Enqueue(() => _plexContentSync.CacheContent(false)); + OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(PlexContentSync)), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "false" } })); return true; } @@ -128,7 +131,7 @@ namespace Ombi.Controllers [HttpPost("plexrecentlyadded")] public bool StartRecentlyAdded() { - BackgroundJob.Enqueue(() => _plexContentSync.CacheContent(true)); + OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(PlexContentSync)), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "true" } })); return true; } diff --git a/src/Ombi/Startup.cs b/src/Ombi/Startup.cs index 2d86d4471..45d554831 100644 --- a/src/Ombi/Startup.cs +++ b/src/Ombi/Startup.cs @@ -147,6 +147,8 @@ namespace Ombi ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); + app.UseQuartz(); + var ctx = serviceProvider.GetService(); loggerFactory.AddSerilog(); From f67ea821874fe9f6577ba834b9d422cfa0845d20 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 18 Feb 2019 15:49:11 +0000 Subject: [PATCH 02/58] New translations en.json (French) --- src/Ombi/wwwroot/translations/fr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/wwwroot/translations/fr.json b/src/Ombi/wwwroot/translations/fr.json index c2df9306b..d4e23e278 100644 --- a/src/Ombi/wwwroot/translations/fr.json +++ b/src/Ombi/wwwroot/translations/fr.json @@ -74,7 +74,7 @@ "ViewOnEmby": "Regarder sur Emby", "RequestAdded": "La demande pour {{title}} a été ajoutée avec succès", "Similar": "Similaires", - "Refine": "Refine", + "Refine": "Affiner", "Movies": { "PopularMovies": "Films populaires", "UpcomingMovies": "Films à venir", From 09b2b6fe6f7eb94942feb6c889cc53aa06568817 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 19 Feb 2019 20:01:56 +0000 Subject: [PATCH 03/58] New translations en.json (Polish) --- src/Ombi/wwwroot/translations/pl.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/wwwroot/translations/pl.json b/src/Ombi/wwwroot/translations/pl.json index ddd3ed24d..af5f83efb 100644 --- a/src/Ombi/wwwroot/translations/pl.json +++ b/src/Ombi/wwwroot/translations/pl.json @@ -64,7 +64,7 @@ "Title": "Szukaj", "Paragraph": "Chcesz obejrzeć coś, co nie jest obecnie dostępne? Żaden problem, po prostu wyszukaj poniżej i dodaj zgłoszenie!", "MoviesTab": "Filmy", - "TvTab": "Seriale", + "TvTab": "Programy TV", "MusicTab": "Muzyka", "Suggestions": "Sugestie", "NoResults": "Niestety nic nie znaleziono!", From bd06af8ca0407ea38f1b8f5bcd362ebbeb0e8f99 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Wed, 20 Feb 2019 21:37:32 +0000 Subject: [PATCH 04/58] !wip just some small minor improvements --- .../Rule/Rules/Search/AvailabilityRuleHelper.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs index 428de9ce5..58a0c300f 100644 --- a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs +++ b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs @@ -24,7 +24,7 @@ namespace Ombi.Core.Rule.Rules.Search if (!airedButNotAvailable) { var unairedEpisodes = search.SeasonRequests.Any(x => - x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date)); + x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date && c.AirDate != DateTime.MinValue)); if (unairedEpisodes) { search.FullyAvailable = true; @@ -41,21 +41,21 @@ namespace Ombi.Core.Rule.Rules.Search { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.ImdbId == item.ImdbId.ToString()); + x.Series.ImdbId.Equals(item.ImdbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); } if (useTheMovieDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TheMovieDbId == item.TheMovieDbId.ToString()); + x.Series.TheMovieDbId.Equals(item.TheMovieDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); } if (useTvDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TvDbId == item.TvDbId.ToString()); + x.Series.TvDbId.Equals(item.TvDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); } if (epExists != null) @@ -71,21 +71,21 @@ namespace Ombi.Core.Rule.Rules.Search { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.ImdbId == item.ImdbId.ToString()); + x.Series.ImdbId.Equals(item.ImdbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); } if (useTheMovieDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TheMovieDbId == item.TheMovieDbId.ToString()); + x.Series.TheMovieDbId.Equals(item.TheMovieDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); } if (useTvDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TvDbId == item.TvDbId.ToString()); + x.Series.TvDbId.Equals(item.TvDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); } if (epExists != null) From 099e7d3436840177dc095654219d4c23d3ba10c2 Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 20 Feb 2019 20:10:03 -0500 Subject: [PATCH 05/58] fix typo --- src/Ombi/ClientApp/app/settings/emby/emby.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/ClientApp/app/settings/emby/emby.component.html b/src/Ombi/ClientApp/app/settings/emby/emby.component.html index 62188aaf6..66cac8c8b 100644 --- a/src/Ombi/ClientApp/app/settings/emby/emby.component.html +++ b/src/Ombi/ClientApp/app/settings/emby/emby.component.html @@ -67,7 +67,7 @@
From 3a690e321ea8b72940a5087ffdd13f738fca0898 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Fri, 22 Feb 2019 08:08:58 +0000 Subject: [PATCH 06/58] Fixed an issue where the Subscribe button was appearing on available movies. --- src/Ombi.Core/Engine/MovieSearchEngine.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs index 84cb8afcf..520f052a9 100644 --- a/src/Ombi.Core/Engine/MovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs @@ -227,7 +227,7 @@ namespace Ombi.Core.Engine } var request = await RequestService.MovieRequestService.GetAll() .AnyAsync(x => x.RequestedUserId.Equals(user.Id) && x.TheMovieDbId == viewModel.Id); - if (request) + if (request || viewModel.Available) { viewModel.ShowSubscribe = false; } From c84d5f9f5d5e06845eabc71274d331180b4daf1a Mon Sep 17 00:00:00 2001 From: TidusJar Date: Fri, 22 Feb 2019 09:05:47 +0000 Subject: [PATCH 07/58] Fixed a regression issue where TV Shows couldn't be requested --- .../Rule/Rules/Search/AvailabilityRuleHelper.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs index 58a0c300f..503296400 100644 --- a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs +++ b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs @@ -2,7 +2,6 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Query; using Ombi.Core.Models.Search; using Ombi.Store.Entities; using Ombi.Store.Repository.Requests; @@ -41,21 +40,21 @@ namespace Ombi.Core.Rule.Rules.Search { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.ImdbId.Equals(item.ImdbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); + x.Series.ImdbId == item.ImdbId); } if (useTheMovieDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TheMovieDbId.Equals(item.TheMovieDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); + x.Series.TheMovieDbId == item.TheMovieDbId); } if (useTvDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TvDbId.Equals(item.TvDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); + x.Series.TvDbId == item.TvDbId); } if (epExists != null) @@ -71,21 +70,21 @@ namespace Ombi.Core.Rule.Rules.Search { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.ImdbId.Equals(item.ImdbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); + x.Series.ImdbId == item.ImdbId); } if (useTheMovieDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TheMovieDbId.Equals(item.TheMovieDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); + x.Series.TheMovieDbId == item.TheMovieDbId); } if (useTvDb) { epExists = await allEpisodes.FirstOrDefaultAsync(x => x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TvDbId.Equals(item.TvDbId.ToString(), StringComparison.InvariantCultureIgnoreCase)); + x.Series.TvDbId == item.TvDbId); } if (epExists != null) From 8be3ef205a6c955f11fbd3032adf78ff5685b08e Mon Sep 17 00:00:00 2001 From: TidusJar Date: Fri, 22 Feb 2019 12:15:33 +0000 Subject: [PATCH 08/58] update dependancies --- src/Ombi.Core/Ombi.Core.csproj | 4 ++-- src/Ombi.Schedule/Ombi.Schedule.csproj | 4 ++-- src/Ombi.Store/Ombi.Store.csproj | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Ombi.Core/Ombi.Core.csproj b/src/Ombi.Core/Ombi.Core.csproj index 35688a6fe..790aa8500 100644 --- a/src/Ombi.Core/Ombi.Core.csproj +++ b/src/Ombi.Core/Ombi.Core.csproj @@ -11,9 +11,9 @@ - + - + diff --git a/src/Ombi.Schedule/Ombi.Schedule.csproj b/src/Ombi.Schedule/Ombi.Schedule.csproj index ff3a17115..256a3df7a 100644 --- a/src/Ombi.Schedule/Ombi.Schedule.csproj +++ b/src/Ombi.Schedule/Ombi.Schedule.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/src/Ombi.Store/Ombi.Store.csproj b/src/Ombi.Store/Ombi.Store.csproj index f905c9ffe..31c69c8d8 100644 --- a/src/Ombi.Store/Ombi.Store.csproj +++ b/src/Ombi.Store/Ombi.Store.csproj @@ -12,8 +12,8 @@ - - + + From 6a36fa3974b51c9dd0cddd4fa64a4e7c540bea62 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Mon, 25 Feb 2019 08:42:06 +0000 Subject: [PATCH 09/58] Fixed #2847 --- src/Ombi.Notifications/Agents/MattermostNotification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Notifications/Agents/MattermostNotification.cs b/src/Ombi.Notifications/Agents/MattermostNotification.cs index f64a0fe21..ed3084c19 100644 --- a/src/Ombi.Notifications/Agents/MattermostNotification.cs +++ b/src/Ombi.Notifications/Agents/MattermostNotification.cs @@ -52,7 +52,7 @@ namespace Ombi.Notifications.Agents private void AddOtherInformation(NotificationOptions model, NotificationMessage notification, NotificationMessageContent parsed) { - notification.Other.Add("image", parsed.Image); + notification.Other.Add("image", parsed?.Image ?? string.Empty); notification.Other.Add("title", model.RequestType == RequestType.Movie ? MovieRequest.Title : TvRequest.Title); } From d1086e8ae08cf16335a1834d758e57137b8203e5 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Mon, 25 Feb 2019 08:47:16 +0000 Subject: [PATCH 10/58] Prevented #2848 from erroring out causing further issues. --- .../Rules/Search/AvailabilityRuleHelper.cs | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs index 503296400..dd4f6c918 100644 --- a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs +++ b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; using Ombi.Core.Models.Search; using Ombi.Store.Entities; using Ombi.Store.Repository.Requests; @@ -33,28 +34,36 @@ namespace Ombi.Core.Rule.Rules.Search } public static async Task SingleEpisodeCheck(bool useImdb, IQueryable allEpisodes, EpisodeRequests episode, - SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb) + SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log) { PlexEpisode epExists = null; - if (useImdb) + try { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.ImdbId == item.ImdbId); - } - if (useTheMovieDb) - { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TheMovieDbId == item.TheMovieDbId); - } + if (useImdb) + { + epExists = await allEpisodes.FirstOrDefaultAsync(x => + x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && + x.Series.ImdbId == item.ImdbId); + } - if (useTvDb) + if (useTheMovieDb) + { + epExists = await allEpisodes.FirstOrDefaultAsync(x => + x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && + x.Series.TheMovieDbId == item.TheMovieDbId); + } + + if (useTvDb) + { + epExists = await allEpisodes.FirstOrDefaultAsync(x => + x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && + x.Series.TvDbId == item.TvDbId); + } + } + catch (Exception e) { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TvDbId == item.TvDbId); + log.LogError(e, "Exception thrown when attempting to check if something is available"); } if (epExists != null) From d233d2faebe8699020c918bae542f73ce0cdc7e5 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 25 Feb 2019 17:01:30 +0000 Subject: [PATCH 11/58] New translations en.json (Norwegian) --- src/Ombi/wwwroot/translations/no.json | 30 +++++++++++++-------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Ombi/wwwroot/translations/no.json b/src/Ombi/wwwroot/translations/no.json index 93ed1342e..b65c9b53c 100644 --- a/src/Ombi/wwwroot/translations/no.json +++ b/src/Ombi/wwwroot/translations/no.json @@ -13,7 +13,7 @@ "ContinueButton": "Gå videre", "Available": "Tilgjengelig", "PartiallyAvailable": "Partially Available", - "Monitored": "Monitored", + "Monitored": "Overvåket", "NotAvailable": "Ikke tilgjengelig", "ProcessingRequest": "Behandler forespørsel", "PendingApproval": "Venter på godkjenning", @@ -48,7 +48,7 @@ "Requests": "Forespørsler", "UserManagement": "Brukeradministrasjon", "Issues": "Mangler", - "Vote": "Vote", + "Vote": "Stem", "Donate": "Doner!", "DonateLibraryMaintainer": "Doner til vedlikeholderen av biblioteket", "DonateTooltip": "Dette er hvordan jeg overbevise min kone til å la meg bruke min fritid til å utvikle Ombi ;)", @@ -58,14 +58,14 @@ "UpdateDetails": "Oppdater detaljer", "Logout": "Logg av", "OpenMobileApp": "Åpne mobilapp", - "RecentlyAdded": "Recently Added" + "RecentlyAdded": "Nylig lagt til" }, "Search": { "Title": "Søk", "Paragraph": "Vil du se noe som foreløpig ikke er tilgjengelig? Ikke noe problem, bare søk etter det nedenfor og be om det!", "MoviesTab": "Filmer", "TvTab": "TV serier", - "MusicTab": "Music", + "MusicTab": "Musikk", "Suggestions": "Forslag", "NoResults": "Beklager, vi fant ingen resultater!", "DigitalDate": "Digital utgivelse: {{date}}", @@ -104,7 +104,7 @@ "Paragraph": "Nedenfor kan du se dine og alle andres forespørsler, du ser også status for nedlasting og godkjenning.", "MoviesTab": "Filmer", "TvTab": "TV serier", - "MusicTab": "Music", + "MusicTab": "Musikk", "RequestedBy": "Etterspurt av:", "Status": "Status:", "RequestStatus": "Status for forespørsel:", @@ -128,10 +128,10 @@ "GridStatus": "Status", "ReportIssue": "Rapportér en feil", "Filter": "Filter", - "Sort": "Sort", + "Sort": "Sorter", "SeasonNumberHeading": "Sesong: {seasonNumber}", - "SortTitleAsc": "Title ▲", - "SortTitleDesc": "Title ▼", + "SortTitleAsc": "Tittel ▲", + "SortTitleDesc": "Tittel ▼", "SortRequestDateAsc": "Request Date ▲", "SortRequestDateDesc": "Request Date ▼", "SortStatusAsc": "Status ▲", @@ -168,18 +168,18 @@ "FilterHeaderAvailability": "Tilgjengelighet", "FilterHeaderRequestStatus": "Status", "Approved": "Godkjent", - "PendingApproval": "Pending Approval" + "PendingApproval": "Venter på godkjenning" }, "UserManagment": { - "TvRemaining": "TV: {{remaining}}/{{total}} remaining", - "MovieRemaining": "Movies: {{remaining}}/{{total}} remaining", - "MusicRemaining": "Music: {{remaining}}/{{total}} remaining", + "TvRemaining": "TV: {{remaining}}/{{total}} gjenstående", + "MovieRemaining": "Filmer: {{remaining}}/{{total}} gjenstående", + "MusicRemaining": "Musikk: {{remaining}}/{{total}} gjenstående", "TvDue": "TV: {{date}}", - "MovieDue": "Movie: {{date}}", - "MusicDue": "Music: {{date}}" + "MovieDue": "Film:{{date}}", + "MusicDue": "Musikk:{{date}}" }, "Votes": { - "CompletedVotesTab": "Voted", + "CompletedVotesTab": "Stemt", "VotesTab": "Votes Needed" } } From c8415f8da9ccd5adc19f1f84f217928ddebb7282 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Mon, 25 Feb 2019 21:36:19 +0000 Subject: [PATCH 12/58] Set the CommandTimeout longer to see if EF can get a handle on the SQLite file when it's locked #2750 --- src/Ombi.Store/Context/ExternalContext.cs | 1 + src/Ombi.Store/Context/OmbiContext.cs | 10 +++++++++- src/Ombi.Store/Context/SettingsContext.cs | 8 +------- src/Ombi/Program.cs | 18 +----------------- 4 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/Ombi.Store/Context/ExternalContext.cs b/src/Ombi.Store/Context/ExternalContext.cs index eb2be6450..ff0581091 100644 --- a/src/Ombi.Store/Context/ExternalContext.cs +++ b/src/Ombi.Store/Context/ExternalContext.cs @@ -13,6 +13,7 @@ namespace Ombi.Store.Context if (_created) return; _created = true; + Database.SetCommandTimeout(60); Database.Migrate(); } diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 47b245603..2f19bc681 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -18,6 +18,7 @@ namespace Ombi.Store.Context if (_created) return; _created = true; + Database.SetCommandTimeout(60); Database.Migrate(); } @@ -107,6 +108,7 @@ namespace Ombi.Store.Context var allAgents = Enum.GetValues(typeof(NotificationAgent)).Cast().ToList(); var allTypes = Enum.GetValues(typeof(NotificationType)).Cast().ToList(); + var needToSave = false; foreach (var agent in allAgents) { foreach (var notificationType in allTypes) @@ -116,6 +118,8 @@ namespace Ombi.Store.Context // We already have this continue; } + + needToSave = true; NotificationTemplates notificationToAdd; switch (notificationType) { @@ -230,7 +234,11 @@ namespace Ombi.Store.Context NotificationTemplates.Add(notificationToAdd); } } - SaveChanges(); + + if (needToSave) + { + SaveChanges(); + } } } } \ No newline at end of file diff --git a/src/Ombi.Store/Context/SettingsContext.cs b/src/Ombi.Store/Context/SettingsContext.cs index 6a53e598f..6c9fad335 100644 --- a/src/Ombi.Store/Context/SettingsContext.cs +++ b/src/Ombi.Store/Context/SettingsContext.cs @@ -14,6 +14,7 @@ namespace Ombi.Store.Context if (_created) return; _created = true; + Database.SetCommandTimeout(60); Database.Migrate(); } @@ -63,13 +64,6 @@ namespace Ombi.Store.Context }); SaveChanges(); } - - SaveChanges(); - } - - ~SettingsContext() - { - } } } \ No newline at end of file diff --git a/src/Ombi/Program.cs b/src/Ombi/Program.cs index acc904875..40fd37e73 100644 --- a/src/Ombi/Program.cs +++ b/src/Ombi/Program.cs @@ -91,9 +91,7 @@ namespace Ombi dbBaseUrl.Value = baseUrl; ctx.SaveChanges(); } - - DeleteSchedulesDb(); - + Console.WriteLine($"We are running on {urlValue}"); CreateWebHostBuilder(args).Build().Run(); @@ -226,20 +224,6 @@ namespace Ombi } } - private static void DeleteSchedulesDb() - { - try - { - if (File.Exists("Schedules.db")) - { - File.Delete("Schedules.db"); - } - } - catch (Exception) - { - } - } - public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup() From ee89f6f16cddfafab1e8211588c3b3a7c8476227 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Mon, 25 Feb 2019 22:26:09 +0000 Subject: [PATCH 13/58] Fixed build !wip --- .../Rule/Search/PlexAvailabilityRuleTests.cs | 3 ++- .../Rule/Rules/Search/PlexAvailabilityRule.cs | 7 +++++-- src/Ombi.Store/Repository/BaseRepository.cs | 10 +++++----- src/Ombi/Ombi.csproj | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Ombi.Core.Tests/Rule/Search/PlexAvailabilityRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/PlexAvailabilityRuleTests.cs index 55177a6ac..5bd35473c 100644 --- a/src/Ombi.Core.Tests/Rule/Search/PlexAvailabilityRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/PlexAvailabilityRuleTests.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Ombi.Core.Models.Search; @@ -14,7 +15,7 @@ namespace Ombi.Core.Tests.Rule.Search public void Setup() { ContextMock = new Mock(); - Rule = new PlexAvailabilityRule(ContextMock.Object); + Rule = new PlexAvailabilityRule(ContextMock.Object, new Mock>().Object); } private PlexAvailabilityRule Rule { get; set; } diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index 7f79e4165..2a239d1d3 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; using Ombi.Helpers; @@ -10,12 +11,14 @@ namespace Ombi.Core.Rule.Rules.Search { public class PlexAvailabilityRule : BaseSearchRule, IRules { - public PlexAvailabilityRule(IPlexContentRepository repo) + public PlexAvailabilityRule(IPlexContentRepository repo, ILogger log) { PlexContentRepository = repo; + Log = log; } private IPlexContentRepository PlexContentRepository { get; } + private ILogger Log { get; } public async Task Execute(SearchViewModel obj) { @@ -72,7 +75,7 @@ namespace Ombi.Core.Rule.Rules.Search { foreach (var episode in season.Episodes) { - await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb); + await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log); } } diff --git a/src/Ombi.Store/Repository/BaseRepository.cs b/src/Ombi.Store/Repository/BaseRepository.cs index 1679035dd..efd277f43 100644 --- a/src/Ombi.Store/Repository/BaseRepository.cs +++ b/src/Ombi.Store/Repository/BaseRepository.cs @@ -40,27 +40,27 @@ namespace Ombi.Store.Repository _db.AddRange(content); if (save) { - await _ctx.SaveChangesAsync(); + await SaveChangesAsync(); } } public async Task Add(T content) { await _db.AddAsync(content); - await _ctx.SaveChangesAsync(); + await SaveChangesAsync(); return content; } public async Task Delete(T request) { _db.Remove(request); - await _ctx.SaveChangesAsync(); + await SaveChangesAsync(); } public async Task DeleteRange(IEnumerable req) { _db.RemoveRange(req); - await _ctx.SaveChangesAsync(); + await SaveChangesAsync(); } public async Task SaveChangesAsync() @@ -79,7 +79,7 @@ namespace Ombi.Store.Repository { await _ctx.Database.ExecuteSqlCommandAsync(sql); } - + private bool _disposed; // Protected implementation of Dispose pattern. diff --git a/src/Ombi/Ombi.csproj b/src/Ombi/Ombi.csproj index dc447dd20..02e11c84b 100644 --- a/src/Ombi/Ombi.csproj +++ b/src/Ombi/Ombi.csproj @@ -65,7 +65,7 @@ - + From e1a82ed8ef11fcbe16430586e6365b1bbd674f44 Mon Sep 17 00:00:00 2001 From: Jamie Date: Tue, 26 Feb 2019 14:32:25 +0000 Subject: [PATCH 14/58] New translations en.json (German) --- src/Ombi/wwwroot/translations/de.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Ombi/wwwroot/translations/de.json b/src/Ombi/wwwroot/translations/de.json index 592d69f9c..b3e93f306 100644 --- a/src/Ombi/wwwroot/translations/de.json +++ b/src/Ombi/wwwroot/translations/de.json @@ -13,7 +13,7 @@ "ContinueButton": "Weiter", "Available": "Verfügbar", "PartiallyAvailable": "Teilweise verfügbar", - "Monitored": "Monitored", + "Monitored": "Überwacht", "NotAvailable": "Nicht verfügbar", "ProcessingRequest": "Anfrage wird bearbeitet", "PendingApproval": "Genehmigung ausstehend", @@ -68,13 +68,13 @@ "MusicTab": "Musik", "Suggestions": "Vorschläge", "NoResults": "Es tut uns leid, wir haben keine Ergebnisse gefunden!", - "DigitalDate": "Digital Release: {{date}}", + "DigitalDate": "Veröffentlichung der digitalen Version: {{date}}", "TheatricalRelease": "Kinostart: {{date}}", "ViewOnPlex": "In Plex anschauen", "ViewOnEmby": "In Emby anschauen", "RequestAdded": "Anfrage für {{title}} wurde erfolgreich hinzugefügt", "Similar": "Ähnliche", - "Refine": "Refine", + "Refine": "Auswahl verfeinern", "Movies": { "PopularMovies": "Beliebte Filme", "UpcomingMovies": "Kommende Filme", @@ -112,7 +112,7 @@ "TheatricalRelease": "Kinostart: {{date}}", "ReleaseDate": "Veröffentlicht: {{date}}", "TheatricalReleaseSort": "Kinostart", - "DigitalRelease": "Digital Release: {{date}}", + "DigitalRelease": "Veröffentlichung der digitalen Version: {{date}}", "RequestDate": "Datum der Anfrage:", "QualityOverride": "Qualitäts Überschreiben:", "RootFolderOverride": "Stammverzeichnis Überschreiben:", @@ -132,16 +132,16 @@ "SeasonNumberHeading": "Staffel: {seasonNumber}", "SortTitleAsc": "Titel ▲", "SortTitleDesc": "Titel ▼", - "SortRequestDateAsc": "Request Date ▲", - "SortRequestDateDesc": "Request Date ▼", + "SortRequestDateAsc": "Datum der Anfrage ▲", + "SortRequestDateDesc": "Datum der Anfrage ▼", "SortStatusAsc": "Status ▲", "SortStatusDesc": "Status ▼", "Remaining": { "Quota": "{{remaining}}/{{total}} Anfragen verbleiben", - "NextDays": "Another request will be added in {{time}} days", - "NextHours": "Another request will be added in {{time}} hours", - "NextMinutes": "Another request will be added in {{time}} minutes", - "NextMinute": "Another request will be added in {{time}} minute" + "NextDays": "Eine weitere Anfrage wird in {{time}} Tagen hinzugefügt", + "NextHours": "Eine weitere Anfrage wird in {{time}} Stunden hinzugefügt", + "NextMinutes": "Eine weitere Anfrage wird in {{time}} Minuten hinzugefügt", + "NextMinute": "Eine weitere Anfrage wird in {{time}} Minute hinzugefügt" } }, "Issues": { From 3592781e94bf85e881f1ae4c0ab2ccd65565fbf9 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Wed, 6 Mar 2019 10:13:11 +0000 Subject: [PATCH 15/58] Added a lock on the database commit level to see if I can improve locked db's --- src/Ombi.Store/Ombi.Store.csproj | 1 + src/Ombi.Store/Repository/BaseRepository.cs | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Ombi.Store/Ombi.Store.csproj b/src/Ombi.Store/Ombi.Store.csproj index 31c69c8d8..8dfcc1c28 100644 --- a/src/Ombi.Store/Ombi.Store.csproj +++ b/src/Ombi.Store/Ombi.Store.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Ombi.Store/Repository/BaseRepository.cs b/src/Ombi.Store/Repository/BaseRepository.cs index efd277f43..21dd2dac5 100644 --- a/src/Ombi.Store/Repository/BaseRepository.cs +++ b/src/Ombi.Store/Repository/BaseRepository.cs @@ -5,6 +5,7 @@ using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; +using Nito.AsyncEx; using Ombi.Store.Context; using Ombi.Store.Entities; @@ -19,6 +20,7 @@ namespace Ombi.Store.Repository } public DbSet _db { get; } private readonly U _ctx; + private readonly AsyncLock _mutex = new AsyncLock(); public async Task Find(object key) { @@ -40,32 +42,32 @@ namespace Ombi.Store.Repository _db.AddRange(content); if (save) { - await SaveChangesAsync(); + await InternalSaveChanges(); } } public async Task Add(T content) { await _db.AddAsync(content); - await SaveChangesAsync(); + await InternalSaveChanges(); return content; } public async Task Delete(T request) { _db.Remove(request); - await SaveChangesAsync(); + await InternalSaveChanges(); } public async Task DeleteRange(IEnumerable req) { _db.RemoveRange(req); - await SaveChangesAsync(); + await InternalSaveChanges(); } public async Task SaveChangesAsync() { - return await _ctx.SaveChangesAsync(); + return await InternalSaveChanges(); } public IIncludableQueryable Include( @@ -79,6 +81,14 @@ namespace Ombi.Store.Repository { await _ctx.Database.ExecuteSqlCommandAsync(sql); } + + private async Task InternalSaveChanges() + { + using (await _mutex.LockAsync()) + { + return await _ctx.SaveChangesAsync(); + } + } private bool _disposed; From b74a4d29c8b9b6c788149eabfe3346f2ca0caa84 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Thu, 7 Mar 2019 08:53:07 +0000 Subject: [PATCH 16/58] Fixed #2860 When a future series is unknown it should appear as available when we have the other seasons --- src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs index dd4f6c918..ab1a0af98 100644 --- a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs +++ b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs @@ -24,7 +24,7 @@ namespace Ombi.Core.Rule.Rules.Search if (!airedButNotAvailable) { var unairedEpisodes = search.SeasonRequests.Any(x => - x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date && c.AirDate != DateTime.MinValue)); + x.Episodes.Any(c => !c.Available && c.AirDate > DateTime.Now.Date || c.AirDate != DateTime.MinValue)); if (unairedEpisodes) { search.FullyAvailable = true; From 12997541f0def3b1722df27d1a55ba806e315759 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Thu, 7 Mar 2019 08:58:02 +0000 Subject: [PATCH 17/58] Fixed build --- build.cake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.cake b/build.cake index e8e4bb8c0..07a20587f 100644 --- a/build.cake +++ b/build.cake @@ -81,9 +81,9 @@ Task("SetVersionInfo") versionInfo = GitVersion(settings); - Information("GitResults -> {0}", versionInfo.Dump()); +// Information("GitResults -> {0}", versionInfo.Dump()); - Information(@"Build:{0}",AppVeyor.Environment.Build.Dump()); +//Information(@"Build:{0}",AppVeyor.Environment.Build.Dump()); var buildVersion = string.Empty; if(string.IsNullOrEmpty(AppVeyor.Environment.Build.Version)) From fa76a57f08bcf32f3d515fedf7eb3608042f3acc Mon Sep 17 00:00:00 2001 From: tidusjar Date: Wed, 13 Mar 2019 20:59:39 +0000 Subject: [PATCH 18/58] Fixed a migration issue --- src/Ombi/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ombi/Program.cs b/src/Ombi/Program.cs index 40fd37e73..f1809a2dc 100644 --- a/src/Ombi/Program.cs +++ b/src/Ombi/Program.cs @@ -115,7 +115,7 @@ namespace Ombi try { - if (ombi.Settings.Any()) + if (ombi.Settings.Any() && !settings.Settings.Any()) { // OK migrate it! var allSettings = ombi.Settings.ToList(); @@ -125,7 +125,7 @@ namespace Ombi // Check for any application settings - if (ombi.ApplicationConfigurations.Any()) + if (ombi.ApplicationConfigurations.Any() && !settings.ApplicationConfigurations.Any()) { // OK migrate it! var allSettings = ombi.ApplicationConfigurations.ToList(); From 1322076aa678207b424f2cc92a4394ba7f187e17 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Mon, 11 Mar 2019 08:33:16 +0000 Subject: [PATCH 19/58] Added a global mutex (not used yet) and moved around the code for loggin in since I suspect the Get Roles call is using deffered execution on the database causing the lock when attempting to access straight away #2750 --- src/Ombi.Helpers/GlobalMutex.cs | 38 +++++++++++++++++++++++++ src/Ombi/Controllers/TokenController.cs | 6 ++-- 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 src/Ombi.Helpers/GlobalMutex.cs diff --git a/src/Ombi.Helpers/GlobalMutex.cs b/src/Ombi.Helpers/GlobalMutex.cs new file mode 100644 index 000000000..ecf9cdf15 --- /dev/null +++ b/src/Ombi.Helpers/GlobalMutex.cs @@ -0,0 +1,38 @@ +using System; +using System.Threading; + +namespace Ombi.Helpers +{ + public static class GlobalMutex + { + public static T Lock(Func func) + { + const string mutexId = "Global\\OMBI"; + + using (var mutex = new Mutex(false, mutexId, out __)) + { + var hasHandle = false; + try + { + try + { + hasHandle = mutex.WaitOne(5000, false); + if (hasHandle == false) + throw new TimeoutException("Timeout waiting for exclusive access"); + } + catch (AbandonedMutexException) + { + hasHandle = true; + } + + return func(); + } + finally + { + if (hasHandle) + mutex.ReleaseMutex(); + } + } + } + } +} diff --git a/src/Ombi/Controllers/TokenController.cs b/src/Ombi/Controllers/TokenController.cs index 44ec5686f..b27c04caa 100644 --- a/src/Ombi/Controllers/TokenController.cs +++ b/src/Ombi/Controllers/TokenController.cs @@ -123,9 +123,6 @@ namespace Ombi.Controllers return new UnauthorizedResult(); } - user.LastLoggedIn = DateTime.UtcNow; - await _userManager.UpdateAsync(user); - var claims = new List { new Claim(JwtRegisteredClaimNames.Sub, user.UserName), @@ -152,6 +149,9 @@ namespace Ombi.Controllers //await _token.CreateToken(new Tokens() {Token = accessToken, User = user}); } + user.LastLoggedIn = DateTime.UtcNow; + await _userManager.UpdateAsync(user); + return new JsonResult(new { access_token = accessToken, From 947c0e74cbe7bb2b471261d3d52a4e6dbdb8e079 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Thu, 14 Mar 2019 11:12:28 +0000 Subject: [PATCH 20/58] Made use of the global mutex, this should now hopefully work #2750 --- src/Ombi.Helpers/GlobalMutex.cs | 9 +++++---- src/Ombi.Store/Repository/BaseRepository.cs | 14 +++++--------- src/Ombi/Controllers/TokenController.cs | 2 +- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/Ombi.Helpers/GlobalMutex.cs b/src/Ombi.Helpers/GlobalMutex.cs index ecf9cdf15..0164e888c 100644 --- a/src/Ombi.Helpers/GlobalMutex.cs +++ b/src/Ombi.Helpers/GlobalMutex.cs @@ -1,15 +1,16 @@ using System; using System.Threading; +using System.Threading.Tasks; +using Nito.AsyncEx; namespace Ombi.Helpers { public static class GlobalMutex { - public static T Lock(Func func) + public static async Task Lock(Func> func) { const string mutexId = "Global\\OMBI"; - - using (var mutex = new Mutex(false, mutexId, out __)) + using (var mutex = new Mutex(false, mutexId, out _)) { var hasHandle = false; try @@ -25,7 +26,7 @@ namespace Ombi.Helpers hasHandle = true; } - return func(); + return await func(); } finally { diff --git a/src/Ombi.Store/Repository/BaseRepository.cs b/src/Ombi.Store/Repository/BaseRepository.cs index 21dd2dac5..ca2937291 100644 --- a/src/Ombi.Store/Repository/BaseRepository.cs +++ b/src/Ombi.Store/Repository/BaseRepository.cs @@ -5,7 +5,7 @@ using System.Linq.Expressions; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Query; -using Nito.AsyncEx; +using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Entities; @@ -20,7 +20,6 @@ namespace Ombi.Store.Repository } public DbSet _db { get; } private readonly U _ctx; - private readonly AsyncLock _mutex = new AsyncLock(); public async Task Find(object key) { @@ -32,7 +31,7 @@ namespace Ombi.Store.Repository return _db.AsQueryable(); } - public async Task FirstOrDefaultAsync(Expression> predicate) + public async Task FirstOrDefaultAsync(Expression> predicate) { return await _db.FirstOrDefaultAsync(predicate); } @@ -84,12 +83,9 @@ namespace Ombi.Store.Repository private async Task InternalSaveChanges() { - using (await _mutex.LockAsync()) - { - return await _ctx.SaveChangesAsync(); - } + return await GlobalMutex.Lock(async () => await _ctx.SaveChangesAsync()); } - + private bool _disposed; // Protected implementation of Dispose pattern. @@ -102,7 +98,7 @@ namespace Ombi.Store.Repository { _ctx?.Dispose(); } - + _disposed = true; } diff --git a/src/Ombi/Controllers/TokenController.cs b/src/Ombi/Controllers/TokenController.cs index b27c04caa..9499dd493 100644 --- a/src/Ombi/Controllers/TokenController.cs +++ b/src/Ombi/Controllers/TokenController.cs @@ -150,7 +150,7 @@ namespace Ombi.Controllers } user.LastLoggedIn = DateTime.UtcNow; - await _userManager.UpdateAsync(user); + await GlobalMutex.Lock(async () => await _userManager.UpdateAsync(user)).ConfigureAwait(false); return new JsonResult(new { From 2b1eebafd106acb975f1ade74f5a52c6c95f7a83 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Thu, 14 Mar 2019 13:52:17 +0000 Subject: [PATCH 21/58] Set the View On Emby Url at runtime so the user can configure and change the URL and it will take effect straight away --- .../Rule/Rules/Search/EmbyAvailabilityRule.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs index 3171c6ada..f80bded7a 100644 --- a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs @@ -3,6 +3,8 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; using Ombi.Helpers; using Ombi.Store.Entities; using Ombi.Store.Repository; @@ -11,12 +13,14 @@ namespace Ombi.Core.Rule.Rules.Search { public class EmbyAvailabilityRule : BaseSearchRule, IRules { - public EmbyAvailabilityRule(IEmbyContentRepository repo) + public EmbyAvailabilityRule(IEmbyContentRepository repo, ISettingsService s) { EmbyContentRepository = repo; + EmbySettings = s; } private IEmbyContentRepository EmbyContentRepository { get; } + private ISettingsService EmbySettings { get; } public async Task Execute(SearchViewModel obj) { @@ -60,7 +64,16 @@ namespace Ombi.Core.Rule.Rules.Search if (item != null) { obj.Available = true; - obj.EmbyUrl = item.Url; + var s = await EmbySettings.GetSettingsAsync(); + var server = s.Servers.FirstOrDefault(x => x.ServerHostname != null); + if ((server?.ServerHostname ?? string.Empty).HasValue()) + { + obj.EmbyUrl = $"{server.ServerHostname}#!/itemdetails.html?id={item.EmbyId}"; + } + else + { + obj.EmbyUrl = $"https://app.emby.media/#!/itemdetails.html?id={item.EmbyId}"; + } if (obj.Type == RequestType.TvShow) { From f048505eed7d14fbd4f159ec593c5c125e276de9 Mon Sep 17 00:00:00 2001 From: TidusJar Date: Thu, 14 Mar 2019 20:58:04 +0000 Subject: [PATCH 22/58] Fixed #2636 --- src/Ombi.Notifications/GenericEmailProvider.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Ombi.Notifications/GenericEmailProvider.cs b/src/Ombi.Notifications/GenericEmailProvider.cs index 462f8918e..e255c4357 100644 --- a/src/Ombi.Notifications/GenericEmailProvider.cs +++ b/src/Ombi.Notifications/GenericEmailProvider.cs @@ -4,7 +4,9 @@ using EnsureThat; using MailKit.Net.Smtp; using Microsoft.Extensions.Logging; using MimeKit; +using MimeKit.Utils; using Ombi.Core.Settings; +using Ombi.Helpers; using Ombi.Notifications.Models; using Ombi.Notifications.Templates; using Ombi.Settings.Settings.Models; @@ -36,6 +38,15 @@ namespace Ombi.Notifications var customization = await CustomizationSettings.GetSettingsAsync(); var html = email.LoadTemplate(model.Subject, model.Message, null, customization.Logo); + + var messageId = MimeUtils.GenerateMessageId(); + if (customization.ApplicationUrl.HasValue()) + { + if (Uri.TryCreate(customization.ApplicationUrl, UriKind.RelativeOrAbsolute, out var url)) + { + messageId = MimeUtils.GenerateMessageId(url.IdnHost); + } + } var textBody = string.Empty; @@ -49,7 +60,8 @@ namespace Ombi.Notifications var message = new MimeMessage { Body = body.ToMessageBody(), - Subject = model.Subject + Subject = model.Subject, + MessageId = messageId }; message.From.Add(new MailboxAddress(string.IsNullOrEmpty(settings.SenderName) ? settings.SenderAddress : settings.SenderName, settings.SenderAddress)); message.To.Add(new MailboxAddress(model.To, model.To)); From 52b75ee4de1ebab4d7d85236e0c75ba8a00756f9 Mon Sep 17 00:00:00 2001 From: Jamie Date: Mon, 18 Mar 2019 12:46:47 +0000 Subject: [PATCH 23/58] Update JobSetup.cs --- src/Ombi.Schedule/JobSetup.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Ombi.Schedule/JobSetup.cs b/src/Ombi.Schedule/JobSetup.cs index 5cc818441..38686396f 100644 --- a/src/Ombi.Schedule/JobSetup.cs +++ b/src/Ombi.Schedule/JobSetup.cs @@ -81,7 +81,6 @@ namespace Ombi.Schedule RecurringJob.AddOrUpdate(() => _embyUserImporter.Start(), JobSettingsHelper.UserImporter(s)); RecurringJob.AddOrUpdate(() => _plexUserImporter.Start(), JobSettingsHelper.UserImporter(s)); RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s)); - RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s)); RecurringJob.AddOrUpdate(() => _resender.Start(), JobSettingsHelper.ResendFailedRequests(s)); RecurringJob.AddOrUpdate(() => _mediaDatabaseRefresh.Start(), JobSettingsHelper.MediaDatabaseRefresh(s)); } From 94b70c2f2cff1675b07f158065f7203425023e55 Mon Sep 17 00:00:00 2001 From: Guillaume Taquet Gasperini Date: Wed, 20 Mar 2019 19:40:37 +0100 Subject: [PATCH 24/58] Add Gotify as notification provider --- README.md | 1 + src/Ombi.Api.Gotify/GotifyApi.cs | 36 ++++++ src/Ombi.Api.Gotify/IGotifyApi.cs | 9 ++ src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj | 15 +++ .../Models/UI/GotifyNotificationViewModel.cs | 23 ++++ src/Ombi.DependencyInjection/IocExtensions.cs | 3 + src/Ombi.Helpers/LoggingEvents.cs | 1 + src/Ombi.Helpers/NotificationAgent.cs | 1 + src/Ombi.Mapping/Profiles/SettingsProfile.cs | 1 + .../Agents/GotifyNotification.cs | 116 ++++++++++++++++++ .../Agents/Interfaces/IGotifyNotification.cs | 6 + .../Ombi.Notifications.csproj | 1 + .../Models/Notifications/GotifySettings.cs | 10 ++ src/Ombi.sln | 9 +- .../app/interfaces/INotificationSettings.ts | 8 ++ .../services/applications/tester.service.ts | 7 +- .../app/services/settings.service.ts | 9 ++ .../notifications/gotify.component.html | 67 ++++++++++ .../notifications/gotify.component.ts | 68 ++++++++++ .../ClientApp/app/settings/settings.module.ts | 3 + .../app/settings/settingsmenu.component.html | 1 + .../Controllers/External/TesterController.cs | 28 ++++- src/Ombi/Controllers/SettingsController.cs | 34 +++++ 23 files changed, 454 insertions(+), 3 deletions(-) create mode 100644 src/Ombi.Api.Gotify/GotifyApi.cs create mode 100644 src/Ombi.Api.Gotify/IGotifyApi.cs create mode 100644 src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj create mode 100644 src/Ombi.Core/Models/UI/GotifyNotificationViewModel.cs create mode 100644 src/Ombi.Notifications/Agents/GotifyNotification.cs create mode 100644 src/Ombi.Notifications/Agents/Interfaces/IGotifyNotification.cs create mode 100644 src/Ombi.Settings/Settings/Models/Notifications/GotifySettings.cs create mode 100644 src/Ombi/ClientApp/app/settings/notifications/gotify.component.html create mode 100644 src/Ombi/ClientApp/app/settings/notifications/gotify.component.ts diff --git a/README.md b/README.md index 61cda24f3..0af908f65 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ We integrate with the following applications: Supported notifications: * SMTP Notifications (Email) * Discord +* Gotify * Slack * Pushbullet * Pushover diff --git a/src/Ombi.Api.Gotify/GotifyApi.cs b/src/Ombi.Api.Gotify/GotifyApi.cs new file mode 100644 index 000000000..8cd79a689 --- /dev/null +++ b/src/Ombi.Api.Gotify/GotifyApi.cs @@ -0,0 +1,36 @@ +using System.Net.Http; +using System.Threading.Tasks; + +namespace Ombi.Api.Gotify +{ + public class GotifyApi : IGotifyApi + { + public GotifyApi(IApi api) + { + _api = api; + } + + private readonly IApi _api; + + public async Task PushAsync(string baseUrl, string accessToken, string subject, string body, sbyte priority) + { + var request = new Request("/message", baseUrl, HttpMethod.Post); + request.AddQueryString("token", accessToken); + + request.AddHeader("Access-Token", accessToken); + request.ApplicationJsonContentType(); + + + var jsonBody = new + { + message = body, + title = subject, + priority = priority + }; + + request.AddJsonBody(jsonBody); + + await _api.Request(request); + } + } +} diff --git a/src/Ombi.Api.Gotify/IGotifyApi.cs b/src/Ombi.Api.Gotify/IGotifyApi.cs new file mode 100644 index 000000000..e6a6b4060 --- /dev/null +++ b/src/Ombi.Api.Gotify/IGotifyApi.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Ombi.Api.Gotify +{ + public interface IGotifyApi + { + Task PushAsync(string endpoint, string accessToken, string subject, string body, sbyte priority); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj b/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj new file mode 100644 index 000000000..ce5475fae --- /dev/null +++ b/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + 3.0.0.0 + 3.0.0.0 + + + + + + + + + diff --git a/src/Ombi.Core/Models/UI/GotifyNotificationViewModel.cs b/src/Ombi.Core/Models/UI/GotifyNotificationViewModel.cs new file mode 100644 index 000000000..93ce66724 --- /dev/null +++ b/src/Ombi.Core/Models/UI/GotifyNotificationViewModel.cs @@ -0,0 +1,23 @@ + +using System.Collections.Generic; +using Ombi.Settings.Settings.Models.Notifications; +using Ombi.Store.Entities; + +namespace Ombi.Core.Models.UI +{ + /// + /// The view model for the notification settings page + /// + /// + public class GotifyNotificationViewModel : GotifySettings + { + /// + /// Gets or sets the notification templates. + /// + /// + /// The notification templates. + /// + public List NotificationTemplates { get; set; } + + } +} diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 68a363706..69e6bd3ca 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -32,6 +32,7 @@ using Ombi.Api.CouchPotato; using Ombi.Api.DogNzb; using Ombi.Api.FanartTv; using Ombi.Api.Github; +using Ombi.Api.Gotify; using Ombi.Api.Lidarr; using Ombi.Api.Mattermost; using Ombi.Api.Notifications; @@ -120,6 +121,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); @@ -170,6 +172,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.Helpers/LoggingEvents.cs b/src/Ombi.Helpers/LoggingEvents.cs index 3893dc879..0723800ab 100644 --- a/src/Ombi.Helpers/LoggingEvents.cs +++ b/src/Ombi.Helpers/LoggingEvents.cs @@ -32,6 +32,7 @@ namespace Ombi.Helpers public static EventId MattermostNotification => new EventId(4004); public static EventId PushoverNotification => new EventId(4005); public static EventId TelegramNotifcation => new EventId(4006); + public static EventId GotifyNotification => new EventId(4007); public static EventId TvSender => new EventId(5000); public static EventId SonarrSender => new EventId(5001); diff --git a/src/Ombi.Helpers/NotificationAgent.cs b/src/Ombi.Helpers/NotificationAgent.cs index 8990eeba9..18f28105a 100644 --- a/src/Ombi.Helpers/NotificationAgent.cs +++ b/src/Ombi.Helpers/NotificationAgent.cs @@ -10,5 +10,6 @@ Slack = 5, Mattermost = 6, Mobile = 7, + Gotify = 8, } } \ No newline at end of file diff --git a/src/Ombi.Mapping/Profiles/SettingsProfile.cs b/src/Ombi.Mapping/Profiles/SettingsProfile.cs index 139290f2b..f460ce78b 100644 --- a/src/Ombi.Mapping/Profiles/SettingsProfile.cs +++ b/src/Ombi.Mapping/Profiles/SettingsProfile.cs @@ -19,6 +19,7 @@ namespace Ombi.Mapping.Profiles CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } } \ No newline at end of file diff --git a/src/Ombi.Notifications/Agents/GotifyNotification.cs b/src/Ombi.Notifications/Agents/GotifyNotification.cs new file mode 100644 index 000000000..e1c9fc1db --- /dev/null +++ b/src/Ombi.Notifications/Agents/GotifyNotification.cs @@ -0,0 +1,116 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Ombi.Api.Gotify; +using Ombi.Core.Settings; +using Ombi.Helpers; +using Ombi.Notifications.Models; +using Ombi.Settings.Settings.Models; +using Ombi.Settings.Settings.Models.Notifications; +using Ombi.Store.Entities; +using Ombi.Store.Repository; +using Ombi.Store.Repository.Requests; + +namespace Ombi.Notifications.Agents +{ + public class GotifyNotification : BaseNotification, IGotifyNotification + { + public GotifyNotification(IGotifyApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, + ISettingsService s, IRepository sub, IMusicRequestRepository music, + IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + { + Api = api; + Logger = log; + } + + public override string NotificationName => "GotifyNotification"; + + private IGotifyApi Api { get; } + private ILogger Logger { get; } + + protected override bool ValidateConfiguration(GotifySettings settings) + { + return settings.Enabled && !string.IsNullOrEmpty(settings.BaseUrl) && !string.IsNullOrEmpty(settings.ApplicationToken); + } + + protected override async Task NewRequest(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.NewRequest); + } + + + protected override async Task NewIssue(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.Issue); + } + + protected override async Task IssueComment(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.IssueComment); + } + + protected override async Task IssueResolved(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.IssueResolved); + } + + protected override async Task AddedToRequestQueue(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.ItemAddedToFaultQueue); + } + + protected override async Task RequestDeclined(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.RequestDeclined); + } + + protected override async Task RequestApproved(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.RequestApproved); + } + + protected override async Task AvailableRequest(NotificationOptions model, GotifySettings settings) + { + await Run(model, settings, NotificationType.RequestAvailable); + } + + protected override async Task Send(NotificationMessage model, GotifySettings settings) + { + try + { + await Api.PushAsync(settings.BaseUrl, settings.ApplicationToken, model.Subject, model.Message, settings.Priority); + } + catch (Exception e) + { + Logger.LogError(LoggingEvents.GotifyNotification, e, "Failed to send Gotify notification"); + } + } + + protected override async Task Test(NotificationOptions model, GotifySettings settings) + { + var message = $"This is a test from Ombi, if you can see this then we have successfully pushed a notification!"; + var notification = new NotificationMessage + { + Message = message, + }; + await Send(notification, settings); + } + + private async Task Run(NotificationOptions model, GotifySettings settings, NotificationType type) + { + var parsed = await LoadTemplate(NotificationAgent.Gotify, type, model); + if (parsed.Disabled) + { + Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Gotify}"); + return; + } + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + await Send(notification, settings); + } + } +} diff --git a/src/Ombi.Notifications/Agents/Interfaces/IGotifyNotification.cs b/src/Ombi.Notifications/Agents/Interfaces/IGotifyNotification.cs new file mode 100644 index 000000000..a85421938 --- /dev/null +++ b/src/Ombi.Notifications/Agents/Interfaces/IGotifyNotification.cs @@ -0,0 +1,6 @@ +namespace Ombi.Notifications.Agents +{ + public interface IGotifyNotification : INotification + { + } +} \ No newline at end of file diff --git a/src/Ombi.Notifications/Ombi.Notifications.csproj b/src/Ombi.Notifications/Ombi.Notifications.csproj index 2b5c95154..3fa4b4830 100644 --- a/src/Ombi.Notifications/Ombi.Notifications.csproj +++ b/src/Ombi.Notifications/Ombi.Notifications.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Ombi.Settings/Settings/Models/Notifications/GotifySettings.cs b/src/Ombi.Settings/Settings/Models/Notifications/GotifySettings.cs new file mode 100644 index 000000000..f0325b0f2 --- /dev/null +++ b/src/Ombi.Settings/Settings/Models/Notifications/GotifySettings.cs @@ -0,0 +1,10 @@ +namespace Ombi.Settings.Settings.Models.Notifications +{ + public class GotifySettings : Settings + { + public bool Enabled { get; set; } + public string BaseUrl { get; set; } + public string ApplicationToken { get; set; } + public sbyte Priority { get; set; } = 4; + } +} \ No newline at end of file diff --git a/src/Ombi.sln b/src/Ombi.sln index 2b9be2c42..f4f683c11 100644 --- a/src/Ombi.sln +++ b/src/Ombi.sln @@ -96,7 +96,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Notifications", "O EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Lidarr", "Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj", "{4FA21A20-92F4-462C-B929-2C517A88CC56}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Helpers.Tests", "Ombi.Helpers.Tests\Ombi.Helpers.Tests.csproj", "{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Helpers.Tests", "Ombi.Helpers.Tests\Ombi.Helpers.Tests.csproj", "{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Gotify", "Ombi.Api.Gotify\Ombi.Api.Gotify.csproj", "{105EA346-766E-45B8-928B-DE6991DCB7EB}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -256,6 +258,10 @@ Global {CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.Build.0 = Release|Any CPU + {105EA346-766E-45B8-928B-DE6991DCB7EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {105EA346-766E-45B8-928B-DE6991DCB7EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {105EA346-766E-45B8-928B-DE6991DCB7EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {105EA346-766E-45B8-928B-DE6991DCB7EB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -293,6 +299,7 @@ Global {10D1FE9D-9124-42B7-B1E1-CEB99B832618} = {9293CA11-360A-4C20-A674-B9E794431BF5} {4FA21A20-92F4-462C-B929-2C517A88CC56} = {9293CA11-360A-4C20-A674-B9E794431BF5} {CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3} = {6F42AB98-9196-44C4-B888-D5E409F415A1} + {105EA346-766E-45B8-928B-DE6991DCB7EB} = {9293CA11-360A-4C20-A674-B9E794431BF5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869} diff --git a/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts b/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts index f368ee035..5472a6c7c 100644 --- a/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts +++ b/src/Ombi/ClientApp/app/interfaces/INotificationSettings.ts @@ -93,6 +93,14 @@ export interface IPushoverNotificationSettings extends INotificationSettings { sound: string; } +export interface IGotifyNotificationSettings extends INotificationSettings { + accessToken: string; + notificationTemplates: INotificationTemplates[]; + baseUrl: string; + applicationToken: string; + priority: number; +} + export interface IMattermostNotifcationSettings extends INotificationSettings { webhookUrl: string; username: string; diff --git a/src/Ombi/ClientApp/app/services/applications/tester.service.ts b/src/Ombi/ClientApp/app/services/applications/tester.service.ts index e692b9196..af619d583 100644 --- a/src/Ombi/ClientApp/app/services/applications/tester.service.ts +++ b/src/Ombi/ClientApp/app/services/applications/tester.service.ts @@ -11,6 +11,7 @@ import { IDiscordNotifcationSettings, IEmailNotificationSettings, IEmbyServer, + IGotifyNotificationSettings, ILidarrSettings, IMattermostNotifcationSettings, IMobileNotificationTestSettings, @@ -40,7 +41,11 @@ export class TesterService extends ServiceHelpers { } public pushoverTest(settings: IPushoverNotificationSettings): Observable { - return this.http.post(`${this.url}pushover`, JSON.stringify(settings), {headers: this.headers}); + return this.http.post(`${this.url}pushover`, JSON.stringify(settings), { headers: this.headers }); + } + + public gotifyTest(settings: IGotifyNotificationSettings): Observable { + return this.http.post(`${this.url}gotify`, JSON.stringify(settings), { headers: this.headers }); } public mattermostTest(settings: IMattermostNotifcationSettings): Observable { diff --git a/src/Ombi/ClientApp/app/services/settings.service.ts b/src/Ombi/ClientApp/app/services/settings.service.ts index 64a6edd14..a80cfd772 100644 --- a/src/Ombi/ClientApp/app/services/settings.service.ts +++ b/src/Ombi/ClientApp/app/services/settings.service.ts @@ -14,6 +14,7 @@ import { IDogNzbSettings, IEmailNotificationSettings, IEmbySettings, + IGotifyNotificationSettings, IIssueSettings, IJobSettings, IJobSettingsViewModel, @@ -182,6 +183,14 @@ export class SettingsService extends ServiceHelpers { .post(`${this.url}/notifications/pushover`, JSON.stringify(settings), {headers: this.headers}); } + public getGotifyNotificationSettings(): Observable { + return this.http.get(`${this.url}/notifications/gotify`, { headers: this.headers }); + } + public saveGotifyNotificationSettings(settings: IGotifyNotificationSettings): Observable { + return this.http + .post(`${this.url}/notifications/gotify`, JSON.stringify(settings), { headers: this.headers }); + } + public getSlackNotificationSettings(): Observable { return this.http.get(`${this.url}/notifications/slack`, {headers: this.headers}); } diff --git a/src/Ombi/ClientApp/app/settings/notifications/gotify.component.html b/src/Ombi/ClientApp/app/settings/notifications/gotify.component.html new file mode 100644 index 000000000..9148cb880 --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/gotify.component.html @@ -0,0 +1,67 @@ + + +
+
+ Gotify Notifications +
+
+ +
+
+ + +
+
+ +
+ + + + The Base URL is required +
+ +
+ + + + The Application Token is required +
+ +
+ +
+ +
+
+ + +
+
+ +
+
+ + + +
+
+ +
+
+
+
+ + +
+ +
+
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/gotify.component.ts b/src/Ombi/ClientApp/app/settings/notifications/gotify.component.ts new file mode 100644 index 000000000..f6c08d41b --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/gotify.component.ts @@ -0,0 +1,68 @@ +import { Component, OnInit } from "@angular/core"; +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; + +import { IGotifyNotificationSettings, INotificationTemplates, NotificationType } from "../../interfaces"; +import { TesterService } from "../../services"; +import { NotificationService } from "../../services"; +import { SettingsService } from "../../services"; + +@Component({ + templateUrl: "./gotify.component.html", +}) +export class GotifyComponent implements OnInit { + public NotificationType = NotificationType; + public templates: INotificationTemplates[]; + public form: FormGroup; + + constructor(private settingsService: SettingsService, + private notificationService: NotificationService, + private fb: FormBuilder, + private testerService: TesterService) { } + + public ngOnInit() { + this.settingsService.getGotifyNotificationSettings().subscribe(x => { + this.templates = x.notificationTemplates; + + this.form = this.fb.group({ + enabled: [x.enabled], + baseUrl: [x.baseUrl, [Validators.required]], + applicationToken: [x.applicationToken, [Validators.required]], + priority: [x.priority], + }); + }); + } + + public onSubmit(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Please check your entered values"); + return; + } + + const settings = form.value; + settings.notificationTemplates = this.templates; + + this.settingsService.saveGotifyNotificationSettings(settings).subscribe(x => { + if (x) { + this.notificationService.success("Successfully saved the Gotify settings"); + } else { + this.notificationService.success("There was an error when saving the Gotify settings"); + } + }); + + } + + public test(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Please check your entered values"); + return; + } + + this.testerService.gotifyTest(form.value).subscribe(x => { + if (x) { + this.notificationService.success("Successfully sent a Gotify message"); + } else { + this.notificationService.error("There was an error when sending the Gotify message. Please check your settings"); + } + }); + } +} diff --git a/src/Ombi/ClientApp/app/settings/settings.module.ts b/src/Ombi/ClientApp/app/settings/settings.module.ts index fb1a10abe..6fb69dc27 100644 --- a/src/Ombi/ClientApp/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/app/settings/settings.module.ts @@ -27,6 +27,7 @@ import { LidarrComponent } from "./lidarr/lidarr.component"; import { MassEmailComponent } from "./massemail/massemail.component"; import { DiscordComponent } from "./notifications/discord.component"; import { EmailNotificationComponent } from "./notifications/emailnotification.component"; +import { GotifyComponent } from "./notifications/gotify.component"; import { MattermostComponent } from "./notifications/mattermost.component"; import { MobileComponent } from "./notifications/mobile.component"; import { NewsletterComponent } from "./notifications/newsletter.component"; @@ -63,6 +64,7 @@ const routes: Routes = [ { path: "Slack", component: SlackComponent, canActivate: [AuthGuard] }, { path: "Pushover", component: PushoverComponent, canActivate: [AuthGuard] }, { path: "Pushbullet", component: PushbulletComponent, canActivate: [AuthGuard] }, + { path: "Gotify", component: GotifyComponent, canActivate: [AuthGuard] }, { path: "Mattermost", component: MattermostComponent, canActivate: [AuthGuard] }, { path: "UserManagement", component: UserManagementComponent, canActivate: [AuthGuard] }, { path: "Update", component: UpdateComponent, canActivate: [AuthGuard] }, @@ -117,6 +119,7 @@ const routes: Routes = [ PushoverComponent, MattermostComponent, PushbulletComponent, + GotifyComponent, UserManagementComponent, UpdateComponent, AboutComponent, diff --git a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html index 91405d1c5..81f901ecc 100644 --- a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html @@ -74,6 +74,7 @@
  • Pushover
  • Mattermost
  • Telegram
  • +
  • Gotify
  • diff --git a/src/Ombi/Controllers/External/TesterController.cs b/src/Ombi/Controllers/External/TesterController.cs index 5e3156bde..2894542f6 100644 --- a/src/Ombi/Controllers/External/TesterController.cs +++ b/src/Ombi/Controllers/External/TesterController.cs @@ -40,7 +40,7 @@ namespace Ombi.Controllers.External IPushbulletNotification pushbullet, ISlackNotification slack, IPushoverNotification po, IMattermostNotification mm, IPlexApi plex, IEmbyApi emby, IRadarrApi radarr, ISonarrApi sonarr, ILogger log, IEmailProvider provider, ICouchPotatoApi cpApi, ITelegramNotification telegram, ISickRageApi srApi, INewsletterJob newsletter, IMobileNotification mobileNotification, - ILidarrApi lidarrApi) + ILidarrApi lidarrApi, IGotifyNotification gotifyNotification) { Service = service; DiscordNotification = notification; @@ -61,6 +61,7 @@ namespace Ombi.Controllers.External Newsletter = newsletter; MobileNotification = mobileNotification; LidarrApi = lidarrApi; + GotifyNotification = gotifyNotification; } private INotificationService Service { get; } @@ -69,6 +70,7 @@ namespace Ombi.Controllers.External private IPushbulletNotification PushbulletNotification { get; } private ISlackNotification SlackNotification { get; } private IPushoverNotification PushoverNotification { get; } + private IGotifyNotification GotifyNotification { get; } private IMattermostNotification MattermostNotification { get; } private IPlexApi PlexApi { get; } private IRadarrApi RadarrApi { get; } @@ -155,6 +157,30 @@ namespace Ombi.Controllers.External } + /// + /// Sends a test message to Gotify using the provided settings + /// + /// The settings. + /// + [HttpPost("gotify")] + public bool Gotify([FromBody] GotifySettings settings) + { + try + { + settings.Enabled = true; + GotifyNotification.NotifyAsync( + new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); + + return true; + } + catch (Exception e) + { + Log.LogError(LoggingEvents.Api, e, "Could not test Gotify"); + return false; + } + + } + /// /// Sends a test message to mattermost using the provided settings /// diff --git a/src/Ombi/Controllers/SettingsController.cs b/src/Ombi/Controllers/SettingsController.cs index b5ec57e29..823461e35 100644 --- a/src/Ombi/Controllers/SettingsController.cs +++ b/src/Ombi/Controllers/SettingsController.cs @@ -947,6 +947,40 @@ namespace Ombi.Controllers return model; } + /// + /// Saves the gotify notification settings. + /// + /// The model. + /// + [HttpPost("notifications/gotify")] + public async Task GotifyNotificationSettings([FromBody] GotifyNotificationViewModel model) + { + // Save the email settings + var settings = Mapper.Map(model); + var result = await Save(settings); + + // Save the templates + await TemplateRepository.UpdateRange(model.NotificationTemplates); + + return result; + } + + /// + /// Gets the gotify Notification Settings. + /// + /// + [HttpGet("notifications/gotify")] + public async Task GotifyNotificationSettings() + { + var settings = await Get(); + var model = Mapper.Map(settings); + + // Lookup to see if we have any templates saved + model.NotificationTemplates = BuildTemplates(NotificationAgent.Gotify); + + return model; + } + /// /// Saves the Newsletter notification settings. /// From 41d96238975b663a92664507ef62d09e153ece74 Mon Sep 17 00:00:00 2001 From: Guillaume Taquet Gasperini Date: Wed, 20 Mar 2019 19:57:21 +0100 Subject: [PATCH 25/58] Fix cake build by setting Incubator version --- build.cake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.cake b/build.cake index e8e4bb8c0..c25447906 100644 --- a/build.cake +++ b/build.cake @@ -3,7 +3,7 @@ #addin "Cake.Gulp" #addin "SharpZipLib" #addin nuget:?package=Cake.Compression&version=0.1.4 -#addin "Cake.Incubator" +#addin "Cake.Incubator&version=3.1.0" #addin "Cake.Yarn" ////////////////////////////////////////////////////////////////////// From 4920ac3da0ce947f522e8ec01b283e608f6f88ec Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 21 Mar 2019 15:33:10 +0000 Subject: [PATCH 26/58] Take out the lastlogindate update for now #2750 --- src/Ombi/Controllers/TokenController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/Controllers/TokenController.cs b/src/Ombi/Controllers/TokenController.cs index 44ec5686f..6604c6dbb 100644 --- a/src/Ombi/Controllers/TokenController.cs +++ b/src/Ombi/Controllers/TokenController.cs @@ -124,7 +124,7 @@ namespace Ombi.Controllers } user.LastLoggedIn = DateTime.UtcNow; - await _userManager.UpdateAsync(user); + //await _userManager.UpdateAsync(user); var claims = new List { From 826517cbfff0db35ee51ab858cab5a8f198d9d10 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Thu, 21 Mar 2019 15:34:22 +0000 Subject: [PATCH 27/58] !wip --- src/Ombi/Controllers/TokenController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/Controllers/TokenController.cs b/src/Ombi/Controllers/TokenController.cs index 9499dd493..9f9747f0e 100644 --- a/src/Ombi/Controllers/TokenController.cs +++ b/src/Ombi/Controllers/TokenController.cs @@ -150,7 +150,7 @@ namespace Ombi.Controllers } user.LastLoggedIn = DateTime.UtcNow; - await GlobalMutex.Lock(async () => await _userManager.UpdateAsync(user)).ConfigureAwait(false); + //await GlobalMutex.Lock(async () => await _userManager.UpdateAsync(user)).ConfigureAwait(false); return new JsonResult(new { From cf9bb889edaf4afa34c4504808432b07ca061672 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Fri, 22 Mar 2019 22:31:11 +0000 Subject: [PATCH 28/58] Fixed the issue where it was not picking up roles until the JWT was refreshed --- .../Rule/Request/CanRequestRuleTests.cs | 1 + .../Rule/Rules/Request/AutoApproveRule.cs | 21 +++++++----- .../Rule/Rules/Request/CanRequestRule.cs | 34 +++++++++++-------- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs index c9db5875a..69b6a76df 100644 --- a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using Moq; using NUnit.Framework; using Ombi.Core.Rule.Rules; +using Ombi.Core.Rule.Rules.Request; using Ombi.Helpers; using Ombi.Store.Entities.Requests; diff --git a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs index a55868db8..685f02b54 100644 --- a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs @@ -1,5 +1,7 @@ using System.Security.Principal; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Authentication; using Ombi.Core.Models.Requests; using Ombi.Core.Rule.Interfaces; using Ombi.Helpers; @@ -10,28 +12,31 @@ namespace Ombi.Core.Rule.Rules.Request { public class AutoApproveRule : BaseRequestRule, IRules { - public AutoApproveRule(IPrincipal principal) + public AutoApproveRule(IPrincipal principal, OmbiUserManager um) { User = principal; + _manager = um; } private IPrincipal User { get; } + private readonly OmbiUserManager _manager; - public Task Execute(BaseRequest obj) + public async Task Execute(BaseRequest obj) { - if (User.IsInRole(OmbiRoles.Admin)) + var user = await _manager.Users.FirstOrDefaultAsync(x => x.UserName == User.Identity.Name); + if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin)) { obj.Approved = true; - return Task.FromResult(Success()); + return Success(); } - if (obj.RequestType == RequestType.Movie && User.IsInRole(OmbiRoles.AutoApproveMovie)) + if (obj.RequestType == RequestType.Movie && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie)) obj.Approved = true; - if (obj.RequestType == RequestType.TvShow && User.IsInRole(OmbiRoles.AutoApproveTv)) + if (obj.RequestType == RequestType.TvShow && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveTv)) obj.Approved = true; - if (obj.RequestType == RequestType.Album && User.IsInRole(OmbiRoles.AutoApproveMusic)) + if (obj.RequestType == RequestType.Album && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMusic)) obj.Approved = true; - return Task.FromResult(Success()); // We don't really care, we just don't set the obj to approve + return Success(); // We don't really care, we just don't set the obj to approve } } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs index 1cdf03955..a2c70fcc5 100644 --- a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs @@ -1,46 +1,52 @@ -using Ombi.Store.Entities; +using System.Security.Claims; using System.Security.Principal; using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Authentication; using Ombi.Core.Rule.Interfaces; using Ombi.Helpers; +using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; -namespace Ombi.Core.Rule.Rules +namespace Ombi.Core.Rule.Rules.Request { public class CanRequestRule : BaseRequestRule, IRules { - public CanRequestRule(IPrincipal principal) + public CanRequestRule(IPrincipal principal, OmbiUserManager manager) { User = principal; + _manager = manager; } private IPrincipal User { get; } + private readonly OmbiUserManager _manager; - public Task Execute(BaseRequest obj) + public async Task Execute(BaseRequest obj) { - if (User.IsInRole(OmbiRoles.Admin)) - return Task.FromResult(Success()); + var user = await _manager.Users.FirstOrDefaultAsync(x => x.UserName == User.Identity.Name); + if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin)) + return Success(); if (obj.RequestType == RequestType.Movie) { - if (User.IsInRole(OmbiRoles.RequestMovie) || User.IsInRole(OmbiRoles.AutoApproveMovie)) - return Task.FromResult(Success()); - return Task.FromResult(Fail("You do not have permissions to Request a Movie")); + if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMovie) || await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie)) + return Success(); + return Fail("You do not have permissions to Request a Movie"); } if (obj.RequestType == RequestType.TvShow) { - if (User.IsInRole(OmbiRoles.RequestTv) || User.IsInRole(OmbiRoles.AutoApproveTv)) - return Task.FromResult(Success()); + if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestTv) || await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveTv)) + return Success(); } if (obj.RequestType == RequestType.Album) { - if (User.IsInRole(OmbiRoles.RequestMusic) || User.IsInRole(OmbiRoles.AutoApproveMusic)) - return Task.FromResult(Success()); + if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMusic) || await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMusic)) + return Success(); } - return Task.FromResult(Fail("You do not have permissions to Request a TV Show")); + return Fail("You do not have permissions to Request a TV Show"); } } } \ No newline at end of file From 89e275df744ded175fec2492e1282c8045ccc563 Mon Sep 17 00:00:00 2001 From: Jamie Date: Sat, 23 Mar 2019 00:08:04 +0000 Subject: [PATCH 29/58] Update JobSetup.cs --- src/Ombi.Schedule/JobSetup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi.Schedule/JobSetup.cs b/src/Ombi.Schedule/JobSetup.cs index 38686396f..811f5ca42 100644 --- a/src/Ombi.Schedule/JobSetup.cs +++ b/src/Ombi.Schedule/JobSetup.cs @@ -81,7 +81,7 @@ namespace Ombi.Schedule RecurringJob.AddOrUpdate(() => _embyUserImporter.Start(), JobSettingsHelper.UserImporter(s)); RecurringJob.AddOrUpdate(() => _plexUserImporter.Start(), JobSettingsHelper.UserImporter(s)); RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s)); - RecurringJob.AddOrUpdate(() => _resender.Start(), JobSettingsHelper.ResendFailedRequests(s)); + // RecurringJob.AddOrUpdate(() => _resender.Start(), JobSettingsHelper.ResendFailedRequests(s)); RecurringJob.AddOrUpdate(() => _mediaDatabaseRefresh.Start(), JobSettingsHelper.MediaDatabaseRefresh(s)); } From 775e18e2d3e6efc163ce65630aeb5e830df1d08d Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Mon, 25 Mar 2019 08:25:18 +0000 Subject: [PATCH 30/58] Fixed #2803 in regards to the Request Button showing up. Still need to investiagte the availability side of things --- src/Ombi/ClientApp/app/search/music/albumsearch.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ombi/ClientApp/app/search/music/albumsearch.component.html b/src/Ombi/ClientApp/app/search/music/albumsearch.component.html index 8f2fe73ce..2b31df040 100644 --- a/src/Ombi/ClientApp/app/search/music/albumsearch.component.html +++ b/src/Ombi/ClientApp/app/search/music/albumsearch.component.html @@ -80,7 +80,7 @@ {{ 'Common.Available' | translate }}
    -
    +
    From 42662924d94097fdd76fa83c09d1b2f30f69e7f2 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Mon, 25 Mar 2019 08:31:31 +0000 Subject: [PATCH 31/58] Removed the auditing, was not used anyway #2750 --- src/Ombi.Core/Engine/TvRequestEngine.cs | 16 +++------ src/Ombi/package-lock.json | 47 ++++++++----------------- 2 files changed, 18 insertions(+), 45 deletions(-) diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index 58144d3ce..1cb0ad65a 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -31,14 +31,13 @@ namespace Ombi.Core.Engine { public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, IPrincipal user, INotificationHelper helper, IRuleEvaluator rule, OmbiUserManager manager, - ITvSender sender, IAuditRepository audit, IRepository rl, ISettingsService settings, ICacheService cache, + ITvSender sender, IRepository rl, ISettingsService settings, ICacheService cache, IRepository sub) : base(user, requestService, rule, manager, cache, settings, sub) { TvApi = tvApi; MovieDbApi = movApi; NotificationHelper = helper; TvSender = sender; - Audit = audit; _requestLog = rl; } @@ -46,7 +45,6 @@ namespace Ombi.Core.Engine private ITvMazeApi TvApi { get; } private IMovieDbApi MovieDbApi { get; } private ITvSender TvSender { get; } - private IAuditRepository Audit { get; } private readonly IRepository _requestLog; public async Task RequestTvShow(TvRequestViewModel tv) @@ -351,7 +349,6 @@ namespace Ombi.Core.Engine public async Task UpdateTvRequest(TvRequests request) { - await Audit.Record(AuditType.Updated, AuditArea.TvRequest, $"Updated Request {request.Title}", Username); var allRequests = TvRepository.Get(); var results = await allRequests.FirstOrDefaultAsync(x => x.Id == request.Id); @@ -394,7 +391,6 @@ namespace Ombi.Core.Engine if (request.Approved) { NotificationHelper.Notify(request, NotificationType.RequestApproved); - await Audit.Record(AuditType.Approved, AuditArea.TvRequest, $"Approved Request {request.Title}", Username); // Autosend await TvSender.Send(request); } @@ -426,9 +422,7 @@ namespace Ombi.Core.Engine public async Task UpdateChildRequest(ChildRequests request) { - await Audit.Record(AuditType.Updated, AuditArea.TvRequest, $"Updated Request {request.Title}", Username); - - await TvRepository.UpdateChild(request); + await TvRepository.UpdateChild(request); return request; } @@ -446,16 +440,14 @@ namespace Ombi.Core.Engine // Delete the parent TvRepository.Db.TvRequests.Remove(parent); } - await Audit.Record(AuditType.Deleted, AuditArea.TvRequest, $"Deleting Request {request.Title}", Username); - + await TvRepository.Db.SaveChangesAsync(); } public async Task RemoveTvRequest(int requestId) { var request = await TvRepository.Get().FirstOrDefaultAsync(x => x.Id == requestId); - await Audit.Record(AuditType.Deleted, AuditArea.TvRequest, $"Deleting Request {request.Title}", Username); - await TvRepository.Delete(request); + await TvRepository.Delete(request); } public async Task UserHasRequest(string userId) diff --git a/src/Ombi/package-lock.json b/src/Ombi/package-lock.json index 4ad391ab8..fff834922 100644 --- a/src/Ombi/package-lock.json +++ b/src/Ombi/package-lock.json @@ -1766,9 +1766,9 @@ } }, "bootstrap": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.0.tgz", - "integrity": "sha512-F1yTDO9OHKH0xjl03DsOe8Nu1OWBIeAugGMhy3UTIYDdbbIPesQIhCEbj+HEr6wqlwweGAlP8F3OBC6kEuhFuw==" + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", + "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==" }, "bootswatch": { "version": "3.4.0", @@ -4190,8 +4190,7 @@ }, "ansi-regex": { "version": "2.1.1", - "bundled": true, - "optional": true + "bundled": true }, "aproba": { "version": "1.2.0", @@ -4209,13 +4208,11 @@ }, "balanced-match": { "version": "1.0.0", - "bundled": true, - "optional": true + "bundled": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4228,18 +4225,15 @@ }, "code-point-at": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "concat-map": { "version": "0.0.1", - "bundled": true, - "optional": true + "bundled": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, - "optional": true + "bundled": true }, "core-util-is": { "version": "1.0.2", @@ -4342,8 +4336,7 @@ }, "inherits": { "version": "2.0.3", - "bundled": true, - "optional": true + "bundled": true }, "ini": { "version": "1.3.5", @@ -4353,7 +4346,6 @@ "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4366,20 +4358,17 @@ "minimatch": { "version": "3.0.4", "bundled": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "bundled": true, - "optional": true + "bundled": true }, "minipass": { "version": "2.3.5", "bundled": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4396,7 +4385,6 @@ "mkdirp": { "version": "0.5.1", "bundled": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -4469,8 +4457,7 @@ }, "number-is-nan": { "version": "1.0.1", - "bundled": true, - "optional": true + "bundled": true }, "object-assign": { "version": "4.1.1", @@ -4480,7 +4467,6 @@ "once": { "version": "1.4.0", "bundled": true, - "optional": true, "requires": { "wrappy": "1" } @@ -4556,8 +4542,7 @@ }, "safe-buffer": { "version": "5.1.2", - "bundled": true, - "optional": true + "bundled": true }, "safer-buffer": { "version": "2.1.2", @@ -4587,7 +4572,6 @@ "string-width": { "version": "1.0.2", "bundled": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4605,7 +4589,6 @@ "strip-ansi": { "version": "3.0.1", "bundled": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -4644,13 +4627,11 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "optional": true + "bundled": true }, "yallist": { "version": "3.0.3", - "bundled": true, - "optional": true + "bundled": true } } }, From e6e24c6a97447ca2a8762eaee4c24539395183ff Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Mon, 25 Mar 2019 08:41:15 +0000 Subject: [PATCH 32/58] More for #2750 --- src/Ombi.Store/Repository/BaseRepository.cs | 2 +- .../Repository/EmbyContentRepository.cs | 7 +++--- .../NotificationTemplatesRepository.cs | 11 +++++++--- .../Repository/PlexContentRepository.cs | 10 ++++----- .../Requests/MovieRequestRepository.cs | 10 +++++++-- .../Requests/MusicRequestRepository.cs | 9 ++++++-- .../Requests/TvRequestRepository.cs | 22 ++++++++++++------- .../Repository/SettingsJsonRepository.cs | 9 ++++++-- src/Ombi.Store/Repository/TokenRepository.cs | 7 +++++- 9 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/Ombi.Store/Repository/BaseRepository.cs b/src/Ombi.Store/Repository/BaseRepository.cs index ca2937291..1ca78ee50 100644 --- a/src/Ombi.Store/Repository/BaseRepository.cs +++ b/src/Ombi.Store/Repository/BaseRepository.cs @@ -81,7 +81,7 @@ namespace Ombi.Store.Repository await _ctx.Database.ExecuteSqlCommandAsync(sql); } - private async Task InternalSaveChanges() + protected async Task InternalSaveChanges() { return await GlobalMutex.Lock(async () => await _ctx.SaveChangesAsync()); } diff --git a/src/Ombi.Store/Repository/EmbyContentRepository.cs b/src/Ombi.Store/Repository/EmbyContentRepository.cs index 4d32e8da2..2ada709ab 100644 --- a/src/Ombi.Store/Repository/EmbyContentRepository.cs +++ b/src/Ombi.Store/Repository/EmbyContentRepository.cs @@ -72,7 +72,7 @@ namespace Ombi.Store.Repository public async Task Update(EmbyContent existingContent) { Db.EmbyContent.Update(existingContent); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public IQueryable GetAllEpisodes() @@ -83,7 +83,7 @@ namespace Ombi.Store.Repository public async Task Add(EmbyEpisode content) { await Db.EmbyEpisode.AddAsync(content); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); return content; } public async Task GetEpisodeByEmbyId(string key) @@ -94,12 +94,13 @@ namespace Ombi.Store.Repository public async Task AddRange(IEnumerable content) { Db.EmbyEpisode.AddRange(content); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public void UpdateWithoutSave(EmbyContent existingContent) { Db.EmbyContent.Update(existingContent); } + } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs b/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs index 175d0e6a9..eb4816d50 100644 --- a/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs +++ b/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs @@ -45,7 +45,7 @@ namespace Ombi.Store.Repository Db.Attach(template); Db.Entry(template).State = EntityState.Modified; } - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task UpdateRange(IEnumerable templates) @@ -56,16 +56,21 @@ namespace Ombi.Store.Repository Db.Attach(t); Db.Entry(t).State = EntityState.Modified; } - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task Insert(NotificationTemplates entity) { var settings = await Db.NotificationTemplates.AddAsync(entity).ConfigureAwait(false); - await Db.SaveChangesAsync().ConfigureAwait(false); + await InternalSaveChanges().ConfigureAwait(false); return settings.Entity; } + private async Task InternalSaveChanges() + { + return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); + } + private bool _disposed; // Protected implementation of Dispose pattern. protected virtual void Dispose(bool disposing) diff --git a/src/Ombi.Store/Repository/PlexContentRepository.cs b/src/Ombi.Store/Repository/PlexContentRepository.cs index 2c9c28d09..37275a47c 100644 --- a/src/Ombi.Store/Repository/PlexContentRepository.cs +++ b/src/Ombi.Store/Repository/PlexContentRepository.cs @@ -96,7 +96,7 @@ namespace Ombi.Store.Repository public async Task Update(PlexServerContent existingContent) { Db.PlexServerContent.Update(existingContent); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public void UpdateWithoutSave(PlexServerContent existingContent) { @@ -106,7 +106,7 @@ namespace Ombi.Store.Repository public async Task UpdateRange(IEnumerable existingContent) { Db.PlexServerContent.UpdateRange(existingContent); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public IQueryable GetAllEpisodes() @@ -127,14 +127,14 @@ namespace Ombi.Store.Repository public async Task Add(PlexEpisode content) { await Db.PlexEpisode.AddAsync(content); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); return content; } public async Task DeleteEpisode(PlexEpisode content) { Db.PlexEpisode.Remove(content); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task GetEpisodeByKey(int key) @@ -144,7 +144,7 @@ namespace Ombi.Store.Repository public async Task AddRange(IEnumerable content) { Db.PlexEpisode.AddRange(content); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs b/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs index d4a550528..d96363d29 100644 --- a/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Entities.Requests; @@ -70,12 +71,17 @@ namespace Ombi.Store.Repository.Requests Db.MovieRequests.Attach(request); Db.Update(request); } - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task Save() { - await Db.SaveChangesAsync(); + await InternalSaveChanges(); + } + + private async Task InternalSaveChanges() + { + return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs b/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs index 59edf265a..5179513d2 100644 --- a/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Entities.Requests; @@ -61,12 +62,16 @@ namespace Ombi.Store.Repository.Requests Db.AlbumRequests.Attach(request); Db.Update(request); } - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task Save() { - await Db.SaveChangesAsync(); + await InternalSaveChanges(); + } + private async Task InternalSaveChanges() + { + return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs index daac7d4df..d3486358a 100644 --- a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Ombi.Helpers; using Ombi.Store.Context; using Ombi.Store.Entities.Requests; @@ -101,20 +102,20 @@ namespace Ombi.Store.Repository.Requests public async Task Save() { - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task Add(TvRequests request) { await Db.TvRequests.AddAsync(request); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); return request; } public async Task AddChild(ChildRequests request) { await Db.ChildRequests.AddAsync(request); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); return request; } @@ -122,33 +123,38 @@ namespace Ombi.Store.Repository.Requests public async Task Delete(TvRequests request) { Db.TvRequests.Remove(request); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task DeleteChild(ChildRequests request) { Db.ChildRequests.Remove(request); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task DeleteChildRange(IEnumerable request) { Db.ChildRequests.RemoveRange(request); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task Update(TvRequests request) { Db.Update(request); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task UpdateChild(ChildRequests request) { Db.Update(request); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); + } + + private async Task InternalSaveChanges() + { + return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/SettingsJsonRepository.cs b/src/Ombi.Store/Repository/SettingsJsonRepository.cs index 66cf57b18..6140fd7a1 100644 --- a/src/Ombi.Store/Repository/SettingsJsonRepository.cs +++ b/src/Ombi.Store/Repository/SettingsJsonRepository.cs @@ -62,14 +62,14 @@ namespace Ombi.Store.Repository { //_cache.Remove(GetName(entity.SettingsName)); Db.Settings.Remove(entity); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public async Task UpdateAsync(GlobalSettings entity) { //_cache.Remove(GetName(entity.SettingsName)); Db.Update(entity); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public void Delete(GlobalSettings entity) @@ -91,6 +91,11 @@ namespace Ombi.Store.Repository return $"{entity}Json"; } + private async Task InternalSaveChanges() + { + return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); + } + private bool _disposed; protected virtual void Dispose(bool disposing) { diff --git a/src/Ombi.Store/Repository/TokenRepository.cs b/src/Ombi.Store/Repository/TokenRepository.cs index d766c5690..3f82e3948 100644 --- a/src/Ombi.Store/Repository/TokenRepository.cs +++ b/src/Ombi.Store/Repository/TokenRepository.cs @@ -4,6 +4,7 @@ using Ombi.Store.Entities; using System; using System.Linq; using System.Threading.Tasks; +using Ombi.Helpers; namespace Ombi.Store.Repository { @@ -19,12 +20,16 @@ namespace Ombi.Store.Repository public async Task CreateToken(Tokens token) { await Db.Tokens.AddAsync(token); - await Db.SaveChangesAsync(); + await InternalSaveChanges(); } public IQueryable GetToken(string tokenId) { return Db.Tokens.Where(x => x.Token == tokenId); } + private async Task InternalSaveChanges() + { + return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); + } } } From 5d9e6bd1130d7cebe2f8679bd161c046e4340896 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Mon, 25 Mar 2019 09:24:32 +0000 Subject: [PATCH 33/58] Fixed build !wip --- src/Ombi.Core/Engine/TvRequestEngine.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index 1cb0ad65a..796e2fe6a 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -82,8 +82,6 @@ namespace Ombi.Core.Engine } } - await Audit.Record(AuditType.Added, AuditArea.TvRequest, $"Added Request {tvBuilder.ChildRequest.Title}", Username); - var existingRequest = await TvRepository.Get().FirstOrDefaultAsync(x => x.TvDbId == tv.TvDbId); if (existingRequest != null) { From 117bd1cd8b14a5d93c495139918631a30ca1d3f4 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Tue, 26 Mar 2019 12:12:58 +0000 Subject: [PATCH 34/58] #2750 stuff --- .../Authentication/OmbiUserManager.cs | 2 +- src/Ombi.DependencyInjection/IocExtensions.cs | 36 +++++++++---------- src/Ombi.Store/Context/OmbiContext.cs | 1 + src/Ombi/Startup.cs | 3 -- 4 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/Ombi.Core/Authentication/OmbiUserManager.cs b/src/Ombi.Core/Authentication/OmbiUserManager.cs index 2c78f39bf..6155672b3 100644 --- a/src/Ombi.Core/Authentication/OmbiUserManager.cs +++ b/src/Ombi.Core/Authentication/OmbiUserManager.cs @@ -158,7 +158,7 @@ namespace Ombi.Core.Authentication if (!email.Equals(result.User?.Email)) { user.Email = result.User?.Email; - await UpdateAsync(user); + await GlobalMutex.Lock(async () => await UpdateAsync(user)); } return true; diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 69e6bd3ca..466b74bb0 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -134,28 +134,28 @@ namespace Ombi.DependencyInjection } public static void RegisterStore(this IServiceCollection services) { - services.AddEntityFrameworkSqlite().AddDbContext(); - services.AddEntityFrameworkSqlite().AddDbContext(); - services.AddEntityFrameworkSqlite().AddDbContext(); + services.AddDbContext(); + services.AddDbContext(); + services.AddDbContext(); services.AddScoped(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6 services.AddScoped(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6 services.AddScoped(); // https://docs.microsoft.com/en-us/aspnet/core/data/entity-framework-6 - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(); - services.AddTransient(typeof(ISettingsService<>), typeof(SettingsService<>)); - services.AddTransient(typeof(IRepository<>), typeof(Repository<>)); - services.AddTransient(typeof(IExternalRepository<>), typeof(ExternalRepository<>)); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(typeof(ISettingsService<>), typeof(SettingsService<>)); + services.AddScoped(typeof(IRepository<>), typeof(Repository<>)); + services.AddScoped(typeof(IExternalRepository<>), typeof(ExternalRepository<>)); } public static void RegisterServices(this IServiceCollection services) { @@ -163,7 +163,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); - services.AddTransient(); + services.AddSingleton(); services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 2f19bc681..98f4cd9c3 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -17,6 +17,7 @@ namespace Ombi.Store.Context { if (_created) return; + _created = true; Database.SetCommandTimeout(60); Database.Migrate(); diff --git a/src/Ombi/Startup.cs b/src/Ombi/Startup.cs index bbf56c517..fa70df147 100644 --- a/src/Ombi/Startup.cs +++ b/src/Ombi/Startup.cs @@ -56,9 +56,6 @@ namespace Ombi // This method gets called by the runtime. Use this method to add services to the container. public IServiceProvider ConfigureServices(IServiceCollection services) { - // Add framework services. - services.AddDbContext(); - services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders() From a499782ec0dc445abdfd14c7f999c876df901b04 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 26 Mar 2019 22:12:47 +0000 Subject: [PATCH 35/58] Delete the schedules db on startup, we don't want it trying to recover the jobs --- src/Ombi/Program.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Ombi/Program.cs b/src/Ombi/Program.cs index f1809a2dc..2365f6748 100644 --- a/src/Ombi/Program.cs +++ b/src/Ombi/Program.cs @@ -49,6 +49,7 @@ namespace Ombi demoInstance.Demo = demo; instance.StoragePath = storagePath ?? string.Empty; // Check if we need to migrate the settings + DeleteSchedules(); CheckAndMigrate(); var ctx = new SettingsContext(); var config = ctx.ApplicationConfigurations.ToList(); @@ -97,6 +98,20 @@ namespace Ombi CreateWebHostBuilder(args).Build().Run(); } + private static void DeleteSchedules() + { + try + { + if (File.Exists("Schedules.db")) + { + File.Delete("Schedules.db"); + } + } + catch (Exception) + { + } + } + /// /// This is to remove the Settings from the Ombi.db to the "new" /// OmbiSettings.db From 439dc395d05ba08ff0e06ba49bf0b4cfc69e160f Mon Sep 17 00:00:00 2001 From: tidusjar Date: Wed, 27 Mar 2019 10:19:36 +0000 Subject: [PATCH 36/58] Reverted the global app lock for the db #2750 --- .../Rule/Request/AutoApproveRuleTests.cs | 3 +- .../Rule/Request/CanRequestRuleTests.cs | 2 +- .../Rule/Search/EmbyAvailabilityRuleTests.cs | 2 +- .../Authentication/OmbiUserManager.cs | 2 +- src/Ombi.Helpers/GlobalMutex.cs | 39 ------------------- src/Ombi.Store/Repository/BaseRepository.cs | 2 +- .../NotificationTemplatesRepository.cs | 2 +- .../Requests/MovieRequestRepository.cs | 5 --- .../Requests/MusicRequestRepository.cs | 4 -- .../Requests/TvRequestRepository.cs | 2 +- .../Repository/SettingsJsonRepository.cs | 2 +- src/Ombi.Store/Repository/TokenRepository.cs | 2 +- 12 files changed, 10 insertions(+), 57 deletions(-) delete mode 100644 src/Ombi.Helpers/GlobalMutex.cs diff --git a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs index 7ff8283da..34c21e008 100644 --- a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs @@ -4,6 +4,7 @@ using Moq; using Ombi.Core.Rule.Rules.Request; using Ombi.Store.Entities.Requests; using NUnit.Framework; +using Ombi.Core.Authentication; using Ombi.Helpers; namespace Ombi.Core.Tests.Rule.Request @@ -16,7 +17,7 @@ namespace Ombi.Core.Tests.Rule.Request { PrincipalMock = new Mock(); - Rule = new AutoApproveRule(PrincipalMock.Object); + Rule = new AutoApproveRule(PrincipalMock.Object, null); } diff --git a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs index 69b6a76df..f2781c8d2 100644 --- a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs @@ -16,7 +16,7 @@ namespace Ombi.Core.Tests.Rule.Request { PrincipalMock = new Mock(); - Rule = new CanRequestRule(PrincipalMock.Object); + Rule = new CanRequestRule(PrincipalMock.Object, null); } diff --git a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs index 99ff5b6bd..0171e37a1 100644 --- a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs @@ -16,7 +16,7 @@ namespace Ombi.Core.Tests.Rule.Search public void Setup() { ContextMock = new Mock(); - Rule = new EmbyAvailabilityRule(ContextMock.Object); + Rule = new EmbyAvailabilityRule(ContextMock.Object, null); } private EmbyAvailabilityRule Rule { get; set; } diff --git a/src/Ombi.Core/Authentication/OmbiUserManager.cs b/src/Ombi.Core/Authentication/OmbiUserManager.cs index 6155672b3..2c78f39bf 100644 --- a/src/Ombi.Core/Authentication/OmbiUserManager.cs +++ b/src/Ombi.Core/Authentication/OmbiUserManager.cs @@ -158,7 +158,7 @@ namespace Ombi.Core.Authentication if (!email.Equals(result.User?.Email)) { user.Email = result.User?.Email; - await GlobalMutex.Lock(async () => await UpdateAsync(user)); + await UpdateAsync(user); } return true; diff --git a/src/Ombi.Helpers/GlobalMutex.cs b/src/Ombi.Helpers/GlobalMutex.cs deleted file mode 100644 index 0164e888c..000000000 --- a/src/Ombi.Helpers/GlobalMutex.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Threading; -using System.Threading.Tasks; -using Nito.AsyncEx; - -namespace Ombi.Helpers -{ - public static class GlobalMutex - { - public static async Task Lock(Func> func) - { - const string mutexId = "Global\\OMBI"; - using (var mutex = new Mutex(false, mutexId, out _)) - { - var hasHandle = false; - try - { - try - { - hasHandle = mutex.WaitOne(5000, false); - if (hasHandle == false) - throw new TimeoutException("Timeout waiting for exclusive access"); - } - catch (AbandonedMutexException) - { - hasHandle = true; - } - - return await func(); - } - finally - { - if (hasHandle) - mutex.ReleaseMutex(); - } - } - } - } -} diff --git a/src/Ombi.Store/Repository/BaseRepository.cs b/src/Ombi.Store/Repository/BaseRepository.cs index 1ca78ee50..0741a79b6 100644 --- a/src/Ombi.Store/Repository/BaseRepository.cs +++ b/src/Ombi.Store/Repository/BaseRepository.cs @@ -83,7 +83,7 @@ namespace Ombi.Store.Repository protected async Task InternalSaveChanges() { - return await GlobalMutex.Lock(async () => await _ctx.SaveChangesAsync()); + return await _ctx.SaveChangesAsync(); } diff --git a/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs b/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs index eb4816d50..8f3968dc0 100644 --- a/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs +++ b/src/Ombi.Store/Repository/NotificationTemplatesRepository.cs @@ -68,7 +68,7 @@ namespace Ombi.Store.Repository private async Task InternalSaveChanges() { - return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); + return await Db.SaveChangesAsync(); } private bool _disposed; diff --git a/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs b/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs index d96363d29..2cea81200 100644 --- a/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/MovieRequestRepository.cs @@ -78,10 +78,5 @@ namespace Ombi.Store.Repository.Requests { await InternalSaveChanges(); } - - private async Task InternalSaveChanges() - { - return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); - } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs b/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs index 5179513d2..971d53b39 100644 --- a/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/MusicRequestRepository.cs @@ -69,9 +69,5 @@ namespace Ombi.Store.Repository.Requests { await InternalSaveChanges(); } - private async Task InternalSaveChanges() - { - return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); - } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs index d3486358a..91e885b37 100644 --- a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs @@ -154,7 +154,7 @@ namespace Ombi.Store.Repository.Requests private async Task InternalSaveChanges() { - return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); + return await Db.SaveChangesAsync(); } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/SettingsJsonRepository.cs b/src/Ombi.Store/Repository/SettingsJsonRepository.cs index 6140fd7a1..909a68480 100644 --- a/src/Ombi.Store/Repository/SettingsJsonRepository.cs +++ b/src/Ombi.Store/Repository/SettingsJsonRepository.cs @@ -93,7 +93,7 @@ namespace Ombi.Store.Repository private async Task InternalSaveChanges() { - return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); + return await Db.SaveChangesAsync(); } private bool _disposed; diff --git a/src/Ombi.Store/Repository/TokenRepository.cs b/src/Ombi.Store/Repository/TokenRepository.cs index 3f82e3948..d0a501bd5 100644 --- a/src/Ombi.Store/Repository/TokenRepository.cs +++ b/src/Ombi.Store/Repository/TokenRepository.cs @@ -29,7 +29,7 @@ namespace Ombi.Store.Repository } private async Task InternalSaveChanges() { - return await GlobalMutex.Lock(async () => await Db.SaveChangesAsync()); + return await Db.SaveChangesAsync(); } } } From 78395a38f7be433b6badf631245a33e0fa658280 Mon Sep 17 00:00:00 2001 From: PotatoQuality Date: Thu, 4 Apr 2019 20:21:05 +0200 Subject: [PATCH 37/58] Fix for broken twitch url in readme file Fixing the twitch url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 79aba2c3a..e34e74aa8 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ___ Follow me developing Ombi! -[![Twitch](https://img.shields.io/badge/Twitch-Watch-blue.svg?style=flat-square&logo=twitch)](https://twitch.tv/tiusjar) +[![Twitch](https://img.shields.io/badge/Twitch-Watch-blue.svg?style=flat-square&logo=twitch)](https://www.twitch.tv/tidusjar) ___ From c556334f79d2f83ac6f415c31a5093405565d069 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sat, 6 Apr 2019 21:43:26 +0100 Subject: [PATCH 38/58] Fixed #2910 --- src/Ombi.Helpers/CacheService.cs | 57 +++++++++---------- .../Jobs/Ombi/MediaDatabaseRefresh.cs | 1 + src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs | 4 ++ .../Jobs/Plex/PlexContentSync.cs | 1 + .../Jobs/Plex/PlexEpisodeSync.cs | 1 + .../Jobs/Plex/PlexUserImporter.cs | 2 + src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs | 1 + .../Jobs/SickRage/SickRageSync.cs | 1 + src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs | 1 + 9 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/Ombi.Helpers/CacheService.cs b/src/Ombi.Helpers/CacheService.cs index 4eef62bda..ae57a9f61 100644 --- a/src/Ombi.Helpers/CacheService.cs +++ b/src/Ombi.Helpers/CacheService.cs @@ -28,18 +28,15 @@ namespace Ombi.Helpers return result; } - using (await _mutex.LockAsync()) + if (_memoryCache.TryGetValue(cacheKey, out result)) { - if (_memoryCache.TryGetValue(cacheKey, out result)) - { - return result; - } - - result = await factory(); - _memoryCache.Set(cacheKey, result, absoluteExpiration); - return result; } + + result = await factory(); + _memoryCache.Set(cacheKey, result, absoluteExpiration); + + return result; } public void Remove(string key) @@ -47,34 +44,34 @@ namespace Ombi.Helpers _memoryCache.Remove(key); } - - - public T GetOrAdd(string cacheKey, Func factory, DateTime absoluteExpiration) + + + public T GetOrAdd(string cacheKey, Func factory, DateTime absoluteExpiration) + { + // locks get and set internally + if (_memoryCache.TryGetValue(cacheKey, out var result)) { - // locks get and set internally - if (_memoryCache.TryGetValue(cacheKey, out var result)) + return result; + } + + lock (TypeLock.Lock) + { + if (_memoryCache.TryGetValue(cacheKey, out result)) { return result; } - lock (TypeLock.Lock) - { - if (_memoryCache.TryGetValue(cacheKey, out result)) - { - return result; - } - - result = factory(); - _memoryCache.Set(cacheKey, result, absoluteExpiration); + result = factory(); + _memoryCache.Set(cacheKey, result, absoluteExpiration); - return result; - } + return result; } + } + + private static class TypeLock + { + public static object Lock { get; } = new object(); + } - private static class TypeLock - { - public static object Lock { get; } = new object(); - } - } } diff --git a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs index ed0bf227f..fcf8529ce 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs @@ -22,6 +22,7 @@ namespace Ombi.Schedule.Jobs.Ombi _plexRepo = plexRepo; _embyRepo = embyRepo; _embyContentSync = embySync; + _settings.ClearCache(); } private readonly ISettingsService _settings; diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs index 6c59f4c0f..12415f6e4 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs @@ -57,6 +57,10 @@ namespace Ombi.Schedule.Jobs.Ombi _ombiSettings = ombiSettings; _plexSettings = plexSettings; _embySettings = embySettings; + _ombiSettings.ClearCache(); + _plexSettings.ClearCache(); + _emailSettings.ClearCache(); + _customizationSettings.ClearCache(); } private readonly IPlexContentRepository _plex; diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index 964832b44..9df1edf97 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -57,6 +57,7 @@ namespace Ombi.Schedule.Jobs.Plex EpisodeSync = epsiodeSync; Metadata = metadataRefresh; Checker = checker; + Plex.ClearCache(); } private ISettingsService Plex { get; } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index 6ab5a5941..5652d126b 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -26,6 +26,7 @@ namespace Ombi.Schedule.Jobs.Plex _api = plexApi; _repo = repo; _availabilityChecker = a; + _settings.ClearCache(); } private readonly ISettingsService _settings; diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs index 105e8876d..53c82465c 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs @@ -24,6 +24,8 @@ namespace Ombi.Schedule.Jobs.Plex _log = log; _plexSettings = plexSettings; _userManagementSettings = ums; + _plexSettings.ClearCache(); + _userManagementSettings.ClearCache(); } private readonly IPlexApi _api; diff --git a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs index f61747ac6..5c954def8 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs @@ -22,6 +22,7 @@ namespace Ombi.Schedule.Jobs.Radarr RadarrApi = radarrApi; Logger = log; _ctx = ctx; + RadarrSettings.ClearCache(); } private ISettingsService RadarrSettings { get; } diff --git a/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs b/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs index 2c8d03b1d..92e0c2d55 100644 --- a/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs +++ b/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs @@ -22,6 +22,7 @@ namespace Ombi.Schedule.Jobs.SickRage _api = api; _log = l; _ctx = ctx; + _settings.ClearCache(); } private readonly ISettingsService _settings; diff --git a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs index c77e23394..e4c00c726 100644 --- a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs @@ -25,6 +25,7 @@ namespace Ombi.Schedule.Jobs.Sonarr _api = api; _log = l; _ctx = ctx; + _settings.ClearCache(); } private readonly ISettingsService _settings; From 6dccea77c2bcad5719dda4d18f7370c8b310a990 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sat, 6 Apr 2019 23:56:55 +0100 Subject: [PATCH 39/58] Fixed the mixed content warnings and the error when removing a album request #2884 --- src/Ombi.Core/Engine/MusicSearchEngine.cs | 5 +++-- src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs | 1 + .../app/requests/music/musicrequests.component.ts | 11 +++++------ src/Ombi/ClientApp/app/services/request.service.ts | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/Ombi.Core/Engine/MusicSearchEngine.cs b/src/Ombi.Core/Engine/MusicSearchEngine.cs index d0e577801..16f727da7 100644 --- a/src/Ombi.Core/Engine/MusicSearchEngine.cs +++ b/src/Ombi.Core/Engine/MusicSearchEngine.cs @@ -152,7 +152,8 @@ namespace Ombi.Core.Engine Rating = a.ratings?.value ?? 0m, ReleaseDate = a.releaseDate, Title = a.title, - Disk = a.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url + Disk = a.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url?.Replace("http","https"), + Genres = a.genres }; if (a.artistId > 0) { @@ -169,7 +170,7 @@ namespace Ombi.Core.Engine vm.ArtistName = a.artist?.artistName; } - vm.Cover = a.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url; + vm.Cover = a.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url?.Replace("http", "https"); if (vm.Cover.IsNullOrEmpty()) { vm.Cover = a.remoteCover; diff --git a/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs b/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs index a494a3cb5..3823d7789 100644 --- a/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs +++ b/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs @@ -16,6 +16,7 @@ namespace Ombi.Core.Models.Search public string Cover { get; set; } public string Disk { get; set; } public decimal PercentOfTracks { get; set; } + public object[] Genres { get; set; } public override RequestType Type => RequestType.Album; public bool PartiallyAvailable => PercentOfTracks != 100 && PercentOfTracks > 0; public bool FullyAvailable => PercentOfTracks == 100; diff --git a/src/Ombi/ClientApp/app/requests/music/musicrequests.component.ts b/src/Ombi/ClientApp/app/requests/music/musicrequests.component.ts index b10173042..2bc7b6282 100644 --- a/src/Ombi/ClientApp/app/requests/music/musicrequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/music/musicrequests.component.ts @@ -90,11 +90,10 @@ export class MusicRequestsComponent implements OnInit { this.searchChanged.next(text.target.value); } - public removeRequest(request: IAlbumRequest) { - this.requestService.removeAlbumRequest(request).subscribe(x => { - this.removeRequestFromUi(request); - this.loadRequests(this.amountToLoad, this.currentlyLoaded = 0); - }); + public async removeRequest(request: IAlbumRequest) { + await this.requestService.removeAlbumRequest(request).toPromise(); + this.removeRequestFromUi(request); + this.loadRequests(this.amountToLoad, this.currentlyLoaded = 0); } public changeAvailability(request: IAlbumRequest, available: boolean) { @@ -335,7 +334,7 @@ export class MusicRequestsComponent implements OnInit { } private setAlbumBackground(req: IAlbumRequest) { if (req.disk === null) { - if(req.cover === null) { + if (req.cover === null) { req.disk = this.defaultPoster; } else { req.disk = req.cover; diff --git a/src/Ombi/ClientApp/app/services/request.service.ts b/src/Ombi/ClientApp/app/services/request.service.ts index f7e2b3875..5353ea580 100644 --- a/src/Ombi/ClientApp/app/services/request.service.ts +++ b/src/Ombi/ClientApp/app/services/request.service.ts @@ -182,7 +182,7 @@ export class RequestService extends ServiceHelpers { } public removeAlbumRequest(request: IAlbumRequest): any { - this.http.delete(`${this.url}music/${request.id}`, {headers: this.headers}).subscribe(); + return this.http.delete(`${this.url}music/${request.id}`, {headers: this.headers}); } } From ca010a02824229f8e81052be1133a2c2547f3531 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 7 Apr 2019 00:09:19 +0100 Subject: [PATCH 40/58] Added some defensive coding around when we create an artist for #2915 --- src/Ombi.Core/Senders/MusicSender.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Ombi.Core/Senders/MusicSender.cs b/src/Ombi.Core/Senders/MusicSender.cs index 76a9fc14c..0e9db9192 100644 --- a/src/Ombi.Core/Senders/MusicSender.cs +++ b/src/Ombi.Core/Senders/MusicSender.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using EnsureThat; using Microsoft.Extensions.Logging; using Ombi.Api.Lidarr; using Ombi.Api.Lidarr.Models; @@ -87,6 +88,11 @@ namespace Ombi.Core.Senders if (artist == null || artist.id <= 0) { + EnsureArg.IsNotNullOrEmpty(model.ForeignArtistId, nameof(model.ForeignArtistId)); + EnsureArg.IsNotNullOrEmpty(model.ForeignAlbumId, nameof(model.ForeignAlbumId)); + EnsureArg.IsNotNullOrEmpty(model.ArtistName, nameof(model.ArtistName)); + EnsureArg.IsNotNullOrEmpty(rootFolderPath, nameof(rootFolderPath)); + // Create artist var newArtist = new ArtistAdd { From c2764fe780deae7a274c568489207b8beea6b548 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 9 Apr 2019 21:56:55 +0100 Subject: [PATCH 41/58] !wip on Music API --- src/Ombi.Api.Lidarr/ILidarrApi.cs | 1 + src/Ombi.Api.Lidarr/LidarrApi.cs | 26 +++++++++ src/Ombi.Api.Lidarr/Models/AlbumLookup.cs | 5 ++ src/Ombi.Api.Lidarr/Models/LidarrLinks.cs | 12 ++++ src/Ombi.Api.Lidarr/Models/LidarrRatings.cs | 8 +++ src/Ombi.Api.Lidarr/Models/LidarrTrack.cs | 22 ++++++++ .../Engine/Interfaces/IMusicSearchEngine.cs | 1 + src/Ombi.Core/Engine/MusicSearchEngine.cs | 56 ++++++++++++++++++- .../Models/Search/SearchAlbumViewModel.cs | 4 ++ src/Ombi/Controllers/SearchController.cs | 13 +++++ 10 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 src/Ombi.Api.Lidarr/Models/LidarrLinks.cs create mode 100644 src/Ombi.Api.Lidarr/Models/LidarrRatings.cs create mode 100644 src/Ombi.Api.Lidarr/Models/LidarrTrack.cs diff --git a/src/Ombi.Api.Lidarr/ILidarrApi.cs b/src/Ombi.Api.Lidarr/ILidarrApi.cs index 4a23c6200..0eac960d0 100644 --- a/src/Ombi.Api.Lidarr/ILidarrApi.cs +++ b/src/Ombi.Api.Lidarr/ILidarrApi.cs @@ -23,5 +23,6 @@ namespace Ombi.Api.Lidarr Task> GetLanguageProfile(string apiKey, string baseUrl); Task Status(string apiKey, string baseUrl); Task AlbumSearch(int[] albumIds, string apiKey, string baseUrl); + Task AlbumInformation(string albumId, string apiKey, string baseUrl); } } \ No newline at end of file diff --git a/src/Ombi.Api.Lidarr/LidarrApi.cs b/src/Ombi.Api.Lidarr/LidarrApi.cs index a6a283703..cb8db759e 100644 --- a/src/Ombi.Api.Lidarr/LidarrApi.cs +++ b/src/Ombi.Api.Lidarr/LidarrApi.cs @@ -105,6 +105,32 @@ namespace Ombi.Api.Lidarr return Api.Request>(request); } + public async Task AlbumInformation(string albumId, string apiKey, string baseUrl) + { + var request = new Request($"{ApiVersion}/album", baseUrl, HttpMethod.Get); + request.AddQueryString("foreignAlbumId", albumId); + AddHeaders(request, apiKey); + var albums = await Api.Request>(request); + return albums.Where(x => x.foreignAlbumId.Equals(albumId, StringComparison.InvariantCultureIgnoreCase)) + .FirstOrDefault(); + } + + + /// + /// THIS ONLY SUPPORTS ALBUMS THAT THE ARTIST IS IN LIDARR + /// + /// + /// + /// + /// + public Task> GetTracksForAlbum(int albumId, string apiKey, string baseUrl) + { + var request = new Request($"{ApiVersion}/album", baseUrl, HttpMethod.Get); + request.AddQueryString("albumId", albumId.ToString()); + AddHeaders(request, apiKey); + return Api.Request>(request); + } + public Task AddArtist(ArtistAdd artist, string apiKey, string baseUrl) { var request = new Request($"{ApiVersion}/artist", baseUrl, HttpMethod.Post); diff --git a/src/Ombi.Api.Lidarr/Models/AlbumLookup.cs b/src/Ombi.Api.Lidarr/Models/AlbumLookup.cs index b2394eb5f..1e909cf4c 100644 --- a/src/Ombi.Api.Lidarr/Models/AlbumLookup.cs +++ b/src/Ombi.Api.Lidarr/Models/AlbumLookup.cs @@ -1,10 +1,15 @@ using System; +using System.Collections.Generic; namespace Ombi.Api.Lidarr.Models { public class AlbumLookup { public string title { get; set; } + public string status { get; set; } + public string artistType { get; set; } + public string disambiguation { get; set; } + public List links { get; set; } public int artistId { get; set; } public string foreignAlbumId { get; set; } public bool monitored { get; set; } diff --git a/src/Ombi.Api.Lidarr/Models/LidarrLinks.cs b/src/Ombi.Api.Lidarr/Models/LidarrLinks.cs new file mode 100644 index 000000000..e8bdb8975 --- /dev/null +++ b/src/Ombi.Api.Lidarr/Models/LidarrLinks.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ombi.Api.Lidarr.Models +{ + public class LidarrLinks + { + public string url { get; set; } + public string name { get; set; } + } +} diff --git a/src/Ombi.Api.Lidarr/Models/LidarrRatings.cs b/src/Ombi.Api.Lidarr/Models/LidarrRatings.cs new file mode 100644 index 000000000..7728d58bf --- /dev/null +++ b/src/Ombi.Api.Lidarr/Models/LidarrRatings.cs @@ -0,0 +1,8 @@ +namespace Ombi.Api.Lidarr.Models +{ + public class LidarrRatings + { + public int votes { get; set; } + public decimal value { get; set; } + } +} diff --git a/src/Ombi.Api.Lidarr/Models/LidarrTrack.cs b/src/Ombi.Api.Lidarr/Models/LidarrTrack.cs new file mode 100644 index 000000000..367e8cc7c --- /dev/null +++ b/src/Ombi.Api.Lidarr/Models/LidarrTrack.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ombi.Api.Lidarr.Models +{ + public class LidarrTrack + { + public int artistId { get; set; } + public int trackFileId { get; set; } + public int albumId { get; set; } + public bool _explicit { get; set; } + public int absoluteTrackNumber { get; set; } + public string trackNumber { get; set; } + public string title { get; set; } + public int duration { get; set; } + public int mediumNumber { get; set; } + public bool hasFile { get; set; } + public bool monitored { get; set; } + public int id { get; set; } + } +} diff --git a/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngine.cs b/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngine.cs index 03294982a..71c02af9d 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMusicSearchEngine.cs @@ -12,5 +12,6 @@ namespace Ombi.Core.Engine Task> GetArtistAlbums(string foreignArtistId); Task> SearchAlbum(string search); Task> SearchArtist(string search); + Task GetAlbumInformation(string foreignAlbumId); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/MusicSearchEngine.cs b/src/Ombi.Core/Engine/MusicSearchEngine.cs index 16f727da7..c8d285766 100644 --- a/src/Ombi.Core/Engine/MusicSearchEngine.cs +++ b/src/Ombi.Core/Engine/MusicSearchEngine.cs @@ -60,6 +60,18 @@ namespace Ombi.Core.Engine return vm; } + public async Task GetAlbumInformation(string foreignAlbumId) + { + var settings = await GetSettings(); + var result = await _lidarrApi.AlbumInformation(foreignAlbumId, settings.ApiKey, settings.FullUri); + + + var vm = await MapIntoAlbumVm(result, settings); + + + return vm; + } + /// /// Searches the specified artist /// @@ -143,6 +155,48 @@ namespace Ombi.Core.Engine return vm; } + + // TODO + private async Task MapIntoAlbumVm(AlbumResponse a, LidarrSettings settings) + { + var vm = new SearchAlbumViewModel + { + ForeignAlbumId = a.foreignAlbumId, + Monitored = a.monitored, + Rating = a.ratings?.value ?? 0m, + ReleaseDate = a.releaseDate, + Title = a.title, + Disk = a.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url?.Replace("http", "https"), + Genres = a.genres + }; + if (a.artistId > 0) + { + //TODO THEY HAVE FIXED THIS IN DEV + // The JSON is different for some stupid reason + // Need to lookup the artist now and all the images -.-" + var artist = await _lidarrApi.GetArtist(a.artistId, settings.ApiKey, settings.FullUri); + vm.ArtistName = artist.artistName; + vm.ForeignArtistId = artist.foreignArtistId; + } + else + { + //vm.ForeignArtistId = a.artistId?.foreignArtistId; + //vm.ArtistName = a.artist?.artistName; + } + + vm.Cover = a.images?.FirstOrDefault(x => x.coverType.Equals("cover"))?.url?.Replace("http", "https"); + if (vm.Cover.IsNullOrEmpty()) + { + //vm.Cover = a.remoteCover; + } + + await Rules.StartSpecificRules(vm, SpecificRules.LidarrAlbum); + + await RunSearchRules(vm); + + return vm; + } + private async Task MapIntoAlbumVm(AlbumLookup a, LidarrSettings settings) { var vm = new SearchAlbumViewModel @@ -152,7 +206,7 @@ namespace Ombi.Core.Engine Rating = a.ratings?.value ?? 0m, ReleaseDate = a.releaseDate, Title = a.title, - Disk = a.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url?.Replace("http","https"), + Disk = a.images?.FirstOrDefault(x => x.coverType.Equals("disc"))?.url?.Replace("http", "https"), Genres = a.genres }; if (a.artistId > 0) diff --git a/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs b/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs index 3823d7789..e9f9c5f9e 100644 --- a/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs +++ b/src/Ombi.Core/Models/Search/SearchAlbumViewModel.cs @@ -20,5 +20,9 @@ namespace Ombi.Core.Models.Search public override RequestType Type => RequestType.Album; public bool PartiallyAvailable => PercentOfTracks != 100 && PercentOfTracks > 0; public bool FullyAvailable => PercentOfTracks == 100; + + + // Below is from the INFO call NEED A SEPERATE VM FOR THIS IN V4 TODO + // TODO ADD TRACK COUNT } } \ No newline at end of file diff --git a/src/Ombi/Controllers/SearchController.cs b/src/Ombi/Controllers/SearchController.cs index bdeacee2a..d5b5e3098 100644 --- a/src/Ombi/Controllers/SearchController.cs +++ b/src/Ombi/Controllers/SearchController.cs @@ -369,6 +369,19 @@ namespace Ombi.Controllers return await MusicEngine.SearchAlbum(searchTerm); } + /// + /// Returns the album information specified by the foreignAlbumId passed in + /// + /// We use Lidarr as the Provider + /// + [HttpGet("music/album/info/{foreignAlbumId}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesDefaultResponseType] + public async Task GetAlbumInformation(string foreignAlbumId) + { + return await MusicEngine.GetAlbumInformation(foreignAlbumId); + } + /// /// Returns all albums for the artist using the ForeignArtistId /// From 52d9a7a5863ee3524230451f8f84486f5e45334f Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 9 Apr 2019 23:24:30 +0100 Subject: [PATCH 42/58] moved the jobs to use quartz --- src/Ombi.Helpers/Cron.cs | 48 ++++++++++++++--- src/Ombi.Schedule/JobSetup.cs | 32 +++++------ .../Jobs/Couchpotato/CouchPotatoSync.cs | 3 +- .../Jobs/Couchpotato/ICouchPotatoSync.cs | 1 - .../Jobs/Emby/EmbyAvaliabilityChecker.cs | 3 +- .../Jobs/Emby/EmbyContentSync.cs | 7 +-- .../Jobs/Emby/EmbyEpisodeSync.cs | 5 +- .../Jobs/Emby/EmbyUserImporter.cs | 3 +- .../Jobs/Emby/IEmbyAvaliabilityChecker.cs | 1 - .../Jobs/Emby/IEmbyContentSync.cs | 1 - .../Jobs/Emby/IEmbyEpisodeSync.cs | 1 - .../Jobs/Emby/IEmbyUserImporter.cs | 1 - src/Ombi.Schedule/Jobs/IBaseJob.cs | 3 +- .../Jobs/Lidarr/ILidarrArtistSync.cs | 4 +- .../Jobs/Lidarr/LidarrArtistSync.cs | 3 +- .../Jobs/Ombi/Interfaces/IIssuesPurge.cs | 3 +- .../Ombi/Interfaces/IMediaDatabaseRefresh.cs | 1 - .../Jobs/Ombi/Interfaces/INewsletterJob.cs | 1 - .../Ombi/Interfaces/IOmbiAutomaticUpdater.cs | 1 - .../Jobs/Ombi/Interfaces/IRefreshMetadata.cs | 1 - .../Ombi/Interfaces/IResendFailedRequests.cs | 6 +-- .../Jobs/Ombi/Interfaces/IWelcomeEmail.cs | 2 +- .../Jobs/Ombi/Interfaces/IssuesPurge.cs | 3 +- .../Jobs/Ombi/MediaDatabaseRefresh.cs | 5 +- src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs | 3 +- .../Jobs/Ombi/OmbiAutomaticUpdater.cs | 10 ++-- .../Jobs/Ombi/RefreshMetadata.cs | 7 +-- .../Jobs/Ombi/ResendFailedRequests.cs | 3 +- .../Interfaces/IPlexAvailabilityChecker.cs | 1 - .../Jobs/Plex/Interfaces/IPlexEpisodeSync.cs | 1 - .../Jobs/Plex/Interfaces/IPlexUserImporter.cs | 1 - .../Jobs/Plex/PlexAvailabilityChecker.cs | 3 +- .../Jobs/Plex/PlexContentSync.cs | 4 +- .../Jobs/Plex/PlexEpisodeSync.cs | 5 +- .../Jobs/Plex/PlexUserImporter.cs | 3 +- src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs | 1 - src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs | 3 +- .../Jobs/SickRage/ISickRageSync.cs | 1 - .../Jobs/SickRage/SickRageSync.cs | 3 +- src/Ombi.Schedule/Jobs/Sonarr/ISonarrSync.cs | 1 - src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs | 3 +- src/Ombi.Schedule/Ombi.Schedule.csproj | 2 +- src/Ombi.Schedule/OmbiQuartz.cs | 9 ++-- src/Ombi.Schedule/OmbiScheduler.cs | 53 +++++++++++++++++-- src/Ombi.Settings/Ombi.Settings.csproj | 1 + .../Settings/Models/JobSettingsHelper.cs | 3 +- src/Ombi/Controllers/JobController.cs | 10 ++-- src/Ombi/Controllers/SettingsController.cs | 2 +- src/Ombi/Startup.cs | 4 +- 49 files changed, 178 insertions(+), 98 deletions(-) diff --git a/src/Ombi.Helpers/Cron.cs b/src/Ombi.Helpers/Cron.cs index 35b141eda..8197dae77 100644 --- a/src/Ombi.Helpers/Cron.cs +++ b/src/Ombi.Helpers/Cron.cs @@ -16,7 +16,6 @@ // You should have received a copy of the GNU Lesser General Public // License along with Hangfire. If not, see . - using System; /// /// Helper class that provides common values for the cron expressions. /// @@ -44,7 +43,7 @@ /// The minute in which the schedule will be activated (0-59). public static string Hourly(int minute) { - return $"{minute} * * * *"; + return $"0 {minute} 0/1 1/1 * ? *"; } /// @@ -73,7 +72,7 @@ /// The minute in which the schedule will be activated (0-59). public static string Daily(int hour, int minute) { - return $"{minute} {hour} * * *"; + return $"0 {minute} {hour} 1/1 * ? *"; } /// @@ -114,7 +113,7 @@ /// The minute in which the schedule will be activated (0-59). public static string Weekly(DayOfWeek dayOfWeek, int hour, int minute) { - return $"{minute} {hour} * * {(int)dayOfWeek}"; + return $"0 {minute} {hour} ? * {(int)dayOfWeek} *"; } /// @@ -219,7 +218,7 @@ /// The number of minutes to wait between every activation. public static string MinuteInterval(int interval) { - return $"*/{interval} * * * *"; + return $" 0 0/{interval} * 1/1 * ? *"; } /// @@ -228,7 +227,7 @@ /// The number of hours to wait between every activation. public static string HourInterval(int interval) { - return $"0 */{interval} * * *"; + return $"0 0 0/{interval} 1/1 * ? *"; } /// @@ -237,7 +236,7 @@ /// The number of days to wait between every activation. public static string DayInterval(int interval) { - return $"0 0 */{interval} * *"; + return $"0 0 12 1/{interval} * ? *"; } /// @@ -249,4 +248,39 @@ return $"0 0 1 */{interval} *"; } } + + // + // Summary: + // Specifies the day of the week. + public enum DayOfWeek + { + // + // Summary: + // Indicates Sunday. + Sunday = 1, + // + // Summary: + // Indicates Monday. + Monday = 2, + // + // Summary: + // Indicates Tuesday. + Tuesday = 3, + // + // Summary: + // Indicates Wednesday. + Wednesday = 4, + // + // Summary: + // Indicates Thursday. + Thursday = 5, + // + // Summary: + // Indicates Friday. + Friday = 6, + // + // Summary: + // Indicates Saturday. + Saturday = 7 + } } \ No newline at end of file diff --git a/src/Ombi.Schedule/JobSetup.cs b/src/Ombi.Schedule/JobSetup.cs index 1f3752c78..f0f53f128 100644 --- a/src/Ombi.Schedule/JobSetup.cs +++ b/src/Ombi.Schedule/JobSetup.cs @@ -65,24 +65,24 @@ namespace Ombi.Schedule { var s = _jobSettings.GetSettings(); - RecurringJob.AddOrUpdate(() => _embyContentSync.Start(), JobSettingsHelper.EmbyContent(s)); - RecurringJob.AddOrUpdate(() => _sonarrSync.Start(), JobSettingsHelper.Sonarr(s)); - RecurringJob.AddOrUpdate(() => _radarrSync.CacheContent(), JobSettingsHelper.Radarr(s)); - //RecurringJob.AddOrUpdate(() => _plexContentSync.Execute(null), JobSettingsHelper.PlexContent(s)); - //RecurringJob.AddOrUpdate(() => _plexRecentlyAddedSync.Start(), JobSettingsHelper.PlexRecentlyAdded(s)); - RecurringJob.AddOrUpdate(() => _cpCache.Start(), JobSettingsHelper.CouchPotato(s)); - RecurringJob.AddOrUpdate(() => _srSync.Start(), JobSettingsHelper.SickRageSync(s)); - RecurringJob.AddOrUpdate(() => _refreshMetadata.Start(), JobSettingsHelper.RefreshMetadata(s)); - RecurringJob.AddOrUpdate(() => _lidarrArtistSync.CacheContent(), JobSettingsHelper.LidarrArtistSync(s)); - RecurringJob.AddOrUpdate(() => _issuesPurge.Start(), JobSettingsHelper.IssuePurge(s)); + // RecurringJob.AddOrUpdate(() => _embyContentSync.Start(), JobSettingsHelper.EmbyContent(s)); + // RecurringJob.AddOrUpdate(() => _sonarrSync.Start(), JobSettingsHelper.Sonarr(s)); + // RecurringJob.AddOrUpdate(() => _radarrSync.CacheContent(), JobSettingsHelper.Radarr(s)); + // //RecurringJob.AddOrUpdate(() => _plexContentSync.Execute(null), JobSettingsHelper.PlexContent(s)); + // //RecurringJob.AddOrUpdate(() => _plexRecentlyAddedSync.Start(), JobSettingsHelper.PlexRecentlyAdded(s)); + // RecurringJob.AddOrUpdate(() => _cpCache.Start(), JobSettingsHelper.CouchPotato(s)); + // RecurringJob.AddOrUpdate(() => _srSync.Start(), JobSettingsHelper.SickRageSync(s)); + // RecurringJob.AddOrUpdate(() => _refreshMetadata.Start(), JobSettingsHelper.RefreshMetadata(s)); + // RecurringJob.AddOrUpdate(() => _lidarrArtistSync.CacheContent(), JobSettingsHelper.LidarrArtistSync(s)); + // RecurringJob.AddOrUpdate(() => _issuesPurge.Start(), JobSettingsHelper.IssuePurge(s)); - RecurringJob.AddOrUpdate(() => _updater.Update(null), JobSettingsHelper.Updater(s)); + // RecurringJob.AddOrUpdate(() => _updater.Update(null), JobSettingsHelper.Updater(s)); - RecurringJob.AddOrUpdate(() => _embyUserImporter.Start(), JobSettingsHelper.UserImporter(s)); - RecurringJob.AddOrUpdate(() => _plexUserImporter.Start(), JobSettingsHelper.UserImporter(s)); - RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s)); - // RecurringJob.AddOrUpdate(() => _resender.Start(), JobSettingsHelper.ResendFailedRequests(s)); - RecurringJob.AddOrUpdate(() => _mediaDatabaseRefresh.Start(), JobSettingsHelper.MediaDatabaseRefresh(s)); + // RecurringJob.AddOrUpdate(() => _embyUserImporter.Start(), JobSettingsHelper.UserImporter(s)); + // RecurringJob.AddOrUpdate(() => _plexUserImporter.Start(), JobSettingsHelper.UserImporter(s)); + // RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s)); + //// RecurringJob.AddOrUpdate(() => _resender.Start(), JobSettingsHelper.ResendFailedRequests(s)); + // RecurringJob.AddOrUpdate(() => _mediaDatabaseRefresh.Start(), JobSettingsHelper.MediaDatabaseRefresh(s)); } private bool _disposed; diff --git a/src/Ombi.Schedule/Jobs/Couchpotato/CouchPotatoSync.cs b/src/Ombi.Schedule/Jobs/Couchpotato/CouchPotatoSync.cs index 5e9f13534..ca848e56f 100644 --- a/src/Ombi.Schedule/Jobs/Couchpotato/CouchPotatoSync.cs +++ b/src/Ombi.Schedule/Jobs/Couchpotato/CouchPotatoSync.cs @@ -36,6 +36,7 @@ using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; +using Quartz; namespace Ombi.Schedule.Jobs.Couchpotato { @@ -56,7 +57,7 @@ namespace Ombi.Schedule.Jobs.Couchpotato private readonly ILogger _log; private readonly IExternalContext _ctx; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { var settings = await _settings.GetSettingsAsync(); if (!settings.Enabled) diff --git a/src/Ombi.Schedule/Jobs/Couchpotato/ICouchPotatoSync.cs b/src/Ombi.Schedule/Jobs/Couchpotato/ICouchPotatoSync.cs index caa390834..fa23d5030 100644 --- a/src/Ombi.Schedule/Jobs/Couchpotato/ICouchPotatoSync.cs +++ b/src/Ombi.Schedule/Jobs/Couchpotato/ICouchPotatoSync.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Couchpotato { public interface ICouchPotatoSync : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs index 7007b3743..929f8d7b9 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs @@ -37,6 +37,7 @@ using Ombi.Notifications.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; +using Quartz; namespace Ombi.Schedule.Jobs.Emby { @@ -58,7 +59,7 @@ namespace Ombi.Schedule.Jobs.Emby private readonly INotificationService _notificationService; private readonly ILogger _log; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { await ProcessMovies(); await ProcessTv(); diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index e22c0ca51..656719a1f 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -12,6 +12,7 @@ using Ombi.Helpers; using Ombi.Schedule.Jobs.Ombi; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Quartz; using Serilog; using EmbyMediaType = Ombi.Store.Entities.EmbyMediaType; @@ -38,7 +39,7 @@ namespace Ombi.Schedule.Jobs.Emby private readonly IRefreshMetadata _metadata; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { var embySettings = await _settings.GetSettingsAsync(); if (!embySettings.Enable) @@ -57,8 +58,8 @@ namespace Ombi.Schedule.Jobs.Emby } // Episodes - BackgroundJob.Enqueue(() => _episodeSync.Start()); - BackgroundJob.Enqueue(() => _metadata.Start()); + //BackgroundJob.Enqueue(() => _episodeSync.Start()); + //BackgroundJob.Enqueue(() => _metadata.Start()); } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index 962b08cda..82dbb06a0 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -36,6 +36,7 @@ using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Quartz; namespace Ombi.Schedule.Jobs.Emby { @@ -58,7 +59,7 @@ namespace Ombi.Schedule.Jobs.Emby private readonly IEmbyAvaliabilityChecker _avaliabilityChecker; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { var settings = await _settings.GetSettingsAsync(); @@ -67,7 +68,7 @@ namespace Ombi.Schedule.Jobs.Emby await CacheEpisodes(server); } - BackgroundJob.Enqueue(() => _avaliabilityChecker.Start()); + //BackgroundJob.Enqueue(() => _avaliabilityChecker.Start()); } private async Task CacheEpisodes(EmbyServers server) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs index 280a61ab4..5cb7b368d 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyUserImporter.cs @@ -37,6 +37,7 @@ using Ombi.Core.Settings.Models.External; using Ombi.Helpers; using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; +using Quartz; namespace Ombi.Schedule.Jobs.Emby { @@ -58,7 +59,7 @@ namespace Ombi.Schedule.Jobs.Emby private readonly ISettingsService _embySettings; private readonly ISettingsService _userManagementSettings; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { var userManagementSettings = await _userManagementSettings.GetSettingsAsync(); if (!userManagementSettings.ImportEmbyUsers) diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs index ce9792f3b..ce2d7dba7 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyAvaliabilityChecker.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Emby { public interface IEmbyAvaliabilityChecker : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs index 5ba8ea6f9..8dd85bab4 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyContentSync.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Emby { public interface IEmbyContentSync : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs index 42d761832..bff623ff8 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyEpisodeSync.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Emby { public interface IEmbyEpisodeSync : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs b/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs index c8bd6fc0e..1c3a51340 100644 --- a/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Emby/IEmbyUserImporter.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Emby { public interface IEmbyUserImporter : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/IBaseJob.cs b/src/Ombi.Schedule/Jobs/IBaseJob.cs index d43d21b9a..bec0db7a0 100644 --- a/src/Ombi.Schedule/Jobs/IBaseJob.cs +++ b/src/Ombi.Schedule/Jobs/IBaseJob.cs @@ -25,11 +25,12 @@ // ************************************************************************/ #endregion +using Quartz; using System; namespace Ombi.Schedule { - public interface IBaseJob : IDisposable + public interface IBaseJob : IJob, IDisposable { } diff --git a/src/Ombi.Schedule/Jobs/Lidarr/ILidarrArtistSync.cs b/src/Ombi.Schedule/Jobs/Lidarr/ILidarrArtistSync.cs index 1d3424756..3ba74e7cf 100644 --- a/src/Ombi.Schedule/Jobs/Lidarr/ILidarrArtistSync.cs +++ b/src/Ombi.Schedule/Jobs/Lidarr/ILidarrArtistSync.cs @@ -1,12 +1,12 @@ using System.Collections.Generic; using System.Threading.Tasks; using Ombi.Store.Entities; +using Quartz; namespace Ombi.Schedule.Jobs.Lidarr { - public interface ILidarrArtistSync + public interface ILidarrArtistSync : IJob { - Task CacheContent(); void Dispose(); Task> GetCachedContent(); } diff --git a/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs b/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs index e9a64f2a3..200c50223 100644 --- a/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs +++ b/src/Ombi.Schedule/Jobs/Lidarr/LidarrArtistSync.cs @@ -11,6 +11,7 @@ using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; +using Quartz; using ILogger = Microsoft.Extensions.Logging.ILogger; namespace Ombi.Schedule.Jobs.Lidarr @@ -35,7 +36,7 @@ namespace Ombi.Schedule.Jobs.Lidarr private readonly IBackgroundJobClient _job; private readonly ILidarrAlbumSync _albumSync; - public async Task CacheContent() + public async Task Execute(IJobExecutionContext job) { try { diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IIssuesPurge.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IIssuesPurge.cs index fbd1e3aaf..d72b062ce 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IIssuesPurge.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IIssuesPurge.cs @@ -3,7 +3,6 @@ namespace Ombi.Schedule.Jobs.Ombi { public interface IIssuesPurge : IBaseJob - { - Task Start(); + { } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IMediaDatabaseRefresh.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IMediaDatabaseRefresh.cs index 11fe7c51a..06ac9421c 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IMediaDatabaseRefresh.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IMediaDatabaseRefresh.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Plex.Interfaces { public interface IMediaDatabaseRefresh : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/INewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/INewsletterJob.cs index 887508d34..d8b5c3f3f 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/INewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/INewsletterJob.cs @@ -5,7 +5,6 @@ namespace Ombi.Schedule.Jobs.Ombi { public interface INewsletterJob : IBaseJob { - Task Start(); Task Start(NewsletterSettings settings, bool test); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs index 48f03b65d..484700c85 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IOmbiAutomaticUpdater.cs @@ -5,7 +5,6 @@ namespace Ombi.Schedule.Jobs.Ombi { public interface IOmbiAutomaticUpdater : IBaseJob { - Task Update(PerformContext context); string[] GetVersion(); Task UpdateAvailable(string branch, string currentVersion); } diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IRefreshMetadata.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IRefreshMetadata.cs index ed13280b0..a7e7d5fdc 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IRefreshMetadata.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IRefreshMetadata.cs @@ -5,7 +5,6 @@ namespace Ombi.Schedule.Jobs.Ombi { public interface IRefreshMetadata : IBaseJob { - Task Start(); Task ProcessPlexServerContent(IEnumerable contentIds); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IResendFailedRequests.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IResendFailedRequests.cs index b55c0f69b..c740b71d9 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IResendFailedRequests.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IResendFailedRequests.cs @@ -1,9 +1,9 @@ -using System.Threading.Tasks; +using Quartz; +using System.Threading.Tasks; namespace Ombi.Schedule.Jobs.Ombi { - public interface IResendFailedRequests + public interface IResendFailedRequests : IJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IWelcomeEmail.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IWelcomeEmail.cs index 6b1270669..b4be7cbef 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IWelcomeEmail.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IWelcomeEmail.cs @@ -3,7 +3,7 @@ using Ombi.Store.Entities; namespace Ombi.Schedule.Jobs.Ombi { - public interface IWelcomeEmail : IBaseJob + public interface IWelcomeEmail { Task SendEmail(OmbiUser user); } diff --git a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs index 5af4b565d..6a16aad70 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/Interfaces/IssuesPurge.cs @@ -5,6 +5,7 @@ using Ombi.Core.Settings; using Ombi.Settings.Settings.Models; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; +using Quartz; namespace Ombi.Schedule.Jobs.Ombi { @@ -20,7 +21,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly IRepository _issuesRepository; private readonly ISettingsService _settings; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { var settings = await _settings.GetSettingsAsync(); if (!settings.DeleteIssues) diff --git a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs index fcf8529ce..8dc8fcf1f 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs @@ -9,6 +9,7 @@ using Ombi.Helpers; using Ombi.Schedule.Jobs.Emby; using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Store.Repository; +using Quartz; namespace Ombi.Schedule.Jobs.Ombi { @@ -31,7 +32,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly IEmbyContentRepository _embyRepo; private readonly IEmbyContentSync _embyContentSync; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { try { @@ -60,7 +61,7 @@ namespace Ombi.Schedule.Jobs.Ombi await _embyRepo.ExecuteSql(episodeSQL); await _embyRepo.ExecuteSql(mainSql); - BackgroundJob.Enqueue(() => _embyContentSync.Start()); + //BackgroundJob.Enqueue(() => _embyContentSync.Start()); // TODO } catch (Exception e) { diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs index 12415f6e4..84798cc61 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs @@ -26,6 +26,7 @@ using Ombi.Settings.Settings.Models.External; using Ombi.Settings.Settings.Models.Notifications; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Quartz; using ContentType = Ombi.Store.Entities.ContentType; namespace Ombi.Schedule.Jobs.Ombi @@ -288,7 +289,7 @@ namespace Ombi.Schedule.Jobs.Ombi } } - public async Task Start() + public async Task Execute(IJobExecutionContext job) { var newsletterSettings = await _newsletterSettings.GetSettingsAsync(); await Start(newsletterSettings, false); diff --git a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs index 783fe5f9d..4c66b2e2f 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs @@ -20,6 +20,7 @@ using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Updater; +using Quartz; using SharpCompress.Readers; using SharpCompress.Readers.Tar; @@ -41,7 +42,6 @@ namespace Ombi.Schedule.Jobs.Ombi private IChangeLogProcessor Processor { get; } private ISettingsService Settings { get; } private readonly IProcessProvider _processProvider; - private static PerformContext Ctx { get; set; } private readonly IApplicationConfigRepository _appConfig; public string[] GetVersion() @@ -59,10 +59,8 @@ namespace Ombi.Schedule.Jobs.Ombi } - [AutomaticRetry(Attempts = 1)] - public async Task Update(PerformContext c) + public async Task Execute(IJobExecutionContext job) { - Ctx = c; Logger.LogDebug(LoggingEvents.Updater, "Starting Update job"); var settings = await Settings.GetSettingsAsync(); @@ -182,7 +180,7 @@ namespace Ombi.Schedule.Jobs.Ombi } Logger.LogDebug(LoggingEvents.Updater, "Starting Download"); - await DownloadAsync(download.Url, zipDir, c); + await DownloadAsync(download.Url, zipDir); Logger.LogDebug(LoggingEvents.Updater, "Finished Download"); } catch (Exception e) @@ -321,7 +319,7 @@ namespace Ombi.Schedule.Jobs.Ombi } } - public async Task DownloadAsync(string requestUri, string filename, PerformContext ctx) + public async Task DownloadAsync(string requestUri, string filename) { Logger.LogDebug(LoggingEvents.Updater, "Starting the DownloadAsync"); using (var client = new WebClient()) diff --git a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs index c9ba5c6b3..b1240593d 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs @@ -15,6 +15,7 @@ using Ombi.Schedule.Jobs.Emby; using Ombi.Schedule.Jobs.Plex; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Quartz; namespace Ombi.Schedule.Jobs.Ombi { @@ -48,7 +49,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly ISettingsService _embySettings; private readonly IEmbyApi _embyApi; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { _log.LogInformation("Starting the Metadata refresh"); try @@ -93,12 +94,12 @@ namespace Ombi.Schedule.Jobs.Ombi { if (plexSettings.Enable) { - BackgroundJob.Enqueue(() => _plexAvailabilityChecker.Start()); + //BackgroundJob.Enqueue(() => _plexAvailabilityChecker.Start()); // TODO } if (embySettings.Enable) { - BackgroundJob.Enqueue(() => _embyAvaliabilityChecker.Start()); + //BackgroundJob.Enqueue(() => _embyAvaliabilityChecker.Start()); // TODO } } diff --git a/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs b/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs index bc8f93a97..344e3a874 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs @@ -7,6 +7,7 @@ using Ombi.Core.Senders; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; +using Quartz; namespace Ombi.Schedule.Jobs.Ombi { @@ -32,7 +33,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly ITvRequestRepository _tvRequestRepository; private readonly IMusicRequestRepository _musicRequestRepository; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { // Get all the failed ones! var failedRequests = _requestQueue.GetAll().Where(x => !x.Completed.HasValue); diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs index 2d115ab88..112e3be38 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexAvailabilityChecker.cs @@ -5,6 +5,5 @@ namespace Ombi.Schedule.Jobs.Plex { public interface IPlexAvailabilityChecker : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs index 7de7c3c0c..8eed35066 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexEpisodeSync.cs @@ -9,7 +9,6 @@ namespace Ombi.Schedule.Jobs.Plex.Interfaces { public interface IPlexEpisodeSync : IBaseJob { - Task Start(); Task> ProcessEpsiodes(Metadata[] episodes, IQueryable currentEpisodes); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs index 431ce3ee3..fede60475 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexUserImporter.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Plex { public interface IPlexUserImporter : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs index e0278f854..9a7a8601a 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs @@ -12,6 +12,7 @@ using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; +using Quartz; namespace Ombi.Schedule.Jobs.Plex { @@ -35,7 +36,7 @@ namespace Ombi.Schedule.Jobs.Plex private readonly IBackgroundJobClient _backgroundJobClient; private readonly ILogger _log; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { try { diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index 3131e5963..add1a9674 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -105,7 +105,7 @@ namespace Ombi.Schedule.Jobs.Plex if (!recentlyAddedSearch) { Logger.LogInformation("Starting EP Cacher"); - BackgroundJob.Enqueue(() => EpisodeSync.Start()); + //BackgroundJob.Enqueue(() => EpisodeSync.Start()); //TODO } if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch) @@ -116,7 +116,7 @@ namespace Ombi.Schedule.Jobs.Plex if ((processedContent?.HasProcessedEpisodes ?? false) && recentlyAddedSearch) { - BackgroundJob.Enqueue(() => Checker.Start()); + //BackgroundJob.Enqueue(() => Checker.Start()); // TODO } } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index 5652d126b..7e751d0d9 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -13,6 +13,7 @@ using Ombi.Helpers; using Ombi.Schedule.Jobs.Plex.Interfaces; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Quartz; namespace Ombi.Schedule.Jobs.Plex { @@ -35,7 +36,7 @@ namespace Ombi.Schedule.Jobs.Plex private readonly IPlexContentRepository _repo; private readonly IPlexAvailabilityChecker _availabilityChecker; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { try { @@ -56,7 +57,7 @@ namespace Ombi.Schedule.Jobs.Plex _log.LogError(LoggingEvents.Cacher, e, "Caching Episodes Failed"); } - BackgroundJob.Enqueue(() => _availabilityChecker.Start()); + //BackgroundJob.Enqueue(() => _availabilityChecker.Start()); // TODO } private async Task Cache(PlexServers settings) diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs index 53c82465c..7d30d780a 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexUserImporter.cs @@ -11,6 +11,7 @@ using Ombi.Core.Settings.Models.External; using Ombi.Helpers; using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; +using Quartz; namespace Ombi.Schedule.Jobs.Plex { @@ -35,7 +36,7 @@ namespace Ombi.Schedule.Jobs.Plex private readonly ISettingsService _userManagementSettings; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { var userManagementSettings = await _userManagementSettings.GetSettingsAsync(); if (!userManagementSettings.ImportPlexUsers) diff --git a/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs index a9f8edfcd..1fb191fd1 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs @@ -6,7 +6,6 @@ namespace Ombi.Schedule.Jobs.Radarr { public interface IRadarrSync : IBaseJob { - Task CacheContent(); Task> GetCachedContent(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs index 5c954def8..8212aad3b 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs @@ -10,6 +10,7 @@ using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; +using Quartz; using Serilog; namespace Ombi.Schedule.Jobs.Radarr @@ -32,7 +33,7 @@ namespace Ombi.Schedule.Jobs.Radarr private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1); - public async Task CacheContent() + public async Task Execute(IJobExecutionContext job) { await SemaphoreSlim.WaitAsync(); try diff --git a/src/Ombi.Schedule/Jobs/SickRage/ISickRageSync.cs b/src/Ombi.Schedule/Jobs/SickRage/ISickRageSync.cs index df51698fe..2fcd435a8 100644 --- a/src/Ombi.Schedule/Jobs/SickRage/ISickRageSync.cs +++ b/src/Ombi.Schedule/Jobs/SickRage/ISickRageSync.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.SickRage { public interface ISickRageSync : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs b/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs index 92e0c2d55..8c5652f3a 100644 --- a/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs +++ b/src/Ombi.Schedule/Jobs/SickRage/SickRageSync.cs @@ -11,6 +11,7 @@ using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; +using Quartz; namespace Ombi.Schedule.Jobs.SickRage { @@ -30,7 +31,7 @@ namespace Ombi.Schedule.Jobs.SickRage private readonly ILogger _log; private readonly IExternalContext _ctx; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { try { diff --git a/src/Ombi.Schedule/Jobs/Sonarr/ISonarrSync.cs b/src/Ombi.Schedule/Jobs/Sonarr/ISonarrSync.cs index a1ba9f3c2..f190be3c5 100644 --- a/src/Ombi.Schedule/Jobs/Sonarr/ISonarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Sonarr/ISonarrSync.cs @@ -4,6 +4,5 @@ namespace Ombi.Schedule.Jobs.Sonarr { public interface ISonarrSync : IBaseJob { - Task Start(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs index e4c00c726..eaa285cc7 100644 --- a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs @@ -14,6 +14,7 @@ using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; +using Quartz; namespace Ombi.Schedule.Jobs.Sonarr { @@ -33,7 +34,7 @@ namespace Ombi.Schedule.Jobs.Sonarr private readonly ILogger _log; private readonly IExternalContext _ctx; - public async Task Start() + public async Task Execute(IJobExecutionContext job) { try { diff --git a/src/Ombi.Schedule/Ombi.Schedule.csproj b/src/Ombi.Schedule/Ombi.Schedule.csproj index 15128f768..ef6b1d447 100644 --- a/src/Ombi.Schedule/Ombi.Schedule.csproj +++ b/src/Ombi.Schedule/Ombi.Schedule.csproj @@ -17,7 +17,7 @@ - + diff --git a/src/Ombi.Schedule/OmbiQuartz.cs b/src/Ombi.Schedule/OmbiQuartz.cs index 20c12bf23..de9209738 100644 --- a/src/Ombi.Schedule/OmbiQuartz.cs +++ b/src/Ombi.Schedule/OmbiQuartz.cs @@ -35,7 +35,6 @@ namespace Ombi.Schedule return Scheduler; } - public async void AddJob(string name, string group, string cronExpression, Dictionary jobData = null) where T : IJob { @@ -49,13 +48,13 @@ namespace Ombi.Schedule } } - var job = jobBuilder.Build(); - - + var job = jobBuilder.Build(); ITrigger jobTrigger = TriggerBuilder.Create() .WithIdentity(name + "Trigger", group) - .StartNow() + + .StartNow() + .WithCronSchedule(cronExpression) .Build(); diff --git a/src/Ombi.Schedule/OmbiScheduler.cs b/src/Ombi.Schedule/OmbiScheduler.cs index f728a9ba4..17b68fdd9 100644 --- a/src/Ombi.Schedule/OmbiScheduler.cs +++ b/src/Ombi.Schedule/OmbiScheduler.cs @@ -2,7 +2,16 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Builder; using Ombi.Core.Settings; +using Ombi.Schedule.Jobs; +using Ombi.Schedule.Jobs.Couchpotato; +using Ombi.Schedule.Jobs.Emby; +using Ombi.Schedule.Jobs.Lidarr; +using Ombi.Schedule.Jobs.Ombi; using Ombi.Schedule.Jobs.Plex; +using Ombi.Schedule.Jobs.Plex.Interfaces; +using Ombi.Schedule.Jobs.Radarr; +using Ombi.Schedule.Jobs.SickRage; +using Ombi.Schedule.Jobs.Sonarr; using Ombi.Settings.Settings.Models; using Quartz; using Quartz.Spi; @@ -38,12 +47,48 @@ namespace Ombi.Schedule // Set job factory OmbiQuartz.Instance.UseJobFactory(jobFactory); - // Run configuration - OmbiQuartz.Instance.AddJob(nameof(PlexContentSync), "Plex", JobSettingsHelper.PlexContent(s), new Dictionary{{ "recentlyAddedSearch", "false" } }); - OmbiQuartz.Instance.AddJob(nameof(PlexContentSync), "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "true" } }); - // Run Quartz OmbiQuartz.Start(); + + // Run configuration + AddPlex(s); + AddEmby(s); + AddDvrApps(s); + AddSystem(s); + + } + + private static void AddSystem(JobSettings s) + { + OmbiQuartz.Instance.AddJob(nameof(IRefreshMetadata), "System", JobSettingsHelper.RefreshMetadata(s)); + OmbiQuartz.Instance.AddJob(nameof(IIssuesPurge), "System", JobSettingsHelper.IssuePurge(s)); + //OmbiQuartz.Instance.AddJob(nameof(IOmbiAutomaticUpdater), "System", JobSettingsHelper.Updater(s)); + OmbiQuartz.Instance.AddJob(nameof(INewsletterJob), "System", JobSettingsHelper.Newsletter(s)); + OmbiQuartz.Instance.AddJob(nameof(IResendFailedRequests), "System", JobSettingsHelper.ResendFailedRequests(s)); + OmbiQuartz.Instance.AddJob(nameof(IMediaDatabaseRefresh), "System", JobSettingsHelper.MediaDatabaseRefresh(s)); + } + + private static void AddDvrApps(JobSettings s) + { + OmbiQuartz.Instance.AddJob(nameof(ISonarrSync), "DVR", JobSettingsHelper.Sonarr(s)); + OmbiQuartz.Instance.AddJob(nameof(IRadarrSync), "DVR", JobSettingsHelper.Radarr(s)); + OmbiQuartz.Instance.AddJob(nameof(ICouchPotatoSync), "DVR", JobSettingsHelper.CouchPotato(s)); + OmbiQuartz.Instance.AddJob(nameof(ISickRageSync), "DVR", JobSettingsHelper.SickRageSync(s)); + OmbiQuartz.Instance.AddJob(nameof(ILidarrArtistSync), "DVR", JobSettingsHelper.LidarrArtistSync(s)); + } + + private static void AddPlex(JobSettings s) + { + OmbiQuartz.Instance.AddJob(nameof(IPlexContentSync), "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "false" } }); + OmbiQuartz.Instance.AddJob(nameof(IPlexContentSync) + "RecentlyAdded", "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "true" } }); + OmbiQuartz.Instance.AddJob(nameof(IPlexRecentlyAddedSync), "Plex", JobSettingsHelper.PlexRecentlyAdded(s)); + OmbiQuartz.Instance.AddJob(nameof(IPlexUserImporter), "Plex", JobSettingsHelper.UserImporter(s)); + } + + private static void AddEmby(JobSettings s) + { + OmbiQuartz.Instance.AddJob(nameof(IEmbyContentSync), "Emby", JobSettingsHelper.EmbyContent(s)); + OmbiQuartz.Instance.AddJob(nameof(IEmbyUserImporter), "Emby", JobSettingsHelper.UserImporter(s)); } } } \ No newline at end of file diff --git a/src/Ombi.Settings/Ombi.Settings.csproj b/src/Ombi.Settings/Ombi.Settings.csproj index 6db0768aa..39e53c9ff 100644 --- a/src/Ombi.Settings/Ombi.Settings.csproj +++ b/src/Ombi.Settings/Ombi.Settings.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs index e2080e3cb..e03ba28ba 100644 --- a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs +++ b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs @@ -13,6 +13,7 @@ namespace Ombi.Settings.Settings.Models public static string Sonarr(JobSettings s) { return Get(s.SonarrSync, Cron.Hourly(10)); + //return Get(s.SonarrSync, Cron.Hourly(10)); } public static string EmbyContent(JobSettings s) @@ -42,7 +43,7 @@ namespace Ombi.Settings.Settings.Models } public static string Newsletter(JobSettings s) { - return Get(s.Newsletter, Cron.Weekly(DayOfWeek.Friday, 12)); + return Get(s.Newsletter, Cron.Weekly(Helpers.DayOfWeek.Friday, 12)); } public static string SickRageSync(JobSettings s) { diff --git a/src/Ombi/Controllers/JobController.cs b/src/Ombi/Controllers/JobController.cs index d9f21f67d..42f332af4 100644 --- a/src/Ombi/Controllers/JobController.cs +++ b/src/Ombi/Controllers/JobController.cs @@ -50,7 +50,7 @@ namespace Ombi.Controllers [HttpPost("update")] public bool ForceUpdate() { - BackgroundJob.Enqueue(() => _updater.Update(null)); + //BackgroundJob.Enqueue(() => _updater.Update(null)); return true; } @@ -99,7 +99,7 @@ namespace Ombi.Controllers [HttpPost("plexuserimporter")] public bool PlexUserImporter() { - BackgroundJob.Enqueue(() => _plexUserImporter.Start()); + //BackgroundJob.Enqueue(() => _plexUserImporter.Start()); //TODO return true; } @@ -110,7 +110,7 @@ namespace Ombi.Controllers [HttpPost("embyuserimporter")] public bool EmbyUserImporter() { - BackgroundJob.Enqueue(() => _embyUserImporter.Start()); + //BackgroundJob.Enqueue(() => _embyUserImporter.Start()); // TODO return true; } @@ -143,7 +143,7 @@ namespace Ombi.Controllers [HttpPost("embycontentcacher")] public bool StartEmbyContentCacher() { - BackgroundJob.Enqueue(() => _embyContentSync.Start()); + //BackgroundJob.Enqueue(() => _embyContentSync.Start()); // TODO return true; } @@ -154,7 +154,7 @@ namespace Ombi.Controllers [HttpPost("newsletter")] public bool StartNewsletter() { - BackgroundJob.Enqueue(() => _newsletterJob.Start()); + //BackgroundJob.Enqueue(() => _newsletterJob.Start()); // TODO return true; } } diff --git a/src/Ombi/Controllers/SettingsController.cs b/src/Ombi/Controllers/SettingsController.cs index 823461e35..e77a8fd7a 100644 --- a/src/Ombi/Controllers/SettingsController.cs +++ b/src/Ombi/Controllers/SettingsController.cs @@ -387,7 +387,7 @@ namespace Ombi.Controllers { _cache.Remove(CacheKeys.RadarrRootProfiles); _cache.Remove(CacheKeys.RadarrQualityProfiles); - BackgroundJob.Enqueue(() => _radarrSync.CacheContent()); + //BackgroundJob.Enqueue(() => _radarrSync.CacheContent()); // TODO } return result; } diff --git a/src/Ombi/Startup.cs b/src/Ombi/Startup.cs index 4a46a0840..308e37a69 100644 --- a/src/Ombi/Startup.cs +++ b/src/Ombi/Startup.cs @@ -192,8 +192,8 @@ namespace Ombi GlobalJobFilters.Filters.Add(new AutomaticRetryAttribute { Attempts = 3 }); // Setup the scheduler - var jobSetup = app.ApplicationServices.GetService(); - jobSetup.Setup(); + //var jobSetup = app.ApplicationServices.GetService(); + //jobSetup.Setup(); ctx.Seed(); var settingsctx = serviceProvider.GetService(); var externalctx = serviceProvider.GetService(); From c3c0228b4557ed3208f666db5d8e6b5c77dd0eda Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Thu, 11 Apr 2019 12:56:32 +0100 Subject: [PATCH 43/58] swap out the scheduler #2750 --- src/Ombi.Schedule.Tests/IssuesPurgeTests.cs | 6 +-- src/Ombi.Schedule.Tests/OmbiQuartzTests.cs | 36 +++++++++++++ .../PlexAvailabilityCheckerTests.cs | 8 +-- .../Jobs/Emby/EmbyContentSync.cs | 10 ++-- .../Jobs/Emby/EmbyEpisodeSync.cs | 9 ++-- .../Jobs/Ombi/MediaDatabaseRefresh.cs | 6 +-- .../Jobs/Ombi/RefreshMetadata.cs | 11 ++-- .../Jobs/Plex/PlexContentSync.cs | 10 ++-- .../Jobs/Plex/PlexEpisodeSync.cs | 6 +-- src/Ombi.Schedule/OmbiQuartz.cs | 19 ++++--- src/Ombi.Schedule/OmbiScheduler.cs | 53 ++++++++++--------- src/Ombi/Controllers/JobController.cs | 21 ++++---- src/Ombi/Controllers/SettingsController.cs | 7 ++- src/Ombi/Startup.cs | 2 +- 14 files changed, 117 insertions(+), 87 deletions(-) create mode 100644 src/Ombi.Schedule.Tests/OmbiQuartzTests.cs diff --git a/src/Ombi.Schedule.Tests/IssuesPurgeTests.cs b/src/Ombi.Schedule.Tests/IssuesPurgeTests.cs index 932022cd8..1606cb2d5 100644 --- a/src/Ombi.Schedule.Tests/IssuesPurgeTests.cs +++ b/src/Ombi.Schedule.Tests/IssuesPurgeTests.cs @@ -32,7 +32,7 @@ namespace Ombi.Schedule.Tests [Test] public async Task DoesNotRun_WhenDisabled() { - await Job.Start(); + await Job.Execute(null); Repo.Verify(x => x.GetAll(),Times.Never); } @@ -50,7 +50,7 @@ namespace Ombi.Schedule.Tests Settings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new IssueSettings { DeleteIssues = true, DaysAfterResolvedToDelete = 5 }); Repo.Setup(x => x.GetAll()).Returns(new EnumerableQuery(issues)); - await Job.Start(); + await Job.Execute(null); Assert.That(issues.First().Status, Is.EqualTo(IssueStatus.Deleted)); Repo.Verify(x => x.SaveChangesAsync(), Times.Once); @@ -75,7 +75,7 @@ namespace Ombi.Schedule.Tests Settings.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new IssueSettings { DeleteIssues = true, DaysAfterResolvedToDelete = 5 }); Repo.Setup(x => x.GetAll()).Returns(new EnumerableQuery(issues)); - await Job.Start(); + await Job.Execute(null); Assert.That(issues[0].Status, Is.Not.EqualTo(IssueStatus.Deleted)); Assert.That(issues[1].Status, Is.EqualTo(IssueStatus.Deleted)); diff --git a/src/Ombi.Schedule.Tests/OmbiQuartzTests.cs b/src/Ombi.Schedule.Tests/OmbiQuartzTests.cs new file mode 100644 index 000000000..a8136a5ce --- /dev/null +++ b/src/Ombi.Schedule.Tests/OmbiQuartzTests.cs @@ -0,0 +1,36 @@ +using Moq; +using NUnit.Framework; +using Quartz; +using System.Threading; +using System.Threading.Tasks; + +namespace Ombi.Schedule.Tests +{ + [TestFixture] + public class OmbiQuartzTests + { + + [Test] + [Ignore("Cannot get this to work")] + public async Task Test() + { + var scheduleMock = new Mock(); + scheduleMock.Setup(x => x.TriggerJob(It.IsAny(), + It.IsAny())); + var sut = new QuartzMock(scheduleMock); + + await QuartzMock.TriggerJob("ABC"); + + scheduleMock.Verify(x => x.TriggerJob(It.Is(j => j.Name == "ABC"), + default(CancellationToken)), Times.Once); + } + } + public class QuartzMock : OmbiQuartz + { + public QuartzMock(Mock mock) + { + _instance = this; + _scheduler = mock.Object; + } + } +} diff --git a/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs index 55c9dc288..028c044b7 100644 --- a/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs +++ b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs @@ -46,7 +46,7 @@ namespace Ombi.Schedule.Tests _movie.Setup(x => x.GetAll()).Returns(new List { request }.AsQueryable()); _repo.Setup(x => x.Get("test")).ReturnsAsync(new PlexServerContent()); - await Checker.Start(); + await Checker.Execute(null); _movie.Verify(x => x.Save(), Times.Once); @@ -62,8 +62,8 @@ namespace Ombi.Schedule.Tests }; _movie.Setup(x => x.GetAll()).Returns(new List { request }.AsQueryable()); - await Checker.Start(); - + await Checker.Execute(null); + Assert.False(request.Available); } @@ -107,7 +107,7 @@ namespace Ombi.Schedule.Tests }.AsQueryable); _repo.Setup(x => x.Include(It.IsAny>(),It.IsAny>>())); - await Checker.Start(); + await Checker.Execute(null); _tv.Verify(x => x.Save(), Times.Once); diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 656719a1f..3e1e750ae 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -21,22 +21,18 @@ namespace Ombi.Schedule.Jobs.Emby public class EmbyContentSync : IEmbyContentSync { public EmbyContentSync(ISettingsService settings, IEmbyApi api, ILogger logger, - IEmbyContentRepository repo, IEmbyEpisodeSync epSync, IRefreshMetadata metadata) + IEmbyContentRepository repo) { _logger = logger; _settings = settings; _api = api; _repo = repo; - _episodeSync = epSync; - _metadata = metadata; } private readonly ILogger _logger; private readonly ISettingsService _settings; private readonly IEmbyApi _api; private readonly IEmbyContentRepository _repo; - private readonly IEmbyEpisodeSync _episodeSync; - private readonly IRefreshMetadata _metadata; public async Task Execute(IJobExecutionContext job) @@ -58,6 +54,10 @@ namespace Ombi.Schedule.Jobs.Emby } // Episodes + + await OmbiQuartz.TriggerJob(nameof(IEmbyEpisodeSync)); + + await OmbiQuartz.TriggerJob(nameof(IRefreshMetadata)); //BackgroundJob.Enqueue(() => _episodeSync.Start()); //BackgroundJob.Enqueue(() => _metadata.Start()); } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index 82dbb06a0..00a1b7da4 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -42,21 +42,18 @@ namespace Ombi.Schedule.Jobs.Emby { public class EmbyEpisodeSync : IEmbyEpisodeSync { - public EmbyEpisodeSync(ISettingsService s, IEmbyApi api, ILogger l, IEmbyContentRepository repo, - IEmbyAvaliabilityChecker checker) + public EmbyEpisodeSync(ISettingsService s, IEmbyApi api, ILogger l, IEmbyContentRepository repo) { _api = api; _logger = l; _settings = s; _repo = repo; - _avaliabilityChecker = checker; } private readonly ISettingsService _settings; private readonly IEmbyApi _api; private readonly ILogger _logger; private readonly IEmbyContentRepository _repo; - private readonly IEmbyAvaliabilityChecker _avaliabilityChecker; public async Task Execute(IJobExecutionContext job) @@ -68,7 +65,8 @@ namespace Ombi.Schedule.Jobs.Emby await CacheEpisodes(server); } - //BackgroundJob.Enqueue(() => _avaliabilityChecker.Start()); + + await OmbiQuartz.TriggerJob(nameof(IEmbyAvaliabilityChecker)); } private async Task CacheEpisodes(EmbyServers server) @@ -143,7 +141,6 @@ namespace Ombi.Schedule.Jobs.Emby { _settings?.Dispose(); _repo?.Dispose(); - _avaliabilityChecker?.Dispose(); } _disposed = true; } diff --git a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs index 8dc8fcf1f..82f4ec883 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs @@ -16,13 +16,12 @@ namespace Ombi.Schedule.Jobs.Ombi public class MediaDatabaseRefresh : IMediaDatabaseRefresh { public MediaDatabaseRefresh(ISettingsService s, ILogger log, - IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo, IEmbyContentSync embySync) + IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo) { _settings = s; _log = log; _plexRepo = plexRepo; _embyRepo = embyRepo; - _embyContentSync = embySync; _settings.ClearCache(); } @@ -30,7 +29,6 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly ILogger _log; private readonly IPlexContentRepository _plexRepo; private readonly IEmbyContentRepository _embyRepo; - private readonly IEmbyContentSync _embyContentSync; public async Task Execute(IJobExecutionContext job) { @@ -61,7 +59,7 @@ namespace Ombi.Schedule.Jobs.Ombi await _embyRepo.ExecuteSql(episodeSQL); await _embyRepo.ExecuteSql(mainSql); - //BackgroundJob.Enqueue(() => _embyContentSync.Start()); // TODO + await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync)); } catch (Exception e) { diff --git a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs index b1240593d..a2cebb36c 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs @@ -23,8 +23,7 @@ namespace Ombi.Schedule.Jobs.Ombi { public RefreshMetadata(IPlexContentRepository plexRepo, IEmbyContentRepository embyRepo, ILogger log, ITvMazeApi tvApi, ISettingsService plexSettings, - IMovieDbApi movieApi, ISettingsService embySettings, IPlexAvailabilityChecker plexAvailability, IEmbyAvaliabilityChecker embyAvaliability, - IEmbyApi embyApi) + IMovieDbApi movieApi, ISettingsService embySettings, IEmbyApi embyApi) { _plexRepo = plexRepo; _embyRepo = embyRepo; @@ -33,15 +32,11 @@ namespace Ombi.Schedule.Jobs.Ombi _tvApi = tvApi; _plexSettings = plexSettings; _embySettings = embySettings; - _plexAvailabilityChecker = plexAvailability; - _embyAvaliabilityChecker = embyAvaliability; _embyApi = embyApi; } private readonly IPlexContentRepository _plexRepo; private readonly IEmbyContentRepository _embyRepo; - private readonly IPlexAvailabilityChecker _plexAvailabilityChecker; - private readonly IEmbyAvaliabilityChecker _embyAvaliabilityChecker; private readonly ILogger _log; private readonly IMovieDbApi _movieApi; private readonly ITvMazeApi _tvApi; @@ -94,12 +89,12 @@ namespace Ombi.Schedule.Jobs.Ombi { if (plexSettings.Enable) { - //BackgroundJob.Enqueue(() => _plexAvailabilityChecker.Start()); // TODO + await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker)); } if (embySettings.Enable) { - //BackgroundJob.Enqueue(() => _embyAvaliabilityChecker.Start()); // TODO + await OmbiQuartz.TriggerJob(nameof(IEmbyAvaliabilityChecker)); } } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index add1a9674..f1c35abdb 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -49,7 +49,7 @@ namespace Ombi.Schedule.Jobs.Plex public class PlexContentSync : IPlexContentSync { public PlexContentSync(ISettingsService plex, IPlexApi plexApi, ILogger logger, IPlexContentRepository repo, - IPlexEpisodeSync epsiodeSync, IRefreshMetadata metadataRefresh, IPlexAvailabilityChecker checker) + IPlexEpisodeSync epsiodeSync, IRefreshMetadata metadataRefresh) { Plex = plex; PlexApi = plexApi; @@ -57,7 +57,6 @@ namespace Ombi.Schedule.Jobs.Plex Repo = repo; EpisodeSync = epsiodeSync; Metadata = metadataRefresh; - Checker = checker; Plex.ClearCache(); } @@ -67,7 +66,6 @@ namespace Ombi.Schedule.Jobs.Plex private IPlexContentRepository Repo { get; } private IPlexEpisodeSync EpisodeSync { get; } private IRefreshMetadata Metadata { get; } - private IPlexAvailabilityChecker Checker { get; } public async Task Execute(IJobExecutionContext context) { @@ -105,7 +103,8 @@ namespace Ombi.Schedule.Jobs.Plex if (!recentlyAddedSearch) { Logger.LogInformation("Starting EP Cacher"); - //BackgroundJob.Enqueue(() => EpisodeSync.Start()); //TODO + + await OmbiQuartz.TriggerJob(nameof(IPlexEpisodeSync)); } if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch) @@ -116,7 +115,8 @@ namespace Ombi.Schedule.Jobs.Plex if ((processedContent?.HasProcessedEpisodes ?? false) && recentlyAddedSearch) { - //BackgroundJob.Enqueue(() => Checker.Start()); // TODO + + await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker)); } } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index 7e751d0d9..433051e43 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -20,13 +20,12 @@ namespace Ombi.Schedule.Jobs.Plex public class PlexEpisodeSync : IPlexEpisodeSync { public PlexEpisodeSync(ISettingsService s, ILogger log, IPlexApi plexApi, - IPlexContentRepository repo, IPlexAvailabilityChecker a) + IPlexContentRepository repo) { _settings = s; _log = log; _api = plexApi; _repo = repo; - _availabilityChecker = a; _settings.ClearCache(); } @@ -34,7 +33,6 @@ namespace Ombi.Schedule.Jobs.Plex private readonly ILogger _log; private readonly IPlexApi _api; private readonly IPlexContentRepository _repo; - private readonly IPlexAvailabilityChecker _availabilityChecker; public async Task Execute(IJobExecutionContext job) { @@ -57,6 +55,8 @@ namespace Ombi.Schedule.Jobs.Plex _log.LogError(LoggingEvents.Cacher, e, "Caching Episodes Failed"); } + + await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker)); //BackgroundJob.Enqueue(() => _availabilityChecker.Start()); // TODO } diff --git a/src/Ombi.Schedule/OmbiQuartz.cs b/src/Ombi.Schedule/OmbiQuartz.cs index de9209738..1eb509b08 100644 --- a/src/Ombi.Schedule/OmbiQuartz.cs +++ b/src/Ombi.Schedule/OmbiQuartz.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using Quartz; using Quartz.Impl; using Quartz.Spi; @@ -7,19 +8,19 @@ namespace Ombi.Schedule { public class OmbiQuartz { - private IScheduler _scheduler; + protected IScheduler _scheduler { get; set; } public static IScheduler Scheduler => Instance._scheduler; // Singleton - private static OmbiQuartz _instance; + protected static OmbiQuartz _instance; /// /// Singleton /// public static OmbiQuartz Instance => _instance ?? (_instance = new OmbiQuartz()); - private OmbiQuartz() + protected OmbiQuartz() { Init(); } @@ -35,7 +36,7 @@ namespace Ombi.Schedule return Scheduler; } - public async void AddJob(string name, string group, string cronExpression, Dictionary jobData = null) + public async Task AddJob(string name, string group, string cronExpression, Dictionary jobData = null) where T : IJob { var jobBuilder = JobBuilder.Create() @@ -52,16 +53,18 @@ namespace Ombi.Schedule ITrigger jobTrigger = TriggerBuilder.Create() .WithIdentity(name + "Trigger", group) - - .StartNow() - .WithCronSchedule(cronExpression) .Build(); await Scheduler.ScheduleJob(job, jobTrigger); } + + public static async Task TriggerJob(string jobName) + { + await Scheduler.TriggerJob(new JobKey(jobName)); + } - public static async void Start() + public static async Task Start() { await Scheduler.Start(); } diff --git a/src/Ombi.Schedule/OmbiScheduler.cs b/src/Ombi.Schedule/OmbiScheduler.cs index 17b68fdd9..0e000ad46 100644 --- a/src/Ombi.Schedule/OmbiScheduler.cs +++ b/src/Ombi.Schedule/OmbiScheduler.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Ombi.Core.Settings; using Ombi.Schedule.Jobs; @@ -38,7 +39,7 @@ namespace Ombi.Schedule // .Build(); //} - public static void UseQuartz(this IApplicationBuilder app) + public static async Task UseQuartz(this IApplicationBuilder app) { // Job Factory through IOC container var jobFactory = (IJobFactory)app.ApplicationServices.GetService(typeof(IJobFactory)); @@ -48,47 +49,47 @@ namespace Ombi.Schedule OmbiQuartz.Instance.UseJobFactory(jobFactory); // Run Quartz - OmbiQuartz.Start(); + await OmbiQuartz.Start(); // Run configuration - AddPlex(s); - AddEmby(s); - AddDvrApps(s); - AddSystem(s); + await AddPlex(s); + await AddEmby(s); + await AddDvrApps(s); + await AddSystem(s); } - private static void AddSystem(JobSettings s) + private static async Task AddSystem(JobSettings s) { - OmbiQuartz.Instance.AddJob(nameof(IRefreshMetadata), "System", JobSettingsHelper.RefreshMetadata(s)); - OmbiQuartz.Instance.AddJob(nameof(IIssuesPurge), "System", JobSettingsHelper.IssuePurge(s)); + await OmbiQuartz.Instance.AddJob(nameof(IRefreshMetadata), "System", JobSettingsHelper.RefreshMetadata(s)); + await OmbiQuartz.Instance.AddJob(nameof(IIssuesPurge), "System", JobSettingsHelper.IssuePurge(s)); //OmbiQuartz.Instance.AddJob(nameof(IOmbiAutomaticUpdater), "System", JobSettingsHelper.Updater(s)); - OmbiQuartz.Instance.AddJob(nameof(INewsletterJob), "System", JobSettingsHelper.Newsletter(s)); - OmbiQuartz.Instance.AddJob(nameof(IResendFailedRequests), "System", JobSettingsHelper.ResendFailedRequests(s)); - OmbiQuartz.Instance.AddJob(nameof(IMediaDatabaseRefresh), "System", JobSettingsHelper.MediaDatabaseRefresh(s)); + await OmbiQuartz.Instance.AddJob(nameof(INewsletterJob), "System", JobSettingsHelper.Newsletter(s)); + await OmbiQuartz.Instance.AddJob(nameof(IResendFailedRequests), "System", JobSettingsHelper.ResendFailedRequests(s)); + await OmbiQuartz.Instance.AddJob(nameof(IMediaDatabaseRefresh), "System", JobSettingsHelper.MediaDatabaseRefresh(s)); } - private static void AddDvrApps(JobSettings s) + private static async Task AddDvrApps(JobSettings s) { - OmbiQuartz.Instance.AddJob(nameof(ISonarrSync), "DVR", JobSettingsHelper.Sonarr(s)); - OmbiQuartz.Instance.AddJob(nameof(IRadarrSync), "DVR", JobSettingsHelper.Radarr(s)); - OmbiQuartz.Instance.AddJob(nameof(ICouchPotatoSync), "DVR", JobSettingsHelper.CouchPotato(s)); - OmbiQuartz.Instance.AddJob(nameof(ISickRageSync), "DVR", JobSettingsHelper.SickRageSync(s)); - OmbiQuartz.Instance.AddJob(nameof(ILidarrArtistSync), "DVR", JobSettingsHelper.LidarrArtistSync(s)); + await OmbiQuartz.Instance.AddJob(nameof(ISonarrSync), "DVR", JobSettingsHelper.Sonarr(s)); + await OmbiQuartz.Instance.AddJob(nameof(IRadarrSync), "DVR", JobSettingsHelper.Radarr(s)); + await OmbiQuartz.Instance.AddJob(nameof(ICouchPotatoSync), "DVR", JobSettingsHelper.CouchPotato(s)); + await OmbiQuartz.Instance.AddJob(nameof(ISickRageSync), "DVR", JobSettingsHelper.SickRageSync(s)); + await OmbiQuartz.Instance.AddJob(nameof(ILidarrArtistSync), "DVR", JobSettingsHelper.LidarrArtistSync(s)); } - private static void AddPlex(JobSettings s) + private static async Task AddPlex(JobSettings s) { - OmbiQuartz.Instance.AddJob(nameof(IPlexContentSync), "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "false" } }); - OmbiQuartz.Instance.AddJob(nameof(IPlexContentSync) + "RecentlyAdded", "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "true" } }); - OmbiQuartz.Instance.AddJob(nameof(IPlexRecentlyAddedSync), "Plex", JobSettingsHelper.PlexRecentlyAdded(s)); - OmbiQuartz.Instance.AddJob(nameof(IPlexUserImporter), "Plex", JobSettingsHelper.UserImporter(s)); + await OmbiQuartz.Instance.AddJob(nameof(IPlexContentSync), "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "false" } }); + await OmbiQuartz.Instance.AddJob(nameof(IPlexContentSync) + "RecentlyAdded", "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "true" } }); + await OmbiQuartz.Instance.AddJob(nameof(IPlexRecentlyAddedSync), "Plex", JobSettingsHelper.PlexRecentlyAdded(s)); + await OmbiQuartz.Instance.AddJob(nameof(IPlexUserImporter), "Plex", JobSettingsHelper.UserImporter(s)); } - private static void AddEmby(JobSettings s) + private static async Task AddEmby(JobSettings s) { - OmbiQuartz.Instance.AddJob(nameof(IEmbyContentSync), "Emby", JobSettingsHelper.EmbyContent(s)); - OmbiQuartz.Instance.AddJob(nameof(IEmbyUserImporter), "Emby", JobSettingsHelper.UserImporter(s)); + await OmbiQuartz.Instance.AddJob(nameof(IEmbyContentSync), "Emby", JobSettingsHelper.EmbyContent(s)); + await OmbiQuartz.Instance.AddJob(nameof(IEmbyUserImporter), "Emby", JobSettingsHelper.UserImporter(s)); } } } \ No newline at end of file diff --git a/src/Ombi/Controllers/JobController.cs b/src/Ombi/Controllers/JobController.cs index 42f332af4..e9fd987ba 100644 --- a/src/Ombi/Controllers/JobController.cs +++ b/src/Ombi/Controllers/JobController.cs @@ -48,9 +48,10 @@ namespace Ombi.Controllers /// /// [HttpPost("update")] - public bool ForceUpdate() + public async Task ForceUpdate() { - //BackgroundJob.Enqueue(() => _updater.Update(null)); + + await OmbiQuartz.TriggerJob(nameof(IOmbiAutomaticUpdater)); return true; } @@ -97,9 +98,9 @@ namespace Ombi.Controllers /// /// [HttpPost("plexuserimporter")] - public bool PlexUserImporter() + public async Task PlexUserImporter() { - //BackgroundJob.Enqueue(() => _plexUserImporter.Start()); //TODO + await OmbiQuartz.TriggerJob(nameof(IPlexUserImporter)); return true; } @@ -108,9 +109,9 @@ namespace Ombi.Controllers /// /// [HttpPost("embyuserimporter")] - public bool EmbyUserImporter() + public async Task EmbyUserImporter() { - //BackgroundJob.Enqueue(() => _embyUserImporter.Start()); // TODO + await OmbiQuartz.TriggerJob(nameof(IEmbyUserImporter)); return true; } @@ -141,9 +142,9 @@ namespace Ombi.Controllers /// /// [HttpPost("embycontentcacher")] - public bool StartEmbyContentCacher() + public async Task StartEmbyContentCacher() { - //BackgroundJob.Enqueue(() => _embyContentSync.Start()); // TODO + await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync)); return true; } @@ -152,9 +153,9 @@ namespace Ombi.Controllers /// /// [HttpPost("newsletter")] - public bool StartNewsletter() + public async Task StartNewsletter() { - //BackgroundJob.Enqueue(() => _newsletterJob.Start()); // TODO + await OmbiQuartz.TriggerJob(nameof(INewsletterJob)); return true; } } diff --git a/src/Ombi/Controllers/SettingsController.cs b/src/Ombi/Controllers/SettingsController.cs index e77a8fd7a..399375f95 100644 --- a/src/Ombi/Controllers/SettingsController.cs +++ b/src/Ombi/Controllers/SettingsController.cs @@ -27,6 +27,7 @@ using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Api.Github; using Ombi.Core.Engine; +using Ombi.Schedule; namespace Ombi.Controllers { @@ -44,7 +45,6 @@ namespace Ombi.Controllers IMapper mapper, INotificationTemplatesRepository templateRepo, IEmbyApi embyApi, - IRadarrSync radarrSync, ICacheService memCache, IGithubApi githubApi, IRecentlyAddedEngine engine) @@ -53,7 +53,6 @@ namespace Ombi.Controllers Mapper = mapper; TemplateRepository = templateRepo; _embyApi = embyApi; - _radarrSync = radarrSync; _cache = memCache; _githubApi = githubApi; _recentlyAdded = engine; @@ -63,7 +62,6 @@ namespace Ombi.Controllers private IMapper Mapper { get; } private INotificationTemplatesRepository TemplateRepository { get; } private readonly IEmbyApi _embyApi; - private readonly IRadarrSync _radarrSync; private readonly ICacheService _cache; private readonly IGithubApi _githubApi; private readonly IRecentlyAddedEngine _recentlyAdded; @@ -387,7 +385,8 @@ namespace Ombi.Controllers { _cache.Remove(CacheKeys.RadarrRootProfiles); _cache.Remove(CacheKeys.RadarrQualityProfiles); - //BackgroundJob.Enqueue(() => _radarrSync.CacheContent()); // TODO + + await OmbiQuartz.TriggerJob(nameof(IRadarrSync)); } return result; } diff --git a/src/Ombi/Startup.cs b/src/Ombi/Startup.cs index 308e37a69..6f0d4a7ff 100644 --- a/src/Ombi/Startup.cs +++ b/src/Ombi/Startup.cs @@ -123,7 +123,7 @@ namespace Ombi ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); - app.UseQuartz(); + app.UseQuartz().GetAwaiter().GetResult(); var ctx = serviceProvider.GetService(); loggerFactory.AddSerilog(); From d9f338f78c19375ac8a84448f644331a28e0048c Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Thu, 11 Apr 2019 13:07:10 +0100 Subject: [PATCH 44/58] Added some validation around the new crons --- .../Settings/Models/JobSettingsHelper.cs | 54 +++++++++++++------ src/Ombi/Controllers/JobController.cs | 15 +----- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs index e03ba28ba..272ad3444 100644 --- a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs +++ b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs @@ -1,5 +1,6 @@ using System; using Ombi.Helpers; +using Quartz; namespace Ombi.Settings.Settings.Models { @@ -7,72 +8,93 @@ namespace Ombi.Settings.Settings.Models { public static string Radarr(JobSettings s) { - return Get(s.RadarrSync, Cron.Hourly(15)); + return ValidateCron(Get(s.RadarrSync, Cron.Hourly(15))); } public static string Sonarr(JobSettings s) { - return Get(s.SonarrSync, Cron.Hourly(10)); - //return Get(s.SonarrSync, Cron.Hourly(10)); + return ValidateCron(Get(s.SonarrSync, Cron.Hourly(10))); } public static string EmbyContent(JobSettings s) { - return Get(s.EmbyContentSync, Cron.Hourly(5)); + return ValidateCron(Get(s.EmbyContentSync, Cron.Hourly(5))); } + public static string PlexContent(JobSettings s) { - return Get(s.PlexContentSync, Cron.Daily(2)); + return ValidateCron(Get(s.PlexContentSync, Cron.Daily(2))); } + public static string PlexRecentlyAdded(JobSettings s) { - return Get(s.PlexRecentlyAddedSync, Cron.MinuteInterval(30)); + return ValidateCron(Get(s.PlexRecentlyAddedSync, Cron.MinuteInterval(30))); } + public static string CouchPotato(JobSettings s) { - return Get(s.CouchPotatoSync, Cron.Hourly(30)); + return ValidateCron(Get(s.CouchPotatoSync, Cron.Hourly(30))); } public static string Updater(JobSettings s) { - return Get(s.AutomaticUpdater, Cron.HourInterval(6)); + return ValidateCron(Get(s.AutomaticUpdater, Cron.HourInterval(6))); } + public static string UserImporter(JobSettings s) { - return Get(s.UserImporter, Cron.Daily()); + return ValidateCron(Get(s.UserImporter, Cron.Daily())); } + public static string Newsletter(JobSettings s) { - return Get(s.Newsletter, Cron.Weekly(Helpers.DayOfWeek.Friday, 12)); + return ValidateCron(Get(s.Newsletter, Cron.Weekly(Helpers.DayOfWeek.Friday, 12))); } + public static string SickRageSync(JobSettings s) { - return Get(s.SickRageSync, Cron.Hourly(35)); + return ValidateCron(Get(s.SickRageSync, Cron.Hourly(35))); } + public static string RefreshMetadata(JobSettings s) { - return Get(s.RefreshMetadata, Cron.DayInterval(3)); + return ValidateCron(Get(s.RefreshMetadata, Cron.DayInterval(3))); } + public static string LidarrArtistSync(JobSettings s) { - return Get(s.LidarrArtistSync, Cron.Hourly(40)); + return ValidateCron(Get(s.LidarrArtistSync, Cron.Hourly(40))); } public static string IssuePurge(JobSettings s) { - return Get(s.IssuesPurge, Cron.Daily()); + return ValidateCron(Get(s.IssuesPurge, Cron.Daily())); } + public static string ResendFailedRequests(JobSettings s) { - return Get(s.RetryRequests, Cron.Daily(6)); + return ValidateCron(Get(s.RetryRequests, Cron.Daily(6))); } + public static string MediaDatabaseRefresh(JobSettings s) { - return Get(s.MediaDatabaseRefresh, Cron.DayInterval(5)); + return ValidateCron(Get(s.MediaDatabaseRefresh, Cron.DayInterval(5))); } + private static string Get(string settings, string defaultCron) { return settings.HasValue() ? settings : defaultCron; } + + private const string _defaultCron = "0 0 12 1/1 * ? *"; + + private static string ValidateCron(string cron) + { + if (CronExpression.IsValidExpression(cron)) + { + return cron; + } + return _defaultCron; + } } } \ No newline at end of file diff --git a/src/Ombi/Controllers/JobController.cs b/src/Ombi/Controllers/JobController.cs index e9fd987ba..f588bf4f6 100644 --- a/src/Ombi/Controllers/JobController.cs +++ b/src/Ombi/Controllers/JobController.cs @@ -22,27 +22,14 @@ namespace Ombi.Controllers [ApiController] public class JobController : ControllerBase { - public JobController(IOmbiAutomaticUpdater updater, IPlexUserImporter userImporter, - ICacheService mem, IEmbyUserImporter embyImporter, IPlexContentSync plexContentSync, - IEmbyContentSync embyContentSync, INewsletterJob newsletter) + public JobController(IOmbiAutomaticUpdater updater, ICacheService mem) { _updater = updater; - _plexUserImporter = userImporter; - _embyUserImporter = embyImporter; _memCache = mem; - _plexContentSync = plexContentSync; - _embyContentSync = embyContentSync; - _newsletterJob = newsletter; } private readonly IOmbiAutomaticUpdater _updater; - private readonly IPlexUserImporter _plexUserImporter; - private readonly IEmbyUserImporter _embyUserImporter; private readonly ICacheService _memCache; - private readonly IPlexContentSync _plexContentSync; - private readonly IEmbyContentSync _embyContentSync; - private readonly INewsletterJob _newsletterJob; - /// /// Runs the update job /// From 2789c9b452dc00d94ec1d9634c0995d94b88d315 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Sun, 14 Apr 2019 20:55:10 +0100 Subject: [PATCH 45/58] attempting to get the new triggers working --- src/Ombi/Controllers/JobController.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Ombi/Controllers/JobController.cs b/src/Ombi/Controllers/JobController.cs index f588bf4f6..42f774351 100644 --- a/src/Ombi/Controllers/JobController.cs +++ b/src/Ombi/Controllers/JobController.cs @@ -109,7 +109,8 @@ namespace Ombi.Controllers [HttpPost("plexcontentcacher")] public bool StartPlexContentCacher() { - OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(PlexContentSync)), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "false" } })); + OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync) + + "Trigger"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "false" } })); return true; } From 8f50213867b18f8fa486d83ec26fa6bee911af93 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Sun, 14 Apr 2019 21:48:31 +0100 Subject: [PATCH 46/58] Fixed the scheduler! --- src/Ombi.Schedule.Tests/OmbiQuartzTests.cs | 2 +- src/Ombi.Schedule/IocJobFactory.cs | 8 ++++- .../Jobs/Emby/EmbyContentSync.cs | 7 ++-- .../Jobs/Emby/EmbyEpisodeSync.cs | 2 +- .../Jobs/Ombi/MediaDatabaseRefresh.cs | 2 +- .../Jobs/Ombi/RefreshMetadata.cs | 4 +-- .../Jobs/Plex/PlexContentSync.cs | 6 ++-- .../Jobs/Plex/PlexEpisodeSync.cs | 3 +- src/Ombi.Schedule/OmbiQuartz.cs | 32 +++++++++++++------ src/Ombi.Schedule/OmbiScheduler.cs | 4 +++ src/Ombi/Controllers/JobController.cs | 15 ++++----- src/Ombi/Controllers/SettingsController.cs | 2 +- 12 files changed, 52 insertions(+), 35 deletions(-) diff --git a/src/Ombi.Schedule.Tests/OmbiQuartzTests.cs b/src/Ombi.Schedule.Tests/OmbiQuartzTests.cs index a8136a5ce..6d00f8ef6 100644 --- a/src/Ombi.Schedule.Tests/OmbiQuartzTests.cs +++ b/src/Ombi.Schedule.Tests/OmbiQuartzTests.cs @@ -19,7 +19,7 @@ namespace Ombi.Schedule.Tests It.IsAny())); var sut = new QuartzMock(scheduleMock); - await QuartzMock.TriggerJob("ABC"); + //await QuartzMock.TriggerJob("ABC"); scheduleMock.Verify(x => x.TriggerJob(It.Is(j => j.Name == "ABC"), default(CancellationToken)), Times.Once); diff --git a/src/Ombi.Schedule/IocJobFactory.cs b/src/Ombi.Schedule/IocJobFactory.cs index d9a300eee..83ab5a974 100644 --- a/src/Ombi.Schedule/IocJobFactory.cs +++ b/src/Ombi.Schedule/IocJobFactory.cs @@ -1,4 +1,5 @@ using System; +using Microsoft.Extensions.DependencyInjection; using Quartz; using Quartz.Spi; @@ -14,7 +15,12 @@ namespace Ombi.Schedule } public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler) { - return _factory.GetService(bundle.JobDetail.JobType) as IJob; + var scopeFactory = _factory.GetService(); + var scope = scopeFactory.CreateScope(); + var scopedContainer = scope.ServiceProvider; + + var implementation = scopedContainer.GetRequiredService(bundle.JobDetail.JobType) as IJob; + return implementation; } public void ReturnJob(IJob job) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 3e1e750ae..3f64a6505 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -55,11 +55,8 @@ namespace Ombi.Schedule.Jobs.Emby // Episodes - await OmbiQuartz.TriggerJob(nameof(IEmbyEpisodeSync)); - - await OmbiQuartz.TriggerJob(nameof(IRefreshMetadata)); - //BackgroundJob.Enqueue(() => _episodeSync.Start()); - //BackgroundJob.Enqueue(() => _metadata.Start()); + await OmbiQuartz.TriggerJob(nameof(IEmbyEpisodeSync), "Emby"); + await OmbiQuartz.TriggerJob(nameof(IRefreshMetadata), "Emby"); } diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index 00a1b7da4..e55c46d26 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -66,7 +66,7 @@ namespace Ombi.Schedule.Jobs.Emby } - await OmbiQuartz.TriggerJob(nameof(IEmbyAvaliabilityChecker)); + await OmbiQuartz.TriggerJob(nameof(IEmbyAvaliabilityChecker), "Emby"); } private async Task CacheEpisodes(EmbyServers server) diff --git a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs index 82f4ec883..cadabba4e 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/MediaDatabaseRefresh.cs @@ -59,7 +59,7 @@ namespace Ombi.Schedule.Jobs.Ombi await _embyRepo.ExecuteSql(episodeSQL); await _embyRepo.ExecuteSql(mainSql); - await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync)); + await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync), "Emby"); } catch (Exception e) { diff --git a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs index a2cebb36c..e4f175855 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs @@ -89,12 +89,12 @@ namespace Ombi.Schedule.Jobs.Ombi { if (plexSettings.Enable) { - await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker)); + await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex"); } if (embySettings.Enable) { - await OmbiQuartz.TriggerJob(nameof(IEmbyAvaliabilityChecker)); + await OmbiQuartz.TriggerJob(nameof(IEmbyAvaliabilityChecker), "Emby"); } } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index f1c35abdb..9144f2eae 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -104,19 +104,19 @@ namespace Ombi.Schedule.Jobs.Plex { Logger.LogInformation("Starting EP Cacher"); - await OmbiQuartz.TriggerJob(nameof(IPlexEpisodeSync)); + await OmbiQuartz.TriggerJob(nameof(IPlexEpisodeSync), "Plex"); } if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch) { // Just check what we send it - BackgroundJob.Enqueue(() => Metadata.ProcessPlexServerContent(processedContent.Content)); + await OmbiQuartz.TriggerJob(nameof(IMediaDatabaseRefresh), "System"); } if ((processedContent?.HasProcessedEpisodes ?? false) && recentlyAddedSearch) { - await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker)); + await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex"); } } diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index 433051e43..7414294be 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -56,8 +56,7 @@ namespace Ombi.Schedule.Jobs.Plex } - await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker)); - //BackgroundJob.Enqueue(() => _availabilityChecker.Start()); // TODO + await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex"); } private async Task Cache(PlexServers settings) diff --git a/src/Ombi.Schedule/OmbiQuartz.cs b/src/Ombi.Schedule/OmbiQuartz.cs index 1eb509b08..a4bd28312 100644 --- a/src/Ombi.Schedule/OmbiQuartz.cs +++ b/src/Ombi.Schedule/OmbiQuartz.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Ombi.Helpers; using Quartz; using Quartz.Impl; using Quartz.Spi; @@ -40,7 +41,7 @@ namespace Ombi.Schedule where T : IJob { var jobBuilder = JobBuilder.Create() - .WithIdentity(name, group); + .WithIdentity(new JobKey(name, group)); if (jobData != null) { foreach (var o in jobData) @@ -49,19 +50,30 @@ namespace Ombi.Schedule } } - var job = jobBuilder.Build(); - - ITrigger jobTrigger = TriggerBuilder.Create() - .WithIdentity(name + "Trigger", group) - .WithCronSchedule(cronExpression) - .Build(); + if(!cronExpression.HasValue()) + { + jobBuilder.StoreDurably(true); + } + + var job = jobBuilder.Build(); + if (cronExpression.HasValue()) + { + ITrigger jobTrigger = TriggerBuilder.Create() + .WithIdentity(name + "Trigger", group) + .WithCronSchedule(cronExpression) + .Build(); + await Scheduler.ScheduleJob(job, jobTrigger); + } + else + { + await Scheduler.AddJob(job, true); + } - await Scheduler.ScheduleJob(job, jobTrigger); } - public static async Task TriggerJob(string jobName) + public static async Task TriggerJob(string jobName, string group) { - await Scheduler.TriggerJob(new JobKey(jobName)); + await Scheduler.TriggerJob(new JobKey(jobName, group)); } public static async Task Start() diff --git a/src/Ombi.Schedule/OmbiScheduler.cs b/src/Ombi.Schedule/OmbiScheduler.cs index 0e000ad46..31f4282e6 100644 --- a/src/Ombi.Schedule/OmbiScheduler.cs +++ b/src/Ombi.Schedule/OmbiScheduler.cs @@ -84,11 +84,15 @@ namespace Ombi.Schedule await OmbiQuartz.Instance.AddJob(nameof(IPlexContentSync) + "RecentlyAdded", "Plex", JobSettingsHelper.PlexContent(s), new Dictionary { { "recentlyAddedSearch", "true" } }); await OmbiQuartz.Instance.AddJob(nameof(IPlexRecentlyAddedSync), "Plex", JobSettingsHelper.PlexRecentlyAdded(s)); await OmbiQuartz.Instance.AddJob(nameof(IPlexUserImporter), "Plex", JobSettingsHelper.UserImporter(s)); + await OmbiQuartz.Instance.AddJob(nameof(IPlexEpisodeSync), "Plex", null); + await OmbiQuartz.Instance.AddJob(nameof(IPlexAvailabilityChecker), "Plex", null); } private static async Task AddEmby(JobSettings s) { await OmbiQuartz.Instance.AddJob(nameof(IEmbyContentSync), "Emby", JobSettingsHelper.EmbyContent(s)); + await OmbiQuartz.Instance.AddJob(nameof(IEmbyEpisodeSync), "Emby", null); + await OmbiQuartz.Instance.AddJob(nameof(IEmbyAvaliabilityChecker), "Emby", null); await OmbiQuartz.Instance.AddJob(nameof(IEmbyUserImporter), "Emby", JobSettingsHelper.UserImporter(s)); } } diff --git a/src/Ombi/Controllers/JobController.cs b/src/Ombi/Controllers/JobController.cs index 42f774351..ccc6a6702 100644 --- a/src/Ombi/Controllers/JobController.cs +++ b/src/Ombi/Controllers/JobController.cs @@ -38,7 +38,7 @@ namespace Ombi.Controllers public async Task ForceUpdate() { - await OmbiQuartz.TriggerJob(nameof(IOmbiAutomaticUpdater)); + await OmbiQuartz.TriggerJob(nameof(IOmbiAutomaticUpdater), "System"); return true; } @@ -87,7 +87,7 @@ namespace Ombi.Controllers [HttpPost("plexuserimporter")] public async Task PlexUserImporter() { - await OmbiQuartz.TriggerJob(nameof(IPlexUserImporter)); + await OmbiQuartz.TriggerJob(nameof(IPlexUserImporter), "Plex"); return true; } @@ -98,7 +98,7 @@ namespace Ombi.Controllers [HttpPost("embyuserimporter")] public async Task EmbyUserImporter() { - await OmbiQuartz.TriggerJob(nameof(IEmbyUserImporter)); + await OmbiQuartz.TriggerJob(nameof(IEmbyUserImporter), "Emby"); return true; } @@ -109,8 +109,7 @@ namespace Ombi.Controllers [HttpPost("plexcontentcacher")] public bool StartPlexContentCacher() { - OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync) + - "Trigger"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "false" } })); + OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync), "Plex"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "false" } })); return true; } @@ -121,7 +120,7 @@ namespace Ombi.Controllers [HttpPost("plexrecentlyadded")] public bool StartRecentlyAdded() { - OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(PlexContentSync)), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "true" } })); + OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync), "Plex"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "true" } })); return true; } @@ -132,7 +131,7 @@ namespace Ombi.Controllers [HttpPost("embycontentcacher")] public async Task StartEmbyContentCacher() { - await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync)); + await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync), "Emby"); return true; } @@ -143,7 +142,7 @@ namespace Ombi.Controllers [HttpPost("newsletter")] public async Task StartNewsletter() { - await OmbiQuartz.TriggerJob(nameof(INewsletterJob)); + await OmbiQuartz.TriggerJob(nameof(INewsletterJob), "Emby"); return true; } } diff --git a/src/Ombi/Controllers/SettingsController.cs b/src/Ombi/Controllers/SettingsController.cs index 399375f95..e8f4154b8 100644 --- a/src/Ombi/Controllers/SettingsController.cs +++ b/src/Ombi/Controllers/SettingsController.cs @@ -386,7 +386,7 @@ namespace Ombi.Controllers _cache.Remove(CacheKeys.RadarrRootProfiles); _cache.Remove(CacheKeys.RadarrQualityProfiles); - await OmbiQuartz.TriggerJob(nameof(IRadarrSync)); + await OmbiQuartz.TriggerJob(nameof(IRadarrSync), "DVR"); } return result; } From 59e26aaa2d66b79ba2f3fb1dc791075bb6d7bbb2 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Tue, 16 Apr 2019 21:52:05 +0100 Subject: [PATCH 47/58] Reset all of the schedules due to Quartz using a different CRON system. Updated the UI code to reflect this --- .../20190416204533_ResetSchedules.Designer.cs | 50 +++++++++++++++++++ .../Settings/20190416204533_ResetSchedules.cs | 20 ++++++++ .../Settings/SettingsContextModelSnapshot.cs | 2 +- .../ClientApp/app/interfaces/ISettings.ts | 1 - .../app/settings/jobs/jobs.component.html | 9 +--- .../app/settings/jobs/jobs.component.ts | 9 +--- src/Ombi/Controllers/SettingsController.cs | 20 ++++---- src/Ombi/Models/CronTestModel.cs | 1 - 8 files changed, 85 insertions(+), 27 deletions(-) create mode 100644 src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.Designer.cs create mode 100644 src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.cs diff --git a/src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.Designer.cs b/src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.Designer.cs new file mode 100644 index 000000000..205a98b11 --- /dev/null +++ b/src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.Designer.cs @@ -0,0 +1,50 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context; + +namespace Ombi.Store.Migrations.Settings +{ + [DbContext(typeof(SettingsContext))] + [Migration("20190416204533_ResetSchedules")] + partial class ResetSchedules + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.2.2-servicing-10034"); + + 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.GlobalSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd(); + + b.Property("Content"); + + b.Property("SettingsName"); + + b.HasKey("Id"); + + b.ToTable("GlobalSettings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.cs b/src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.cs new file mode 100644 index 000000000..0a3b9312c --- /dev/null +++ b/src/Ombi.Store/Migrations/Settings/20190416204533_ResetSchedules.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Ombi.Store.Migrations.Settings +{ + public partial class ResetSchedules : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.Sql(@" + DELETE FROM GlobalSettings + WHERE SettingsName = 'JobSettings' +"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Ombi.Store/Migrations/Settings/SettingsContextModelSnapshot.cs b/src/Ombi.Store/Migrations/Settings/SettingsContextModelSnapshot.cs index fe063ef8b..7a605792d 100644 --- a/src/Ombi.Store/Migrations/Settings/SettingsContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/Settings/SettingsContextModelSnapshot.cs @@ -13,7 +13,7 @@ namespace Ombi.Store.Migrations.Settings { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "2.2.0-rtm-35687"); + .HasAnnotation("ProductVersion", "2.2.2-servicing-10034"); modelBuilder.Entity("Ombi.Store.Entities.ApplicationConfiguration", b => { diff --git a/src/Ombi/ClientApp/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/app/interfaces/ISettings.ts index 070dabb8d..2145ba9e6 100644 --- a/src/Ombi/ClientApp/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/app/interfaces/ISettings.ts @@ -222,7 +222,6 @@ export interface IIssueCategory extends ISettings { export interface ICronTestModel { success: boolean; message: string; - schedule: Date[]; } export interface ICronViewModelBody { diff --git a/src/Ombi/ClientApp/app/settings/jobs/jobs.component.html b/src/Ombi/ClientApp/app/settings/jobs/jobs.component.html index 4532af9b3..0806fdcc8 100644 --- a/src/Ombi/ClientApp/app/settings/jobs/jobs.component.html +++ b/src/Ombi/ClientApp/app/settings/jobs/jobs.component.html @@ -7,7 +7,8 @@ Job Settings
    - Changes to any of the below requires you to restart Ombi. + Changes to any of the below requires you to restart Ombi. + You can generate valid CRON Expressions here: http://www.cronmaker.com/
    @@ -121,9 +122,3 @@
    - - -
      -
    • {{item | date:'short'}}
    • -
    -
    diff --git a/src/Ombi/ClientApp/app/settings/jobs/jobs.component.ts b/src/Ombi/ClientApp/app/settings/jobs/jobs.component.ts index 747a4bfde..1a543f885 100644 --- a/src/Ombi/ClientApp/app/settings/jobs/jobs.component.ts +++ b/src/Ombi/ClientApp/app/settings/jobs/jobs.component.ts @@ -3,8 +3,6 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { NotificationService, SettingsService } from "../../services"; -import { ICronTestModel } from "../../interfaces"; - @Component({ templateUrl: "./jobs.component.html", }) @@ -13,8 +11,6 @@ export class JobsComponent implements OnInit { public form: FormGroup; public profilesRunning: boolean; - public testModel: ICronTestModel; - public displayTest: boolean; constructor(private readonly settingsService: SettingsService, private readonly fb: FormBuilder, @@ -44,9 +40,8 @@ export class JobsComponent implements OnInit { public testCron(expression: string) { this.settingsService.testCron({ expression }).subscribe(x => { - if(x.success) { - this.testModel = x; - this.displayTest = true; + if(x.success) { + this.notificationService.success("Cron is Valid"); } else { this.notificationService.error(x.message); } diff --git a/src/Ombi/Controllers/SettingsController.cs b/src/Ombi/Controllers/SettingsController.cs index e8f4154b8..ebc2fbe66 100644 --- a/src/Ombi/Controllers/SettingsController.cs +++ b/src/Ombi/Controllers/SettingsController.cs @@ -28,6 +28,7 @@ using Ombi.Store.Repository; using Ombi.Api.Github; using Ombi.Core.Engine; using Ombi.Schedule; +using Quartz; namespace Ombi.Controllers { @@ -546,8 +547,8 @@ namespace Ombi.Controllers try { - var r = CrontabSchedule.TryParse(expression); - if (r == null) + var isValid = CronExpression.IsValidExpression(expression); + if (!isValid) { return new JobSettingsViewModel { @@ -577,14 +578,15 @@ namespace Ombi.Controllers var model = new CronTestModel(); try { - var time = DateTime.UtcNow; - var result = CrontabSchedule.TryParse(body.Expression); - for (int i = 0; i < 10; i++) + var isValid = CronExpression.IsValidExpression(body.Expression); + if (!isValid) { - var next = result.GetNextOccurrence(time); - model.Schedule.Add(next); - time = next; + return new CronTestModel + { + Message = $"CRON Expression {body.Expression} is not valid" + }; } + model.Success = true; return model; } @@ -595,8 +597,6 @@ namespace Ombi.Controllers Message = $"CRON Expression {body.Expression} is not valid" }; } - - } diff --git a/src/Ombi/Models/CronTestModel.cs b/src/Ombi/Models/CronTestModel.cs index 9698afbff..d8193aef5 100644 --- a/src/Ombi/Models/CronTestModel.cs +++ b/src/Ombi/Models/CronTestModel.cs @@ -7,6 +7,5 @@ namespace Ombi.Models { public bool Success { get; set; } public string Message { get; set; } - public List Schedule { get; set; } = new List(); } } \ No newline at end of file From fdad3a564cf41f180e49ef1202062f22f02238cc Mon Sep 17 00:00:00 2001 From: Kris Klosterman Date: Thu, 18 Apr 2019 08:26:42 -0400 Subject: [PATCH 48/58] Placeholder Text for Search Boxes (#2939) --- src/Ombi/ClientApp/app/search/moviesearch.component.html | 4 ++-- .../ClientApp/app/search/music/musicsearch.component.html | 4 ++-- src/Ombi/ClientApp/app/search/search.component.html | 2 +- src/Ombi/ClientApp/app/search/search.component.scss | 4 ++++ src/Ombi/ClientApp/app/search/tvsearch.component.html | 4 ++-- src/Ombi/wwwroot/translations/en.json | 1 + 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Ombi/ClientApp/app/search/moviesearch.component.html b/src/Ombi/ClientApp/app/search/moviesearch.component.html index 7d8a4653a..ed669e0f5 100644 --- a/src/Ombi/ClientApp/app/search/moviesearch.component.html +++ b/src/Ombi/ClientApp/app/search/moviesearch.component.html @@ -2,7 +2,7 @@
    -
    @@ -181,4 +181,4 @@ \ No newline at end of file + [issueCategory]="issueCategorySelected" [id]="issueRequestId" [providerId]="issueProviderId"> diff --git a/src/Ombi/ClientApp/app/search/music/musicsearch.component.html b/src/Ombi/ClientApp/app/search/music/musicsearch.component.html index e0d95203b..89af8de01 100644 --- a/src/Ombi/ClientApp/app/search/music/musicsearch.component.html +++ b/src/Ombi/ClientApp/app/search/music/musicsearch.component.html @@ -1,7 +1,7 @@ 
    - +
    @@ -49,4 +49,4 @@ \ No newline at end of file + [issueCategory]="issueCategorySelected" [id]="issueRequestId" [providerId]="issueProviderId"> diff --git a/src/Ombi/ClientApp/app/search/search.component.html b/src/Ombi/ClientApp/app/search/search.component.html index 046635812..7e1d280d2 100644 --- a/src/Ombi/ClientApp/app/search/search.component.html +++ b/src/Ombi/ClientApp/app/search/search.component.html @@ -4,7 +4,7 @@ -