This commit is contained in:
Jamie Rees 2019-11-26 08:32:16 +00:00
commit bea8551cd3
60 changed files with 12547 additions and 482 deletions

View file

@ -1,6 +1,77 @@
# Changelog # 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** ### **New Features**
@ -34,6 +105,8 @@
### **Fixes** ### **Fixes**
- Gitchangelog. [tidusjar]
- Fixed #3078. [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] - 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]

View file

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

View file

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

View file

@ -159,8 +159,7 @@ namespace Ombi.Core.Engine
.Skip(position).Take(count).ToListAsync(); .Skip(position).Take(count).ToListAsync();
} }
await CheckForSubscription(shouldHide, allRequests);
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
return new RequestsViewModel<TvRequests> return new RequestsViewModel<TvRequests>
{ {
@ -195,7 +194,8 @@ namespace Ombi.Core.Engine
{ {
return new RequestsViewModel<TvRequests>(); return new RequestsViewModel<TvRequests>();
} }
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); });
await CheckForSubscription(shouldHide, allRequests);
return new RequestsViewModel<TvRequests> return new RequestsViewModel<TvRequests>
{ {
@ -217,7 +217,7 @@ namespace Ombi.Core.Engine
allRequests = await TvRepository.Get().ToListAsync(); allRequests = await TvRepository.Get().ToListAsync();
} }
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); }); await CheckForSubscription(shouldHide, allRequests);
return allRequests; return allRequests;
} }
@ -262,7 +262,8 @@ namespace Ombi.Core.Engine
allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase) allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
? allRequests.OrderBy(x => prop.GetValue(x)).ToList() ? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
: allRequests.OrderByDescending(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 // Make sure we do not show duplicate child requests
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList(); allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
@ -315,7 +316,7 @@ namespace Ombi.Core.Engine
allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase) allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase)
? allRequests.OrderBy(x => prop.GetValue(x)).ToList() ? allRequests.OrderBy(x => prop.GetValue(x)).ToList()
: allRequests.OrderByDescending(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 // Make sure we do not show duplicate child requests
allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList(); allRequests = allRequests.DistinctBy(x => x.ParentRequest.Title).ToList();
@ -344,7 +345,7 @@ namespace Ombi.Core.Engine
allRequests = await TvRepository.GetLite().ToListAsync(); allRequests = await TvRepository.GetLite().ToListAsync();
} }
allRequests.ForEach(async r => { await CheckForSubscription(shouldHide, r); }); await CheckForSubscription(shouldHide, allRequests);
return allRequests; return allRequests;
} }
@ -363,7 +364,7 @@ namespace Ombi.Core.Engine
request = await TvRepository.Get().Where(x => x.Id == requestId).FirstOrDefaultAsync(); request = await TvRepository.Get().Where(x => x.Id == requestId).FirstOrDefaultAsync();
} }
await CheckForSubscription(shouldHide, request); await CheckForSubscription(shouldHide, new List<TvRequests>{request});
return 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 = 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; return allRequests;
} }
@ -436,7 +437,7 @@ namespace Ombi.Core.Engine
} }
var results = await allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToListAsync(); 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; return results;
} }
@ -501,7 +502,7 @@ namespace Ombi.Core.Engine
if (request.Approved) if (request.Approved)
{ {
NotificationHelper.Notify(request, NotificationType.RequestApproved); await NotificationHelper.Notify(request, NotificationType.RequestApproved);
// Autosend // Autosend
await TvSender.Send(request); await TvSender.Send(request);
} }
@ -524,7 +525,7 @@ namespace Ombi.Core.Engine
request.Denied = true; request.Denied = true;
request.DeniedReason = reason; request.DeniedReason = reason;
await TvRepository.UpdateChild(request); await TvRepository.UpdateChild(request);
NotificationHelper.Notify(request, NotificationType.RequestDeclined); await NotificationHelper.Notify(request, NotificationType.RequestDeclined);
return new RequestEngineResult return new RequestEngineResult
{ {
Result = true Result = true
@ -612,7 +613,7 @@ namespace Ombi.Core.Engine
} }
} }
await TvRepository.UpdateChild(request); await TvRepository.UpdateChild(request);
NotificationHelper.Notify(request, NotificationType.RequestAvailable); await NotificationHelper.Notify(request, NotificationType.RequestAvailable);
return new RequestEngineResult return new RequestEngineResult
{ {
Result = true, Result = true,
@ -633,15 +634,21 @@ 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)
{
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)
{ {
if (shouldHide.UserId == x.RequestedUserId) if (shouldHide.UserId == x.RequestedUserId)
{ {
@ -650,9 +657,9 @@ namespace Ombi.Core.Engine
else else
{ {
x.ShowSubscribe = true; x.ShowSubscribe = true;
var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s => var result = relevantSubs.FirstOrDefault(s => s.RequestId == x.Id);
s.UserId == shouldHide.UserId && s.RequestId == x.Id && s.RequestType == RequestType.TvShow); x.Subscribed = result != null;
x.Subscribed = sub != null; }
} }
} }
@ -691,7 +698,7 @@ namespace Ombi.Core.Engine
var sendRuleResult = await RunSpecificRule(model, SpecificRules.CanSendNotification); var sendRuleResult = await RunSpecificRule(model, SpecificRules.CanSendNotification);
if (sendRuleResult.Success) if (sendRuleResult.Success)
{ {
NotificationHelper.NewRequest(model); await NotificationHelper.NewRequest(model);
} }
await _requestLog.Add(new RequestLog await _requestLog.Add(new RequestLog
@ -706,7 +713,7 @@ namespace Ombi.Core.Engine
if (model.Approved) if (model.Approved)
{ {
// Autosend // Autosend
NotificationHelper.Notify(model, NotificationType.RequestApproved); await NotificationHelper.Notify(model, NotificationType.RequestApproved);
var result = await TvSender.Send(model); var result = await TvSender.Send(model);
if (result.Success) if (result.Success)
{ {

View file

@ -1,5 +1,6 @@
using System; using System;
using Hangfire; using System.Collections.Generic;
using System.Threading.Tasks;
using Ombi.Core.Notifications; using Ombi.Core.Notifications;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Notifications.Models; using Ombi.Notifications.Models;
@ -9,13 +10,7 @@ namespace Ombi.Core
{ {
public class NotificationHelper : INotificationHelper public class NotificationHelper : INotificationHelper
{ {
public NotificationHelper(INotificationService service) public async Task NewRequest(FullBaseRequest model)
{
NotificationService = service;
}
private INotificationService NotificationService { get; }
public void NewRequest(FullBaseRequest model)
{ {
var notificationModel = new NotificationOptions var notificationModel = new NotificationOptions
{ {
@ -24,11 +19,13 @@ namespace Ombi.Core
NotificationType = NotificationType.NewRequest, NotificationType = NotificationType.NewRequest,
RequestType = model.RequestType 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 var notificationModel = new NotificationOptions
{ {
@ -37,10 +34,13 @@ namespace Ombi.Core
NotificationType = NotificationType.NewRequest, NotificationType = NotificationType.NewRequest,
RequestType = model.RequestType 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 var notificationModel = new NotificationOptions
{ {
@ -49,11 +49,14 @@ namespace Ombi.Core
NotificationType = NotificationType.NewRequest, NotificationType = NotificationType.NewRequest,
RequestType = model.RequestType 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 var notificationModel = new NotificationOptions
{ {
@ -64,9 +67,12 @@ namespace Ombi.Core
Recipient = model.RequestedUser?.Email ?? string.Empty 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 var notificationModel = new NotificationOptions
{ {
@ -76,10 +82,13 @@ namespace Ombi.Core
RequestType = model.RequestType, RequestType = model.RequestType,
Recipient = model.RequestedUser?.Email ?? string.Empty 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 var notificationModel = new NotificationOptions
{ {
@ -90,7 +99,18 @@ namespace Ombi.Core
Recipient = model.RequestedUser?.Email ?? string.Empty 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}
});
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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://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/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.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");
} }
} }

View file

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

View file

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

View file

@ -1,11 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ombi.Helpers;
using Quartz; using Quartz;
using Quartz.Impl; using Quartz.Impl;
using Quartz.Spi; using Quartz.Spi;
namespace Ombi.Schedule namespace Ombi.Helpers
{ {
public class OmbiQuartz public class OmbiQuartz
{ {
@ -79,6 +78,11 @@ namespace Ombi.Schedule
await Scheduler.TriggerJob(new JobKey(jobName, group)); 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() public static async Task Start()
{ {
await Scheduler.Start(); await Scheduler.Start();

View file

@ -34,13 +34,14 @@ namespace Ombi.Helpers
public class PlexHelper public class PlexHelper
{ {
private const string ImdbMatchExpression = "tt([0-9]{1,10})"; 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 TvDbIdMatchExpression = "//[0-9]+/?([0-9]{1,3})/?([0-9]{1,3})";
public static ProviderId GetProviderIdFromPlexGuid(string guid) public static ProviderId GetProviderIdFromPlexGuid(string guid)
{ {
//com.plexapp.agents.thetvdb://269586/2/8?lang=en //com.plexapp.agents.thetvdb://269586/2/8?lang=en
//com.plexapp.agents.themoviedb://390043?lang=en //com.plexapp.agents.themoviedb://390043?lang=en
//com.plexapp.agents.imdb://tt2543164?lang=en //com.plexapp.agents.imdb://tt2543164?lang=en
// https://github.com/tidusjar/Ombi/issues/3277
if (string.IsNullOrEmpty(guid)) if (string.IsNullOrEmpty(guid))
{ {
return new ProviderId(); return new ProviderId();
@ -55,7 +56,7 @@ namespace Ombi.Helpers
{ {
TheTvDb = guidSplit[1] TheTvDb = guidSplit[1]
}; };
} else }
if (guid.Contains("themoviedb", CompareOptions.IgnoreCase)) if (guid.Contains("themoviedb", CompareOptions.IgnoreCase))
{ {
return new ProviderId return new ProviderId
@ -63,7 +64,6 @@ namespace Ombi.Helpers
TheMovieDb = guidSplit[1] TheMovieDb = guidSplit[1]
}; };
} }
else
if (guid.Contains("imdb", CompareOptions.IgnoreCase)) if (guid.Contains("imdb", CompareOptions.IgnoreCase))
{ {
return new ProviderId return new ProviderId
@ -71,8 +71,7 @@ namespace Ombi.Helpers
ImdbId = guidSplit[1] ImdbId = guidSplit[1]
}; };
} }
else
{
var imdbRegex = new Regex(ImdbMatchExpression, RegexOptions.Compiled); var imdbRegex = new Regex(ImdbMatchExpression, RegexOptions.Compiled);
var tvdbRegex = new Regex(TvDbIdMatchExpression, RegexOptions.Compiled); var tvdbRegex = new Regex(TvDbIdMatchExpression, RegexOptions.Compiled);
var imdbMatch = imdbRegex.IsMatch(guid); var imdbMatch = imdbRegex.IsMatch(guid);
@ -83,8 +82,7 @@ namespace Ombi.Helpers
ImdbId = guidSplit[1] ImdbId = guidSplit[1]
}; };
} }
else
{
// Check if it matches the TvDb pattern // Check if it matches the TvDb pattern
var tvdbMatch = tvdbRegex.IsMatch(guid); var tvdbMatch = tvdbRegex.IsMatch(guid);
if (tvdbMatch) if (tvdbMatch)
@ -95,50 +93,9 @@ namespace Ombi.Helpers
}; };
} }
} }
}
}
return new ProviderId(); 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)
{
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))
{
ep.ProviderId = new ProviderId { ImdbId = guidSplit[1] };
}
ep.SeasonNumber = int.Parse(guidSplit[2]);
ep.EpisodeNumber = int.Parse(guidSplit[3]);
}
return ep;
}
catch (Exception)
{
return ep;
}
}
public static string GetPlexMediaUrl(string machineId, int mediaId) public static string GetPlexMediaUrl(string machineId, int mediaId)
{ {
var url = var url =
@ -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 class ProviderId
{ {
public string TheTvDb { get; set; } public string TheTvDb { get; set; }

View file

@ -1,13 +1,12 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Ombi.Notifications; using Ombi.Notifications;
using Ombi.Notifications.Models; using Ombi.Notifications.Models;
using Quartz;
namespace Ombi.Core.Notifications 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);
} }
} }

View file

@ -7,16 +7,56 @@ using Microsoft.Extensions.Logging;
using Ombi.Core.Notifications; using Ombi.Core.Notifications;
using Ombi.Helpers; using Ombi.Helpers;
using Ombi.Notifications.Models; using Ombi.Notifications.Models;
using Quartz;
namespace Ombi.Notifications namespace Ombi.Notifications
{ {
public class NotificationService : INotificationService public class NotificationService : INotificationService
{ {
private readonly IServiceProvider _provider;
public NotificationService(IServiceProvider provider, ILogger<NotificationService> log) public NotificationService(IServiceProvider provider, ILogger<NotificationService> log)
{ {
_provider = provider;
Log = log; Log = log;
NotificationAgents = new List<INotification>(); NotificationAgents = new List<INotification>();
PopulateAgents();
}
private List<INotification> NotificationAgents { get; }
private ILogger<NotificationService> Log { get; }
/// <summary>
/// Sends a notification to the user. This one is used in normal notification scenarios
/// </summary>
/// <param name="context">The model.</param>
/// <returns></returns>
public async Task Execute(IJobExecutionContext context)
{
JobDataMap dataMap = context.MergedJobDataMap;
var model = (NotificationOptions)dataMap.Get(JobDataKeys.NotificationOptions);
foreach (var agent in NotificationAgents)
{
await NotifyAsync(agent, model);
}
}
private async Task NotifyAsync(INotification notification, NotificationOptions model)
{
try
{
await notification.NotifyAsync(model);
}
catch (Exception ex)
{
Log.LogError(LoggingEvents.Notification, ex, "Failed to notify for notification: {@notification}", notification);
}
}
private void PopulateAgents()
{
var baseSearchType = typeof(BaseNotification<>).Name; var baseSearchType = typeof(BaseNotification<>).Name;
var ass = typeof(NotificationService).GetTypeInfo().Assembly; var ass = typeof(NotificationService).GetTypeInfo().Assembly;
@ -32,7 +72,7 @@ namespace Ombi.Notifications
var services = new List<object>(); var services = new List<object>();
foreach (var param in ctor.GetParameters()) foreach (var param in ctor.GetParameters())
{ {
services.Add(provider.GetService(param.ParameterType)); services.Add(_provider.GetService(param.ParameterType));
} }
var item = Activator.CreateInstance(type, services.ToArray()); var item = Activator.CreateInstance(type, services.ToArray());
@ -40,72 +80,5 @@ namespace Ombi.Notifications
} }
} }
} }
private List<INotification> NotificationAgents { get; }
private ILogger<NotificationService> Log { get; }
/// <summary>^
/// Sends a notification to the user. This one is used in normal notification scenarios
/// </summary>
/// <param name="model">The model.</param>
/// <returns></returns>
public async Task Publish(NotificationOptions model)
{
var notificationTasks = new List<Task>();
foreach (var agent in NotificationAgents)
{
notificationTasks.Add(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);
}
catch (Exception ex)
{
Log.LogError(LoggingEvents.Notification, ex, "Failed to notify for notification: {@notification}", notification);
}
}
private async Task NotifyAsync(INotification notification, NotificationOptions model, Ombi.Settings.Settings.Models.Settings settings)
{
if (model.RequestId == 0)
{
throw new ArgumentException("RequestId is not set");
}
try
{
await notification.NotifyAsync(model, settings).ConfigureAwait(false);
}
catch (Exception ex)
{
throw new InvalidOperationException(ex.Message);
}
}
public async Task PublishTest(NotificationOptions model, Ombi.Settings.Settings.Models.Settings settings, INotification type)
{
await type.NotifyAsync(model, settings);
}
} }
} }

View file

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

View file

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

View file

@ -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;
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -29,7 +29,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Hangfire;
using Microsoft.AspNetCore.SignalR; using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -120,9 +119,6 @@ namespace Ombi.Schedule.Jobs.Plex
{ {
Logger.LogInformation("Kicking off Plex Availability Checker"); Logger.LogInformation("Kicking off Plex Availability Checker");
await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex"); 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) if ((processedContent?.HasProcessedContent ?? false) && recentlyAddedSearch)
@ -669,7 +665,6 @@ namespace Ombi.Schedule.Jobs.Plex
if (disposing) if (disposing)
{ {
Plex?.Dispose(); Plex?.Dispose();
Repo?.Dispose();
EpisodeSync?.Dispose(); EpisodeSync?.Dispose();
} }
_disposed = true; _disposed = true;

View file

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

View file

@ -10,13 +10,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper" Version="1.50.2" /> <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="Quartz" Version="3.0.7" />
<PackageReference Include="Serilog" Version="2.8.0" /> <PackageReference Include="Serilog" Version="2.8.0" />
<PackageReference Include="SharpCompress" Version="0.24.0" /> <PackageReference Include="SharpCompress" Version="0.24.0" />

View file

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

View file

@ -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);
}
}
}
}

View file

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

View file

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

View file

@ -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 If running migrations for any db provider other than Sqlite, then ensure the database.json is pointing at the correct DB type

View file

@ -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
}
}
}

View file

@ -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)
{
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -30,7 +30,7 @@ $warn: mat-color($ombi-app-warn);
// DARK // 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)); $backgroundTint-dark: mat-color(mat-palette($mat-grey, 900));
$text-dark: white; $text-dark: white;
$panel: mat-color(mat-palette($mat-grey, 800)); $panel: mat-color(mat-palette($mat-grey, 800));

View file

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

View file

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

View file

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

View file

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

View file

@ -58,8 +58,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="6.1.1" /> <PackageReference Include="AutoMapper" Version="6.1.1" />
<PackageReference Include="CommandLineParser" Version="2.6.0" /> <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.Configuration.CommandLine" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.0.0" />

View file

@ -1,8 +1,5 @@
using AutoMapper; using AutoMapper;
using AutoMapper.EquivalencyExpression; using AutoMapper.EquivalencyExpression;
using Hangfire;
using Hangfire.Dashboard;
using Hangfire.MemoryStorage;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -94,15 +91,6 @@ namespace Ombi
services.AddSwagger(); services.AddSwagger();
services.AddAppSettingsValues(Configuration); 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 => services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{ {
builder.AllowAnyHeader() builder.AllowAnyHeader()
@ -171,9 +159,9 @@ namespace Ombi
app.UsePathBase(settings.BaseUrl); app.UsePathBase(settings.BaseUrl);
} }
app.UseHangfireServer(new BackgroundJobServerOptions // Setup the scheduler
{WorkerCount = 1, ServerTimeout = TimeSpan.FromDays(1), ShutdownTimeout = TimeSpan.FromDays(1)}); //var jobSetup = app.ApplicationServices.GetService<IJobSetup>();
//jobSetup.Setup();
ctx.Seed(); ctx.Seed();
var settingsctx = serviceProvider.GetService<SettingsContext>(); var settingsctx = serviceProvider.GetService<SettingsContext>();
settingsctx.Seed(); settingsctx.Seed();

11640
src/Ombi/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff