mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-14 01:02:57 -07:00
Pretty much finished the actual newsletter. Still need to work on the UI !wip
This commit is contained in:
parent
9767380f83
commit
1528cdfc03
15 changed files with 463 additions and 24 deletions
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Core.Models;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
|
@ -10,5 +11,6 @@ namespace Ombi.Core.Engine
|
|||
IEnumerable<RecentlyAddedMovieModel> GetRecentlyAddedMovies(DateTime from, DateTime to);
|
||||
IEnumerable<RecentlyAddedTvModel> GetRecentlyAddedTv(DateTime from, DateTime to, bool groupBySeason);
|
||||
IEnumerable<RecentlyAddedTvModel> GetRecentlyAddedTv(bool groupBySeason);
|
||||
Task<bool> UpdateRecentlyAddedDatabase();
|
||||
}
|
||||
}
|
|
@ -1,27 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Internal;
|
||||
using Ombi.Core.Models;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using RecentlyAddedType = Ombi.Store.Entities.RecentlyAddedType;
|
||||
|
||||
namespace Ombi.Core.Engine
|
||||
{
|
||||
public class RecentlyAddedEngine : IRecentlyAddedEngine
|
||||
{
|
||||
public RecentlyAddedEngine(IPlexContentRepository plex, IEmbyContentRepository emby)
|
||||
public RecentlyAddedEngine(IPlexContentRepository plex, IEmbyContentRepository emby, IRepository<RecentlyAddedLog> recentlyAdded)
|
||||
{
|
||||
_plex = plex;
|
||||
_emby = emby;
|
||||
_recentlyAddedLog = recentlyAdded;
|
||||
}
|
||||
|
||||
private readonly IPlexContentRepository _plex;
|
||||
private readonly IEmbyContentRepository _emby;
|
||||
private readonly IRepository<RecentlyAddedLog> _recentlyAddedLog;
|
||||
|
||||
public IEnumerable<RecentlyAddedMovieModel> GetRecentlyAddedMovies(DateTime from, DateTime to)
|
||||
{
|
||||
|
@ -55,6 +56,67 @@ namespace Ombi.Core.Engine
|
|||
return GetRecentlyAddedTv(plexTv, embyTv, groupBySeason);
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateRecentlyAddedDatabase()
|
||||
{
|
||||
var plexContent = _plex.GetAll().Include(x => x.Episodes);
|
||||
var embyContent = _emby.GetAll().Include(x => x.Episodes);
|
||||
var recentlyAddedLog = new HashSet<RecentlyAddedLog>();
|
||||
foreach (var p in plexContent)
|
||||
{
|
||||
if (p.Type == PlexMediaTypeEntity.Movie)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Plex,
|
||||
ContentId = p.Id
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the episodes
|
||||
foreach (var ep in p.Episodes)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Plex,
|
||||
ContentId = ep.Id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var e in embyContent)
|
||||
{
|
||||
if (e.Type == EmbyMediaType.Movie)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Emby,
|
||||
ContentId = e.Id
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the episodes
|
||||
foreach (var ep in e.Episodes)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Plex,
|
||||
ContentId = ep.Id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
await _recentlyAddedLog.AddRange(recentlyAddedLog);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private IEnumerable<RecentlyAddedTvModel> GetRecentlyAddedTv(IQueryable<PlexServerContent> plexTv, IQueryable<EmbyContent> embyTv,
|
||||
bool groupBySeason)
|
||||
{
|
||||
|
|
23
src/Ombi.Core/Models/UI/NewsletterNotificationViewModel.cs
Normal file
23
src/Ombi.Core/Models/UI/NewsletterNotificationViewModel.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using Ombi.Settings.Settings.Models.Notifications;
|
||||
using Ombi.Store.Entities;
|
||||
|
||||
namespace Ombi.Core.Models.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// The view model for the notification settings page
|
||||
/// </summary>
|
||||
/// <seealso cref="NewsletterNotificationViewModel" />
|
||||
public class NewsletterNotificationViewModel : NewsletterSettings
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the notification templates.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The notification templates.
|
||||
/// </value>
|
||||
public NotificationTemplates NotificationTemplate { get; set; }
|
||||
|
||||
}
|
||||
}
|
|
@ -9,5 +9,6 @@
|
|||
public const string RequestTv = nameof(RequestTv);
|
||||
public const string RequestMovie = nameof(RequestMovie);
|
||||
public const string Disabled = nameof(Disabled);
|
||||
public const string RecievesNewsletter = nameof(RecievesNewsletter);
|
||||
}
|
||||
}
|
|
@ -38,6 +38,13 @@ namespace Ombi.Notifications
|
|||
AdditionalInformation = opts?.AdditionalInformation ?? string.Empty;
|
||||
}
|
||||
|
||||
public void SetupNewsletter(CustomizationSettings s, string username)
|
||||
{
|
||||
ApplicationUrl = (s?.ApplicationUrl.HasValue() ?? false) ? s.ApplicationUrl : string.Empty;
|
||||
ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s?.ApplicationName;
|
||||
RequestedUser = username;
|
||||
}
|
||||
|
||||
public void Setup(NotificationOptions opts, ChildRequests req, CustomizationSettings s)
|
||||
{
|
||||
LoadIssues(opts);
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Ombi.Api.TheMovieDb;
|
||||
using Ombi.Api.TheMovieDb.Models;
|
||||
|
@ -22,7 +24,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
public NewsletterJob(IPlexContentRepository plex, IEmbyContentRepository emby, IRepository<RecentlyAddedLog> addedLog,
|
||||
IMovieDbApi movieApi, ITvMazeApi tvApi, IEmailProvider email, ISettingsService<CustomizationSettings> custom,
|
||||
ISettingsService<EmailNotificationSettings> emailSettings, INotificationTemplatesRepository templateRepo)
|
||||
ISettingsService<EmailNotificationSettings> emailSettings, INotificationTemplatesRepository templateRepo,
|
||||
UserManager<OmbiUser> um, ISettingsService<NewsletterSettings> newsletter)
|
||||
{
|
||||
_plex = plex;
|
||||
_emby = emby;
|
||||
|
@ -33,6 +36,8 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
_customizationSettings = custom;
|
||||
_templateRepo = templateRepo;
|
||||
_emailSettings = emailSettings;
|
||||
_newsletterSettings = newsletter;
|
||||
_userManager = um;
|
||||
}
|
||||
|
||||
private readonly IPlexContentRepository _plex;
|
||||
|
@ -44,9 +49,16 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
private readonly ISettingsService<CustomizationSettings> _customizationSettings;
|
||||
private readonly INotificationTemplatesRepository _templateRepo;
|
||||
private readonly ISettingsService<EmailNotificationSettings> _emailSettings;
|
||||
private readonly ISettingsService<NewsletterSettings> _newsletterSettings;
|
||||
private readonly UserManager<OmbiUser> _userManager;
|
||||
|
||||
public async Task Start()
|
||||
{
|
||||
var newsletterSettings = await _newsletterSettings.GetSettingsAsync();
|
||||
if (!newsletterSettings.Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var template = await _templateRepo.GetTemplate(NotificationAgent.Email, NotificationType.Newsletter);
|
||||
if (!template.Enabled)
|
||||
{
|
||||
|
@ -59,40 +71,146 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
return;
|
||||
}
|
||||
|
||||
var customization = await _customizationSettings.GetSettingsAsync();
|
||||
|
||||
// Get the Content
|
||||
var plexContent = _plex.GetAll().Include(x => x.Episodes);
|
||||
var embyContent = _emby.GetAll().Include(x => x.Episodes);
|
||||
|
||||
var addedLog = _recentlyAddedLog.GetAll();
|
||||
var addedPlexLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Plex).Select(x => x.ContentId);
|
||||
var addedEmbyLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Emby).Select(x => x.ContentId);
|
||||
var addedPlexMovieLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Parent).Select(x => x.ContentId);
|
||||
var addedEmbyMoviesLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Emby && x.ContentType == ContentType.Parent).Select(x => x.ContentId);
|
||||
|
||||
var addedPlexEpisodesLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Episode).Select(x => x.ContentId);
|
||||
var addedEmbyEpisodesLogIds = addedLog.Where(x => x.Type == RecentlyAddedType.Emby && x.ContentType == ContentType.Episode).Select(x => x.ContentId);
|
||||
|
||||
// Filter out the ones that we haven't sent yet
|
||||
var plexContentToSend = plexContent.Where(x => !addedPlexLogIds.Contains(x.Id));
|
||||
var embyContentToSend = embyContent.Where(x => !addedEmbyLogIds.Contains(x.Id));
|
||||
var plexContentMoviesToSend = plexContent.Where(x => !addedPlexMovieLogIds.Contains(x.Id));
|
||||
var embyContentMoviesToSend = embyContent.Where(x => !addedEmbyMoviesLogIds.Contains(x.Id));
|
||||
|
||||
var plexContentTvToSend = plexContent.Where(x => x.Episodes.Any(e => !addedPlexEpisodesLogIds.Contains(e.Id)));
|
||||
var embyContentTvToSend = embyContent.Where(x => x.Episodes.Any(e => !addedEmbyEpisodesLogIds.Contains(e.Id)));
|
||||
|
||||
var plexContentToSend = plexContentMoviesToSend.Union(plexContentTvToSend);
|
||||
var embyContentToSend = embyContentMoviesToSend.Union(embyContentTvToSend);
|
||||
|
||||
|
||||
var body = await BuildHtml(plexContentToSend, embyContentToSend);
|
||||
|
||||
// Get the users to send it to
|
||||
var users = await _userManager.GetUsersInRoleAsync(OmbiRoles.RecievesNewsletter);
|
||||
if (!users.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var emailTasks = new List<Task>();
|
||||
foreach (var user in users)
|
||||
{
|
||||
if (user.Email.IsNullOrEmpty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var html = LoadTemplate(body, template, customization, user.Alias);
|
||||
|
||||
emailTasks.Add(_email.Send(new NotificationMessage { Message = html, Subject = template.Subject, To = user.Email }, emailSettings));
|
||||
}
|
||||
|
||||
// Now add all of this to the Recently Added log
|
||||
var recentlyAddedLog = new HashSet<RecentlyAddedLog>();
|
||||
foreach (var p in plexContentMoviesToSend)
|
||||
{
|
||||
if (p.Type == PlexMediaTypeEntity.Movie)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Plex,
|
||||
ContentId = p.Id
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the episodes
|
||||
foreach (var ep in p.Episodes)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Plex,
|
||||
ContentId = ep.Id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var e in embyContentMoviesToSend)
|
||||
{
|
||||
if (e.Type == EmbyMediaType.Movie)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Emby,
|
||||
ContentId = e.Id
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add the episodes
|
||||
foreach (var ep in e.Episodes)
|
||||
{
|
||||
recentlyAddedLog.Add(new RecentlyAddedLog
|
||||
{
|
||||
AddedAt = DateTime.Now,
|
||||
Type = RecentlyAddedType.Plex,
|
||||
ContentId = ep.Id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
await _recentlyAddedLog.AddRange(recentlyAddedLog);
|
||||
|
||||
await Task.WhenAll(emailTasks.ToArray());
|
||||
}
|
||||
|
||||
private string LoadTemplate(string body, NotificationTemplates template, CustomizationSettings settings, string username)
|
||||
{
|
||||
var email = new NewsletterTemplate();
|
||||
|
||||
var customization = await _customizationSettings.GetSettingsAsync();
|
||||
var resolver = new NotificationMessageResolver();
|
||||
var curlys = new NotificationMessageCurlys();
|
||||
|
||||
var html = email.LoadTemplate(template.Subject, template.Message, body, customization.Logo);
|
||||
curlys.SetupNewsletter(settings, username);
|
||||
|
||||
await _email.Send(new NotificationMessage {Message = html, Subject = template.Subject, To = "tidusjar@gmail.com"}, emailSettings);
|
||||
var parsed = resolver.ParseMessage(template, curlys);
|
||||
|
||||
var html = email.LoadTemplate(parsed.Subject, parsed.Message, body, settings.Logo);
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
private async Task<string> BuildHtml(IQueryable<PlexServerContent> plexContentToSend, IQueryable<EmbyContent> embyContentToSend)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var plexMovies = plexContentToSend.Where(x => x.Type == PlexMediaTypeEntity.Movie);
|
||||
var embyMovies = embyContentToSend.Where(x => x.Type == EmbyMediaType.Movie);
|
||||
if (plexMovies.Any() || embyMovies.Any())
|
||||
{
|
||||
sb.Append("<h1>New Movies:</h1><br /><br />");
|
||||
await ProcessPlexMovies(plexContentToSend.Where(x => x.Type == PlexMediaTypeEntity.Movie), sb);
|
||||
await ProcessEmbyMovies(embyContentToSend.Where(x => x.Type == EmbyMediaType.Movie), sb);
|
||||
await ProcessPlexMovies(plexMovies, sb);
|
||||
await ProcessEmbyMovies(embyMovies, sb);
|
||||
}
|
||||
|
||||
var plexTv = plexContentToSend.Where(x => x.Type == PlexMediaTypeEntity.Show);
|
||||
var embyTv = embyContentToSend.Where(x => x.Type == EmbyMediaType.Series);
|
||||
if (plexTv.Any() || embyTv.Any())
|
||||
{
|
||||
sb.Append("<h1>New Episodes:</h1><br /><br />");
|
||||
await ProcessPlexTv(plexContentToSend.Where(x => x.Type == PlexMediaTypeEntity.Show), sb);
|
||||
await ProcessEmbyMovies(embyContentToSend.Where(x => x.Type == EmbyMediaType.Series), sb);
|
||||
await ProcessPlexTv(plexTv, sb);
|
||||
await ProcessEmbyMovies(embyTv, sb);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
@ -426,6 +544,12 @@ namespace Ombi.Schedule.Jobs.Ombi
|
|||
{
|
||||
_plex?.Dispose();
|
||||
_emby?.Dispose();
|
||||
_newsletterSettings?.Dispose();
|
||||
_customizationSettings?.Dispose();
|
||||
_emailSettings.Dispose();
|
||||
_recentlyAddedLog.Dispose();
|
||||
_templateRepo?.Dispose();
|
||||
_userManager?.Dispose();
|
||||
}
|
||||
_disposed = true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
namespace Ombi.Settings.Settings.Models.Notifications
|
||||
{
|
||||
public class NewsletterSettings : Settings
|
||||
{
|
||||
public bool Enabled { get; set; }
|
||||
}
|
||||
}
|
|
@ -7,13 +7,20 @@ namespace Ombi.Store.Entities
|
|||
public class RecentlyAddedLog : Entity
|
||||
{
|
||||
public RecentlyAddedType Type { get; set; }
|
||||
public ContentType ContentType { get; set; }
|
||||
public int ContentId { get; set; } // This is dependant on the type
|
||||
public DateTime AddedAt { get; set; }
|
||||
}
|
||||
|
||||
public enum RecentlyAddedType
|
||||
{
|
||||
Plex,
|
||||
Emby
|
||||
Plex = 0,
|
||||
Emby = 1
|
||||
}
|
||||
|
||||
public enum ContentType
|
||||
{
|
||||
Parent = 0,
|
||||
Episode = 1
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Ombi.Helpers;
|
||||
|
@ -6,7 +7,7 @@ using Ombi.Store.Entities;
|
|||
|
||||
namespace Ombi.Store.Repository
|
||||
{
|
||||
public interface INotificationTemplatesRepository
|
||||
public interface INotificationTemplatesRepository : IDisposable
|
||||
{
|
||||
IQueryable<NotificationTemplates> All();
|
||||
Task<IEnumerable<NotificationTemplates>> GetAllTemplates();
|
||||
|
|
|
@ -60,5 +60,26 @@ namespace Ombi.Store.Repository
|
|||
await Db.SaveChangesAsync().ConfigureAwait(false);
|
||||
return settings.Entity;
|
||||
}
|
||||
|
||||
private bool _disposed;
|
||||
// Protected implementation of Dispose pattern.
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Db?.Dispose();
|
||||
}
|
||||
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -54,6 +54,10 @@ export interface IDiscordNotifcationSettings extends INotificationSettings {
|
|||
notificationTemplates: INotificationTemplates[];
|
||||
}
|
||||
|
||||
export interface INewsletterNotificationSettings extends INotificationSettings {
|
||||
notificationTemplate: INotificationTemplates;
|
||||
}
|
||||
|
||||
export interface ITelegramNotifcationSettings extends INotificationSettings {
|
||||
botApi: string;
|
||||
chatId: string;
|
||||
|
|
|
@ -20,6 +20,7 @@ import {
|
|||
ILandingPageSettings,
|
||||
IMattermostNotifcationSettings,
|
||||
IMobileNotifcationSettings,
|
||||
INewsletterNotificationSettings,
|
||||
IOmbiSettings,
|
||||
IPlexSettings,
|
||||
IPushbulletNotificationSettings,
|
||||
|
@ -265,4 +266,17 @@ export class SettingsService extends ServiceHelpers {
|
|||
return this.http
|
||||
.post<boolean>(`${this.url}/issues`, JSON.stringify(settings), {headers: this.headers});
|
||||
}
|
||||
|
||||
public getNewsletterSettings(): Observable<INewsletterNotificationSettings> {
|
||||
return this.http.get<INewsletterNotificationSettings>(`${this.url}/notifications/newsletter`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public updateNewsletterDatabase(): Observable<boolean> {
|
||||
return this.http.post<boolean>(`${this.url}/notifications/newsletterdatabase`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public saveNewsletterSettings(settings: INewsletterNotificationSettings): Observable<boolean> {
|
||||
return this.http
|
||||
.post<boolean>(`${this.url}/notifications/newsletter`, JSON.stringify(settings), {headers: this.headers});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<settings-menu></settings-menu>
|
||||
|
||||
<div *ngIf="form">
|
||||
<fieldset>
|
||||
<legend>Newsletter</legend>
|
||||
<div class="col-md-6">
|
||||
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="enable" formControlName="enabled">
|
||||
<label for="enable">Enabled</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input type="checkbox" id="enabled" [(ngModel)]="template.enabled" ng-checked="template.enabled">
|
||||
<label for="enabled">Enable</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" *ngIf="showSubject">
|
||||
<label class="control-label">Subject</label>
|
||||
<div>
|
||||
<input type="text" class="form-control form-control-custom" [(ngModel)]="template.subject" value="{{template.subject}}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">Message</label>
|
||||
<div>
|
||||
<textarea type="text" class="form-control form-control-custom" [(ngModel)]="template.message" value="{{template.message}}"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" type="button" (click)="updateDatabase()" class="btn btn-info-outline" tooltipPosition="top" pTooltip="I reccomend running this with a fresh Ombi install, this will set all the current *found* content to have been sent via Newsletter,
|
||||
if you do not do this then eventhing that Ombi has found in your libraries will go out on the first email!">Update Database</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-6">
|
||||
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
|
@ -0,0 +1,71 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder, FormGroup } from "@angular/forms";
|
||||
|
||||
import { INewsletterNotificationSettings, INotificationTemplates, NotificationType } from "../../interfaces";
|
||||
import { TesterService } from "../../services";
|
||||
import { NotificationService } from "../../services";
|
||||
import { SettingsService } from "../../services";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./newsletter.component.html",
|
||||
})
|
||||
export class NewsletterComponent implements OnInit {
|
||||
|
||||
public NotificationType = NotificationType;
|
||||
public template: INotificationTemplates;
|
||||
public form: FormGroup;
|
||||
|
||||
constructor(private settingsService: SettingsService,
|
||||
private notificationService: NotificationService,
|
||||
private fb: FormBuilder,
|
||||
private testerService: TesterService) { }
|
||||
|
||||
public ngOnInit() {
|
||||
this.settingsService.getNewsletterSettings().subscribe(x => {
|
||||
this.template = x.notificationTemplate;
|
||||
|
||||
this.form = this.fb.group({
|
||||
enabled: [x.enabled],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public updateDatabase() {
|
||||
this.settingsService.updateNewsletterDatabase().subscribe();
|
||||
}
|
||||
|
||||
public onSubmit(form: FormGroup) {
|
||||
if (form.invalid) {
|
||||
this.notificationService.error("Please check your entered values");
|
||||
return;
|
||||
}
|
||||
|
||||
const settings = <INewsletterNotificationSettings>form.value;
|
||||
settings.notificationTemplate = this.template;
|
||||
|
||||
this.settingsService.saveNewsletterSettings(settings).subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Successfully saved the Newsletter settings");
|
||||
} else {
|
||||
this.notificationService.error("There was an error when saving the Newsletter settings");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public test(form: FormGroup) {
|
||||
if (form.invalid) {
|
||||
this.notificationService.error("Please check your entered values");
|
||||
return;
|
||||
}
|
||||
|
||||
this.testerService.discordTest(form.value).subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Successfully sent a Discord message, please check the discord channel");
|
||||
} else {
|
||||
this.notificationService.error("There was an error when sending the Discord message. Please check your settings");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
|
@ -32,6 +32,7 @@ using Ombi.Settings.Settings.Models.Notifications;
|
|||
using Ombi.Store.Entities;
|
||||
using Ombi.Store.Repository;
|
||||
using Ombi.Api.Github;
|
||||
using Ombi.Core.Engine;
|
||||
|
||||
namespace Ombi.Controllers
|
||||
{
|
||||
|
@ -60,7 +61,8 @@ namespace Ombi.Controllers
|
|||
IEmbyApi embyApi,
|
||||
IRadarrSync radarrSync,
|
||||
ICacheService memCache,
|
||||
IGithubApi githubApi)
|
||||
IGithubApi githubApi,
|
||||
IRecentlyAddedEngine engine)
|
||||
{
|
||||
SettingsResolver = resolver;
|
||||
Mapper = mapper;
|
||||
|
@ -78,6 +80,7 @@ namespace Ombi.Controllers
|
|||
private readonly IRadarrSync _radarrSync;
|
||||
private readonly ICacheService _cache;
|
||||
private readonly IGithubApi _githubApi;
|
||||
private readonly IRecentlyAddedEngine _recentlyAdded;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Ombi settings.
|
||||
|
@ -865,13 +868,53 @@ namespace Ombi.Controllers
|
|||
return model;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the Newsletter notification settings.
|
||||
/// </summary>
|
||||
/// <param name="model">The model.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("notifications/newsletter")]
|
||||
public async Task<bool> NewsletterSettings([FromBody] NewsletterNotificationViewModel model)
|
||||
{
|
||||
// Save the email settings
|
||||
var settings = Mapper.Map<NewsletterSettings>(model);
|
||||
var result = await Save(settings);
|
||||
|
||||
// Save the templates
|
||||
await TemplateRepository.Update(model.NotificationTemplate);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
[HttpPost("notifications/newsletterdatabase")]
|
||||
public async Task<bool> UpdateNewsletterDatabase()
|
||||
{
|
||||
return await _recentlyAdded.UpdateRecentlyAddedDatabase();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Newsletter Notification Settings.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("notifications/newsletter")]
|
||||
public async Task<NewsletterNotificationViewModel> NewsletterSettings()
|
||||
{
|
||||
var settings = await Get<NewsletterSettings>();
|
||||
var model = Mapper.Map<NewsletterNotificationViewModel>(settings);
|
||||
|
||||
// Lookup to see if we have any templates saved
|
||||
var templates = await BuildTemplates(NotificationAgent.Email);
|
||||
model.NotificationTemplate = templates.FirstOrDefault(x => x.NotificationType == NotificationType.Newsletter);
|
||||
return model;
|
||||
}
|
||||
|
||||
private async Task<List<NotificationTemplates>> BuildTemplates(NotificationAgent agent)
|
||||
{
|
||||
var templates = await TemplateRepository.GetAllTemplates(agent);
|
||||
return templates.OrderBy(x => x.NotificationType.ToString()).ToList();
|
||||
}
|
||||
|
||||
|
||||
private async Task<T> Get<T>()
|
||||
{
|
||||
var settings = SettingsResolver.Resolve<T>();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue