pull/3338/head
Jamie Rees 5 years ago
commit bea8551cd3

@ -1,6 +1,77 @@
# Changelog
## v3.0.4817 (2019-10-15)
## (unreleased)
### **New Features**
- Update login.component.ts. [Jamie]
- Update CHANGELOG.md. [Jamie]
- Updated SlackNotification.cs. [Tim]
### **Fixes**
- Fixed the issue where we couldn't always pick up stuff on the sync. [tidusjar]
- Removed hangfire completly from Ombi. [tidusjar]
- Fixed the notifications issue. [tidusjar]
- Fixed the issues where the DB was being disposed too early. [tidusjar]
- Fixed an error with the newsletter with the new db structure. [tidusjar]
- Output some useful stuff to the about window regarding the databases. [tidusjar]
- Fixed the migration for combined databases. [tidusjar]
- Fixed the issue where exisitng databases would now fail due to the DB structure changes. [tidusjar]
- Finished it! [tidusjar]
- Got MySql working. [tidusjar]
- Got the new DB structure in place. [tidusjar]
- Fix for #3219. [tidusjar]
- Fixed the error in the newsletter. [tidusjar]
- Fixed #3208. [tidusjar]
- Use tags and autocomplete for excluded keywords. [Taylor Buchanan]
- Add comments to clarify filter decisions. [Taylor Buchanan]
- Fix TS import order. [Taylor Buchanan]
- Add adult movie filtering. [Taylor Buchanan]
- Fix search bar overlap on mobile. [Taylor Buchanan]
- New translations en.json (Slovak) [Jamie]
- New translations en.json (Slovak) [Jamie]
- New translations en.json (Slovak) [Jamie]
- New translations en.json (Slovak) [Jamie]
- New translations en.json (Slovak) [Jamie]
- New translations en.json (Slovak) [Jamie]
- New translations en.json (Slovak) [Jamie]
- Add SK lang. [Jamie Rees]
- Add the migration to the correct database... #3214. [tidusjar]
- Hopefully provide a fix now for #2998 Theory is that the refresh metadata was using stale data and then overriding the availbility that just happened on that media item. [tidusjar]
## v3.0.4817 (2019-10-12)
### **New Features**
@ -34,6 +105,8 @@
### **Fixes**
- Gitchangelog. [tidusjar]
- Fixed #3078. [tidusjar]
- Fixes issue #3195 The new string extension method ToHttpsUrl ensures that URLs starting with "https" are no longer turned into "httpss" The commit also replaces all occurances of the error prone .Replace("http", "https") in the whole solution. [msdeibel]

@ -189,11 +189,7 @@ namespace Ombi.Core.Engine
var requests = await (OrderMovies(allRequests, orderFilter.OrderType)).Skip(position).Take(count)
.ToListAsync();
requests.ForEach(async x =>
{
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
await CheckForSubscription(shouldHide, x);
});
await CheckForSubscription(shouldHide, requests);
return new RequestsViewModel<MovieRequests>
{
Collection = requests,
@ -236,11 +232,8 @@ namespace Ombi.Core.Engine
var total = await allRequests.CountAsync();
var requests = await allRequests.Skip(position).Take(count)
.ToListAsync();
requests.ForEach(async x =>
{
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
await CheckForSubscription(shouldHide, x);
});
await CheckForSubscription(shouldHide, requests);
return new RequestsViewModel<MovieRequests>
{
Collection = requests,
@ -282,11 +275,8 @@ namespace Ombi.Core.Engine
var total = await allRequests.CountAsync();
var requests = await allRequests.Skip(position).Take(count)
.ToListAsync();
requests.ForEach(async x =>
{
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
await CheckForSubscription(shouldHide, x);
});
await CheckForSubscription(shouldHide, requests);
return new RequestsViewModel<MovieRequests>
{
Collection = requests,
@ -369,35 +359,38 @@ namespace Ombi.Core.Engine
allRequests = await MovieRepository.GetWithUser().ToListAsync();
}
allRequests.ForEach(async x =>
{
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
await CheckForSubscription(shouldHide, x);
});
await CheckForSubscription(shouldHide, allRequests);
return allRequests;
}
public async Task<MovieRequests> GetRequest(int requestId)
{
var request = await MovieRepository.GetWithUser().Where(x => x.Id == requestId).FirstOrDefaultAsync();
request.PosterPath = PosterPathHelper.FixPosterPath(request.PosterPath);
await CheckForSubscription(new HideResult(), request);
await CheckForSubscription(new HideResult(), new List<MovieRequests>{request });
return request;
}
private async Task CheckForSubscription(HideResult shouldHide, MovieRequests x)
private async Task CheckForSubscription(HideResult shouldHide, List<MovieRequests> movieRequests)
{
if (shouldHide.UserId == x.RequestedUserId)
{
x.ShowSubscribe = false;
}
else
var requestIds = movieRequests.Select(x => x.Id);
var sub = await _subscriptionRepository.GetAll().Where(s =>
s.UserId == shouldHide.UserId && requestIds.Contains(s.RequestId) && s.RequestType == RequestType.Movie)
.ToListAsync();
foreach (var x in movieRequests)
{
x.ShowSubscribe = true;
var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s =>
s.UserId == shouldHide.UserId && s.RequestId == x.Id && s.RequestType == RequestType.Movie);
x.Subscribed = sub != null;
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
if (shouldHide.UserId == x.RequestedUserId)
{
x.ShowSubscribe = false;
}
else
{
x.ShowSubscribe = true;
var hasSub = sub.FirstOrDefault(r => r.RequestId == x.Id);
x.Subscribed = hasSub != null;
}
}
}
@ -420,11 +413,8 @@ namespace Ombi.Core.Engine
}
var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToList();
results.ForEach(async x =>
{
x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath);
await CheckForSubscription(shouldHide, x);
});
await CheckForSubscription(shouldHide, results);
return results;
}
@ -448,7 +438,7 @@ namespace Ombi.Core.Engine
request.Denied = true;
request.DeniedReason = denyReason;
// We are denying a request
NotificationHelper.Notify(request, NotificationType.RequestDeclined);
await NotificationHelper.Notify(request, NotificationType.RequestDeclined);
await MovieRepository.Update(request);
return new RequestEngineResult
@ -476,7 +466,7 @@ namespace Ombi.Core.Engine
var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification);
if (canNotify.Success)
{
NotificationHelper.Notify(request, NotificationType.RequestApproved);
await NotificationHelper.Notify(request, NotificationType.RequestApproved);
}
if (request.Approved)
@ -592,7 +582,7 @@ namespace Ombi.Core.Engine
request.Available = true;
request.MarkedAsAvailable = DateTime.Now;
NotificationHelper.Notify(request, NotificationType.RequestAvailable);
await NotificationHelper.Notify(request, NotificationType.RequestAvailable);
await MovieRepository.Update(request);
return new RequestEngineResult
@ -608,8 +598,8 @@ namespace Ombi.Core.Engine
var result = await RunSpecificRule(model, SpecificRules.CanSendNotification);
if (result.Success)
{
NotificationHelper.NewRequest(model);
{
await NotificationHelper.NewRequest(model);
}
await _requestLog.Add(new RequestLog

@ -320,7 +320,7 @@ namespace Ombi.Core.Engine
request.Denied = true;
request.DeniedReason = reason;
// We are denying a request
NotificationHelper.Notify(request, NotificationType.RequestDeclined);
await NotificationHelper.Notify(request, NotificationType.RequestDeclined);
await MusicRepository.Update(request);
return new RequestEngineResult
@ -348,7 +348,7 @@ namespace Ombi.Core.Engine
var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification);
if (canNotify.Success)
{
NotificationHelper.Notify(request, NotificationType.RequestApproved);
await NotificationHelper.Notify(request, NotificationType.RequestApproved);
}
if (request.Approved)
@ -475,7 +475,7 @@ namespace Ombi.Core.Engine
request.Available = true;
request.MarkedAsAvailable = DateTime.Now;
NotificationHelper.Notify(request, NotificationType.RequestAvailable);
await NotificationHelper.Notify(request, NotificationType.RequestAvailable);
await MusicRepository.Update(request);
return new RequestEngineResult
@ -492,7 +492,7 @@ namespace Ombi.Core.Engine
var result = await RunSpecificRule(model, SpecificRules.CanSendNotification);
if (result.Success)
{
NotificationHelper.NewRequest(model);
await NotificationHelper.NewRequest(model);
}
await _requestLog.Add(new RequestLog

@ -159,8 +159,7 @@ namespace Ombi.Core.Engine
.Skip(position).Take(count).ToListAsync();
}
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
return new RequestsViewModel<TvRequests>
{
@ -195,7 +194,8 @@ namespace Ombi.Core.Engine
{
return new RequestsViewModel<TvRequests>();
}
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
return new RequestsViewModel<TvRequests>
{
@ -217,7 +217,7 @@ namespace Ombi.Core.Engine
allRequests = await TvRepository.Get().ToListAsync();
}
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
return allRequests;
}
@ -262,7 +262,8 @@ namespace Ombi.Core.Engine
allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
// Make sure we do not show duplicate child requests
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
@ -315,7 +316,7 @@ namespace Ombi.Core.Engine
allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
: allRequests.OrderByDescending(x => prop.GetValue(x)).ToList();
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
// Make sure we do not show duplicate child requests
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
@ -344,7 +345,7 @@ namespace Ombi.Core.Engine
allRequests = await TvRepository.GetLite().ToListAsync();
}
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
return allRequests;
}
@ -363,7 +364,7 @@ namespace Ombi.Core.Engine
request = await TvRepository.Get().Where(x => x.Id == requestId).FirstOrDefaultAsync();
}
await CheckForSubscription(shouldHide, request);
await CheckForSubscription(shouldHide, new List<TvRequests>{request});
return request;
}
@ -417,7 +418,7 @@ namespace Ombi.Core.Engine
allRequests = await TvRepository.GetChild().Include(x => x.SeasonRequests).Where(x => x.ParentRequestId == tvId).ToListAsync();
}
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
return allRequests;
}
@ -436,7 +437,7 @@ namespace Ombi.Core.Engine
}
var results = await allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToListAsync();
results.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, results);
return results;
}
@ -501,7 +502,7 @@ namespace Ombi.Core.Engine
if (request.Approved)
{
NotificationHelper.Notify(request, NotificationType.RequestApproved);
await NotificationHelper.Notify(request, NotificationType.RequestApproved);
// Autosend
await TvSender.Send(request);
}
@ -524,7 +525,7 @@ namespace Ombi.Core.Engine
request.Denied = true;
request.DeniedReason = reason;
await TvRepository.UpdateChild(request);
NotificationHelper.Notify(request, NotificationType.RequestDeclined);
await NotificationHelper.Notify(request, NotificationType.RequestDeclined);
return new RequestEngineResult
{
Result = true
@ -533,7 +534,7 @@ namespace Ombi.Core.Engine
public async Task<ChildRequests> UpdateChildRequest(ChildRequests request)
{
await TvRepository.UpdateChild(request);
await TvRepository.UpdateChild(request);
return request;
}
@ -551,14 +552,14 @@ namespace Ombi.Core.Engine
// Delete the parent
TvRepository.Db.TvRequests.Remove(parent);
}
await TvRepository.Db.SaveChangesAsync();
}
public async Task RemoveTvRequest(int requestId)
{
var request = await TvRepository.Get().FirstOrDefaultAsync(x => x.Id == requestId);
await TvRepository.Delete(request);
await TvRepository.Delete(request);
}
public async Task<bool> UserHasRequest(string userId)
@ -612,7 +613,7 @@ namespace Ombi.Core.Engine
}
}
await TvRepository.UpdateChild(request);
NotificationHelper.Notify(request, NotificationType.RequestAvailable);
await NotificationHelper.Notify(request, NotificationType.RequestAvailable);
return new RequestEngineResult
{
Result = true,
@ -633,26 +634,32 @@ namespace Ombi.Core.Engine
}
}
private async Task CheckForSubscription(HideResult shouldHide, TvRequests x)
private async Task CheckForSubscription(HideResult shouldHide, List<TvRequests> x)
{
foreach (var tv in x.ChildRequests)
foreach (var tvRequest in x)
{
await CheckForSubscription(shouldHide, tv);
await CheckForSubscription(shouldHide, tvRequest.ChildRequests);
}
}
private async Task CheckForSubscription(HideResult shouldHide, ChildRequests x)
private async Task CheckForSubscription(HideResult shouldHide, List<ChildRequests> childRequests)
{
if (shouldHide.UserId == x.RequestedUserId)
var sub = _subscriptionRepository.GetAll();
var childIds = childRequests.Select(x => x.Id);
var relevantSubs = await sub.Where(s =>
s.UserId == shouldHide.UserId && childIds.Contains(s.Id) && s.RequestType == RequestType.TvShow).ToListAsync();
foreach (var x in childRequests)
{
x.ShowSubscribe = false;
}
else
{
x.ShowSubscribe = true;
var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s =>
s.UserId == shouldHide.UserId && s.RequestId == x.Id && s.RequestType == RequestType.TvShow);
x.Subscribed = sub != null;
if (shouldHide.UserId == x.RequestedUserId)
{
x.ShowSubscribe = false;
}
else
{
x.ShowSubscribe = true;
var result = relevantSubs.FirstOrDefault(s => s.RequestId == x.Id);
x.Subscribed = result != null;
}
}
}
@ -691,7 +698,7 @@ namespace Ombi.Core.Engine
var sendRuleResult = await RunSpecificRule(model, SpecificRules.CanSendNotification);
if (sendRuleResult.Success)
{
NotificationHelper.NewRequest(model);
await NotificationHelper.NewRequest(model);
}
await _requestLog.Add(new RequestLog
@ -706,7 +713,7 @@ namespace Ombi.Core.Engine
if (model.Approved)
{
// Autosend
NotificationHelper.Notify(model, NotificationType.RequestApproved);
await NotificationHelper.Notify(model, NotificationType.RequestApproved);
var result = await TvSender.Send(model);
if (result.Success)
{

@ -1,5 +1,6 @@
using System;
using Hangfire;
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Notifications;
using Ombi.Helpers;
using Ombi.Notifications.Models;
@ -9,13 +10,7 @@ namespace Ombi.Core
{
public class NotificationHelper : INotificationHelper
{
public NotificationHelper(INotificationService service)
{
NotificationService = service;
}
private INotificationService NotificationService { get; }
public void NewRequest(FullBaseRequest model)
public async Task NewRequest(FullBaseRequest model)
{
var notificationModel = new NotificationOptions
{
@ -24,11 +19,13 @@ namespace Ombi.Core
NotificationType = NotificationType.NewRequest,
RequestType = model.RequestType
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
await OmbiQuartz.TriggerJob(nameof(INotificationService), "Notifications", new Dictionary<string, object>
{
{JobDataKeys.NotificationOptions, notificationModel}
});
}
public void NewRequest(ChildRequests model)
public async Task NewRequest(ChildRequests model)
{
var notificationModel = new NotificationOptions
{
@ -36,11 +33,14 @@ namespace Ombi.Core
DateTime = DateTime.Now,
NotificationType = NotificationType.NewRequest,
RequestType = model.RequestType
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
};
await OmbiQuartz.TriggerJob(nameof(INotificationService), "Notifications", new Dictionary<string, object>
{
{JobDataKeys.NotificationOptions, notificationModel}
});
}
public void NewRequest(AlbumRequest model)
public async Task NewRequest(AlbumRequest model)
{
var notificationModel = new NotificationOptions
{
@ -48,12 +48,15 @@ namespace Ombi.Core
DateTime = DateTime.Now,
NotificationType = NotificationType.NewRequest,
RequestType = model.RequestType
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
};
await OmbiQuartz.TriggerJob(nameof(INotificationService), "Notifications", new Dictionary<string, object>
{
{JobDataKeys.NotificationOptions, notificationModel}
});
}
public void Notify(MovieRequests model, NotificationType type)
public async Task Notify(MovieRequests model, NotificationType type)
{
var notificationModel = new NotificationOptions
{
@ -63,10 +66,13 @@ namespace Ombi.Core
RequestType = model.RequestType,
Recipient = model.RequestedUser?.Email ?? string.Empty
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
await OmbiQuartz.TriggerJob(nameof(INotificationService), "Notifications", new Dictionary<string, object>
{
{JobDataKeys.NotificationOptions, notificationModel}
});
}
public void Notify(ChildRequests model, NotificationType type)
public async Task Notify(ChildRequests model, NotificationType type)
{
var notificationModel = new NotificationOptions
{
@ -76,10 +82,13 @@ namespace Ombi.Core
RequestType = model.RequestType,
Recipient = model.RequestedUser?.Email ?? string.Empty
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
await OmbiQuartz.TriggerJob(nameof(INotificationService), "Notifications", new Dictionary<string, object>
{
{JobDataKeys.NotificationOptions, notificationModel}
});
}
public void Notify(AlbumRequest model, NotificationType type)
public async Task Notify(AlbumRequest model, NotificationType type)
{
var notificationModel = new NotificationOptions
{
@ -90,7 +99,18 @@ namespace Ombi.Core
Recipient = model.RequestedUser?.Email ?? string.Empty
};
BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel));
await OmbiQuartz.TriggerJob(nameof(INotificationService), "Notifications", new Dictionary<string, object>
{
{JobDataKeys.NotificationOptions, notificationModel}
});
}
public async Task Notify(NotificationOptions model)
{
await OmbiQuartz.TriggerJob(nameof(INotificationService), "Notifications", new Dictionary<string, object>
{
{JobDataKeys.NotificationOptions, model}
});
}
}
}

@ -11,7 +11,6 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="6.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="3.2.0" />
<PackageReference Include="Hangfire" Version="1.7.0" />
<PackageReference Include="Microsoft.AspNetCore.Cryptography.KeyDerivation" Version="2.2.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
<PackageReference Include="MusicBrainzAPI" Version="2.0.1" />

@ -1,16 +1,19 @@
using Ombi.Core.Models.Requests;
using System.Threading.Tasks;
using Ombi.Core.Models.Requests;
using Ombi.Helpers;
using Ombi.Notifications.Models;
using Ombi.Store.Entities.Requests;
namespace Ombi.Core
{
public interface INotificationHelper
{
void NewRequest(FullBaseRequest model);
void NewRequest(ChildRequests model);
void NewRequest(AlbumRequest model);
void Notify(MovieRequests model, NotificationType type);
void Notify(ChildRequests model, NotificationType type);
void Notify(AlbumRequest model, NotificationType type);
Task NewRequest(FullBaseRequest model);
Task NewRequest(ChildRequests model);
Task NewRequest(AlbumRequest model);
Task Notify(MovieRequests model, NotificationType type);
Task Notify(ChildRequests model, NotificationType type);
Task Notify(AlbumRequest model, NotificationType type);
Task Notify(NotificationOptions model);
}
}

@ -95,7 +95,7 @@ namespace Ombi.Core.Senders
Type = RequestType.Movie,
RetryCount = 0
});
_notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
await _notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
}
}

@ -65,7 +65,7 @@ namespace Ombi.Core.Senders
Type = RequestType.Album,
RetryCount = 0
});
_notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
await _notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
}
}

@ -128,7 +128,7 @@ namespace Ombi.Core.Senders
Type = RequestType.TvShow,
RetryCount = 0
});
_notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
await _notificationHelper.Notify(model, NotificationType.ItemAddedToFaultQueue);
}
}

@ -1,6 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Security.Principal;
using Hangfire;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
@ -197,8 +196,8 @@ namespace Ombi.DependencyInjection
public static void RegisterJobs(this IServiceCollection services)
{
services.AddSingleton<IJobFactory, IoCJobFactory>(provider => new IoCJobFactory(provider));
services.AddTransient<IBackgroundJobClient, BackgroundJobClient>();
services.AddSingleton<QuartzJobRunner>();
services.AddSingleton<IJobFactory, IoCJobFactory>();
services.AddTransient<IPlexContentSync, PlexContentSync>();
services.AddTransient<IEmbyContentSync, EmbyContentSync>();

@ -39,6 +39,8 @@ namespace Ombi.Helpers.Tests
yield return new TestCaseData("com.plexapp.agents.agent47://tt2543456?lang=en", ProviderIdType.Imdb).Returns("tt2543456").SetName("Unknown IMDB agent");
yield return new TestCaseData("com.plexapp.agents.agent47://456822/1/1?lang=en", ProviderIdType.TvDb).Returns("456822").SetName("Unknown TvDb agent");
yield return new TestCaseData("com.plexapp.agents.agent47://456822/999/999?lang=en", ProviderIdType.TvDb).Returns("456822").SetName("Unknown TvDb agent, large episode and season");
yield return new TestCaseData("com.plexapp.agents.xbmcnfotv://153021/2/1?lang=xn", ProviderIdType.TvDb).Returns("153021").SetName("xmbc agent, tv episode");
yield return new TestCaseData("com.plexapp.agents.xbmcnfotv://153021?lang=xn", ProviderIdType.TvDb).Returns("153021").SetName("xmbc agent, tv show");
}
}

@ -1,7 +1,8 @@
namespace Ombi.Schedule
namespace Ombi.Helpers
{
public class JobDataKeys
{
public const string RecentlyAddedSearch = "recentlyAddedSearch";
public const string NotificationOptions = nameof(NotificationOptions);
}
}

@ -14,6 +14,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
<PackageReference Include="Nito.AsyncEx" Version="5.0.0-pre-05" />
<PackageReference Include="Quartz" Version="3.0.7" />
<PackageReference Include="System.Security.Claims" Version="4.3.0" />
</ItemGroup>

@ -1,11 +1,10 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Helpers;
using Quartz;
using Quartz.Impl;
using Quartz.Spi;
namespace Ombi.Schedule
namespace Ombi.Helpers
{
public class OmbiQuartz
{
@ -78,7 +77,12 @@ namespace Ombi.Schedule
{
await Scheduler.TriggerJob(new JobKey(jobName, group));
}
public static async Task TriggerJob(string jobName, string group, IDictionary<string, object> data)
{
await Scheduler.TriggerJob(new JobKey(jobName, group), new JobDataMap(data));
}
public static async Task Start()
{
await Scheduler.Start();

@ -33,14 +33,15 @@ namespace Ombi.Helpers
{
public class PlexHelper
{
private const string ImdbMatchExpression = "tt([0-9]{1,10})";
private const string TvDbIdMatchExpression = "//[0-9]+/([0-9]{1,3})/([0-9]{1,3})";
private const string ImdbMatchExpression = "tt([0-9]{1,10})";
private const string TvDbIdMatchExpression = "//[0-9]+/?([0-9]{1,3})/?([0-9]{1,3})";
public static ProviderId GetProviderIdFromPlexGuid(string guid)
{
//com.plexapp.agents.thetvdb://269586/2/8?lang=en
//com.plexapp.agents.themoviedb://390043?lang=en
//com.plexapp.agents.imdb://tt2543164?lang=en
// https://github.com/tidusjar/Ombi/issues/3277
if (string.IsNullOrEmpty(guid))
{
return new ProviderId();
@ -55,7 +56,7 @@ namespace Ombi.Helpers
{
TheTvDb = guidSplit[1]
};
} else
}
if (guid.Contains("themoviedb", CompareOptions.IgnoreCase))
{
return new ProviderId
@ -63,7 +64,6 @@ namespace Ombi.Helpers
TheMovieDb = guidSplit[1]
};
}
else
if (guid.Contains("imdb", CompareOptions.IgnoreCase))
{
return new ProviderId
@ -71,72 +71,29 @@ namespace Ombi.Helpers
ImdbId = guidSplit[1]
};
}
else
var imdbRegex = new Regex(ImdbMatchExpression, RegexOptions.Compiled);
var tvdbRegex = new Regex(TvDbIdMatchExpression, RegexOptions.Compiled);
var imdbMatch = imdbRegex.IsMatch(guid);
if (imdbMatch)
{
var imdbRegex = new Regex(ImdbMatchExpression, RegexOptions.Compiled);
var tvdbRegex = new Regex(TvDbIdMatchExpression, RegexOptions.Compiled);
var imdbMatch = imdbRegex.IsMatch(guid);
if (imdbMatch)
{
return new ProviderId
{
ImdbId = guidSplit[1]
};
}
else
return new ProviderId
{
// Check if it matches the TvDb pattern
var tvdbMatch = tvdbRegex.IsMatch(guid);
if (tvdbMatch)
{
return new ProviderId
{
TheTvDb = guidSplit[1]
};
}
}
ImdbId = guidSplit[1]
};
}
}
return new ProviderId();
}
public static EpisodeModelHelper GetSeasonsAndEpisodesFromPlexGuid(string guid)
{
var ep = new EpisodeModelHelper();
//com.plexapp.agents.thetvdb://269586/2/8?lang=en
//com.plexapp.agents.themoviedb://390043?lang=en
//com.plexapp.agents.imdb://tt2543164?lang=en
if (string.IsNullOrEmpty(guid))
return null;
try
{
var guidSplit = guid.Split(new[] { '/', '?' }, StringSplitOptions.RemoveEmptyEntries);
if (guidSplit.Length > 2)
// Check if it matches the TvDb pattern
var tvdbMatch = tvdbRegex.IsMatch(guid);
if (tvdbMatch)
{
if (guid.Contains("thetvdb", CompareOptions.IgnoreCase))
{
ep.ProviderId = new ProviderId {TheTvDb = guidSplit[1]};
}
if (guid.Contains("themoviedb", CompareOptions.IgnoreCase))
{
ep.ProviderId = new ProviderId { TheMovieDb = guidSplit[1] };
}
if (guid.Contains("imdb", CompareOptions.IgnoreCase))
return new ProviderId
{
ep.ProviderId = new ProviderId { ImdbId = guidSplit[1] };
}
ep.SeasonNumber = int.Parse(guidSplit[2]);
ep.EpisodeNumber = int.Parse(guidSplit[3]);
TheTvDb = guidSplit[1]
};
}
return ep;
}
catch (Exception)
{
return ep;
}
return new ProviderId();
}
public static string GetPlexMediaUrl(string machineId, int mediaId)
@ -147,13 +104,6 @@ namespace Ombi.Helpers
}
}
public class EpisodeModelHelper
{
public ProviderId ProviderId { get; set; }
public int SeasonNumber { get; set; }
public int EpisodeNumber { get; set; }
}
public class ProviderId
{
public string TheTvDb { get; set; }

@ -1,13 +1,12 @@
using System.Threading.Tasks;
using Ombi.Notifications;
using Ombi.Notifications.Models;
using Quartz;
namespace Ombi.Core.Notifications
{
public interface INotificationService
public interface INotificationService : IJob
{
Task Publish(NotificationOptions model);
Task Publish(NotificationOptions model, Ombi.Settings.Settings.Models.Settings settings);
Task PublishTest(NotificationOptions model, Ombi.Settings.Settings.Models.Settings settings, INotification type);
}
}

@ -7,78 +7,46 @@ using Microsoft.Extensions.Logging;
using Ombi.Core.Notifications;
using Ombi.Helpers;
using Ombi.Notifications.Models;
using Quartz;
namespace Ombi.Notifications
{
public class NotificationService : INotificationService
{
private readonly IServiceProvider _provider;
public NotificationService(IServiceProvider provider, ILogger<NotificationService> log)
{
_provider = provider;
Log = log;
NotificationAgents = new List<INotification>();
var baseSearchType = typeof(BaseNotification<>).Name;
var ass = typeof(NotificationService).GetTypeInfo().Assembly;
foreach (var ti in ass.DefinedTypes)
{
if (ti?.BaseType?.Name == baseSearchType)
{
var type = ti?.AsType();
var ctors = type.GetConstructors();
var ctor = ctors.FirstOrDefault();
var services = new List<object>();
foreach (var param in ctor.GetParameters())
{
services.Add(provider.GetService(param.ParameterType));
}
var item = Activator.CreateInstance(type, services.ToArray());
NotificationAgents.Add((INotification)item);
}
}
PopulateAgents();
}
private List<INotification> NotificationAgents { get; }
private ILogger<NotificationService> Log { get; }
/// <summary>^
/// <summary>
/// Sends a notification to the user. This one is used in normal notification scenarios
/// </summary>
/// <param name="model">The model.</param>
/// <param name="context">The model.</param>
/// <returns></returns>
public async Task Publish(NotificationOptions model)
public async Task Execute(IJobExecutionContext context)
{
var notificationTasks = new List<Task>();
JobDataMap dataMap = context.MergedJobDataMap;
var model = (NotificationOptions)dataMap.Get(JobDataKeys.NotificationOptions);
foreach (var agent in NotificationAgents)
{
notificationTasks.Add(NotifyAsync(agent,model));
await NotifyAsync(agent, model);
}
await Task.WhenAll(notificationTasks).ConfigureAwait(false);
}
/// <summary>
/// Sends a notification to the user, this is usually for testing the settings.
/// </summary>
/// <param name="model">The model.</param>
/// <param name="settings">The settings.</param>
/// <returns></returns>
public async Task Publish(NotificationOptions model, Settings.Settings.Models.Settings settings)
{
var notificationTasks = NotificationAgents.Select(notification => NotifyAsync(notification, model, settings));
await Task.WhenAll(notificationTasks).ConfigureAwait(false);
}
private async Task NotifyAsync(INotification notification, NotificationOptions model)
{
try
{
await notification.NotifyAsync(model).ConfigureAwait(false);
await notification.NotifyAsync(model);
}
catch (Exception ex)
{
@ -86,26 +54,31 @@ namespace Ombi.Notifications
}
}
private async Task NotifyAsync(INotification notification, NotificationOptions model, Ombi.Settings.Settings.Models.Settings settings)
private void PopulateAgents()
{
if (model.RequestId == 0)
{
throw new ArgumentException("RequestId is not set");
}
try
{
await notification.NotifyAsync(model, settings).ConfigureAwait(false);
}
catch (Exception ex)
var baseSearchType = typeof(BaseNotification<>).Name;
var ass = typeof(NotificationService).GetTypeInfo().Assembly;
foreach (var ti in ass.DefinedTypes)
{
throw new InvalidOperationException(ex.Message);
}
}
if (ti?.BaseType?.Name == baseSearchType)
{
var type = ti?.AsType();
var ctors = type.GetConstructors();
var ctor = ctors.FirstOrDefault();
public async Task PublishTest(NotificationOptions model, Ombi.Settings.Settings.Models.Settings settings, INotification type)
{
await type.NotifyAsync(model, settings);
var services = new List<object>();
foreach (var param in ctor.GetParameters())
{
services.Add(_provider.GetService(param.ParameterType));
}
var item = Activator.CreateInstance(type, services.ToArray());
NotificationAgents.Add((INotification)item);
}
}
}
}
}

@ -3,6 +3,7 @@ using NUnit.Framework;
using Quartz;
using System.Threading;
using System.Threading.Tasks;
using Ombi.Helpers;
namespace Ombi.Schedule.Tests
{

@ -5,11 +5,11 @@ using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using Castle.Components.DictionaryAdapter;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Moq;
using MockQueryable.Moq;
using NUnit.Framework;
using Ombi.Core;
using Ombi.Core.Notifications;
using Ombi.Hubs;
using Ombi.Schedule.Jobs.Plex;
@ -30,19 +30,19 @@ namespace Ombi.Schedule.Tests
_repo = new Mock<IPlexContentRepository>();
_tv = new Mock<ITvRequestRepository>();
_movie = new Mock<IMovieRequestRepository>();
_notify = new Mock<INotificationService>();
_notify = new Mock<INotificationHelper>();
var hub = new Mock<IHubContext<NotificationHub>>();
hub.Setup(x =>
x.Clients.Clients(It.IsAny<IReadOnlyList<string>>()).SendCoreAsync(It.IsAny<string>(), It.IsAny<object[]>(), It.IsAny<CancellationToken>()));
NotificationHub.UsersOnline.TryAdd("A", new HubUsers());
Checker = new PlexAvailabilityChecker(_repo.Object, _tv.Object, _movie.Object, _notify.Object, new Mock<IBackgroundJobClient>().Object, null, hub.Object);
Checker = new PlexAvailabilityChecker(_repo.Object, _tv.Object, _movie.Object, _notify.Object, null, hub.Object);
}
private Mock<IPlexContentRepository> _repo;
private Mock<ITvRequestRepository> _tv;
private Mock<IMovieRequestRepository> _movie;
private Mock<INotificationService> _notify;
private Mock<INotificationHelper> _notify;
private PlexAvailabilityChecker Checker;
[Test]

@ -1,28 +0,0 @@
using System;
using System.Linq;
using System.Reflection;
using Hangfire;
using Microsoft.Extensions.DependencyInjection;
namespace Ombi.Schedule
{
public class IoCJobActivator : JobActivator
{
private readonly IServiceProvider _container;
public IoCJobActivator(IServiceProvider container)
{
_container = container;
}
public override object ActivateJob(Type type)
{
var scopeFactory = _container.GetService<IServiceScopeFactory>();
var scope = scopeFactory.CreateScope();
var scopedContainer = scope.ServiceProvider;
var interfaceType = type.GetTypeInfo().ImplementedInterfaces.FirstOrDefault();
var implementation = scopedContainer.GetRequiredService(interfaceType);
return implementation;
}
}
}

@ -7,26 +7,18 @@ namespace Ombi.Schedule
{
public class IoCJobFactory : IJobFactory
{
private readonly IServiceProvider _factory;
public IoCJobFactory(IServiceProvider factory)
private readonly IServiceProvider _serviceProvider;
public IoCJobFactory(IServiceProvider serviceProvider)
{
_factory = factory;
_serviceProvider = serviceProvider;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var scopeFactory = _factory.GetService<IServiceScopeFactory>();
var scope = scopeFactory.CreateScope();
var scopedContainer = scope.ServiceProvider;
var implementation = scopedContainer.GetRequiredService(bundle.JobDetail.JobType) as IJob;
return implementation;
return _serviceProvider.GetRequiredService<QuartzJobRunner>();
}
public void ReturnJob(IJob job)
{
var disposable = job as IDisposable;
disposable?.Dispose();
}
}
}

@ -28,10 +28,10 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core;
using Ombi.Core.Notifications;
using Ombi.Helpers;
using Ombi.Hubs;
@ -47,7 +47,7 @@ namespace Ombi.Schedule.Jobs.Emby
public class EmbyAvaliabilityChecker : IEmbyAvaliabilityChecker
{
public EmbyAvaliabilityChecker(IEmbyContentRepository repo, ITvRequestRepository t, IMovieRequestRepository m,
INotificationService n, ILogger<EmbyAvaliabilityChecker> log, IHubContext<NotificationHub> notification)
INotificationHelper n, ILogger<EmbyAvaliabilityChecker> log, IHubContext<NotificationHub> notification)
{
_repo = repo;
_tvRepo = t;
@ -60,7 +60,7 @@ namespace Ombi.Schedule.Jobs.Emby
private readonly ITvRequestRepository _tvRepo;
private readonly IMovieRequestRepository _movieRepo;
private readonly IEmbyContentRepository _repo;
private readonly INotificationService _notificationService;
private readonly INotificationHelper _notificationService;
private readonly ILogger<EmbyAvaliabilityChecker> _log;
private readonly IHubContext<NotificationHub> _notification;
@ -109,14 +109,14 @@ namespace Ombi.Schedule.Jobs.Emby
_log.LogDebug("MovieId: {0}, RequestUser: {1}", movie.Id, recipient);
BackgroundJob.Enqueue(() => _notificationService.Publish(new NotificationOptions
await _notificationService.Notify(new NotificationOptions
{
DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable,
RequestId = movie.Id,
RequestType = RequestType.Movie,
Recipient = recipient,
}));
});
}
}
await _movieRepo.Save();
@ -200,14 +200,14 @@ namespace Ombi.Schedule.Jobs.Emby
// We have fulfulled this request!
child.Available = true;
child.MarkedAsAvailable = DateTime.Now;
BackgroundJob.Enqueue(() => _notificationService.Publish(new NotificationOptions
await _notificationService.Notify(new NotificationOptions
{
DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable,
RequestId = child.Id,
RequestType = RequestType.TvShow,
Recipient = child.RequestedUser.Email
}));
});
}
}
@ -222,7 +222,6 @@ namespace Ombi.Schedule.Jobs.Emby
if (disposing)
{
_movieRepo?.Dispose();
}
_disposed = true;
}

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Ombi.Api.Emby;
@ -15,7 +14,6 @@ using Ombi.Schedule.Jobs.Ombi;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Quartz;
using Serilog;
using EmbyMediaType = Ombi.Store.Entities.EmbyMediaType;
namespace Ombi.Schedule.Jobs.Emby
@ -217,7 +215,6 @@ namespace Ombi.Schedule.Jobs.Emby
if (disposing)
{
_settings?.Dispose();
_repo?.Dispose();
}
_disposed = true;
}

@ -29,13 +29,13 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Ombi.Api.Emby;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Hubs;
using Ombi.Helpers;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
using Quartz;
@ -165,7 +165,6 @@ namespace Ombi.Schedule.Jobs.Emby
if (disposing)
{
_settings?.Dispose();
_repo?.Dispose();
}
_disposed = true;
}

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;
@ -21,14 +20,12 @@ namespace Ombi.Schedule.Jobs.Lidarr
public class LidarrAlbumSync : ILidarrAlbumSync
{
public LidarrAlbumSync(ISettingsService<LidarrSettings> lidarr, ILidarrApi lidarrApi, ILogger<LidarrAlbumSync> log, ExternalContext ctx,
IBackgroundJobClient job, ILidarrAvailabilityChecker availability, IHubContext<NotificationHub> notification)
IHubContext<NotificationHub> notification)
{
_lidarrSettings = lidarr;
_lidarrApi = lidarrApi;
_logger = log;
_ctx = ctx;
_job = job;
_availability = availability;
_notification = notification;
}
@ -36,8 +33,6 @@ namespace Ombi.Schedule.Jobs.Lidarr
private readonly ILidarrApi _lidarrApi;
private readonly ILogger _logger;
private readonly ExternalContext _ctx;
private readonly IBackgroundJobClient _job;
private readonly ILidarrAvailabilityChecker _availability;
private readonly IHubContext<NotificationHub> _notification;
public async Task Execute(IJobExecutionContext ctx)

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Internal;

@ -2,11 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core.Notifications;
using Ombi.Core;
using Ombi.Helpers;
using Ombi.Hubs;
using Ombi.Notifications.Models;
@ -21,12 +20,11 @@ namespace Ombi.Schedule.Jobs.Lidarr
public class LidarrAvailabilityChecker : ILidarrAvailabilityChecker
{
public LidarrAvailabilityChecker(IMusicRequestRepository requests, IRepository<LidarrAlbumCache> albums, ILogger<LidarrAvailabilityChecker> log,
IBackgroundJobClient job, INotificationService notification, IHubContext<NotificationHub> notificationHub)
INotificationHelper notification, IHubContext<NotificationHub> notificationHub)
{
_cachedAlbums = albums;
_requestRepository = requests;
_logger = log;
_job = job;
_notificationService = notification;
_notification = notificationHub;
}
@ -34,8 +32,7 @@ namespace Ombi.Schedule.Jobs.Lidarr
private readonly IMusicRequestRepository _requestRepository;
private readonly IRepository<LidarrAlbumCache> _cachedAlbums;
private readonly ILogger _logger;
private readonly IBackgroundJobClient _job;
private readonly INotificationService _notificationService;
private readonly INotificationHelper _notificationService;
private readonly IHubContext<NotificationHub> _notification;
public async Task Execute(IJobExecutionContext ctx)
@ -67,14 +64,15 @@ namespace Ombi.Schedule.Jobs.Lidarr
_logger.LogDebug("AlbumId: {0}, RequestUser: {1}", albumRequest.Id, recipient);
_job.Enqueue(() => _notificationService.Publish(new NotificationOptions
await _notificationService.Notify(new NotificationOptions
{
DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable,
RequestId = albumRequest.Id,
RequestType = RequestType.Album,
Recipient = recipient,
}));
});
}
await _notification.Clients.Clients(NotificationHub.AdminConnectionIds)

@ -1,5 +1,4 @@
using System.Threading.Tasks;
using Hangfire.Server;
namespace Ombi.Schedule.Jobs.Ombi
{

@ -50,7 +50,6 @@ namespace Ombi.Schedule.Jobs.Ombi
if (disposing)
{
_issuesRepository?.Dispose();
_settings?.Dispose();
}
_disposed = true;

@ -1,8 +1,6 @@
using System;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.Extensions.Logging;
using Ombi.Api.Plex;
using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
@ -99,7 +97,6 @@ namespace Ombi.Schedule.Jobs.Ombi
if (disposing)
{
_plexRepo?.Dispose();
_settings?.Dispose();
}
_disposed = true;

@ -39,7 +39,7 @@ namespace Ombi.Schedule.Jobs.Ombi
IMovieDbApi movieApi, ITvMazeApi tvApi, IEmailProvider email, ISettingsService<CustomizationSettings> custom,
ISettingsService<EmailNotificationSettings> emailSettings, INotificationTemplatesRepository templateRepo,
UserManager<OmbiUser> um, ISettingsService<NewsletterSettings> newsletter, ILogger<NewsletterJob> log,
ILidarrApi lidarrApi, IRepository<LidarrAlbumCache> albumCache, ISettingsService<LidarrSettings> lidarrSettings,
ILidarrApi lidarrApi, IExternalRepository<LidarrAlbumCache> albumCache, ISettingsService<LidarrSettings> lidarrSettings,
ISettingsService<OmbiSettings> ombiSettings, ISettingsService<PlexSettings> plexSettings, ISettingsService<EmbySettings> embySettings
, IHubContext<NotificationHub> notification)
{
@ -82,7 +82,7 @@ namespace Ombi.Schedule.Jobs.Ombi
private readonly UserManager<OmbiUser> _userManager;
private readonly ILogger _log;
private readonly ILidarrApi _lidarrApi;
private readonly IRepository<LidarrAlbumCache> _lidarrAlbumRepository;
private readonly IExternalRepository<LidarrAlbumCache> _lidarrAlbumRepository;
private readonly ISettingsService<LidarrSettings> _lidarrSettings;
private readonly ISettingsService<PlexSettings> _plexSettings;
private readonly ISettingsService<EmbySettings> _embySettings;
@ -945,12 +945,9 @@ namespace Ombi.Schedule.Jobs.Ombi
if (disposing)
{
_plex?.Dispose();
_emby?.Dispose();
_newsletterSettings?.Dispose();
_customizationSettings?.Dispose();
_emailSettings.Dispose();
_recentlyAddedLog.Dispose();
_templateRepo?.Dispose();
_userManager?.Dispose();
}

@ -9,8 +9,6 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Hangfire;
using Hangfire.Server;
using Microsoft.Extensions.Logging;
using Ombi.Core.Processor;
using Ombi.Core.Settings;

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Ombi.Api.Emby;
@ -365,8 +363,6 @@ namespace Ombi.Schedule.Jobs.Ombi
if (disposing)
{
_plexRepo?.Dispose();
_embyRepo?.Dispose();
_plexSettings?.Dispose();
}
_disposed = true;

@ -1,12 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Ombi.Core.Notifications;
using Ombi.Core;
using Ombi.Helpers;
using Ombi.Hubs;
using Ombi.Notifications.Models;
@ -21,13 +19,12 @@ namespace Ombi.Schedule.Jobs.Plex
public class PlexAvailabilityChecker : IPlexAvailabilityChecker
{
public PlexAvailabilityChecker(IPlexContentRepository repo, ITvRequestRepository tvRequest, IMovieRequestRepository movies,
INotificationService notification, IBackgroundJobClient background, ILogger<PlexAvailabilityChecker> log, IHubContext<NotificationHub> hub)
INotificationHelper notification, ILogger<PlexAvailabilityChecker> log, IHubContext<NotificationHub> hub)
{
_tvRepo = tvRequest;
_repo = repo;
_movieRepo = movies;
_notificationService = notification;
_backgroundJobClient = background;
_log = log;
_notification = hub;
}
@ -35,8 +32,7 @@ namespace Ombi.Schedule.Jobs.Plex
private readonly ITvRequestRepository _tvRepo;
private readonly IMovieRequestRepository _movieRepo;
private readonly IPlexContentRepository _repo;
private readonly INotificationService _notificationService;
private readonly IBackgroundJobClient _backgroundJobClient;
private readonly INotificationHelper _notificationService;
private readonly ILogger _log;
private readonly IHubContext<NotificationHub> _notification;
@ -139,7 +135,8 @@ namespace Ombi.Schedule.Jobs.Plex
// We have ful-fulled this request!
child.Available = true;
child.MarkedAsAvailable = DateTime.Now;
await _notificationService.Publish(new NotificationOptions
await _notificationService.Notify(new NotificationOptions
{
DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable,
@ -183,7 +180,7 @@ namespace Ombi.Schedule.Jobs.Plex
item.RequestId = movie.Id;
_log.LogInformation("[PAC] - Movie request {0} is now available, sending notification", $"{movie.Title} - {movie.Id}");
await _notificationService.Publish(new NotificationOptions
await _notificationService.Notify(new NotificationOptions
{
DateTime = DateTime.Now,
NotificationType = NotificationType.RequestAvailable,
@ -206,8 +203,6 @@ namespace Ombi.Schedule.Jobs.Plex
if (disposing)
{
_movieRepo?.Dispose();
_repo?.Dispose();
}
_disposed = true;
}

@ -29,7 +29,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
@ -120,9 +119,6 @@ namespace Ombi.Schedule.Jobs.Plex
{
Logger.LogInformation("Kicking off Plex Availability Checker");
await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex");
Logger.LogInformation("Starting Metadata refresh");
// Just check what we send it
await OmbiQuartz.TriggerJob(nameof(IRefreshMetadata), "System");
}
if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch)
@ -669,7 +665,6 @@ namespace Ombi.Schedule.Jobs.Plex
if (disposing)
{
Plex?.Dispose();
Repo?.Dispose();
EpisodeSync?.Dispose();
}
_disposed = true;

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
@ -12,6 +11,7 @@ using Ombi.Core.Settings;
using Ombi.Core.Settings.Models.External;
using Ombi.Helpers;
using Ombi.Hubs;
using Ombi.Schedule.Jobs.Ombi;
using Ombi.Schedule.Jobs.Plex.Interfaces;
using Ombi.Store.Entities;
using Ombi.Store.Repository;
@ -63,7 +63,7 @@ namespace Ombi.Schedule.Jobs.Plex
_log.LogError(LoggingEvents.Cacher, e, "Caching Episodes Failed");
}
//await OmbiQuartz.TriggerJob(nameof(IRefreshMetadata), "System");
await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex");
await _notification.Clients.Clients(NotificationHub.AdminConnectionIds)
.SendAsync(NotificationHub.NotificationEvent, "Plex Episode Sync Finished");
@ -216,7 +216,6 @@ namespace Ombi.Schedule.Jobs.Plex
if (disposing)
{
_repo?.Dispose();
_settings?.Dispose();
}
_disposed = true;

@ -10,13 +10,6 @@
<ItemGroup>
<PackageReference Include="Dapper" Version="1.50.2" />
<PackageReference Include="Hangfire" Version="1.7.1" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.1" />
<PackageReference Include="Hangfire.Console" Version="1.3.10" />
<PackageReference Include="Hangfire.MemoryStorage.Core" Version="1.4.0" />
<PackageReference Include="Hangfire.RecurringJobExtensions" Version="1.1.6" />
<PackageReference Include="Hangfire.SQLite" Version="1.4.2" />
<PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.1" />
<PackageReference Include="Quartz" Version="3.0.7" />
<PackageReference Include="Serilog" Version="2.8.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" />

@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Ombi.Core.Notifications;
using Ombi.Core.Settings;
using Ombi.Helpers;
using Ombi.Schedule.Jobs;
using Ombi.Schedule.Jobs.Couchpotato;
using Ombi.Schedule.Jobs.Emby;
@ -53,6 +55,7 @@ namespace Ombi.Schedule
await AddEmby(s);
await AddDvrApps(s);
await AddSystem(s);
await AddNotifications(s);
// Run Quartz
await OmbiQuartz.Start();
@ -95,5 +98,9 @@ namespace Ombi.Schedule
await OmbiQuartz.Instance.AddJob<IEmbyAvaliabilityChecker>(nameof(IEmbyAvaliabilityChecker), "Emby", null);
await OmbiQuartz.Instance.AddJob<IEmbyUserImporter>(nameof(IEmbyUserImporter), "Emby", JobSettingsHelper.UserImporter(s));
}
private static async Task AddNotifications(JobSettings s)
{
await OmbiQuartz.Instance.AddJob<INotificationService>(nameof(INotificationService), "Notifications", null);
}
}
}

@ -0,0 +1,27 @@
using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Quartz;
namespace Ombi.Schedule
{
public class QuartzJobRunner : IJob
{
private readonly IServiceProvider _serviceProvider;
public QuartzJobRunner(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public async Task Execute(IJobExecutionContext context)
{
using (var scope = _serviceProvider.CreateScope())
{
var jobType = context.JobDetail.JobType;
var job = scope.ServiceProvider.GetRequiredService(jobType) as IJob;
await job.Execute(context);
}
}
}
}

@ -12,5 +12,10 @@ namespace Ombi.Store.Context.MySql
Database.Migrate();
}
public override void Dispose()
{
base.Dispose();
}
}
}

@ -1,4 +1,5 @@
using System;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
namespace Ombi.Store.Context.Sqlite
@ -13,7 +14,9 @@ namespace Ombi.Store.Context.Sqlite
_created = true;
Upgrade();
Database.SetCommandTimeout(60);
Database.Migrate();
}

@ -1,3 +1,3 @@
dotnet ef migrations add Inital --context OmbiContext --startup-project ../Ombi/Ombi.csproj
dotnet ef migrations add Inital --context OmbiSqliteContext --startup-project ../Ombi/Ombi.csproj
If running migrations for any db provider other than Sqlite, then ensure the database.json is pointing at the correct DB type

@ -0,0 +1,314 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Ombi.Store.Context.Sqlite;
namespace Ombi.Store.Migrations.ExternalSqlite
{
[DbContext(typeof(ExternalSqliteContext))]
[Migration("20191113213617_RequestIdPatch")]
partial class RequestIdPatch
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.2.6-servicing-10079");
modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("TheMovieDbId");
b.HasKey("Id");
b.ToTable("CouchPotatoCache");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<string>("EmbyId")
.IsRequired();
b.Property<string>("ImdbId");
b.Property<string>("ProviderId");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.Property<int>("Type");
b.Property<string>("Url");
b.HasKey("Id");
b.ToTable("EmbyContent");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<string>("EmbyId");
b.Property<int>("EpisodeNumber");
b.Property<string>("ImdbId");
b.Property<string>("ParentId");
b.Property<string>("ProviderId");
b.Property<int>("SeasonNumber");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.HasKey("Id");
b.HasIndex("ParentId");
b.ToTable("EmbyEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<int>("ArtistId");
b.Property<string>("ForeignAlbumId");
b.Property<bool>("Monitored");
b.Property<decimal>("PercentOfTracks");
b.Property<DateTime>("ReleaseDate");
b.Property<string>("Title");
b.Property<int>("TrackCount");
b.HasKey("Id");
b.ToTable("LidarrAlbumCache");
});
modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("ArtistId");
b.Property<string>("ArtistName");
b.Property<string>("ForeignArtistId");
b.Property<bool>("Monitored");
b.HasKey("Id");
b.ToTable("LidarrArtistCache");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("EpisodeNumber");
b.Property<int>("GrandparentKey");
b.Property<int>("Key");
b.Property<int>("ParentKey");
b.Property<int>("SeasonNumber");
b.Property<string>("Title");
b.HasKey("Id");
b.HasIndex("GrandparentKey");
b.ToTable("PlexEpisode");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("ParentKey");
b.Property<int>("PlexContentId");
b.Property<int?>("PlexServerContentId");
b.Property<int>("SeasonKey");
b.Property<int>("SeasonNumber");
b.HasKey("Id");
b.HasIndex("PlexServerContentId");
b.ToTable("PlexSeasonsContent");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<DateTime>("AddedAt");
b.Property<string>("ImdbId");
b.Property<int>("Key");
b.Property<string>("Quality");
b.Property<string>("ReleaseYear");
b.Property<int?>("RequestId");
b.Property<string>("TheMovieDbId");
b.Property<string>("Title");
b.Property<string>("TvDbId");
b.Property<int>("Type");
b.Property<string>("Url");
b.HasKey("Id");
b.ToTable("PlexServerContent");
});
modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("HasFile");
b.Property<int>("TheMovieDbId");
b.HasKey("Id");
b.ToTable("RadarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SickRageCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("EpisodeNumber");
b.Property<int>("SeasonNumber");
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SickRageEpisodeCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SonarrCache");
});
modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("EpisodeNumber");
b.Property<bool>("HasFile");
b.Property<int>("SeasonNumber");
b.Property<int>("TvDbId");
b.HasKey("Id");
b.ToTable("SonarrEpisodeCache");
});
modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b =>
{
b.HasOne("Ombi.Store.Entities.EmbyContent", "Series")
.WithMany("Episodes")
.HasForeignKey("ParentId")
.HasPrincipalKey("EmbyId");
});
modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b =>
{
b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series")
.WithMany("Episodes")
.HasForeignKey("GrandparentKey")
.HasPrincipalKey("Key")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b =>
{
b.HasOne("Ombi.Store.Entities.PlexServerContent")
.WithMany("Seasons")
.HasForeignKey("PlexServerContentId");
});
#pragma warning restore 612, 618
}
}
}

@ -0,0 +1,22 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Ombi.Store.Migrations.ExternalSqlite
{
public partial class RequestIdPatch : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
//migrationBuilder.AddColumn<int>(
// name: "RequestId",
// table: "PlexServerContent",
// nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
}
}

@ -107,25 +107,25 @@ namespace Ombi.Store.Repository
}
private bool _disposed;
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
_ctx?.Dispose();
}
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
//private bool _disposed;
//// Protected implementation of Dispose pattern.
//protected virtual void Dispose(bool disposing)
//{
// if (_disposed)
// return;
// if (disposing)
// {
// _ctx?.Dispose();
// }
// _disposed = true;
//}
//public void Dispose()
//{
// Dispose(true);
// GC.SuppressFinalize(this);
//}
}
}

@ -9,7 +9,7 @@ using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public interface IExternalRepository<T> : IDisposable where T : Entity
public interface IExternalRepository<T> where T : Entity
{
Task<T> Find(object key);
IQueryable<T> GetAll();

@ -9,7 +9,7 @@ using Ombi.Store.Entities;
namespace Ombi.Store.Repository
{
public interface IRepository<T> : IDisposable where T : Entity
public interface IRepository<T> where T : Entity
{
Task<T> Find(object key);
IQueryable<T> GetAll();

@ -806,7 +806,8 @@
"@types/selenium-webdriver": {
"version": "3.0.16",
"resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz",
"integrity": "sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA=="
"integrity": "sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA==",
"optional": true
},
"@types/sizzle": {
"version": "2.3.2",
@ -1247,6 +1248,7 @@
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
"integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
"optional": true,
"requires": {
"delegates": "^1.0.0",
"readable-stream": "^2.0.6"
@ -2429,7 +2431,8 @@
"console-control-strings": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
"optional": true
},
"constants-browserify": {
"version": "1.0.0",
@ -2489,6 +2492,11 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
"dev": true
},
"cookiejar": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz",
"integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA=="
},
"copy-concurrently": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@ -2834,7 +2842,8 @@
"delegates": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
"optional": true
},
"depd": {
"version": "1.1.2",
@ -3614,6 +3623,7 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
"optional": true,
"requires": {
"path-exists": "^2.0.0",
"pinkie-promise": "^2.0.0"
@ -3689,6 +3699,11 @@
"mime-types": "^2.1.12"
}
},
"formidable": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz",
"integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg=="
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
@ -3765,7 +3780,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"aproba": {
"version": "1.2.0",
@ -3786,12 +3802,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -3806,17 +3824,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
@ -3933,7 +3954,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
@ -3945,6 +3967,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -3959,6 +3982,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@ -3966,12 +3990,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -3990,6 +4016,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -4070,7 +4097,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
@ -4082,6 +4110,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -4167,7 +4196,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"safer-buffer": {
"version": "2.1.2",
@ -4203,6 +4233,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -4222,6 +4253,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -4265,12 +4297,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
}
}
},
@ -4278,6 +4312,7 @@
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
"integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"inherits": "~2.0.0",
@ -4285,6 +4320,18 @@
"rimraf": "2"
}
},
"fullcalendar": {
"version": "4.0.0-alpha.4",
"resolved": "https://registry.npmjs.org/fullcalendar/-/fullcalendar-4.0.0-alpha.4.tgz",
"integrity": "sha512-6uup/KTSSlybpj3ntiYvDlpbU82Z9deeW9D8zO/MJLcsKD/i+I4kWEnoJLp1egZdAHq9xGsJ9PLTBU/xz6QqGw==",
"requires": {
"luxon": "^1.10.0",
"moment": "^2.23.0",
"moment-timezone": "^0.5.23",
"rrule": "^2.6.0",
"superagent": "^3.8.3"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -4294,6 +4341,7 @@
"version": "2.7.4",
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"optional": true,
"requires": {
"aproba": "^1.0.3",
"console-control-strings": "^1.0.0",
@ -4328,7 +4376,8 @@
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
"integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
"optional": true
},
"get-stream": {
"version": "4.1.0",
@ -4488,7 +4537,8 @@
"has-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
"optional": true
},
"has-value": {
"version": "1.0.0",
@ -4750,7 +4800,8 @@
"immediate": {
"version": "3.0.6",
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
"optional": true
},
"import-cwd": {
"version": "2.1.0",
@ -5151,7 +5202,8 @@
"is-utf8": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
"integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
"optional": true
},
"is-windows": {
"version": "1.0.2",
@ -5375,6 +5427,7 @@
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.2.tgz",
"integrity": "sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==",
"optional": true,
"requires": {
"lie": "~3.3.0",
"pako": "~1.0.2",
@ -5470,6 +5523,7 @@
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
"integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"optional": true,
"requires": {
"immediate": "~3.0.5"
}
@ -5478,6 +5532,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"parse-json": "^2.2.0",
@ -5589,6 +5644,11 @@
"yallist": "^2.1.2"
}
},
"luxon": {
"version": "1.21.2",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.21.2.tgz",
"integrity": "sha512-yshwnlkA79WfC24/BC9Rd1n0mhorP22Sc7GYn0puRU6wD/douCgNJIzI9qQBuT9m2/bU+n9v1RflVNE4rMPPxQ=="
},
"magic-string": {
"version": "0.25.2",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.2.tgz",
@ -5681,7 +5741,8 @@
"map-obj": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
"optional": true
},
"map-visit": {
"version": "1.0.0",
@ -5755,8 +5816,7 @@
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
"dev": true
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"micromatch": {
"version": "3.1.10",
@ -5791,8 +5851,7 @@
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"dev": true
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.40.0",
@ -5952,6 +6011,14 @@
"resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
"integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
},
"moment-timezone": {
"version": "0.5.27",
"resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.27.tgz",
"integrity": "sha512-EIKQs7h5sAsjhPCqN6ggx6cEbs94GK050254TIJySD1bzoM5JTYDwAU1IoVOeTOL6Gm27kYJ51/uuvq1kIlrbw==",
"requires": {
"moment": ">= 2.9.0"
}
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
@ -6376,6 +6443,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"optional": true,
"requires": {
"are-we-there-yet": "~1.1.2",
"console-control-strings": "~1.1.0",
@ -6751,6 +6819,7 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
"optional": true,
"requires": {
"error-ex": "^1.2.0"
}
@ -6804,6 +6873,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
"optional": true,
"requires": {
"pinkie-promise": "^2.0.0"
}
@ -6839,6 +6909,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
"optional": true,
"requires": {
"graceful-fs": "^4.1.2",
"pify": "^2.0.0",
@ -7091,12 +7162,14 @@
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"optional": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"optional": true,
"requires": {
"ansi-styles": "^2.2.1",
"escape-string-regexp": "^1.0.2",
@ -7117,7 +7190,8 @@
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"optional": true
},
"webdriver-manager": {
"version": "12.1.5",
@ -7221,7 +7295,8 @@
"q": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
"integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4="
"integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
"optional": true
},
"qs": {
"version": "6.5.2",
@ -7349,6 +7424,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
"optional": true,
"requires": {
"load-json-file": "^1.0.0",
"normalize-package-data": "^2.3.2",
@ -7359,6 +7435,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
"optional": true,
"requires": {
"find-up": "^1.0.0",
"read-pkg": "^1.0.0"
@ -7609,6 +7686,15 @@
"inherits": "^2.0.1"
}
},
"rrule": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.3.tgz",
"integrity": "sha512-wWypJiQekvgZLGNKSI8OvC8KtAvA/L/CtF1EjI9qmZEkT/6WIyRL5rdIy5FfeC4z33aRp90/0KuAdHmLdw0KgA==",
"requires": {
"luxon": "^1.3.3",
"tslib": "^1.9.0"
}
},
"run-async": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
@ -7708,7 +7794,8 @@
"sax": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"optional": true
},
"schema-utils": {
"version": "1.0.0",
@ -7752,6 +7839,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz",
"integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==",
"optional": true,
"requires": {
"jszip": "^3.1.3",
"rimraf": "^2.5.4",
@ -7886,7 +7974,8 @@
"set-immediate-shim": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E="
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
"optional": true
},
"set-value": {
"version": "2.0.1",
@ -8588,6 +8677,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
"optional": true,
"requires": {
"is-utf8": "^0.2.0"
}
@ -8673,6 +8763,38 @@
"when": "~3.6.x"
}
},
"superagent": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz",
"integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==",
"requires": {
"component-emitter": "^1.2.0",
"cookiejar": "^2.1.0",
"debug": "^3.1.0",
"extend": "^3.0.0",
"form-data": "^2.3.1",
"formidable": "^1.2.0",
"methods": "^1.1.1",
"mime": "^1.4.1",
"qs": "^6.5.1",
"readable-stream": "^2.3.5"
},
"dependencies": {
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
@ -8785,6 +8907,7 @@
"version": "0.0.30",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
"integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
"optional": true,
"requires": {
"os-tmpdir": "~1.0.1"
}
@ -9708,6 +9831,7 @@
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
"integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
"optional": true,
"requires": {
"string-width": "^1.0.2 || 2"
}
@ -9767,6 +9891,7 @@
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"optional": true,
"requires": {
"sax": ">=0.6.0",
"xmlbuilder": "~9.0.1"
@ -9775,7 +9900,8 @@
"xmlbuilder": {
"version": "9.0.7",
"resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
"optional": true
},
"xmlhttprequest-ssl": {
"version": "1.5.5",

@ -42,7 +42,7 @@
"core-js": "^2.5.4",
"eventemitter2": "^5.0.1",
"font-awesome": "^4.7.0",
"fullcalendar":"^4.0.0-alpha.4",
"fullcalendar": "^4.0.0-alpha.4",
"hammerjs": "^2.0.8",
"jquery": "3.3.1",
"moment": "^2.23.0",

@ -164,7 +164,7 @@ export class LoginComponent implements OnDestroy, OnInit {
duration: 3000
});
this.getPinResult(x.pinId);
}, 10000);
}, 4000);
});
});
}

@ -1,4 +1,3 @@
@import "./Styles.scss";
@import "./shared.scss";
@import "./shared.scss";
@import "./buttons.scss";
@import "./primeng-overrides.scss"

@ -30,7 +30,7 @@ $warn: mat-color($ombi-app-warn);
// DARK
$background-dark: at-color(mat-palette($mat-grey, 800));;
$background-dark: mat-color(mat-palette($mat-grey, 800));;
$backgroundTint-dark: mat-color(mat-palette($mat-grey, 900));
$text-dark: white;
$panel: mat-color(mat-palette($mat-grey, 800));

@ -4,7 +4,6 @@ using System.Linq;
using System.Net;
using System.Threading.Tasks;
using AutoMapper;
using Hangfire;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
@ -860,7 +859,7 @@ namespace Ombi.Controllers.V1
[HttpPost("welcomeEmail")]
[PowerUser]
public void SendWelcomeEmail([FromBody] UserViewModel user)
public async Task<IActionResult> SendWelcomeEmail([FromBody] UserViewModel user)
{
var ombiUser = new OmbiUser
{
@ -868,7 +867,8 @@ namespace Ombi.Controllers.V1
Email = user.EmailAddress,
UserName = user.UserName
};
BackgroundJob.Enqueue(() => WelcomeEmail.SendEmail(ombiUser));
await WelcomeEmail.SendEmail(ombiUser);
return Ok();
}
[HttpGet("accesstoken")]

@ -2,12 +2,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Ombi.Attributes;
using Ombi.Core;
using Ombi.Core.Notifications;
using Ombi.Helpers;
using Ombi.Models;
@ -25,7 +25,7 @@ namespace Ombi.Controllers.V1
public class IssuesController : ControllerBase
{
public IssuesController(IRepository<IssueCategory> categories, IRepository<Issues> issues, IRepository<IssueComments> comments,
UserManager<OmbiUser> userManager, INotificationService notify)
UserManager<OmbiUser> userManager, INotificationHelper notify)
{
_categories = categories;
_issues = issues;
@ -38,7 +38,7 @@ namespace Ombi.Controllers.V1
private readonly IRepository<Issues> _issues;
private readonly IRepository<IssueComments> _issueComments;
private readonly UserManager<OmbiUser> _userManager;
private readonly INotificationService _notification;
private readonly INotificationHelper _notification;
/// <summary>
/// Get's all categories
@ -150,7 +150,7 @@ namespace Ombi.Controllers.V1
AddIssueNotificationSubstitutes(notificationModel, i, User.Identity.Name);
BackgroundJob.Enqueue(() => _notification.Publish(notificationModel));
await _notification.Notify(notificationModel);
return i.Id;
}
@ -237,7 +237,7 @@ namespace Ombi.Controllers.V1
notificationModel.Recipient = user.Email;
}
BackgroundJob.Enqueue(() => _notification.Publish(notificationModel));
await _notification.Notify(notificationModel);
return await _issueComments.Add(newComment);
}
@ -290,7 +290,7 @@ namespace Ombi.Controllers.V1
};
AddIssueNotificationSubstitutes(notificationModel, issue, issue.UserReported?.UserAlias ?? string.Empty);
BackgroundJob.Enqueue(() => _notification.Publish(notificationModel));
await _notification.Notify(notificationModel);
}

@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.Mvc;
using Ombi.Attributes;
using Ombi.Helpers;
using Ombi.Schedule;
using Ombi.Schedule.Jobs;
using Ombi.Schedule.Jobs.Emby;
using Ombi.Schedule.Jobs.Ombi;

@ -7,10 +7,8 @@ using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using AutoMapper;
using Hangfire;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NCrontab;
using Ombi.Api.Emby;
using Ombi.Api.Github;
using Ombi.Attributes;
@ -30,7 +28,6 @@ using Ombi.Store.Repository;
using Ombi.Api.Github;
using Ombi.Core.Engine;
using Ombi.Extensions;
using Ombi.Schedule;
using Quartz;
namespace Ombi.Controllers.V1

@ -58,8 +58,6 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="6.1.1" />
<PackageReference Include="CommandLineParser" Version="2.6.0" />
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.1" />
<PackageReference Include="Hangfire.SQLite" Version="1.4.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />

@ -1,8 +1,5 @@
using AutoMapper;
using AutoMapper.EquivalencyExpression;
using Hangfire;
using Hangfire.Dashboard;
using Hangfire.MemoryStorage;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@ -94,15 +91,6 @@ namespace Ombi
services.AddSwagger();
services.AddAppSettingsValues(Configuration);
services.AddHangfire(x =>
{
x.UseMemoryStorage();
#pragma warning disable ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices'
x.UseActivator(new IoCJobActivator(services.BuildServiceProvider()));
#pragma warning restore ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices'
});
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyHeader()
@ -171,9 +159,9 @@ namespace Ombi
app.UsePathBase(settings.BaseUrl);
}
app.UseHangfireServer(new BackgroundJobServerOptions
{WorkerCount = 1, ServerTimeout = TimeSpan.FromDays(1), ShutdownTimeout = TimeSpan.FromDays(1)});
// Setup the scheduler
//var jobSetup = app.ApplicationServices.GetService<IJobSetup>();
//jobSetup.Setup();
ctx.Seed();
var settingsctx = serviceProvider.GetService<SettingsContext>();
settingsctx.Seed();

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save