From bf043fc76ec736d3aec9518641a61b6760e6b609 Mon Sep 17 00:00:00 2001 From: tidusjar Date: Mon, 21 Aug 2017 17:06:07 +0100 Subject: [PATCH] Fixed some issues around the tv requests area Added mattermost and telegram notifications #1459 #865 #1457 --- src/Ombi.Api.Mattermost/IMattermostApi.cs | 10 ++ src/Ombi.Api.Mattermost/MattermostApi.cs | 27 +++ .../Models/MattermostBody.cs | 45 +++++ .../Ombi.Api.Mattermost.csproj | 15 ++ src/Ombi.Api.Pushover/IPushoverApi.cs | 10 ++ .../Models/PushoverResponse.cs | 12 ++ .../Ombi.Api.Pushover.csproj | 11 ++ src/Ombi.Api.Pushover/PushoverApi.cs | 26 +++ src/Ombi.Core/Engine/TvRequestEngine.cs | 9 +- .../UI/MattermostNotificationsViewModel.cs | 21 +++ .../UI/PushoverNotificationViewModel.cs | 23 +++ src/Ombi.DependencyInjection/IocExtensions.cs | 7 + .../Ombi.DependencyInjection.csproj | 2 + src/Ombi.Helpers/LoggingEvents.cs | 2 + src/Ombi.Helpers/NotificationAgent.cs | 3 +- src/Ombi.Mapping/Profiles/SettingsProfile.cs | 2 + .../Agents/IMattermostNotification.cs | 6 + .../Agents/IPushoverNotification.cs | 6 + .../Agents/MattermostNotification.cs | 164 ++++++++++++++++++ .../Agents/PushoverNotification.cs | 145 ++++++++++++++++ .../Ombi.Notifications.csproj | 2 + .../MattermostNotificationSettings.cs | 11 ++ .../Models/Notifications/PushoverSettings.cs | 12 ++ src/Ombi.Store/Context/OmbiContext.cs | 15 +- .../Requests/TvRequestRepository.cs | 4 + src/Ombi.sln | 22 ++- src/Ombi/ClientApp/app/app.component.ts | 10 +- src/Ombi/ClientApp/app/auth/auth.service.ts | 15 +- .../app/interfaces/INotifcationSettings.ts | 16 +- .../ClientApp/app/interfaces/IRequestModel.ts | 3 +- .../requests/tvrequest-manage.component.ts | 2 + .../app/requests/tvrequests.component.html | 30 ++-- .../app/requests/tvrequests.component.ts | 87 +++++----- .../services/applications/tester.service.ts | 11 +- .../app/services/settings.service.ts | 70 ++++++-- .../notifications/mattermost.component.html | 76 ++++++++ .../notifications/mattermost.component.ts | 72 ++++++++ .../notifications/pushbullet.component.html | 2 +- .../notifications/pushover.component.html | 59 +++++++ .../notifications/pushover.component.ts | 69 ++++++++ .../app/settings/ombi/ombi.component.html | 10 +- .../app/settings/ombi/ombi.component.ts | 8 +- .../ClientApp/app/settings/settings.module.ts | 9 + .../app/settings/settingsmenu.component.html | 3 +- .../Controllers/External/TesterController.cs | 36 +++- src/Ombi/Controllers/SettingsController.cs | 78 +++++++++ src/Ombi/Ombi.csproj | 1 + src/Ombi/Startup.cs | 77 +------- 48 files changed, 1164 insertions(+), 192 deletions(-) create mode 100644 src/Ombi.Api.Mattermost/IMattermostApi.cs create mode 100644 src/Ombi.Api.Mattermost/MattermostApi.cs create mode 100644 src/Ombi.Api.Mattermost/Models/MattermostBody.cs create mode 100644 src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj create mode 100644 src/Ombi.Api.Pushover/IPushoverApi.cs create mode 100644 src/Ombi.Api.Pushover/Models/PushoverResponse.cs create mode 100644 src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj create mode 100644 src/Ombi.Api.Pushover/PushoverApi.cs create mode 100644 src/Ombi.Core/Models/UI/MattermostNotificationsViewModel.cs create mode 100644 src/Ombi.Core/Models/UI/PushoverNotificationViewModel.cs create mode 100644 src/Ombi.Notifications/Agents/IMattermostNotification.cs create mode 100644 src/Ombi.Notifications/Agents/IPushoverNotification.cs create mode 100644 src/Ombi.Notifications/Agents/MattermostNotification.cs create mode 100644 src/Ombi.Notifications/Agents/PushoverNotification.cs create mode 100644 src/Ombi.Settings/Settings/Models/Notifications/MattermostNotificationSettings.cs create mode 100644 src/Ombi.Settings/Settings/Models/Notifications/PushoverSettings.cs create mode 100644 src/Ombi/ClientApp/app/settings/notifications/mattermost.component.html create mode 100644 src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts create mode 100644 src/Ombi/ClientApp/app/settings/notifications/pushover.component.html create mode 100644 src/Ombi/ClientApp/app/settings/notifications/pushover.component.ts diff --git a/src/Ombi.Api.Mattermost/IMattermostApi.cs b/src/Ombi.Api.Mattermost/IMattermostApi.cs new file mode 100644 index 000000000..b07802b25 --- /dev/null +++ b/src/Ombi.Api.Mattermost/IMattermostApi.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Ombi.Api.Mattermost.Models; + +namespace Ombi.Api.Mattermost +{ + public interface IMattermostApi + { + Task PushAsync(string webhook, MattermostBody message); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Mattermost/MattermostApi.cs b/src/Ombi.Api.Mattermost/MattermostApi.cs new file mode 100644 index 000000000..c20641aca --- /dev/null +++ b/src/Ombi.Api.Mattermost/MattermostApi.cs @@ -0,0 +1,27 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Ombi.Api.Mattermost.Models; + +namespace Ombi.Api.Mattermost +{ + public class MattermostApi : IMattermostApi + { + public MattermostApi(IApi api) + { + _api = api; + } + + private readonly IApi _api; + + public async Task PushAsync(string webhook, MattermostBody message) + { + var request = new Request(string.Empty, webhook, HttpMethod.Post); + + request.AddJsonBody(message); + + var result = await _api.RequestContent(request); + return result; + } + } +} diff --git a/src/Ombi.Api.Mattermost/Models/MattermostBody.cs b/src/Ombi.Api.Mattermost/Models/MattermostBody.cs new file mode 100644 index 000000000..383554c26 --- /dev/null +++ b/src/Ombi.Api.Mattermost/Models/MattermostBody.cs @@ -0,0 +1,45 @@ +#region Copyright +// /************************************************************************ +// Copyright (c) 2017 Jamie Rees +// File: MattermostBody.cs +// Created By: Jamie Rees +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// ************************************************************************/ +#endregion + +using Newtonsoft.Json; + +namespace Ombi.Api.Mattermost.Models +{ + public class MattermostBody + { + [JsonConstructor] + public MattermostBody() + { + username = "Ombi"; + } + + public string username { get; set; } = "Ombi"; + public string channel { get; set; } + public string text { get; set; } + public string icon_url { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj b/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj new file mode 100644 index 000000000..123fcdcf4 --- /dev/null +++ b/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj @@ -0,0 +1,15 @@ + + + + netstandard1.6 + + + + + + + + + + + diff --git a/src/Ombi.Api.Pushover/IPushoverApi.cs b/src/Ombi.Api.Pushover/IPushoverApi.cs new file mode 100644 index 000000000..42e8e9060 --- /dev/null +++ b/src/Ombi.Api.Pushover/IPushoverApi.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Ombi.Api.Pushover.Models; + +namespace Ombi.Api.Pushover +{ + public interface IPushoverApi + { + Task PushAsync(string accessToken, string message, string userToken); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Pushover/Models/PushoverResponse.cs b/src/Ombi.Api.Pushover/Models/PushoverResponse.cs new file mode 100644 index 000000000..417c728d0 --- /dev/null +++ b/src/Ombi.Api.Pushover/Models/PushoverResponse.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ombi.Api.Pushover.Models +{ + public class PushoverResponse + { + public int status { get; set; } + public string request { get; set; } + } +} diff --git a/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj b/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj new file mode 100644 index 000000000..105bb5244 --- /dev/null +++ b/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj @@ -0,0 +1,11 @@ + + + + netstandard1.6 + + + + + + + diff --git a/src/Ombi.Api.Pushover/PushoverApi.cs b/src/Ombi.Api.Pushover/PushoverApi.cs new file mode 100644 index 000000000..96f4d2e95 --- /dev/null +++ b/src/Ombi.Api.Pushover/PushoverApi.cs @@ -0,0 +1,26 @@ +using System; +using System.Net.Http; +using System.Threading.Tasks; +using Ombi.Api.Pushover.Models; + +namespace Ombi.Api.Pushover +{ + public class PushoverApi : IPushoverApi + { + public PushoverApi(IApi api) + { + _api = api; + } + + private readonly IApi _api; + private const string PushoverEndpoint = "https://api.pushover.net/1"; + + public async Task PushAsync(string accessToken, string message, string userToken) + { + var request = new Request($"messages.json?token={accessToken}&user={userToken}&message={message}", PushoverEndpoint, HttpMethod.Post); + + var result = await _api.Request(request); + return result; + } + } +} diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index d36ef78bb..4390b0674 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -141,12 +141,9 @@ namespace Ombi.Core.Engine public async Task UpdateChildRequest(ChildRequests request) { await Audit.Record(AuditType.Updated, AuditArea.TvRequest, $"Updated Request {request.Title}", Username); - var allRequests = TvRepository.GetChild(); - var results = await allRequests.FirstOrDefaultAsync(x => x.Id == request.Id); - - // TODO need to check if we need to approve any child requests since they may have updated - await TvRepository.UpdateChild(results); - return results; + + await TvRepository.UpdateChild(request); + return request; } public async Task RemoveTvChild(int requestId) diff --git a/src/Ombi.Core/Models/UI/MattermostNotificationsViewModel.cs b/src/Ombi.Core/Models/UI/MattermostNotificationsViewModel.cs new file mode 100644 index 000000000..d4a03a4b0 --- /dev/null +++ b/src/Ombi.Core/Models/UI/MattermostNotificationsViewModel.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using Ombi.Settings.Settings.Models.Notifications; +using Ombi.Store.Entities; + +namespace Ombi.Core.Models.UI +{ + /// + /// The view model for the notification settings page + /// + /// + public class MattermostNotificationsViewModel : MattermostNotificationSettings + { + /// + /// Gets or sets the notification templates. + /// + /// + /// The notification templates. + /// + public List NotificationTemplates { get; set; } + } +} diff --git a/src/Ombi.Core/Models/UI/PushoverNotificationViewModel.cs b/src/Ombi.Core/Models/UI/PushoverNotificationViewModel.cs new file mode 100644 index 000000000..21fe39ab3 --- /dev/null +++ b/src/Ombi.Core/Models/UI/PushoverNotificationViewModel.cs @@ -0,0 +1,23 @@ + +using System.Collections.Generic; +using Ombi.Settings.Settings.Models.Notifications; +using Ombi.Store.Entities; + +namespace Ombi.Core.Models.UI +{ + /// + /// The view model for the notification settings page + /// + /// + public class PushoverNotificationViewModel : PushoverSettings + { + /// + /// Gets or sets the notification templates. + /// + /// + /// The notification templates. + /// + public List NotificationTemplates { get; set; } + + } +} diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index 44edaf696..d12b4a26c 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -28,7 +28,9 @@ using Ombi.Notifications.Agents; using Ombi.Schedule.Jobs.Radarr; using Ombi.Api; using Ombi.Api.FanartTv; +using Ombi.Api.Mattermost; using Ombi.Api.Pushbullet; +using Ombi.Api.Pushover; using Ombi.Api.Service; using Ombi.Api.Slack; using Ombi.Core.Rule.Interfaces; @@ -78,6 +80,8 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } public static void RegisterStore(this IServiceCollection services) @@ -109,6 +113,9 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddTransient(); + services.AddTransient(); + services.AddTransient(); } public static void RegisterJobs(this IServiceCollection services) diff --git a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj index 414a854e9..86267112b 100644 --- a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj +++ b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj @@ -14,8 +14,10 @@ + + diff --git a/src/Ombi.Helpers/LoggingEvents.cs b/src/Ombi.Helpers/LoggingEvents.cs index 0381b098d..2921df654 100644 --- a/src/Ombi.Helpers/LoggingEvents.cs +++ b/src/Ombi.Helpers/LoggingEvents.cs @@ -18,6 +18,8 @@ namespace Ombi.Helpers public static EventId DiscordNotification => new EventId(4001); public static EventId PushbulletNotification => new EventId(4002); public static EventId SlackNotification => new EventId(4003); + public static EventId MattermostNotification => new EventId(4004); + public static EventId PushoverNotification => new EventId(4005); public static EventId TvSender => new EventId(5000); public static EventId SonarrSender => new EventId(5001); diff --git a/src/Ombi.Helpers/NotificationAgent.cs b/src/Ombi.Helpers/NotificationAgent.cs index c1b3515dc..515277f9e 100644 --- a/src/Ombi.Helpers/NotificationAgent.cs +++ b/src/Ombi.Helpers/NotificationAgent.cs @@ -7,6 +7,7 @@ Pushbullet, Pushover, Telegram, - Slack + Slack, + Mattermost, } } \ No newline at end of file diff --git a/src/Ombi.Mapping/Profiles/SettingsProfile.cs b/src/Ombi.Mapping/Profiles/SettingsProfile.cs index cdb38a35b..339e0eb68 100644 --- a/src/Ombi.Mapping/Profiles/SettingsProfile.cs +++ b/src/Ombi.Mapping/Profiles/SettingsProfile.cs @@ -12,6 +12,8 @@ namespace Ombi.Mapping.Profiles CreateMap().ReverseMap(); CreateMap().ReverseMap(); CreateMap().ReverseMap(); + CreateMap().ReverseMap(); + CreateMap().ReverseMap(); } } } \ No newline at end of file diff --git a/src/Ombi.Notifications/Agents/IMattermostNotification.cs b/src/Ombi.Notifications/Agents/IMattermostNotification.cs new file mode 100644 index 000000000..224514770 --- /dev/null +++ b/src/Ombi.Notifications/Agents/IMattermostNotification.cs @@ -0,0 +1,6 @@ +namespace Ombi.Notifications.Agents +{ + public interface IMattermostNotification : INotification + { + } +} \ No newline at end of file diff --git a/src/Ombi.Notifications/Agents/IPushoverNotification.cs b/src/Ombi.Notifications/Agents/IPushoverNotification.cs new file mode 100644 index 000000000..513bdddf7 --- /dev/null +++ b/src/Ombi.Notifications/Agents/IPushoverNotification.cs @@ -0,0 +1,6 @@ +namespace Ombi.Notifications.Agents +{ + public interface IPushoverNotification : INotification + { + } +} \ No newline at end of file diff --git a/src/Ombi.Notifications/Agents/MattermostNotification.cs b/src/Ombi.Notifications/Agents/MattermostNotification.cs new file mode 100644 index 000000000..683fd4084 --- /dev/null +++ b/src/Ombi.Notifications/Agents/MattermostNotification.cs @@ -0,0 +1,164 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Ombi.Api.Discord; +using Ombi.Api.Discord.Models; +using Ombi.Api.Mattermost; +using Ombi.Api.Mattermost.Models; +using Ombi.Core.Settings; +using Ombi.Helpers; +using Ombi.Notifications.Interfaces; +using Ombi.Notifications.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 MattermostNotification : BaseNotification, IMattermostNotification + { + public MattermostNotification(IMattermostApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t) : base(sn, r, m, t) + { + Api = api; + Logger = log; + } + + public override string NotificationName => "MattermostNotification"; + + private IMattermostApi Api { get; } + private ILogger Logger { get; } + + protected override bool ValidateConfiguration(MattermostNotificationSettings settings) + { + if (!settings.Enabled) + { + return false; + } + if (string.IsNullOrEmpty(settings.WebhookUrl)) + { + return false; + } + + return true; + } + + protected override async Task NewRequest(NotificationOptions model, MattermostNotificationSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.NewRequest, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + notification.Other.Add("image", parsed.Image); + await Send(notification, settings); + } + + protected override async Task Issue(NotificationOptions model, MattermostNotificationSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.Issue, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + notification.Other.Add("image", parsed.Image); + await Send(notification, settings); + } + + protected override async Task AddedToRequestQueue(NotificationOptions model, MattermostNotificationSettings settings) + { + var user = string.Empty; + var title = string.Empty; + var image = string.Empty; + if (model.RequestType == RequestType.Movie) + { + user = MovieRequest.RequestedUser.UserAlias; + title = MovieRequest.Title; + image = MovieRequest.PosterPath; + } + else + { + user = TvRequest.RequestedUser.UserAlias; + title = TvRequest.ParentRequest.Title; + image = TvRequest.ParentRequest.PosterPath; + } + var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; + var notification = new NotificationMessage + { + Message = message + }; + notification.Other.Add("image", image); + await Send(notification, settings); + } + + protected override async Task RequestDeclined(NotificationOptions model, MattermostNotificationSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.RequestDeclined, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + notification.Other.Add("image", parsed.Image); + await Send(notification, settings); + } + + protected override async Task RequestApproved(NotificationOptions model, MattermostNotificationSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.RequestApproved, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + notification.Other.Add("image", parsed.Image); + await Send(notification, settings); + } + + protected override async Task AvailableRequest(NotificationOptions model, MattermostNotificationSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Mattermost, NotificationType.RequestAvailable, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + notification.Other.Add("image", parsed.Image); + await Send(notification, settings); + } + + protected override async Task Send(NotificationMessage model, MattermostNotificationSettings settings) + { + try + { + var body = new MattermostBody + { + username = string.IsNullOrEmpty(settings.Username) ? "Ombi" : settings.Username, + channel = settings.Channel, + text = model.Message, + icon_url = settings.IconUrl + }; + await Api.PushAsync(settings.WebhookUrl, body); + } + catch (Exception e) + { + Logger.LogError(LoggingEvents.MattermostNotification, e, "Failed to send Mattermost Notification"); + } + } + + protected override async Task Test(NotificationOptions model, MattermostNotificationSettings 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); + } + } +} diff --git a/src/Ombi.Notifications/Agents/PushoverNotification.cs b/src/Ombi.Notifications/Agents/PushoverNotification.cs new file mode 100644 index 000000000..3e3ae20e2 --- /dev/null +++ b/src/Ombi.Notifications/Agents/PushoverNotification.cs @@ -0,0 +1,145 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Ombi.Api.Pushbullet; +using Ombi.Api.Pushover; +using Ombi.Core.Settings; +using Ombi.Helpers; +using Ombi.Notifications.Interfaces; +using Ombi.Notifications.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 PushoverNotification : BaseNotification, IPushoverNotification + { + public PushoverNotification(IPushoverApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t) : base(sn, r, m, t) + { + Api = api; + Logger = log; + } + + public override string NotificationName => "PushoverNotification"; + + private IPushoverApi Api { get; } + private ILogger Logger { get; } + + protected override bool ValidateConfiguration(PushoverSettings settings) + { + if (!settings.Enabled) + { + return false; + } + if (string.IsNullOrEmpty(settings.AccessToken)) + { + return false; + } + + return true; + } + + protected override async Task NewRequest(NotificationOptions model, PushoverSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.NewRequest, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + await Send(notification, settings); + } + + protected override async Task Issue(NotificationOptions model, PushoverSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.Issue, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } + + protected override async Task AddedToRequestQueue(NotificationOptions model, PushoverSettings settings) + { + string user; + string title; + if (model.RequestType == RequestType.Movie) + { + user = MovieRequest.RequestedUser.UserAlias; + title = MovieRequest.Title; + } + else + { + user = TvRequest.RequestedUser.UserAlias; + title = TvRequest.ParentRequest.Title; + } + var message = $"Hello! The user '{user}' has requested {title} but it could not be added. This has been added into the requests queue and will keep retrying"; + var notification = new NotificationMessage + { + Message = message + }; + await Send(notification, settings); + } + + protected override async Task RequestDeclined(NotificationOptions model, PushoverSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.RequestDeclined, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } + + protected override async Task RequestApproved(NotificationOptions model, PushoverSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.RequestApproved, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + + await Send(notification, settings); + } + + protected override async Task AvailableRequest(NotificationOptions model, PushoverSettings settings) + { + var parsed = await LoadTemplate(NotificationAgent.Pushover, NotificationType.RequestAvailable, model); + + var notification = new NotificationMessage + { + Message = parsed.Message, + }; + await Send(notification, settings); + } + + protected override async Task Send(NotificationMessage model, PushoverSettings settings) + { + try + { + await Api.PushAsync(settings.AccessToken, model.Message, settings.UserToken); + } + catch (Exception e) + { + Logger.LogError(LoggingEvents.PushoverNotification, e, "Failed to send Pushover Notification"); + } + } + + protected override async Task Test(NotificationOptions model, PushoverSettings 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); + } + } +} diff --git a/src/Ombi.Notifications/Ombi.Notifications.csproj b/src/Ombi.Notifications/Ombi.Notifications.csproj index 293861219..e8ce7ca42 100644 --- a/src/Ombi.Notifications/Ombi.Notifications.csproj +++ b/src/Ombi.Notifications/Ombi.Notifications.csproj @@ -10,7 +10,9 @@ + + diff --git a/src/Ombi.Settings/Settings/Models/Notifications/MattermostNotificationSettings.cs b/src/Ombi.Settings/Settings/Models/Notifications/MattermostNotificationSettings.cs new file mode 100644 index 000000000..4e3f4727d --- /dev/null +++ b/src/Ombi.Settings/Settings/Models/Notifications/MattermostNotificationSettings.cs @@ -0,0 +1,11 @@ +namespace Ombi.Settings.Settings.Models.Notifications +{ + public class MattermostNotificationSettings : Settings + { + public string WebhookUrl { get; set; } + public string Channel { get; set; } + public string Username { get; set; } + public string IconUrl { get; set; } + public bool Enabled { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/Models/Notifications/PushoverSettings.cs b/src/Ombi.Settings/Settings/Models/Notifications/PushoverSettings.cs new file mode 100644 index 000000000..d845e8695 --- /dev/null +++ b/src/Ombi.Settings/Settings/Models/Notifications/PushoverSettings.cs @@ -0,0 +1,12 @@ +using System; +using Newtonsoft.Json; + +namespace Ombi.Settings.Settings.Models.Notifications +{ + public class PushoverSettings : Settings + { + public bool Enabled { get; set; } + public string AccessToken { get; set; } + public string UserToken { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index c1364c87b..e71880db7 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -71,18 +71,23 @@ namespace Ombi.Store.Context } - // Check if templates exist + //Check if templates exist var templates = NotificationTemplates.ToList(); - if (templates.Any()) - { - return; - } + //if (templates.Any()) + //{ + // return; + //} var allAgents = Enum.GetValues(typeof(NotificationAgent)).Cast().ToList(); var allTypes = Enum.GetValues(typeof(NotificationType)).Cast().ToList(); foreach (var agent in allAgents) { + if (templates.Any(x => x.Agent == agent)) + { + // We have all the templates for this notification agent + continue; + } foreach (var notificationType in allTypes) { NotificationTemplates notificationToAdd; diff --git a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs index bead9e4cd..ce535b421 100644 --- a/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs +++ b/src/Ombi.Store/Repository/Requests/TvRequestRepository.cs @@ -74,11 +74,15 @@ namespace Ombi.Store.Repository.Requests public async Task Update(TvRequests request) { + Db.Attach(request).State = EntityState.Modified; + await Db.SaveChangesAsync(); } public async Task UpdateChild(ChildRequests request) { + Db.Attach(request).State = EntityState.Modified; + await Db.SaveChangesAsync(); } } diff --git a/src/Ombi.sln b/src/Ombi.sln index 151454a4f..deb6992ea 100644 --- a/src/Ombi.sln +++ b/src/Ombi.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.26430.16 +VisualStudioVersion = 15.0.26730.8 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi", "Ombi\Ombi.csproj", "{C987AA67-AFE1-468F-ACD3-EAD5A48E1F6A}" EndProject @@ -11,6 +11,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution ..\build.cake = ..\build.cake ..\BuildTask.ps1 = ..\BuildTask.ps1 ..\CHANGELOG.md = ..\CHANGELOG.md + ..\global.json = ..\global.json EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Core", "Ombi.Core\Ombi.Core.csproj", "{F56E79C7-791D-4668-A0EC-29E3BBC8D24B}" @@ -73,7 +74,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.FanartTv", "Ombi.A EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Pushbullet", "Ombi.Api.Pushbullet\Ombi.Api.Pushbullet.csproj", "{E237CDF6-D044-437D-B157-E9A3CC0BCF53}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Slack", "Ombi.Api.Slack\Ombi.Api.Slack.csproj", "{71708256-9152-4E81-9FCA-E3181A185806}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.Slack", "Ombi.Api.Slack\Ombi.Api.Slack.csproj", "{71708256-9152-4E81-9FCA-E3181A185806}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Mattermost", "Ombi.Api.Mattermost\Ombi.Api.Mattermost.csproj", "{737B2620-FE5A-4135-A017-79C269A7D36C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ombi.Api.Pushover", "Ombi.Api.Pushover\Ombi.Api.Pushover.csproj", "{CA55DD4F-4EFF-4906-A848-35FCC7BD5654}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -185,6 +190,14 @@ Global {71708256-9152-4E81-9FCA-E3181A185806}.Debug|Any CPU.Build.0 = Debug|Any CPU {71708256-9152-4E81-9FCA-E3181A185806}.Release|Any CPU.ActiveCfg = Release|Any CPU {71708256-9152-4E81-9FCA-E3181A185806}.Release|Any CPU.Build.0 = Release|Any CPU + {737B2620-FE5A-4135-A017-79C269A7D36C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {737B2620-FE5A-4135-A017-79C269A7D36C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {737B2620-FE5A-4135-A017-79C269A7D36C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {737B2620-FE5A-4135-A017-79C269A7D36C}.Release|Any CPU.Build.0 = Release|Any CPU + {CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CA55DD4F-4EFF-4906-A848-35FCC7BD5654}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -210,5 +223,10 @@ Global {FD947E63-A0D2-4878-8378-2005D5E9AB8A} = {9293CA11-360A-4C20-A674-B9E794431BF5} {E237CDF6-D044-437D-B157-E9A3CC0BCF53} = {9293CA11-360A-4C20-A674-B9E794431BF5} {71708256-9152-4E81-9FCA-E3181A185806} = {9293CA11-360A-4C20-A674-B9E794431BF5} + {737B2620-FE5A-4135-A017-79C269A7D36C} = {9293CA11-360A-4C20-A674-B9E794431BF5} + {CA55DD4F-4EFF-4906-A848-35FCC7BD5654} = {9293CA11-360A-4C20-A674-B9E794431BF5} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869} EndGlobalSection EndGlobal diff --git a/src/Ombi/ClientApp/app/app.component.ts b/src/Ombi/ClientApp/app/app.component.ts index 71e6ee246..5d701e4c5 100644 --- a/src/Ombi/ClientApp/app/app.component.ts +++ b/src/Ombi/ClientApp/app/app.component.ts @@ -15,30 +15,24 @@ import { ICustomizationSettings } from './interfaces/ISettings'; }) export class AppComponent implements OnInit { - constructor(public notificationService: NotificationService, public authService: AuthService, private router: Router, private settingsService: SettingsService) - { - } + constructor(public notificationService: NotificationService, public authService: AuthService, private router: Router, private settingsService: SettingsService) { } customizationSettings: ICustomizationSettings; user: ILocalUser; ngOnInit(): void { - - - this.user = this.authService.claims(); this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x); this.router.events.subscribe(() => { - this.user = this.authService.claims(); this.showNav = this.authService.loggedIn(); }); } hasRole(role: string): boolean { - return this.user.roles.some(r => r === role) + return this.user.roles.some(r => r === role); } logOut() { diff --git a/src/Ombi/ClientApp/app/auth/auth.service.ts b/src/Ombi/ClientApp/app/auth/auth.service.ts index 1b6defc19..b6ec60ab8 100644 --- a/src/Ombi/ClientApp/app/auth/auth.service.ts +++ b/src/Ombi/ClientApp/app/auth/auth.service.ts @@ -1,14 +1,11 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/Rx'; +import { tokenNotExpired, JwtHelper } from 'angular2-jwt'; +import { Http, Headers } from '@angular/http'; import { ServiceHelpers } from '../services/service.helpers'; - import { IUserLogin, ILocalUser } from './IUserLogin'; -import { tokenNotExpired, JwtHelper } from 'angular2-jwt'; - -import { Http, Headers } from '@angular/http'; - @Injectable() export class AuthService extends ServiceHelpers { constructor(http: Http) { @@ -23,7 +20,6 @@ export class AuthService extends ServiceHelpers { return this.http.post(`${this.url}/`, JSON.stringify(login), { headers: this.headers }) .map(this.extractData); - } loggedIn() { @@ -48,13 +44,16 @@ export class AuthService extends ServiceHelpers { } else { u.roles.push(roles); } - return u; - } return {}; } + + hasRole(role: string): boolean { + return this.claims().roles.some(r => r === role); + } + logout() { localStorage.removeItem('id_token'); } diff --git a/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts b/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts index a7e53c53a..513d65735 100644 --- a/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts +++ b/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts @@ -64,4 +64,18 @@ export interface IPushbulletNotificationSettings extends INotificationSettings { accessToken: string, notificationTemplates: INotificationTemplates[], channelTag: string; -} \ No newline at end of file +} + +export interface IPushoverNotificationSettings extends INotificationSettings { + accessToken: string, + notificationTemplates: INotificationTemplates[], + userToken: string; +} + +export interface IMattermostNotifcationSettings extends INotificationSettings { + webhookUrl: string, + username: string, + channel: string, + iconUrl:string, + notificationTemplates: INotificationTemplates[], +} diff --git a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts index df5765ae8..c34c24b8c 100644 --- a/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts +++ b/src/Ombi/ClientApp/app/interfaces/IRequestModel.ts @@ -105,7 +105,8 @@ export interface IBaseRequest { denied: boolean, deniedReason: string, requestType: RequestType, - requestedUser: IUser + requestedUser: IUser, + canApprove:boolean, } export interface ITvRequests { diff --git a/src/Ombi/ClientApp/app/requests/tvrequest-manage.component.ts b/src/Ombi/ClientApp/app/requests/tvrequest-manage.component.ts index d55e614e5..966ab3cf2 100644 --- a/src/Ombi/ClientApp/app/requests/tvrequest-manage.component.ts +++ b/src/Ombi/ClientApp/app/requests/tvrequest-manage.component.ts @@ -48,6 +48,7 @@ export class TvRequestManageComponent { } public deny(request: IChildRequests) { + debugger; request.approved = false; request.denied = true; this.requestService.updateChild(request) @@ -55,6 +56,7 @@ export class TvRequestManageComponent { } public approve(request: IChildRequests) { + debugger; request.approved = true; request.denied = false; this.requestService.updateChild(request) diff --git a/src/Ombi/ClientApp/app/requests/tvrequests.component.html b/src/Ombi/ClientApp/app/requests/tvrequests.component.html index a0d9be84e..1965fcc97 100644 --- a/src/Ombi/ClientApp/app/requests/tvrequests.component.html +++ b/src/Ombi/ClientApp/app/requests/tvrequests.component.html @@ -54,7 +54,6 @@
Release Date: {{node.data.releaseDate | date}}

-
Requested Date: {{node.data.requestedDate | date}}
@@ -72,19 +71,24 @@
Requested By: {{child.requestedUser.userName}} + Requested Date: {{child.requestedDate | date}} + + Available + Denied + Processing Request
-
+
- +
- +
- +
@@ -100,24 +104,16 @@ - - # - + # - - Title - + Title - - Air Date - + Air Date - - Status - + Status diff --git a/src/Ombi/ClientApp/app/requests/tvrequests.component.ts b/src/Ombi/ClientApp/app/requests/tvrequests.component.ts index 70b922eba..d6094ddb2 100644 --- a/src/Ombi/ClientApp/app/requests/tvrequests.component.ts +++ b/src/Ombi/ClientApp/app/requests/tvrequests.component.ts @@ -10,6 +10,7 @@ import 'rxjs/add/operator/distinctUntilChanged'; import 'rxjs/add/operator/map'; import { RequestService } from '../services/request.service'; +import { AuthService } from '../auth/auth.service'; import { IdentityService } from '../services/identity.service'; import { ITvRequests, IChildRequests, INewSeasonRequests, IEpisodesRequests } from '../interfaces/IRequestModel'; @@ -25,7 +26,8 @@ import { TreeNode, } from "primeng/primeng"; encapsulation: ViewEncapsulation.None }) export class TvRequestsComponent implements OnInit, OnDestroy { - constructor(private requestService: RequestService, private identityService: IdentityService) { + constructor(private requestService: RequestService, + private identityService: IdentityService, private authService : AuthService) { this.searchChanged .debounceTime(600) // Wait Xms afterthe last event before emitting last event .distinctUntilChanged() // only emit if value is different from previous value @@ -41,6 +43,17 @@ export class TvRequestsComponent implements OnInit, OnDestroy { .subscribe(m => this.tvRequests = this.transformData(m)); }); } + + ngOnInit() { + this.amountToLoad = 5; + this.currentlyLoaded = 5; + this.tvRequests = []; + this.loadInit(); + this.admin = this.authService.hasRole("admin"); + } + + public admin = false; + openClosestTab(el:any): void { var rowclass = "undefined"; el = el.toElement; @@ -70,17 +83,21 @@ export class TvRequestsComponent implements OnInit, OnDestroy { } transformData(datain: ITvRequests[]): any { var temp: TreeNode[] = []; - datain.forEach(function (value) { - temp.push({ - "data": value, - "children": [{ - "data": this.fixEpisodeSort(value.childRequests), leaf: true - }], - leaf: false - }); - }, this) + datain.forEach(function(value) { + temp.push({ + "data": value, + "children": [ + { + "data": this.fixEpisodeSort(value.childRequests), + leaf: true + } + ], + leaf: false + }); + }, + this); console.log(temp); - return temp; + return temp; } private subscriptions = new Subject(); @@ -97,22 +114,16 @@ export class TvRequestsComponent implements OnInit, OnDestroy { public showChildDialogue = false; // This is for the child modal popup public selectedSeason: ITvRequests; - fixEpisodeSort(items: IChildRequests[]) { - items.forEach(function (value) { - value.seasonRequests.forEach(function (requests: INewSeasonRequests) { - requests.episodes.sort(function (a: IEpisodesRequests, b: IEpisodesRequests) { - return a.episodeNumber - b.episodeNumber; - }) - }) - }) + private fixEpisodeSort(items: IChildRequests[]) : IChildRequests[] { + items.forEach(value => { + value.seasonRequests.forEach((requests: INewSeasonRequests) => { + requests.episodes.sort( + (a: IEpisodesRequests, b: IEpisodesRequests) => a.episodeNumber - b.episodeNumber) + }); + }); return items; } - ngOnInit() { - this.amountToLoad = 5; - this.currentlyLoaded = 5; - this.tvRequests = []; - this.loadInit(); - } + public loadMore() { this.requestService.getTvRequests(this.amountToLoad, this.currentlyLoaded + 1) @@ -143,25 +154,15 @@ export class TvRequestsComponent implements OnInit, OnDestroy { //this.updateRequest(request); } - //Was already here but not sure what's using it...' - //public approve(request: IChildRequests) { - // request.approved = true; - // request.denied = false; - // //this.updateRequest(request); - //} public approve(request: IChildRequests) { request.approved = true; request.denied = false; this.requestService.updateChild(request) .subscribe(); } - //Was already here but not sure what's using it...' - //public deny(request: IChildRequests) { - // request.approved = false; - // request.denied = true; - // //this.updateRequest(request); - //} + public deny(request: IChildRequests) { + debugger; request.approved = false; request.denied = true; this.requestService.updateChild(request) @@ -230,11 +231,13 @@ export class TvRequestsComponent implements OnInit, OnDestroy { } } private removeChildRequestFromUi(key: IChildRequests) { - //var index = this.childRequests.indexOf(key, 0); - //if (index > -1) { - // this.childRequests.splice(index, 1); - //} - //TODO FIX THIS + this.tvRequests.forEach((val) => { + var data = (val).data; + var index = data.childRequests.indexOf(key, 0); + if (index > -1) { + data.childRequests.splice(index, 1); + } + }); } diff --git a/src/Ombi/ClientApp/app/services/applications/tester.service.ts b/src/Ombi/ClientApp/app/services/applications/tester.service.ts index cdce6a72a..1c6fa4208 100644 --- a/src/Ombi/ClientApp/app/services/applications/tester.service.ts +++ b/src/Ombi/ClientApp/app/services/applications/tester.service.ts @@ -8,7 +8,9 @@ import { IDiscordNotifcationSettings, IEmailNotificationSettings, IPushbulletNotificationSettings, - ISlackNotificationSettings + ISlackNotificationSettings, + IPushoverNotificationSettings, + IMattermostNotifcationSettings } from '../../interfaces/INotifcationSettings' @@ -25,6 +27,13 @@ export class TesterService extends ServiceAuthHelpers { pushbulletTest(settings: IPushbulletNotificationSettings): Observable { return this.http.post(`${this.url}pushbullet`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData); } + pushoverTest(settings: IPushoverNotificationSettings): Observable { + return this.http.post(`${this.url}pushover`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData); + } + + mattermostTest(settings: IMattermostNotifcationSettings): Observable { + return this.http.post(`${this.url}mattermost`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData); + } slackTest(settings: ISlackNotificationSettings): Observable { return this.http.post(`${this.url}slack`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData); diff --git a/src/Ombi/ClientApp/app/services/settings.service.ts b/src/Ombi/ClientApp/app/services/settings.service.ts index bc4aa9afa..3b5c9644b 100644 --- a/src/Ombi/ClientApp/app/services/settings.service.ts +++ b/src/Ombi/ClientApp/app/services/settings.service.ts @@ -17,7 +17,9 @@ import { IEmailNotificationSettings, IDiscordNotifcationSettings, IPushbulletNotificationSettings, - ISlackNotificationSettings + ISlackNotificationSettings, + IPushoverNotificationSettings, + IMattermostNotifcationSettings } from '../interfaces/INotifcationSettings'; @Injectable() @@ -31,23 +33,31 @@ export class SettingsService extends ServiceAuthHelpers { } saveOmbi(settings: IOmbiSettings): Observable { - return this.httpAuth.post(`${this.url}/Ombi/`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth.post(`${this.url}/Ombi/`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); + } + + resetOmbiApi(): Observable { + return this.httpAuth.post(`${this.url}/Ombi/resetApi`, { headers: this.headers }).map(this.extractData) + .catch(this.handleError); } getEmby(): Observable { - return this.httpAuth.get(`${this.url}/Emby/`).map(this.extractData).catch(this.handleError) + return this.httpAuth.get(`${this.url}/Emby/`).map(this.extractData).catch(this.handleError); } saveEmby(settings: IEmbySettings): Observable { - return this.httpAuth.post(`${this.url}/Emby/`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth.post(`${this.url}/Emby/`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } getPlex(): Observable { - return this.httpAuth.get(`${this.url}/Plex/`).map(this.extractData).catch(this.handleError) + return this.httpAuth.get(`${this.url}/Plex/`).map(this.extractData).catch(this.handleError); } savePlex(settings: IPlexSettings): Observable { - return this.httpAuth.post(`${this.url}/Plex/`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth.post(`${this.url}/Plex/`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } getSonarr(): Observable { @@ -56,7 +66,8 @@ export class SettingsService extends ServiceAuthHelpers { } saveSonarr(settings: ISonarrSettings): Observable { - return this.httpAuth.post(`${this.url}/Sonarr`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth.post(`${this.url}/Sonarr`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } getRadarr(): Observable { @@ -65,16 +76,18 @@ export class SettingsService extends ServiceAuthHelpers { } saveRadarr(settings: IRadarrSettings): Observable { - return this.httpAuth.post(`${this.url}/Radarr`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth.post(`${this.url}/Radarr`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } // Using http since we need it not to be authenticated to get the landing page settings getLandingPage(): Observable { - return this.nonAuthHttp.get(`${this.url}/LandingPage`).map(this.extractData).catch(this.handleError) + return this.nonAuthHttp.get(`${this.url}/LandingPage`).map(this.extractData).catch(this.handleError); } saveLandingPage(settings: ILandingPageSettings): Observable { - return this.httpAuth.post(`${this.url}/LandingPage`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth.post(`${this.url}/LandingPage`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } // Using http since we need it not to be authenticated to get the customization settings @@ -83,7 +96,8 @@ export class SettingsService extends ServiceAuthHelpers { } saveCustomization(settings: ICustomizationSettings): Observable { - return this.httpAuth.post(`${this.url}/customization`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth.post(`${this.url}/customization`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } getEmailNotificationSettings(): Observable { @@ -91,22 +105,46 @@ export class SettingsService extends ServiceAuthHelpers { } saveEmailNotificationSettings(settings: IEmailNotificationSettings): Observable { - return this.httpAuth.post(`${this.url}/notifications/email`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth + .post(`${this.url}/notifications/email`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } getDiscordNotificationSettings(): Observable { return this.httpAuth.get(`${this.url}/notifications/discord`).map(this.extractData).catch(this.handleError) } + getMattermostNotificationSettings(): Observable { + return this.httpAuth.get(`${this.url}/notifications/mattermost`).map(this.extractData).catch(this.handleError) + } + saveDiscordNotificationSettings(settings: IDiscordNotifcationSettings): Observable { - return this.httpAuth.post(`${this.url}/notifications/discord`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth + .post(`${this.url}/notifications/discord`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); + } + + saveMattermostNotificationSettings(settings: IMattermostNotifcationSettings): Observable { + return this.httpAuth + .post(`${this.url}/notifications/mattermost`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } getPushbulletNotificationSettings(): Observable { return this.httpAuth.get(`${this.url}/notifications/pushbullet`).map(this.extractData).catch(this.handleError) } + getPushoverNotificationSettings(): Observable { + return this.httpAuth.get(`${this.url}/notifications/pushover`).map(this.extractData).catch(this.handleError) + } savePushbulletNotificationSettings(settings: IPushbulletNotificationSettings): Observable { - return this.httpAuth.post(`${this.url}/notifications/pushbullet`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth + .post(`${this.url}/notifications/pushbullet`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); + } + savePushoverNotificationSettings(settings: IPushoverNotificationSettings): Observable { + return this.httpAuth + .post(`${this.url}/notifications/pushover`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } getSlackNotificationSettings(): Observable { @@ -114,6 +152,8 @@ export class SettingsService extends ServiceAuthHelpers { } saveSlackNotificationSettings(settings: ISlackNotificationSettings): Observable { - return this.httpAuth.post(`${this.url}/notifications/slack`, JSON.stringify(settings), { headers: this.headers }).map(this.extractData).catch(this.handleError) + return this.httpAuth + .post(`${this.url}/notifications/slack`, JSON.stringify(settings), { headers: this.headers }) + .map(this.extractData).catch(this.handleError); } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.html b/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.html new file mode 100644 index 000000000..a8400535b --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.html @@ -0,0 +1,76 @@ + + +
+
+ Mattermost Notifications +
+
+ +
+
+ + +
+
+ +
+
The Incoming Webhook Url is required
+
+ +
+ Mattermost > Integrations > Incoming Webhook > Add Incoming Webhook. You will then have a Webhook + +
+ +
+
+ + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + + +
+
+ +
+
+ + + +
+
+ +
+
+
+
+ + +
+ +
+
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts b/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts new file mode 100644 index 000000000..30072057a --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/mattermost.component.ts @@ -0,0 +1,72 @@ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, Validators, FormBuilder } from '@angular/forms'; + +import { INotificationTemplates, IMattermostNotifcationSettings, NotificationType } from '../../interfaces/INotifcationSettings'; +import { SettingsService } from '../../services/settings.service'; +import { NotificationService } from "../../services/notification.service"; +import { TesterService } from "../../services/applications/tester.service"; + +@Component({ + templateUrl: './mattermost.component.html' +}) +export class MattermostComponent implements OnInit { + constructor(private settingsService: SettingsService, + private notificationService: NotificationService, + private fb: FormBuilder, + private testerService : TesterService) { } + + NotificationType = NotificationType; + templates: INotificationTemplates[]; + + form: FormGroup; + + ngOnInit(): void { + this.settingsService.getMattermostNotificationSettings().subscribe(x => { + this.templates = x.notificationTemplates; + + this.form = this.fb.group({ + enabled: [x.enabled], + username: [x.username], + webhookUrl: [x.webhookUrl, [Validators.required]], + channel: [x.channel], + iconUrl:[x.iconUrl] + + }); + }); + } + + onSubmit(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Validation", "Please check your entered values"); + return; + } + + var settings = form.value; + settings.notificationTemplates = this.templates; + + this.settingsService.saveMattermostNotificationSettings(settings).subscribe(x => { + if (x) { + this.notificationService.success("Settings Saved", "Successfully saved the Mattermost settings"); + } else { + this.notificationService.success("Settings Saved", "There was an error when saving the Mattermost settings"); + } + }); + + } + + test(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Validation", "Please check your entered values"); + return; + } + + this.testerService.mattermostTest(form.value).subscribe(x => { + if (x) { + this.notificationService.success("Successful", "Successfully sent a Mattermost message, please check the discord channel"); + } else { + this.notificationService.success("Error", "There was an error when sending the Mattermost message. Please check your settings"); + } + }) + + } +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/pushbullet.component.html b/src/Ombi/ClientApp/app/settings/notifications/pushbullet.component.html index 4f4d0f62b..3b2dc30b8 100644 --- a/src/Ombi/ClientApp/app/settings/notifications/pushbullet.component.html +++ b/src/Ombi/ClientApp/app/settings/notifications/pushbullet.component.html @@ -2,7 +2,7 @@
- Pushbyllet Notifications + Pushbullet Notifications
diff --git a/src/Ombi/ClientApp/app/settings/notifications/pushover.component.html b/src/Ombi/ClientApp/app/settings/notifications/pushover.component.html new file mode 100644 index 000000000..e07316583 --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/pushover.component.html @@ -0,0 +1,59 @@ + + +
+
+ Pushover Notifications +
+ + +
+
+ + +
+
+ +
+
The Access Token is required
+
+
+ +
+ +
+
+ +
+ +
+ +
+
+ + + +
+
+ +
+
+ + + +
+
+ +
+
+ +
+ + +
+ +
+
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/pushover.component.ts b/src/Ombi/ClientApp/app/settings/notifications/pushover.component.ts new file mode 100644 index 000000000..f33fceda0 --- /dev/null +++ b/src/Ombi/ClientApp/app/settings/notifications/pushover.component.ts @@ -0,0 +1,69 @@ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, Validators, FormBuilder } from '@angular/forms'; + +import { INotificationTemplates, IPushoverNotificationSettings, NotificationType } from '../../interfaces/INotifcationSettings'; +import { SettingsService } from '../../services/settings.service'; +import { NotificationService } from "../../services/notification.service"; +import { TesterService } from "../../services/applications/tester.service"; + +@Component({ + templateUrl: './pushover.component.html', +}) +export class PushoverComponent implements OnInit { + constructor(private settingsService: SettingsService, + private notificationService: NotificationService, + private fb: FormBuilder, + private testerService : TesterService) { } + + NotificationType = NotificationType; + templates: INotificationTemplates[]; + + form: FormGroup; + + ngOnInit(): void { + this.settingsService.getPushoverNotificationSettings().subscribe(x => { + this.templates = x.notificationTemplates; + + this.form = this.fb.group({ + enabled: [x.enabled], + userToken: [x.userToken], + accessToken: [x.accessToken, [Validators.required]], + }); + }); + } + + onSubmit(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Validation", "Please check your entered values"); + return; + } + + var settings = form.value; + settings.notificationTemplates = this.templates; + + this.settingsService.savePushoverNotificationSettings(settings).subscribe(x => { + if (x) { + this.notificationService.success("Settings Saved", "Successfully saved the Pushover settings"); + } else { + this.notificationService.success("Settings Saved", "There was an error when saving the Pushover settings"); + } + }); + + } + + test(form: FormGroup) { + if (form.invalid) { + this.notificationService.error("Validation", "Please check your entered values"); + return; + } + + this.testerService.pushoverTest(form.value).subscribe(x => { + if (x) { + this.notificationService.success("Successful", "Successfully sent a Pushbullet message, please check the discord channel"); + } else { + this.notificationService.success("Error", "There was an error when sending the Pushbullet message. Please check your settings"); + } + }) + + } +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/ombi/ombi.component.html b/src/Ombi/ClientApp/app/settings/ombi/ombi.component.html index 9f3896e2b..82e594a4b 100644 --- a/src/Ombi/ClientApp/app/settings/ombi/ombi.component.html +++ b/src/Ombi/ClientApp/app/settings/ombi/ombi.component.html @@ -11,7 +11,7 @@
-
+
@@ -29,20 +29,20 @@
- +
diff --git a/src/Ombi/ClientApp/app/settings/ombi/ombi.component.ts b/src/Ombi/ClientApp/app/settings/ombi/ombi.component.ts index 5afe186e4..b7e3d762a 100644 --- a/src/Ombi/ClientApp/app/settings/ombi/ombi.component.ts +++ b/src/Ombi/ClientApp/app/settings/ombi/ombi.component.ts @@ -29,13 +29,17 @@ export class OmbiComponent implements OnInit { refreshApiKey() { - + this.settingsService.resetOmbiApi().subscribe(x => { + this.form.patchValue({ + apiKey: x + }); + }); } onSubmit(form: FormGroup) { if (form.invalid) { this.notificationService.error("Validation", "Please check your entered values"); - return + return; } this.settingsService.saveOmbi(form.value).subscribe(x => { if (x) { diff --git a/src/Ombi/ClientApp/app/settings/settings.module.ts b/src/Ombi/ClientApp/app/settings/settings.module.ts index f825a3cc0..1320bc6c3 100644 --- a/src/Ombi/ClientApp/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/app/settings/settings.module.ts @@ -22,6 +22,9 @@ import { CustomizationComponent } from './customization/customization.component' import { EmailNotificationComponent } from './notifications/emailnotification.component'; import { DiscordComponent } from './notifications/discord.component'; import { SlackComponent } from './notifications/slack.component'; +import { PushoverComponent } from './notifications/pushover.component'; +import { PushbulletComponent } from './notifications/pushbullet.component'; +import { MattermostComponent } from './notifications/mattermost.component'; import { NotificationTemplate } from './notifications/notificationtemplate.component'; import { SettingsMenuComponent } from './settingsmenu.component'; @@ -40,6 +43,9 @@ const routes: Routes = [ { path: 'Settings/Email', component: EmailNotificationComponent, canActivate: [AuthGuard] }, { path: 'Settings/Discord', component: DiscordComponent, canActivate: [AuthGuard] }, { path: 'Settings/Slack', component: SlackComponent, canActivate: [AuthGuard] }, + { path: 'Settings/Pushover', component: PushoverComponent, canActivate: [AuthGuard] }, + { path: 'Settings/Pushbullet', component: PushbulletComponent, canActivate: [AuthGuard] }, + { path: 'Settings/Mattermost', component: MattermostComponent, canActivate: [AuthGuard] }, ]; @NgModule({ @@ -72,6 +78,9 @@ const routes: Routes = [ EmailNotificationComponent, HumanizePipe, NotificationTemplate, + PushoverComponent, + MattermostComponent, + PushbulletComponent ], exports: [ RouterModule diff --git a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html index 11791d7f4..34e3d52fd 100644 --- a/src/Ombi/ClientApp/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/app/settings/settingsmenu.component.html @@ -47,7 +47,8 @@
  • Discord
  • Slack
  • Pushbullet
  • - +
  • Pushover
  • +
  • Mattermost
  • diff --git a/src/Ombi/Controllers/External/TesterController.cs b/src/Ombi/Controllers/External/TesterController.cs index c4ad1a517..30ab1065d 100644 --- a/src/Ombi/Controllers/External/TesterController.cs +++ b/src/Ombi/Controllers/External/TesterController.cs @@ -27,13 +27,15 @@ namespace Ombi.Controllers.External /// The pushbullet. /// The slack. public TesterController(INotificationService service, IDiscordNotification notification, IEmailNotification emailN, - IPushbulletNotification pushbullet, ISlackNotification slack) + IPushbulletNotification pushbullet, ISlackNotification slack, IPushoverNotification po, IMattermostNotification mm) { Service = service; DiscordNotification = notification; EmailNotification = emailN; PushbulletNotification = pushbullet; SlackNotification = slack; + PushoverNotification = po; + MattermostNotification = mm; } private INotificationService Service { get; } @@ -41,6 +43,8 @@ namespace Ombi.Controllers.External private IEmailNotification EmailNotification { get; } private IPushbulletNotification PushbulletNotification { get; } private ISlackNotification SlackNotification { get; } + private IPushoverNotification PushoverNotification { get; } + private IMattermostNotification MattermostNotification { get; } /// @@ -73,6 +77,36 @@ namespace Ombi.Controllers.External return true; } + /// + /// Sends a test message to Pushover using the provided settings + /// + /// The settings. + /// + [HttpPost("pushover")] + public bool Pushover([FromBody] PushoverSettings settings) + { + settings.Enabled = true; + PushoverNotification.NotifyAsync( + new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); + + return true; + } + + /// + /// Sends a test message to mattermost using the provided settings + /// + /// The settings. + /// + [HttpPost("mattermost")] + public bool Mattermost([FromBody] MattermostNotificationSettings settings) + { + settings.Enabled = true; + MattermostNotification.NotifyAsync( + new NotificationOptions { NotificationType = NotificationType.Test, RequestId = -1 }, settings); + + return true; + } + /// /// Sends a test message to Slack using the provided settings diff --git a/src/Ombi/Controllers/SettingsController.cs b/src/Ombi/Controllers/SettingsController.cs index f53d1645b..49cf3fc77 100644 --- a/src/Ombi/Controllers/SettingsController.cs +++ b/src/Ombi/Controllers/SettingsController.cs @@ -65,6 +65,16 @@ namespace Ombi.Controllers return await Save(ombi); } + [HttpPost("ombi/resetApi")] + public async Task ResetApiKey() + { + var currentSettings = await Get(); + currentSettings.ApiKey = Guid.NewGuid().ToString("N"); + await Save(currentSettings); + + return currentSettings.ApiKey; + } + /// /// Gets the Plex Settings. /// @@ -295,6 +305,40 @@ namespace Ombi.Controllers return model; } + /// + /// Saves the pushover notification settings. + /// + /// The model. + /// + [HttpPost("notifications/pushover")] + public async Task PushoverNotificationSettings([FromBody] PushoverNotificationViewModel model) + { + // Save the email settings + var settings = Mapper.Map(model); + var result = await Save(settings); + + // Save the templates + await TemplateRepository.UpdateRange(model.NotificationTemplates); + + return result; + } + + /// + /// Gets the pushover Notification Settings. + /// + /// + [HttpGet("notifications/pushover")] + public async Task PushoverNotificationSettings() + { + var settings = await Get(); + var model = Mapper.Map(settings); + + // Lookup to see if we have any templates saved + model.NotificationTemplates = await BuildTemplates(NotificationAgent.Pushover); + + return model; + } + /// /// Saves the slack notification settings. @@ -330,6 +374,40 @@ namespace Ombi.Controllers return model; } + /// + /// Saves the Mattermost notification settings. + /// + /// The model. + /// + [HttpPost("notifications/mattermost")] + public async Task MattermostNotificationSettings([FromBody] MattermostNotificationsViewModel model) + { + // Save the email settings + var settings = Mapper.Map(model); + var result = await Save(settings); + + // Save the templates + await TemplateRepository.UpdateRange(model.NotificationTemplates); + + return result; + } + + /// + /// Gets the Mattermost Notification Settings. + /// + /// + [HttpGet("notifications/mattermost")] + public async Task MattermostNotificationSettings() + { + var settings = await Get(); + var model = Mapper.Map(settings); + + // Lookup to see if we have any templates saved + model.NotificationTemplates = await BuildTemplates(NotificationAgent.Mattermost); + + return model; + } + private async Task> BuildTemplates(NotificationAgent agent) { var templates = await TemplateRepository.GetAllTemplates(agent); diff --git a/src/Ombi/Ombi.csproj b/src/Ombi/Ombi.csproj index b7a20b914..cf5527676 100644 --- a/src/Ombi/Ombi.csproj +++ b/src/Ombi/Ombi.csproj @@ -4,6 +4,7 @@ netcoreapp1.1 win10-x64;osx.10.12-x64;ubuntu.16.04-x64;debian.8-x64;centos.7-x64; True + 2.3 diff --git a/src/Ombi/Startup.cs b/src/Ombi/Startup.cs index 480551082..7b715f0ef 100644 --- a/src/Ombi/Startup.cs +++ b/src/Ombi/Startup.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Linq; using System.Security.Principal; using System.Text; using AutoMapper; @@ -31,8 +30,6 @@ using Ombi.Store.Context; using Ombi.Store.Entities; using Serilog; using Serilog.Events; -using StackExchange.Profiling; -using StackExchange.Profiling.Storage; using Swashbuckle.AspNetCore.Swagger; namespace Ombi @@ -80,17 +77,6 @@ namespace Ombi .AddEntityFrameworkStores() .AddDefaultTokenProviders(); - - //services.AddIdentityServer() - // .AddTemporarySigningCredential() - // .AddInMemoryPersistedGrants() - // .AddInMemoryIdentityResources(IdentityConfig.GetIdentityResources()) - // .AddInMemoryApiResources(IdentityConfig.GetApiResources()) - // .AddInMemoryClients(IdentityConfig.GetClients()) - // .AddAspNetIdentity() - // .Services.AddTransient() - // .AddTransient(); - services.Configure(options => { options.Password.RequireDigit = false; @@ -144,8 +130,6 @@ namespace Ombi c.DescribeAllParametersInCamelCase(); }); - - services.AddSingleton(); services.AddScoped(sp => sp.GetService().HttpContext.User); @@ -156,21 +140,10 @@ namespace Ombi services.AddHangfire(x => { - x.UseMemoryStorage(new MemoryStorageOptions()); - //x.UseSQLiteStorage("Data Source=Ombi.db;"); - x.UseActivator(new IoCJobActivator(services.BuildServiceProvider())); }); - -#if DEBUG - // Note .AddMiniProfiler() returns a IMiniProfilerBuilder for easy intellisense - //services.AddMiniProfiler(); -#endif - // Make sure you have memory cache available unless you're using another storage provider - services.AddMemoryCache(); - } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -181,20 +154,6 @@ namespace Ombi var ctx = (IOmbiContext)app.ApplicationServices.GetService(typeof(IOmbiContext)); - // Get the url - var url = ctx.ApplicationConfigurations.FirstOrDefault(x => x.Type == ConfigurationTypes.Url); - var port = ctx.ApplicationConfigurations.FirstOrDefault(x => x.Type == ConfigurationTypes.Port); - - Console.WriteLine($"Using Url {url.Value}:{port.Value} for Identity Server"); - app.UseIdentity(); - -#if !DEBUG - var audience = $"{url.Value}:{port.Value}"; -#else - - var audience = $"http://localhost:52038/"; -#endif - var tokenValidationParameters = new TokenValidationParameters { @@ -212,28 +171,10 @@ namespace Ombi { Audience = "Ombi", AutomaticAuthenticate = true, - TokenValidationParameters = tokenValidationParameters + TokenValidationParameters = tokenValidationParameters, + }); - // app.UseIdentityServer(); - // app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions - // { - //#if !DEBUG - // Authority = $"{url.Value}:{port.Value}", - //#else - // Authority = $"http://localhost:52038/", - //#endif - // ApiName = "api", - // ApiSecret = "secret", - - // EnableCaching = true, - // CacheDuration = TimeSpan.FromMinutes(10), // that's the default - // RequireHttpsMetadata = options.Value.UseHttps, // FOR DEV set to false - // AutomaticAuthenticate = true, - // AutomaticChallenge = true, - - - // }); loggerFactory.AddSerilog(); @@ -244,20 +185,6 @@ namespace Ombi { HotModuleReplacement = true }); - - //app.UseMiniProfiler(new MiniProfilerOptions - //{ - // // Path to use for profiler URLs - // RouteBasePath = "~/profiler", - - // // (Optional) Control which SQL formatter to use - // // (default is no formatter) - // SqlFormatter = new StackExchange.Profiling.SqlFormatters.InlineFormatter(), - - // // (Optional) Control storage - // // (default is 30 minutes in MemoryCacheStorage) - // Storage = new MemoryCacheStorage(cache, TimeSpan.FromMinutes(60)), - //}); } app.UseHangfireServer();