diff --git a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs index cff089c1f..6941acef1 100644 --- a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs @@ -1,4 +1,5 @@ -using Ombi.Core.Claims; +using System; +using Ombi.Core.Claims; using Ombi.Core.Models.Requests; using Ombi.Core.Rule; using Ombi.Core.Rules; @@ -6,7 +7,12 @@ using Ombi.Store.Entities; using System.Collections.Generic; using System.Linq; using System.Security.Principal; +using Hangfire; +using Ombi.Core.Models.Requests.Movie; using Ombi.Core.Models.Search; +using Ombi.Core.Notifications; +using Ombi.Helpers; +using Ombi.Notifications.Models; namespace Ombi.Core.Engine.Interfaces { diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index c290f7fed..71b337cdc 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -1,12 +1,10 @@ -using Hangfire; -using Ombi.Api.TheMovieDb; +using Ombi.Api.TheMovieDb; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Requests.Movie; using Ombi.Core.Models.Search; using Ombi.Core.Rules; using Ombi.Helpers; using Ombi.Notifications; -using Ombi.Notifications.Models; using Ombi.Store.Entities; using System; using System.Collections.Generic; @@ -16,24 +14,22 @@ using System.Security.Principal; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Ombi.Core.Engine.Interfaces; -using Ombi.Core.Notifications; -using Ombi.Store; namespace Ombi.Core.Engine { public class MovieRequestEngine : BaseMediaEngine, IMovieRequestEngine { public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user, - INotificationService notificationService, IRuleEvaluator r, IMovieSender sender, ILogger log) : base(user, requestService, r) + INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger log) : base(user, requestService, r) { MovieApi = movieApi; - NotificationService = notificationService; + NotificationHelper = helper; Sender = sender; Logger = log; } private IMovieDbApi MovieApi { get; } - private INotificationService NotificationService { get; } + private INotificationHelper NotificationHelper { get; } private IMovieSender Sender { get; } private ILogger Logger { get; } @@ -84,6 +80,7 @@ namespace Ombi.Core.Engine // }); //} + var requestModel = new MovieRequestModel { ProviderId = movieInfo.Id, @@ -98,64 +95,41 @@ namespace Ombi.Core.Engine Status = movieInfo.Status, RequestedDate = DateTime.UtcNow, Approved = false, - RequestedUser =Username, + RequestedUser = Username, Issues = IssueState.None }; - try + var ruleResults = RunRequestRules(requestModel).ToList(); + if (ruleResults.Any(x => !x.Success)) { - var ruleResults = RunRequestRules(requestModel).ToList(); - if (ruleResults.Any(x => !x.Success)) + return new RequestEngineResult + { + ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message + }; + } + + if (requestModel.Approved) // The rules have auto approved this + { + var result = await Sender.Send(requestModel); + if (result.Success && result.MovieSent) + { + return await AddMovieRequest(requestModel, /*settings,*/ + $"{fullMovieName} has been successfully added!"); + } + if (!result.Success) + { + Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message); return new RequestEngineResult { - ErrorMessage = ruleResults.FirstOrDefault(x => !string.IsNullOrEmpty(x.Message)).Message + Message = result.Message, + ErrorMessage = result.Message, + RequestAdded = false }; - - if (requestModel.Approved) // The rules have auto approved this - { - var result = await Sender.Send(requestModel); - if (result.Success && result.MovieSent) - { - return await AddMovieRequest(requestModel, /*settings,*/ - $"{fullMovieName} has been successfully added!"); - } - if (!result.Success) - { - Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message); - return new RequestEngineResult - { - Message = result.Message, - ErrorMessage = result.Message, - RequestAdded = false - }; - } } - - return await AddMovieRequest(requestModel, /*settings,*/ - $"{fullMovieName} has been successfully added!"); - } - catch (Exception e) - { - //Log.Fatal(e); - //await FaultQueue.QueueItemAsync(model, movieInfo.Id.ToString(), RequestType.Movie, FaultType.RequestFault, e.Message); - var notification = new NotificationOptions - { - DateTime = DateTime.Now, - RequestedUser = Username, - RequestType = RequestType.Movie, - Title = model.Title, - NotificationType = NotificationType.ItemAddedToFaultQueue - }; - BackgroundJob.Enqueue(() => NotificationService.Publish(notification).Wait()); - - //return Response.AsJson(new JsonResponseModel - //{ - // Result = true, - // Message = $"{fullMovieName} {Resources.UI.Search_SuccessfullyAdded}" - //}); } - return null; + return await AddMovieRequest(requestModel, /*settings,*/ + $"{fullMovieName} has been successfully added!"); } public async Task> GetRequests(int count, int position) @@ -210,21 +184,9 @@ namespace Ombi.Core.Engine if (ShouldSendNotification(model.Type)) { - var notificationModel = new NotificationOptions - { - Title = model.Title, - RequestedUser = Username, - DateTime = DateTime.Now, - NotificationType = NotificationType.NewRequest, - RequestType = model.Type, - ImgSrc = model.Type == RequestType.Movie - ? $"https://image.tmdb.org/t/p/w300/{model.PosterPath}" - : model.PosterPath - }; - - BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel).Wait()); + NotificationHelper.NewRequest(model); } - + //var limit = await RequestLimitRepo.GetAllAsync(); //var usersLimit = limit.FirstOrDefault(x => x.Username == Username && x.RequestType == model.Type); //if (usersLimit == null) diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index f10ea56f0..c09648881 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -15,23 +15,21 @@ using System.Linq; using System.Security.Principal; using System.Threading.Tasks; using Ombi.Core.Engine.Interfaces; -using Ombi.Core.Notifications; -using Ombi.Store; namespace Ombi.Core.Engine { public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine { public TvRequestEngine(ITvMazeApi tvApi, IRequestServiceMain requestService, IPrincipal user, - INotificationService notificationService, IMapper map, + INotificationHelper helper, IMapper map, IRuleEvaluator rule) : base(user, requestService, rule) { TvApi = tvApi; - NotificationService = notificationService; + NotificationHelper = helper; Mapper = map; } - private INotificationService NotificationService { get; } + private INotificationHelper NotificationHelper { get; } private ITvMazeApi TvApi { get; } private IMapper Mapper { get; } @@ -270,24 +268,11 @@ namespace Ombi.Core.Engine return await AfterRequest(model); } - private async Task AfterRequest(TvRequestModel model) + private Task AfterRequest(TvRequestModel model) { if (ShouldSendNotification(model.Type)) { - var n = new NotificationOptions(); - - n.Title = model.Title; - n.RequestedUser = Username; - n.DateTime = DateTime.Now; - n.NotificationType = NotificationType.NewRequest; - n.RequestType = model.Type; - n.ImgSrc = model.PosterPath; - - - BackgroundJob.Enqueue(() => - - NotificationService.Publish(n).Wait() - ); + NotificationHelper.NewRequest(model); } //var limit = await RequestLimitRepo.GetAllAsync(); @@ -308,7 +293,7 @@ namespace Ombi.Core.Engine // await RequestLimitRepo.UpdateAsync(usersLimit); //} - return new RequestEngineResult { RequestAdded = true }; + return Task.FromResult(new RequestEngineResult { RequestAdded = true }); } public async Task> GetApprovedRequests() diff --git a/src/Ombi.Core/INotificationHelper.cs b/src/Ombi.Core/INotificationHelper.cs new file mode 100644 index 000000000..e4120e8d4 --- /dev/null +++ b/src/Ombi.Core/INotificationHelper.cs @@ -0,0 +1,9 @@ +using Ombi.Core.Models.Requests; + +namespace Ombi.Core +{ + public interface INotificationHelper + { + void NewRequest(BaseRequestModel model); + } +} \ No newline at end of file diff --git a/src/Ombi.Core/NotificationHelper.cs b/src/Ombi.Core/NotificationHelper.cs new file mode 100644 index 000000000..ec05e7820 --- /dev/null +++ b/src/Ombi.Core/NotificationHelper.cs @@ -0,0 +1,36 @@ +using System; +using Hangfire; +using Ombi.Core.Models.Requests; +using Ombi.Core.Notifications; +using Ombi.Helpers; +using Ombi.Notifications.Models; +using Ombi.Store.Entities; + +namespace Ombi.Core +{ + public class NotificationHelper : INotificationHelper + { + public NotificationHelper(INotificationService service) + { + NotificationService = service; + } + private INotificationService NotificationService { get; } + + public void NewRequest(BaseRequestModel model) + { + var notificationModel = new NotificationOptions + { + Title = model.Title, + RequestedUser = model.RequestedUser, + DateTime = DateTime.Now, + NotificationType = NotificationType.NewRequest, + RequestType = model.Type, + ImgSrc = model.Type == RequestType.Movie + ? $"https://image.tmdb.org/t/p/w300/{model.PosterPath}" + : model.PosterPath + }; + BackgroundJob.Enqueue(() => NotificationService.Publish(notificationModel)); + + } + } +} \ No newline at end of file diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index f9246a7a6..228d60b8d 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -84,6 +84,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(typeof(IRequestService<>), typeof(JsonRequestService<>)); services.AddSingleton(); + services.AddSingleton(); } public static void RegisterJobs(this IServiceCollection services) diff --git a/src/Ombi.Notifications/Agents/EmailNotification.cs b/src/Ombi.Notifications/Agents/EmailNotification.cs index 76ee5cb00..0648494ce 100644 --- a/src/Ombi.Notifications/Agents/EmailNotification.cs +++ b/src/Ombi.Notifications/Agents/EmailNotification.cs @@ -40,31 +40,43 @@ namespace Ombi.Notifications.Agents return true; } - private async Task LoadTemplate(NotificationType type, NotificationOptions model) + private async Task LoadTemplate(NotificationType type, NotificationOptions model, EmailNotificationSettings settings) { var template = await TemplateRepository.GetTemplate(NotificationAgent.Email, type); + if (!template.Enabled) + { + return null; + } // Need to do the parsing var resolver = new NotificationMessageResolver(); - return resolver.ParseMessage(template, new NotificationMessageCurlys(model.RequestedUser, model.Title, DateTime.Now.ToString("D"), + var parsed = resolver.ParseMessage(template, new NotificationMessageCurlys(model.RequestedUser, model.Title, DateTime.Now.ToString("D"), model.NotificationType.ToString(), null)); - } - - protected override async Task NewRequest(NotificationOptions model, EmailNotificationSettings settings) - { - var template = await LoadTemplate(NotificationType.NewRequest, model); var email = new EmailBasicTemplate(); - var html = email.LoadTemplate(template.Subject, template.Message, model.ImgSrc); + var html = email.LoadTemplate(parsed.Subject, parsed.Message, model.ImgSrc); var message = new NotificationMessage { Message = html, - Subject = $"Ombi: New {model.RequestType} request for {model.Title}!", + Subject = parsed.Subject, To = settings.AdminEmail, }; + return message; + } + + + + protected override async Task NewRequest(NotificationOptions model, EmailNotificationSettings settings) + { + var message = await LoadTemplate(NotificationType.NewRequest, model, settings); + if (message == null) + { + return; + } + message.Other.Add("PlainTextBody", $"Hello! The user '{model.RequestedUser}' has requested the {model.RequestType} '{model.Title}'! Please log in to approve this request. Request Date: {model.DateTime:f}"); await Send(message, settings); @@ -72,18 +84,11 @@ namespace Ombi.Notifications.Agents protected override async Task Issue(NotificationOptions model, EmailNotificationSettings settings) { - var email = new EmailBasicTemplate(); - var html = email.LoadTemplate( - $"Ombi: New issue for {model.Title}!", - $"Hello! The user '{model.RequestedUser}' has reported a new issue {model.Body} for the title {model.Title}!", - model.ImgSrc); - - var message = new NotificationMessage + var message = await LoadTemplate(NotificationType.Issue, model, settings); + if (message == null) { - Message = html, - Subject = $"Ombi: New issue for {model.Title}!", - To = settings.AdminEmail, - }; + return; + } message.Other.Add("PlainTextBody", $"Hello! The user '{model.RequestedUser}' has reported a new issue {model.Body} for the title {model.Title}!"); @@ -113,18 +118,11 @@ namespace Ombi.Notifications.Agents protected override async Task RequestDeclined(NotificationOptions model, EmailNotificationSettings settings) { - var email = new EmailBasicTemplate(); - var html = email.LoadTemplate( - "Ombi: Your request has been declined", - $"Hello! Your request for {model.Title} has been declined, Sorry!", - model.ImgSrc); - - var message = new NotificationMessage + var message = await LoadTemplate(NotificationType.RequestDeclined, model, settings); + if (message == null) { - Message = html, - Subject = $"Ombi: Your request has been declined", - To = model.UserEmail, - }; + return; + } message.Other.Add("PlainTextBody", $"Hello! Your request for {model.Title} has been declined, Sorry!"); @@ -134,18 +132,11 @@ namespace Ombi.Notifications.Agents protected override async Task RequestApproved(NotificationOptions model, EmailNotificationSettings settings) { - var email = new EmailBasicTemplate(); - var html = email.LoadTemplate( - "Ombi: Your request has been approved!", - $"Hello! Your request for {model.Title} has been approved!", - model.ImgSrc); - - var message = new NotificationMessage + var message = await LoadTemplate(NotificationType.RequestApproved, model, settings); + if (message == null) { - Message = html, - Subject = $"Ombi: Your request has been approved!", - To = model.UserEmail, - }; + return; + } message.Other.Add("PlainTextBody", $"Hello! Your request for {model.Title} has been approved!"); @@ -154,19 +145,11 @@ namespace Ombi.Notifications.Agents protected override async Task AvailableRequest(NotificationOptions model, EmailNotificationSettings settings) { - var email = new EmailBasicTemplate(); - var html = email.LoadTemplate( - $"Ombi: {model.Title} is now available!", - $"Hello! You requested {model.Title} on Ombi! This is now available on Plex! :)", - model.ImgSrc); - - - var message = new NotificationMessage + var message = await LoadTemplate(NotificationType.RequestAvailable, model, settings); + if (message == null) { - Message = html, - Subject = $"Ombi: {model.Title} is now available!", - To = model.UserEmail, - }; + return; + } message.Other.Add("PlainTextBody", $"Hello! You requested {model.Title} on Ombi! This is now available on Plex! :)"); diff --git a/src/Ombi.Notifications/Interfaces/BaseNotification.cs b/src/Ombi.Notifications/Interfaces/BaseNotification.cs index ad83ffb34..8b2bfec24 100644 --- a/src/Ombi.Notifications/Interfaces/BaseNotification.cs +++ b/src/Ombi.Notifications/Interfaces/BaseNotification.cs @@ -1,9 +1,12 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Ombi.Core.Settings; using Ombi.Helpers; using Ombi.Notifications.Models; using Ombi.Store; +using Ombi.Store.Entities; using Ombi.Store.Repository; namespace Ombi.Notifications @@ -36,7 +39,6 @@ namespace Ombi.Notifications { return; } - try { switch (model.NotificationType) diff --git a/src/Ombi.Notifications/NotificationMessageResolver.cs b/src/Ombi.Notifications/NotificationMessageResolver.cs index 473089d48..d6332ac6c 100644 --- a/src/Ombi.Notifications/NotificationMessageResolver.cs +++ b/src/Ombi.Notifications/NotificationMessageResolver.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using Ombi.Store.Entities; namespace Ombi.Notifications @@ -18,19 +19,31 @@ namespace Ombi.Notifications Type = type; Issue = issue; } + + // User Defined private string RequestedUser { get; } private string Title { get; } private string RequestedDate { get; } private string Type { get; } private string Issue { get; } + // System Defined + private string LongDate => DateTime.Now.ToString("D"); + private string ShortDate => DateTime.Now.ToString("d"); + private string LongTime => DateTime.Now.ToString("T"); + private string ShortTime => DateTime.Now.ToString("t"); + public Dictionary Curlys => new Dictionary { {nameof(RequestedUser), RequestedUser }, {nameof(Title), Title }, {nameof(RequestedDate), RequestedDate }, {nameof(Type), Type }, - {nameof(Issue), Issue } + {nameof(Issue), Issue }, + {nameof(LongDate),LongDate}, + {nameof(ShortDate),ShortDate}, + {nameof(LongTime),LongTime}, + {nameof(ShortTime),ShortTime}, }; } diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 3cf2db736..8548010c8 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Linq; -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Helpers; using Ombi.Store.Entities; @@ -64,25 +63,27 @@ namespace Ombi.Store.Context { foreach (var notificationType in allTypes) { - var notificationToAdd = new NotificationTemplates(); + NotificationTemplates notificationToAdd; switch (notificationType) { case NotificationType.NewRequest: notificationToAdd = new NotificationTemplates { NotificationType = notificationType, - Message = "Hello! The user '{requestedUser}' has requested the {Type} '{Title}'! Please log in to approve this request. Request Date: {RequestedDate}", + Message = "Hello! The user '{RequestedUser}' has requested the {Type} '{Title}'! Please log in to approve this request. Request Date: {RequestedDate}", Subject = "Ombi: New {Type} request for {Title}!", Agent = agent, + Enabled = true, }; break; case NotificationType.Issue: notificationToAdd = new NotificationTemplates { NotificationType = notificationType, - Message = "Hello! The user '{requestedUser}' has reported a new issue for the title {Title}!
{Issue}", + Message = "Hello! The user '{RequestedUser}' has reported a new issue for the title {Title}!
{Issue}", Subject = "Ombi: New issue for {Title}!", Agent = agent, + Enabled = true, }; break; case NotificationType.RequestAvailable: @@ -92,6 +93,7 @@ namespace Ombi.Store.Context Message = "Hello! You requested {Title} on Ombi! This is now available! :)", Subject = "Ombi: {Title} is now available!", Agent = agent, + Enabled = true, }; break; case NotificationType.RequestApproved: @@ -101,6 +103,7 @@ namespace Ombi.Store.Context Message = "Hello! Your request for {Title} has been approved!", Subject = "Ombi: your request has been approved", Agent = agent, + Enabled = true, }; break; case NotificationType.AdminNote: @@ -110,12 +113,11 @@ namespace Ombi.Store.Context case NotificationType.RequestDeclined: notificationToAdd = new NotificationTemplates { - //"Ombi: Your request has been declined", - //$"Hello! Your request for {model.Title} has been declined, Sorry!", NotificationType = notificationType, Message = "Hello! Your request for {Title} has been declined, Sorry!", Subject = "Ombi: your request has been declined", Agent = agent, + Enabled = true, }; break; case NotificationType.ItemAddedToFaultQueue: diff --git a/src/Ombi.Store/Entities/NotificationTemplates.cs b/src/Ombi.Store/Entities/NotificationTemplates.cs index c5abbd8f1..6b33b335c 100644 --- a/src/Ombi.Store/Entities/NotificationTemplates.cs +++ b/src/Ombi.Store/Entities/NotificationTemplates.cs @@ -10,5 +10,6 @@ namespace Ombi.Store.Entities public NotificationAgent Agent { get; set; } public string Subject { get; set; } public string Message { get; set; } + public bool Enabled { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Store/SqlTables.sql b/src/Ombi.Store/SqlTables.sql index 56a46e5ec..8662324c9 100644 --- a/src/Ombi.Store/SqlTables.sql +++ b/src/Ombi.Store/SqlTables.sql @@ -72,6 +72,7 @@ CREATE TABLE IF NOT EXISTS NotificationTemplates NotificationType INTEGER NOT NULL, Agent INTEGER NOT NULL, Subject BLOB NULL, - Message BLOB NULL + Message BLOB NULL, + Enabled INTEGER NOT NULL ); \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/app.component.ts b/src/Ombi/ClientApp/app/app.component.ts index b5642ed05..76e9bb96f 100644 --- a/src/Ombi/ClientApp/app/app.component.ts +++ b/src/Ombi/ClientApp/app/app.component.ts @@ -14,19 +14,17 @@ 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 { + ngOnInit() : void { this.user = this.authService.claims(); - - - + this.settingsService.getCustomization().subscribe(x => this.customizationSettings = x); this.router.events.subscribe(() => { @@ -34,7 +32,6 @@ export class AppComponent implements OnInit { this.user = this.authService.claims(); this.showNav = this.authService.loggedIn(); }); - } hasRole(role: string): boolean { diff --git a/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts b/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts index 2d3336fe4..97bc849a2 100644 --- a/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts +++ b/src/Ombi/ClientApp/app/interfaces/INotifcationSettings.ts @@ -22,6 +22,7 @@ export interface INotificationTemplates { message: string, notificationType: NotificationType, notificationAgent: NotificationAgent, + enabled:boolean, } export enum NotificationAgent { diff --git a/src/Ombi/ClientApp/app/services/helpers/validation.service.ts b/src/Ombi/ClientApp/app/services/helpers/validation.service.ts new file mode 100644 index 000000000..b8613e59d --- /dev/null +++ b/src/Ombi/ClientApp/app/services/helpers/validation.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@angular/core'; +import { FormGroup, Validators, ValidatorFn } from '@angular/forms'; + +@Injectable() +export class ValidationService { + + /** + * Disable validation on a control + * @param form + * @param name + */ + public disableValidation(form: FormGroup, name: string): void { + form.controls[name].clearValidators(); + form.controls[name].updateValueAndValidity(); + } + + /** + * Enable validation with the default validation attribute of required + * @param form + * @param name + */ + public enableValidation(form: FormGroup, name: string): void; + public enableValidation(form: FormGroup, name: string, validators?: ValidatorFn[]): void { + if (validators) { + // If we provide some use them + form.controls[name].setValidators(validators); + } else { + // It's just required by default + form.controls[name].setValidators([Validators.required]); + } + form.controls[name].updateValueAndValidity(); + } + +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.html b/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.html index b7c3f884a..20582e666 100644 --- a/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.html +++ b/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.html @@ -1,82 +1,99 @@  -
+
Email Notifications
-
-
- - +
+ +
+
+ + +
-
-
-
- +
+
+ +
-
- -
- -
- +
+
Host is required
+
The Port is required
+
The Email Sender is required
+
The Email Sender needs to be a valid email address
+
The Email Sender is required
+
The Admin Email needs to be a valid email address
+
The Username is required
+
The Password is required
-
-
- -
- +
+ +
+ +
-
-
- -
- +
+ +
+ +
-
-
- -
- +
+ +
+ +
-
- -
- -
- +
+ +
+ +
-
-
- -
- + +
+ +
+ +
-
-
-
- +
+ +
+ +
-
- - -
-
- +
+
+ +
-
+ + + +
+
+ +
+
+
+
- +
\ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.ts b/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.ts index 49aa03bf6..6977f8a55 100644 --- a/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.ts +++ b/src/Ombi/ClientApp/app/settings/notifications/emailnotification.component.ts @@ -1,34 +1,87 @@ import { Component, OnInit } from '@angular/core'; +import { FormGroup, Validators, FormBuilder } from '@angular/forms'; -import { IEmailNotificationSettings, NotificationType } from '../../interfaces/INotifcationSettings'; +import { INotificationTemplates, IEmailNotificationSettings, NotificationType } from '../../interfaces/INotifcationSettings'; import { SettingsService } from '../../services/settings.service'; import { NotificationService } from "../../services/notification.service"; +import { ValidationService } from "../../services/helpers/validation.service"; @Component({ templateUrl: './emailnotification.component.html', }) export class EmailNotificationComponent implements OnInit { + constructor(private settingsService: SettingsService, + private notificationService: NotificationService, + private fb: FormBuilder, + private validationService: ValidationService) { } - constructor(private settingsService: SettingsService, private notificationService: NotificationService) { } - - settings: IEmailNotificationSettings; NotificationType = NotificationType; + templates: INotificationTemplates[]; + + emailForm: FormGroup; ngOnInit(): void { - this.settingsService.getEmailNotificationSettings().subscribe(x => this.settings = x); + this.settingsService.getEmailNotificationSettings().subscribe(x => { + this.templates = x.notificationTemplates; + + this.emailForm = this.fb.group({ + enabled: [x.enabled], + authentication: [x.authentication], + host: [x.host, [Validators.required]], + password: [x.password], + port: [x.port, [Validators.required]], + sender: [x.sender, [Validators.required, Validators.email]], + username: [x.username], + adminEmail: [x.adminEmail, [Validators.required, Validators.email]], + }); + + if (x.authentication) { + this.validationService.enableValidation(this.emailForm, 'username'); + this.validationService.enableValidation(this.emailForm, 'password'); + } + + this.subscribeToAuthChanges(); + }); } - test() { - // TODO Emby Service - } + onSubmit(form: FormGroup) { + console.log(form.value, form.valid); - save() { - this.settingsService.saveEmailNotificationSettings(this.settings).subscribe(x => { + if (form.invalid) { + this.notificationService.error("Validation", "Please check your entered values"); + return + } + + var settings = form.value; + settings.notificationTemplates = this.templates; + + this.settingsService.saveEmailNotificationSettings(settings).subscribe(x => { if (x) { this.notificationService.success("Settings Saved", "Successfully saved Email settings"); } else { this.notificationService.success("Settings Saved", "There was an error when saving the Email settings"); } }); + + } + + save() { + + } + + private subscribeToAuthChanges() { + const authCtrl = this.emailForm.controls.authentication; + const changes$ = authCtrl.valueChanges; + + changes$.subscribe((auth: boolean) => { + + if (auth) { + this.validationService.enableValidation(this.emailForm, 'username'); + this.validationService.enableValidation(this.emailForm, 'password'); + } else { + this.validationService.disableValidation(this.emailForm, 'username'); + this.validationService.disableValidation(this.emailForm, 'password'); + } + }); } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.html b/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.html index 9a9ec4ca1..72b13063b 100644 --- a/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.html +++ b/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.html @@ -1,18 +1,27 @@ - + + +
+
- +
+ +
+
+ +
+
- +
diff --git a/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.ts b/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.ts index 943f9bca1..ab888d4e6 100644 --- a/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.ts +++ b/src/Ombi/ClientApp/app/settings/notifications/notificationtemplate.component.ts @@ -9,4 +9,16 @@ import { INotificationTemplates, NotificationType } from '../../interfaces/INoti export class NotificationTemplate { @Input() templates: INotificationTemplates[]; NotificationType = NotificationType; + + helpText = ` +{RequestedUser} : The User who requested the content
+{RequestedDate} : The Date the media was requested
+{Title} : The title of the request e.g. Lion King
+{Type} : The request type e.g. Movie/Tv Show
+{LongDate} : 15 June 2017
+{ShortDate} : 15/06/2017
+{LongTime} : 16:02:34
+{ShortTime} : 16:02
+ +` } \ No newline at end of file diff --git a/src/Ombi/ClientApp/app/settings/settings.module.ts b/src/Ombi/ClientApp/app/settings/settings.module.ts index d14e3f1f8..4bb9b2568 100644 --- a/src/Ombi/ClientApp/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/app/settings/settings.module.ts @@ -1,6 +1,6 @@ import { NgModule, } from '@angular/core'; import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { RouterModule, Routes } from '@angular/router'; import { NgbModule, NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap'; @@ -9,6 +9,7 @@ import { AuthGuard } from '../auth/auth.guard'; import { AuthModule } from '../auth/auth.module'; import { SonarrService } from '../services/applications/sonarr.service'; import { RadarrService } from '../services/applications/radarr.service'; +import { ValidationService } from '../services/helpers/validation.service'; import { OmbiComponent } from './ombi/ombi.component'; import { PlexComponent } from './plex/plex.component'; @@ -23,7 +24,7 @@ import { NotificationTemplate } from './notifications/notificationtemplate.compo import { SettingsMenuComponent } from './settingsmenu.component'; import { HumanizePipe } from '../pipes/HumanizePipe'; -import { MenuModule, InputSwitchModule, InputTextModule, TooltipModule } from 'primeng/primeng'; +import { MenuModule, InputSwitchModule, InputTextModule, TooltipModule, AutoCompleteModule } from 'primeng/primeng'; const routes: Routes = [ { path: 'Settings/Ombi', component: OmbiComponent, canActivate: [AuthGuard] }, @@ -40,6 +41,7 @@ const routes: Routes = [ imports: [ CommonModule, FormsModule, + ReactiveFormsModule, RouterModule.forChild(routes), MenuModule, InputSwitchModule, @@ -47,7 +49,8 @@ const routes: Routes = [ AuthModule, NgbModule, TooltipModule, - NgbAccordionModule + NgbAccordionModule, + AutoCompleteModule ], declarations: [ SettingsMenuComponent, @@ -70,6 +73,7 @@ const routes: Routes = [ AuthService, RadarrService, AuthGuard, + ValidationService ], }) diff --git a/src/Ombi/Controllers/RequestController.cs b/src/Ombi/Controllers/RequestController.cs index a16c1d074..457456ae7 100644 --- a/src/Ombi/Controllers/RequestController.cs +++ b/src/Ombi/Controllers/RequestController.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Ombi.Models; +using Ombi.Notifications.Models; namespace Ombi.Controllers {