mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 21:33:15 -07:00
merge
This commit is contained in:
commit
6aa5f15881
30 changed files with 529 additions and 20 deletions
|
@ -59,6 +59,7 @@ We integrate with the following applications:
|
||||||
Supported notifications:
|
Supported notifications:
|
||||||
* SMTP Notifications (Email)
|
* SMTP Notifications (Email)
|
||||||
* Discord
|
* Discord
|
||||||
|
* Gotify
|
||||||
* Slack
|
* Slack
|
||||||
* Pushbullet
|
* Pushbullet
|
||||||
* Pushover
|
* Pushover
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#addin "Cake.Gulp"
|
#addin "Cake.Gulp"
|
||||||
#addin "SharpZipLib"
|
#addin "SharpZipLib"
|
||||||
#addin nuget:?package=Cake.Compression&version=0.1.4
|
#addin nuget:?package=Cake.Compression&version=0.1.4
|
||||||
#addin "Cake.Incubator"
|
#addin "Cake.Incubator&version=3.1.0"
|
||||||
#addin "Cake.Yarn"
|
#addin "Cake.Yarn"
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
36
src/Ombi.Api.Gotify/GotifyApi.cs
Normal file
36
src/Ombi.Api.Gotify/GotifyApi.cs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ombi.Api.Gotify
|
||||||
|
{
|
||||||
|
public class GotifyApi : IGotifyApi
|
||||||
|
{
|
||||||
|
public GotifyApi(IApi api)
|
||||||
|
{
|
||||||
|
_api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly IApi _api;
|
||||||
|
|
||||||
|
public async Task PushAsync(string baseUrl, string accessToken, string subject, string body, sbyte priority)
|
||||||
|
{
|
||||||
|
var request = new Request("/message", baseUrl, HttpMethod.Post);
|
||||||
|
request.AddQueryString("token", accessToken);
|
||||||
|
|
||||||
|
request.AddHeader("Access-Token", accessToken);
|
||||||
|
request.ApplicationJsonContentType();
|
||||||
|
|
||||||
|
|
||||||
|
var jsonBody = new
|
||||||
|
{
|
||||||
|
message = body,
|
||||||
|
title = subject,
|
||||||
|
priority = priority
|
||||||
|
};
|
||||||
|
|
||||||
|
request.AddJsonBody(jsonBody);
|
||||||
|
|
||||||
|
await _api.Request(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
src/Ombi.Api.Gotify/IGotifyApi.cs
Normal file
9
src/Ombi.Api.Gotify/IGotifyApi.cs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Ombi.Api.Gotify
|
||||||
|
{
|
||||||
|
public interface IGotifyApi
|
||||||
|
{
|
||||||
|
Task PushAsync(string endpoint, string accessToken, string subject, string body, sbyte priority);
|
||||||
|
}
|
||||||
|
}
|
15
src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj
Normal file
15
src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||||
|
<FileVersion>3.0.0.0</FileVersion>
|
||||||
|
<Version></Version>
|
||||||
|
<PackageVersion></PackageVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Ombi.Api\Ombi.Api.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
23
src/Ombi.Core/Models/UI/GotifyNotificationViewModel.cs
Normal file
23
src/Ombi.Core/Models/UI/GotifyNotificationViewModel.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Ombi.Settings.Settings.Models.Notifications;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Models.UI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The view model for the notification settings page
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="GotifyNotificationSettings" />
|
||||||
|
public class GotifyNotificationViewModel : GotifySettings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the notification templates.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>
|
||||||
|
/// The notification templates.
|
||||||
|
/// </value>
|
||||||
|
public List<NotificationTemplates> NotificationTemplates { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Ombi.Core.Models.Search;
|
using Ombi.Core.Models.Search;
|
||||||
using Ombi.Core.Rule.Interfaces;
|
using Ombi.Core.Rule.Interfaces;
|
||||||
|
using Ombi.Core.Settings;
|
||||||
|
using Ombi.Core.Settings.Models.External;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
|
@ -11,12 +13,14 @@ namespace Ombi.Core.Rule.Rules.Search
|
||||||
{
|
{
|
||||||
public class EmbyAvailabilityRule : BaseSearchRule, IRules<SearchViewModel>
|
public class EmbyAvailabilityRule : BaseSearchRule, IRules<SearchViewModel>
|
||||||
{
|
{
|
||||||
public EmbyAvailabilityRule(IEmbyContentRepository repo)
|
public EmbyAvailabilityRule(IEmbyContentRepository repo, ISettingsService<EmbySettings> s)
|
||||||
{
|
{
|
||||||
EmbyContentRepository = repo;
|
EmbyContentRepository = repo;
|
||||||
|
EmbySettings = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEmbyContentRepository EmbyContentRepository { get; }
|
private IEmbyContentRepository EmbyContentRepository { get; }
|
||||||
|
private ISettingsService<EmbySettings> EmbySettings { get; }
|
||||||
|
|
||||||
public async Task<RuleResult> Execute(SearchViewModel obj)
|
public async Task<RuleResult> Execute(SearchViewModel obj)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +64,16 @@ namespace Ombi.Core.Rule.Rules.Search
|
||||||
if (item != null)
|
if (item != null)
|
||||||
{
|
{
|
||||||
obj.Available = true;
|
obj.Available = true;
|
||||||
obj.EmbyUrl = item.Url;
|
var s = await EmbySettings.GetSettingsAsync();
|
||||||
|
var server = s.Servers.FirstOrDefault(x => x.ServerHostname != null);
|
||||||
|
if ((server?.ServerHostname ?? string.Empty).HasValue())
|
||||||
|
{
|
||||||
|
obj.EmbyUrl = $"{server.ServerHostname}#!/itemdetails.html?id={item.EmbyId}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj.EmbyUrl = $"https://app.emby.media/#!/itemdetails.html?id={item.EmbyId}";
|
||||||
|
}
|
||||||
|
|
||||||
if (obj.Type == RequestType.TvShow)
|
if (obj.Type == RequestType.TvShow)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@ using Ombi.Api.CouchPotato;
|
||||||
using Ombi.Api.DogNzb;
|
using Ombi.Api.DogNzb;
|
||||||
using Ombi.Api.FanartTv;
|
using Ombi.Api.FanartTv;
|
||||||
using Ombi.Api.Github;
|
using Ombi.Api.Github;
|
||||||
|
using Ombi.Api.Gotify;
|
||||||
using Ombi.Api.Lidarr;
|
using Ombi.Api.Lidarr;
|
||||||
using Ombi.Api.Mattermost;
|
using Ombi.Api.Mattermost;
|
||||||
using Ombi.Api.Notifications;
|
using Ombi.Api.Notifications;
|
||||||
|
@ -120,6 +121,7 @@ namespace Ombi.DependencyInjection
|
||||||
services.AddTransient<IOmbiService, OmbiService>();
|
services.AddTransient<IOmbiService, OmbiService>();
|
||||||
services.AddTransient<IFanartTvApi, FanartTvApi>();
|
services.AddTransient<IFanartTvApi, FanartTvApi>();
|
||||||
services.AddTransient<IPushoverApi, PushoverApi>();
|
services.AddTransient<IPushoverApi, PushoverApi>();
|
||||||
|
services.AddTransient<IGotifyApi, GotifyApi>();
|
||||||
services.AddTransient<IMattermostApi, MattermostApi>();
|
services.AddTransient<IMattermostApi, MattermostApi>();
|
||||||
services.AddTransient<ICouchPotatoApi, CouchPotatoApi>();
|
services.AddTransient<ICouchPotatoApi, CouchPotatoApi>();
|
||||||
services.AddTransient<IDogNzbApi, DogNzbApi>();
|
services.AddTransient<IDogNzbApi, DogNzbApi>();
|
||||||
|
@ -170,6 +172,7 @@ namespace Ombi.DependencyInjection
|
||||||
services.AddTransient<ISlackNotification, SlackNotification>();
|
services.AddTransient<ISlackNotification, SlackNotification>();
|
||||||
services.AddTransient<IMattermostNotification, MattermostNotification>();
|
services.AddTransient<IMattermostNotification, MattermostNotification>();
|
||||||
services.AddTransient<IPushoverNotification, PushoverNotification>();
|
services.AddTransient<IPushoverNotification, PushoverNotification>();
|
||||||
|
services.AddTransient<IGotifyNotification, GotifyNotification>();
|
||||||
services.AddTransient<ITelegramNotification, TelegramNotification>();
|
services.AddTransient<ITelegramNotification, TelegramNotification>();
|
||||||
services.AddTransient<IMobileNotification, MobileNotification>();
|
services.AddTransient<IMobileNotification, MobileNotification>();
|
||||||
services.AddTransient<IChangeLogProcessor, ChangeLogProcessor>();
|
services.AddTransient<IChangeLogProcessor, ChangeLogProcessor>();
|
||||||
|
|
39
src/Ombi.Helpers/GlobalMutex.cs
Normal file
39
src/Ombi.Helpers/GlobalMutex.cs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Nito.AsyncEx;
|
||||||
|
|
||||||
|
namespace Ombi.Helpers
|
||||||
|
{
|
||||||
|
public static class GlobalMutex
|
||||||
|
{
|
||||||
|
public static async Task<T> Lock<T>(Func<Task<T>> func)
|
||||||
|
{
|
||||||
|
const string mutexId = "Global\\OMBI";
|
||||||
|
using (var mutex = new Mutex(false, mutexId, out _))
|
||||||
|
{
|
||||||
|
var hasHandle = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hasHandle = mutex.WaitOne(5000, false);
|
||||||
|
if (hasHandle == false)
|
||||||
|
throw new TimeoutException("Timeout waiting for exclusive access");
|
||||||
|
}
|
||||||
|
catch (AbandonedMutexException)
|
||||||
|
{
|
||||||
|
hasHandle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await func();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (hasHandle)
|
||||||
|
mutex.ReleaseMutex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,7 @@ namespace Ombi.Helpers
|
||||||
public static EventId MattermostNotification => new EventId(4004);
|
public static EventId MattermostNotification => new EventId(4004);
|
||||||
public static EventId PushoverNotification => new EventId(4005);
|
public static EventId PushoverNotification => new EventId(4005);
|
||||||
public static EventId TelegramNotifcation => new EventId(4006);
|
public static EventId TelegramNotifcation => new EventId(4006);
|
||||||
|
public static EventId GotifyNotification => new EventId(4007);
|
||||||
|
|
||||||
public static EventId TvSender => new EventId(5000);
|
public static EventId TvSender => new EventId(5000);
|
||||||
public static EventId SonarrSender => new EventId(5001);
|
public static EventId SonarrSender => new EventId(5001);
|
||||||
|
|
|
@ -10,5 +10,6 @@
|
||||||
Slack = 5,
|
Slack = 5,
|
||||||
Mattermost = 6,
|
Mattermost = 6,
|
||||||
Mobile = 7,
|
Mobile = 7,
|
||||||
|
Gotify = 8,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@ namespace Ombi.Mapping.Profiles
|
||||||
CreateMap<UpdateSettingsViewModel, UpdateSettings>().ReverseMap();
|
CreateMap<UpdateSettingsViewModel, UpdateSettings>().ReverseMap();
|
||||||
CreateMap<MobileNotificationsViewModel, MobileNotificationSettings>().ReverseMap();
|
CreateMap<MobileNotificationsViewModel, MobileNotificationSettings>().ReverseMap();
|
||||||
CreateMap<NewsletterNotificationViewModel, NewsletterSettings>().ReverseMap();
|
CreateMap<NewsletterNotificationViewModel, NewsletterSettings>().ReverseMap();
|
||||||
|
CreateMap<GotifyNotificationViewModel, GotifySettings>().ReverseMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
116
src/Ombi.Notifications/Agents/GotifyNotification.cs
Normal file
116
src/Ombi.Notifications/Agents/GotifyNotification.cs
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Ombi.Api.Gotify;
|
||||||
|
using Ombi.Core.Settings;
|
||||||
|
using Ombi.Helpers;
|
||||||
|
using Ombi.Notifications.Models;
|
||||||
|
using Ombi.Settings.Settings.Models;
|
||||||
|
using Ombi.Settings.Settings.Models.Notifications;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
using Ombi.Store.Repository;
|
||||||
|
using Ombi.Store.Repository.Requests;
|
||||||
|
|
||||||
|
namespace Ombi.Notifications.Agents
|
||||||
|
{
|
||||||
|
public class GotifyNotification : BaseNotification<GotifySettings>, IGotifyNotification
|
||||||
|
{
|
||||||
|
public GotifyNotification(IGotifyApi api, ISettingsService<GotifySettings> sn, ILogger<GotifyNotification> log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t,
|
||||||
|
ISettingsService<CustomizationSettings> s, IRepository<RequestSubscription> sub, IMusicRequestRepository music,
|
||||||
|
IRepository<UserNotificationPreferences> userPref) : base(sn, r, m, t, s, log, sub, music, userPref)
|
||||||
|
{
|
||||||
|
Api = api;
|
||||||
|
Logger = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string NotificationName => "GotifyNotification";
|
||||||
|
|
||||||
|
private IGotifyApi Api { get; }
|
||||||
|
private ILogger<GotifyNotification> Logger { get; }
|
||||||
|
|
||||||
|
protected override bool ValidateConfiguration(GotifySettings settings)
|
||||||
|
{
|
||||||
|
return settings.Enabled && !string.IsNullOrEmpty(settings.BaseUrl) && !string.IsNullOrEmpty(settings.ApplicationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task NewRequest(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.NewRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override async Task NewIssue(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.Issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task IssueComment(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.IssueComment);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task IssueResolved(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.IssueResolved);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task AddedToRequestQueue(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.ItemAddedToFaultQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task RequestDeclined(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.RequestDeclined);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task RequestApproved(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.RequestApproved);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task AvailableRequest(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
await Run(model, settings, NotificationType.RequestAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task Send(NotificationMessage model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Api.PushAsync(settings.BaseUrl, settings.ApplicationToken, model.Subject, model.Message, settings.Priority);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.LogError(LoggingEvents.GotifyNotification, e, "Failed to send Gotify notification");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task Test(NotificationOptions model, GotifySettings settings)
|
||||||
|
{
|
||||||
|
var message = $"This is a test from Ombi, if you can see this then we have successfully pushed a notification!";
|
||||||
|
var notification = new NotificationMessage
|
||||||
|
{
|
||||||
|
Message = message,
|
||||||
|
};
|
||||||
|
await Send(notification, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Run(NotificationOptions model, GotifySettings settings, NotificationType type)
|
||||||
|
{
|
||||||
|
var parsed = await LoadTemplate(NotificationAgent.Gotify, type, model);
|
||||||
|
if (parsed.Disabled)
|
||||||
|
{
|
||||||
|
Logger.LogInformation($"Template {type} is disabled for {NotificationAgent.Gotify}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var notification = new NotificationMessage
|
||||||
|
{
|
||||||
|
Message = parsed.Message,
|
||||||
|
};
|
||||||
|
|
||||||
|
await Send(notification, settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Ombi.Notifications.Agents
|
||||||
|
{
|
||||||
|
public interface IGotifyNotification : INotification
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ using EnsureThat;
|
||||||
using MailKit.Net.Smtp;
|
using MailKit.Net.Smtp;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
|
using MimeKit.Utils;
|
||||||
using Ombi.Core.Settings;
|
using Ombi.Core.Settings;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Notifications.Models;
|
using Ombi.Notifications.Models;
|
||||||
|
@ -38,6 +39,15 @@ namespace Ombi.Notifications
|
||||||
var customization = await CustomizationSettings.GetSettingsAsync();
|
var customization = await CustomizationSettings.GetSettingsAsync();
|
||||||
var html = email.LoadTemplate(model.Subject, model.Message, null, customization.Logo);
|
var html = email.LoadTemplate(model.Subject, model.Message, null, customization.Logo);
|
||||||
|
|
||||||
|
var messageId = MimeUtils.GenerateMessageId();
|
||||||
|
if (customization.ApplicationUrl.HasValue())
|
||||||
|
{
|
||||||
|
if (Uri.TryCreate(customization.ApplicationUrl, UriKind.RelativeOrAbsolute, out var url))
|
||||||
|
{
|
||||||
|
messageId = MimeUtils.GenerateMessageId(url.IdnHost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var textBody = string.Empty;
|
var textBody = string.Empty;
|
||||||
|
|
||||||
model.Other.TryGetValue("PlainTextBody", out textBody);
|
model.Other.TryGetValue("PlainTextBody", out textBody);
|
||||||
|
@ -50,7 +60,8 @@ namespace Ombi.Notifications
|
||||||
var message = new MimeMessage
|
var message = new MimeMessage
|
||||||
{
|
{
|
||||||
Body = body.ToMessageBody(),
|
Body = body.ToMessageBody(),
|
||||||
Subject = model.Subject
|
Subject = model.Subject,
|
||||||
|
MessageId = messageId
|
||||||
};
|
};
|
||||||
message.From.Add(new MailboxAddress(string.IsNullOrEmpty(settings.SenderName) ? settings.SenderAddress : settings.SenderName, settings.SenderAddress));
|
message.From.Add(new MailboxAddress(string.IsNullOrEmpty(settings.SenderName) ? settings.SenderAddress : settings.SenderName, settings.SenderAddress));
|
||||||
message.To.Add(new MailboxAddress(model.To, model.To));
|
message.To.Add(new MailboxAddress(model.To, model.To));
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Ombi.Api.Discord\Ombi.Api.Discord.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Discord\Ombi.Api.Discord.csproj" />
|
||||||
|
<ProjectReference Include="..\Ombi.Api.Gotify\Ombi.Api.Gotify.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Notifications\Ombi.Api.Notifications.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Notifications\Ombi.Api.Notifications.csproj" />
|
||||||
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
|
<ProjectReference Include="..\Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj" />
|
||||||
|
|
|
@ -81,7 +81,6 @@ namespace Ombi.Schedule
|
||||||
RecurringJob.AddOrUpdate(() => _embyUserImporter.Start(), JobSettingsHelper.UserImporter(s));
|
RecurringJob.AddOrUpdate(() => _embyUserImporter.Start(), JobSettingsHelper.UserImporter(s));
|
||||||
RecurringJob.AddOrUpdate(() => _plexUserImporter.Start(), JobSettingsHelper.UserImporter(s));
|
RecurringJob.AddOrUpdate(() => _plexUserImporter.Start(), JobSettingsHelper.UserImporter(s));
|
||||||
RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s));
|
RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s));
|
||||||
RecurringJob.AddOrUpdate(() => _newsletter.Start(), JobSettingsHelper.Newsletter(s));
|
|
||||||
RecurringJob.AddOrUpdate(() => _resender.Start(), JobSettingsHelper.ResendFailedRequests(s));
|
RecurringJob.AddOrUpdate(() => _resender.Start(), JobSettingsHelper.ResendFailedRequests(s));
|
||||||
RecurringJob.AddOrUpdate(() => _mediaDatabaseRefresh.Start(), JobSettingsHelper.MediaDatabaseRefresh(s));
|
RecurringJob.AddOrUpdate(() => _mediaDatabaseRefresh.Start(), JobSettingsHelper.MediaDatabaseRefresh(s));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
namespace Ombi.Settings.Settings.Models.Notifications
|
||||||
|
{
|
||||||
|
public class GotifySettings : Settings
|
||||||
|
{
|
||||||
|
public bool Enabled { get; set; }
|
||||||
|
public string BaseUrl { get; set; }
|
||||||
|
public string ApplicationToken { get; set; }
|
||||||
|
public sbyte Priority { get; set; } = 4;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ using System.Linq.Expressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.Query;
|
using Microsoft.EntityFrameworkCore.Query;
|
||||||
using Nito.AsyncEx;
|
using Ombi.Helpers;
|
||||||
using Ombi.Store.Context;
|
using Ombi.Store.Context;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ namespace Ombi.Store.Repository
|
||||||
}
|
}
|
||||||
public DbSet<T> _db { get; }
|
public DbSet<T> _db { get; }
|
||||||
private readonly U _ctx;
|
private readonly U _ctx;
|
||||||
private readonly AsyncLock _mutex = new AsyncLock();
|
|
||||||
|
|
||||||
public async Task<T> Find(object key)
|
public async Task<T> Find(object key)
|
||||||
{
|
{
|
||||||
|
@ -84,10 +83,7 @@ namespace Ombi.Store.Repository
|
||||||
|
|
||||||
private async Task<int> InternalSaveChanges()
|
private async Task<int> InternalSaveChanges()
|
||||||
{
|
{
|
||||||
using (await _mutex.LockAsync())
|
return await GlobalMutex.Lock(async () => await _ctx.SaveChangesAsync());
|
||||||
{
|
|
||||||
return await _ctx.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Notifications", "O
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Lidarr", "Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj", "{4FA21A20-92F4-462C-B929-2C517A88CC56}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Lidarr", "Ombi.Api.Lidarr\Ombi.Api.Lidarr.csproj", "{4FA21A20-92F4-462C-B929-2C517A88CC56}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Helpers.Tests", "Ombi.Helpers.Tests\Ombi.Helpers.Tests.csproj", "{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Helpers.Tests", "Ombi.Helpers.Tests\Ombi.Helpers.Tests.csproj", "{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Gotify", "Ombi.Api.Gotify\Ombi.Api.Gotify.csproj", "{105EA346-766E-45B8-928B-DE6991DCB7EB}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -256,6 +258,10 @@ Global
|
||||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{105EA346-766E-45B8-928B-DE6991DCB7EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{105EA346-766E-45B8-928B-DE6991DCB7EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{105EA346-766E-45B8-928B-DE6991DCB7EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{105EA346-766E-45B8-928B-DE6991DCB7EB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@ -293,6 +299,7 @@ Global
|
||||||
{10D1FE9D-9124-42B7-B1E1-CEB99B832618} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
{10D1FE9D-9124-42B7-B1E1-CEB99B832618} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
{4FA21A20-92F4-462C-B929-2C517A88CC56} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
{4FA21A20-92F4-462C-B929-2C517A88CC56} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
|
{CC8CEFCD-0CB6-45BB-845F-508BCAB5BDC3} = {6F42AB98-9196-44C4-B888-D5E409F415A1}
|
||||||
|
{105EA346-766E-45B8-928B-DE6991DCB7EB} = {9293CA11-360A-4C20-A674-B9E794431BF5}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869}
|
||||||
|
|
|
@ -93,6 +93,14 @@ export interface IPushoverNotificationSettings extends INotificationSettings {
|
||||||
sound: string;
|
sound: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IGotifyNotificationSettings extends INotificationSettings {
|
||||||
|
accessToken: string;
|
||||||
|
notificationTemplates: INotificationTemplates[];
|
||||||
|
baseUrl: string;
|
||||||
|
applicationToken: string;
|
||||||
|
priority: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IMattermostNotifcationSettings extends INotificationSettings {
|
export interface IMattermostNotifcationSettings extends INotificationSettings {
|
||||||
webhookUrl: string;
|
webhookUrl: string;
|
||||||
username: string;
|
username: string;
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
IDiscordNotifcationSettings,
|
IDiscordNotifcationSettings,
|
||||||
IEmailNotificationSettings,
|
IEmailNotificationSettings,
|
||||||
IEmbyServer,
|
IEmbyServer,
|
||||||
|
IGotifyNotificationSettings,
|
||||||
ILidarrSettings,
|
ILidarrSettings,
|
||||||
IMattermostNotifcationSettings,
|
IMattermostNotifcationSettings,
|
||||||
IMobileNotificationTestSettings,
|
IMobileNotificationTestSettings,
|
||||||
|
@ -43,6 +44,10 @@ export class TesterService extends ServiceHelpers {
|
||||||
return this.http.post<boolean>(`${this.url}pushover`, JSON.stringify(settings), { headers: this.headers });
|
return this.http.post<boolean>(`${this.url}pushover`, JSON.stringify(settings), { headers: this.headers });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public gotifyTest(settings: IGotifyNotificationSettings): Observable<boolean> {
|
||||||
|
return this.http.post<boolean>(`${this.url}gotify`, JSON.stringify(settings), { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
public mattermostTest(settings: IMattermostNotifcationSettings): Observable<boolean> {
|
public mattermostTest(settings: IMattermostNotifcationSettings): Observable<boolean> {
|
||||||
return this.http.post<boolean>(`${this.url}mattermost`, JSON.stringify(settings), {headers: this.headers});
|
return this.http.post<boolean>(`${this.url}mattermost`, JSON.stringify(settings), {headers: this.headers});
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import {
|
||||||
IDogNzbSettings,
|
IDogNzbSettings,
|
||||||
IEmailNotificationSettings,
|
IEmailNotificationSettings,
|
||||||
IEmbySettings,
|
IEmbySettings,
|
||||||
|
IGotifyNotificationSettings,
|
||||||
IIssueSettings,
|
IIssueSettings,
|
||||||
IJobSettings,
|
IJobSettings,
|
||||||
IJobSettingsViewModel,
|
IJobSettingsViewModel,
|
||||||
|
@ -182,6 +183,14 @@ export class SettingsService extends ServiceHelpers {
|
||||||
.post<boolean>(`${this.url}/notifications/pushover`, JSON.stringify(settings), {headers: this.headers});
|
.post<boolean>(`${this.url}/notifications/pushover`, JSON.stringify(settings), {headers: this.headers});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getGotifyNotificationSettings(): Observable<IGotifyNotificationSettings> {
|
||||||
|
return this.http.get<IGotifyNotificationSettings>(`${this.url}/notifications/gotify`, { headers: this.headers });
|
||||||
|
}
|
||||||
|
public saveGotifyNotificationSettings(settings: IGotifyNotificationSettings): Observable<boolean> {
|
||||||
|
return this.http
|
||||||
|
.post<boolean>(`${this.url}/notifications/gotify`, JSON.stringify(settings), { headers: this.headers });
|
||||||
|
}
|
||||||
|
|
||||||
public getSlackNotificationSettings(): Observable<ISlackNotificationSettings> {
|
public getSlackNotificationSettings(): Observable<ISlackNotificationSettings> {
|
||||||
return this.http.get<ISlackNotificationSettings>(`${this.url}/notifications/slack`, {headers: this.headers});
|
return this.http.get<ISlackNotificationSettings>(`${this.url}/notifications/slack`, {headers: this.headers});
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
<settings-menu></settings-menu>
|
||||||
|
<div *ngIf="form">
|
||||||
|
<fieldset>
|
||||||
|
<legend>Gotify Notifications</legend>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="checkbox">
|
||||||
|
<input type="checkbox" id="enable" formControlName="enabled">
|
||||||
|
<label for="enable">Enabled</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="baseUrl" class="control-label">Base URL</label>
|
||||||
|
|
||||||
|
<input type="text" class="form-control form-control-custom " id="baseUrl" name="baseUrl" [ngClass]="{'form-error': form.get('baseUrl').hasError('required')}" formControlName="baseUrl" pTooltip="Enter the URL of your gotify server.">
|
||||||
|
<small *ngIf="form.get('baseUrl').hasError('required')" class="error-text">The Base URL is required</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="applicationToken" class="control-label">Application Token</label>
|
||||||
|
|
||||||
|
<input type="text" class="form-control form-control-custom " id="applicationToken" name="applicationToken" [ngClass]="{'form-error': form.get('applicationToken').hasError('required')}" formControlName="applicationToken" pTooltip="Enter your Application token from Gotify.">
|
||||||
|
<small *ngIf="form.get('applicationToken').hasError('required')" class="error-text">The Application Token is required</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="priority" class="control-label">Priority</label>
|
||||||
|
<div>
|
||||||
|
<select class="form-control form-control-custom " id="priority" name="priority" formControlName="priority" pTooltip="The priority you want your gotify notifications sent as.">
|
||||||
|
<option value="4">Normal</option>
|
||||||
|
<option value="8">High</option>
|
||||||
|
<option value="2">Low</option>
|
||||||
|
<option value="0">Lowest</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||||
|
Test
|
||||||
|
<div id="spinner"></div>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div>
|
||||||
|
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<notification-templates [templates]="templates" [showSubject]="false"></notification-templates>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||||
|
|
||||||
|
import { IGotifyNotificationSettings, INotificationTemplates, NotificationType } from "../../interfaces";
|
||||||
|
import { TesterService } from "../../services";
|
||||||
|
import { NotificationService } from "../../services";
|
||||||
|
import { SettingsService } from "../../services";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: "./gotify.component.html",
|
||||||
|
})
|
||||||
|
export class GotifyComponent implements OnInit {
|
||||||
|
public NotificationType = NotificationType;
|
||||||
|
public templates: INotificationTemplates[];
|
||||||
|
public form: FormGroup;
|
||||||
|
|
||||||
|
constructor(private settingsService: SettingsService,
|
||||||
|
private notificationService: NotificationService,
|
||||||
|
private fb: FormBuilder,
|
||||||
|
private testerService: TesterService) { }
|
||||||
|
|
||||||
|
public ngOnInit() {
|
||||||
|
this.settingsService.getGotifyNotificationSettings().subscribe(x => {
|
||||||
|
this.templates = x.notificationTemplates;
|
||||||
|
|
||||||
|
this.form = this.fb.group({
|
||||||
|
enabled: [x.enabled],
|
||||||
|
baseUrl: [x.baseUrl, [Validators.required]],
|
||||||
|
applicationToken: [x.applicationToken, [Validators.required]],
|
||||||
|
priority: [x.priority],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public onSubmit(form: FormGroup) {
|
||||||
|
if (form.invalid) {
|
||||||
|
this.notificationService.error("Please check your entered values");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const settings = <IGotifyNotificationSettings> form.value;
|
||||||
|
settings.notificationTemplates = this.templates;
|
||||||
|
|
||||||
|
this.settingsService.saveGotifyNotificationSettings(settings).subscribe(x => {
|
||||||
|
if (x) {
|
||||||
|
this.notificationService.success("Successfully saved the Gotify settings");
|
||||||
|
} else {
|
||||||
|
this.notificationService.success("There was an error when saving the Gotify settings");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public test(form: FormGroup) {
|
||||||
|
if (form.invalid) {
|
||||||
|
this.notificationService.error("Please check your entered values");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.testerService.gotifyTest(form.value).subscribe(x => {
|
||||||
|
if (x) {
|
||||||
|
this.notificationService.success("Successfully sent a Gotify message");
|
||||||
|
} else {
|
||||||
|
this.notificationService.error("There was an error when sending the Gotify message. Please check your settings");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ import { LidarrComponent } from "./lidarr/lidarr.component";
|
||||||
import { MassEmailComponent } from "./massemail/massemail.component";
|
import { MassEmailComponent } from "./massemail/massemail.component";
|
||||||
import { DiscordComponent } from "./notifications/discord.component";
|
import { DiscordComponent } from "./notifications/discord.component";
|
||||||
import { EmailNotificationComponent } from "./notifications/emailnotification.component";
|
import { EmailNotificationComponent } from "./notifications/emailnotification.component";
|
||||||
|
import { GotifyComponent } from "./notifications/gotify.component";
|
||||||
import { MattermostComponent } from "./notifications/mattermost.component";
|
import { MattermostComponent } from "./notifications/mattermost.component";
|
||||||
import { MobileComponent } from "./notifications/mobile.component";
|
import { MobileComponent } from "./notifications/mobile.component";
|
||||||
import { NewsletterComponent } from "./notifications/newsletter.component";
|
import { NewsletterComponent } from "./notifications/newsletter.component";
|
||||||
|
@ -63,6 +64,7 @@ const routes: Routes = [
|
||||||
{ path: "Slack", component: SlackComponent, canActivate: [AuthGuard] },
|
{ path: "Slack", component: SlackComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "Pushover", component: PushoverComponent, canActivate: [AuthGuard] },
|
{ path: "Pushover", component: PushoverComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "Pushbullet", component: PushbulletComponent, canActivate: [AuthGuard] },
|
{ path: "Pushbullet", component: PushbulletComponent, canActivate: [AuthGuard] },
|
||||||
|
{ path: "Gotify", component: GotifyComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "Mattermost", component: MattermostComponent, canActivate: [AuthGuard] },
|
{ path: "Mattermost", component: MattermostComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "UserManagement", component: UserManagementComponent, canActivate: [AuthGuard] },
|
{ path: "UserManagement", component: UserManagementComponent, canActivate: [AuthGuard] },
|
||||||
{ path: "Update", component: UpdateComponent, canActivate: [AuthGuard] },
|
{ path: "Update", component: UpdateComponent, canActivate: [AuthGuard] },
|
||||||
|
@ -117,6 +119,7 @@ const routes: Routes = [
|
||||||
PushoverComponent,
|
PushoverComponent,
|
||||||
MattermostComponent,
|
MattermostComponent,
|
||||||
PushbulletComponent,
|
PushbulletComponent,
|
||||||
|
GotifyComponent,
|
||||||
UserManagementComponent,
|
UserManagementComponent,
|
||||||
UpdateComponent,
|
UpdateComponent,
|
||||||
AboutComponent,
|
AboutComponent,
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Pushover']">Pushover</a></li>
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Pushover']">Pushover</a></li>
|
||||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Mattermost']">Mattermost</a></li>
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Mattermost']">Mattermost</a></li>
|
||||||
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Telegram']">Telegram</a></li>
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Telegram']">Telegram</a></li>
|
||||||
|
<li [routerLinkActive]="['active']"><a [routerLink]="['/Settings/Gotify']">Gotify</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace Ombi.Controllers.External
|
||||||
IPushbulletNotification pushbullet, ISlackNotification slack, IPushoverNotification po, IMattermostNotification mm,
|
IPushbulletNotification pushbullet, ISlackNotification slack, IPushoverNotification po, IMattermostNotification mm,
|
||||||
IPlexApi plex, IEmbyApi emby, IRadarrApi radarr, ISonarrApi sonarr, ILogger<TesterController> log, IEmailProvider provider,
|
IPlexApi plex, IEmbyApi emby, IRadarrApi radarr, ISonarrApi sonarr, ILogger<TesterController> log, IEmailProvider provider,
|
||||||
ICouchPotatoApi cpApi, ITelegramNotification telegram, ISickRageApi srApi, INewsletterJob newsletter, IMobileNotification mobileNotification,
|
ICouchPotatoApi cpApi, ITelegramNotification telegram, ISickRageApi srApi, INewsletterJob newsletter, IMobileNotification mobileNotification,
|
||||||
ILidarrApi lidarrApi)
|
ILidarrApi lidarrApi, IGotifyNotification gotifyNotification)
|
||||||
{
|
{
|
||||||
Service = service;
|
Service = service;
|
||||||
DiscordNotification = notification;
|
DiscordNotification = notification;
|
||||||
|
@ -61,6 +61,7 @@ namespace Ombi.Controllers.External
|
||||||
Newsletter = newsletter;
|
Newsletter = newsletter;
|
||||||
MobileNotification = mobileNotification;
|
MobileNotification = mobileNotification;
|
||||||
LidarrApi = lidarrApi;
|
LidarrApi = lidarrApi;
|
||||||
|
GotifyNotification = gotifyNotification;
|
||||||
}
|
}
|
||||||
|
|
||||||
private INotificationService Service { get; }
|
private INotificationService Service { get; }
|
||||||
|
@ -69,6 +70,7 @@ namespace Ombi.Controllers.External
|
||||||
private IPushbulletNotification PushbulletNotification { get; }
|
private IPushbulletNotification PushbulletNotification { get; }
|
||||||
private ISlackNotification SlackNotification { get; }
|
private ISlackNotification SlackNotification { get; }
|
||||||
private IPushoverNotification PushoverNotification { get; }
|
private IPushoverNotification PushoverNotification { get; }
|
||||||
|
private IGotifyNotification GotifyNotification { get; }
|
||||||
private IMattermostNotification MattermostNotification { get; }
|
private IMattermostNotification MattermostNotification { get; }
|
||||||
private IPlexApi PlexApi { get; }
|
private IPlexApi PlexApi { get; }
|
||||||
private IRadarrApi RadarrApi { get; }
|
private IRadarrApi RadarrApi { get; }
|
||||||
|
@ -155,6 +157,30 @@ namespace Ombi.Controllers.External
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a test message to Gotify using the provided settings
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="settings">The settings.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("gotify")]
|
||||||
|
public bool Gotify([FromBody] GotifySettings settings)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
settings.Enabled = true;
|
||||||
|
GotifyNotification.NotifyAsync(
|
||||||
|
new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log.LogError(LoggingEvents.Api, e, "Could not test Gotify");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends a test message to mattermost using the provided settings
|
/// Sends a test message to mattermost using the provided settings
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -947,6 +947,40 @@ namespace Ombi.Controllers
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves the gotify notification settings.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="model">The model.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("notifications/gotify")]
|
||||||
|
public async Task<bool> GotifyNotificationSettings([FromBody] GotifyNotificationViewModel model)
|
||||||
|
{
|
||||||
|
// Save the email settings
|
||||||
|
var settings = Mapper.Map<GotifySettings>(model);
|
||||||
|
var result = await Save(settings);
|
||||||
|
|
||||||
|
// Save the templates
|
||||||
|
await TemplateRepository.UpdateRange(model.NotificationTemplates);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the gotify Notification Settings.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("notifications/gotify")]
|
||||||
|
public async Task<GotifyNotificationViewModel> GotifyNotificationSettings()
|
||||||
|
{
|
||||||
|
var settings = await Get<GotifySettings>();
|
||||||
|
var model = Mapper.Map<GotifyNotificationViewModel>(settings);
|
||||||
|
|
||||||
|
// Lookup to see if we have any templates saved
|
||||||
|
model.NotificationTemplates = BuildTemplates(NotificationAgent.Gotify);
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the Newsletter notification settings.
|
/// Saves the Newsletter notification settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -123,9 +123,6 @@ namespace Ombi.Controllers
|
||||||
return new UnauthorizedResult();
|
return new UnauthorizedResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
user.LastLoggedIn = DateTime.UtcNow;
|
|
||||||
//await _userManager.UpdateAsync(user);
|
|
||||||
|
|
||||||
var claims = new List<Claim>
|
var claims = new List<Claim>
|
||||||
{
|
{
|
||||||
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
|
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
|
||||||
|
@ -152,6 +149,9 @@ namespace Ombi.Controllers
|
||||||
//await _token.CreateToken(new Tokens() {Token = accessToken, User = user});
|
//await _token.CreateToken(new Tokens() {Token = accessToken, User = user});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.LastLoggedIn = DateTime.UtcNow;
|
||||||
|
await GlobalMutex.Lock(async () => await _userManager.UpdateAsync(user)).ConfigureAwait(false);
|
||||||
|
|
||||||
return new JsonResult(new
|
return new JsonResult(new
|
||||||
{
|
{
|
||||||
access_token = accessToken,
|
access_token = accessToken,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue