All Sln changes

This commit is contained in:
tidusjar 2016-12-19 20:14:31 +00:00
commit 796f0fc188
615 changed files with 68 additions and 747 deletions

View file

@ -0,0 +1,307 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: EmailMessageNotification.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 System;
using System.Threading.Tasks;
using MimeKit;
using NLog;
using Ombi.Core;
using Ombi.Core.Models;
using Ombi.Core.Notification.Templates;
using Ombi.Core.SettingModels;
using Ombi.Services.Interfaces;
using Ombi.Store;
using SmtpClient = MailKit.Net.Smtp.SmtpClient;
namespace Ombi.Services.Notification
{
public class EmailMessageNotification : INotification
{
public EmailMessageNotification(ISettingsService<EmailNotificationSettings> settings)
{
EmailNotificationSettings = settings;
}
private static readonly Logger Log = LogManager.GetCurrentClassLogger();
private ISettingsService<EmailNotificationSettings> EmailNotificationSettings { get; }
public string NotificationName => "EmailMessageNotification";
public async Task NotifyAsync(NotificationModel model)
{
var configuration = GetConfiguration();
await NotifyAsync(model, configuration);
}
public async Task NotifyAsync(NotificationModel model, Settings settings)
{
if (settings == null) await NotifyAsync(model);
var emailSettings = (EmailNotificationSettings)settings;
if (!ValidateConfiguration(emailSettings))
{
return;
}
switch (model.NotificationType)
{
case NotificationType.NewRequest:
await EmailNewRequest(model, emailSettings);
break;
case NotificationType.Issue:
await EmailIssue(model, emailSettings);
break;
case NotificationType.RequestAvailable:
await EmailAvailableRequest(model, emailSettings);
break;
case NotificationType.RequestApproved:
await EmailRequestApproved(model, emailSettings);
break;
case NotificationType.AdminNote:
throw new NotImplementedException();
case NotificationType.Test:
await EmailTest(model, emailSettings);
break;
case NotificationType.RequestDeclined:
await EmailRequestDeclined(model, emailSettings);
break;
case NotificationType.ItemAddedToFaultQueue:
await EmailAddedToRequestQueue(model, emailSettings);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private EmailNotificationSettings GetConfiguration()
{
var settings = EmailNotificationSettings.GetSettings();
return settings;
}
private bool ValidateConfiguration(EmailNotificationSettings settings)
{
if (settings.Authentication)
{
if (string.IsNullOrEmpty(settings.EmailUsername) || string.IsNullOrEmpty(settings.EmailPassword))
{
return false;
}
}
if (string.IsNullOrEmpty(settings.EmailHost) || string.IsNullOrEmpty(settings.RecipientEmail) || string.IsNullOrEmpty(settings.EmailPort.ToString()))
{
return false;
}
if (!settings.EnableUserEmailNotifications)
{
if (!settings.Enabled)
{
return false;
}
}
return true;
}
private async Task EmailNewRequest(NotificationModel model, EmailNotificationSettings settings)
{
var email = new EmailBasicTemplate();
var html = email.LoadTemplate(
$"Plex Requests: New {model.RequestType.GetString()?.ToLower()} request for {model.Title}!",
$"Hello! The user '{model.User}' has requested the {model.RequestType.GetString()?.ToLower()} '{model.Title}'! Please log in to approve this request. Request Date: {model.DateTime.ToString("f")}",
model.ImgSrc);
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! The user '{model.User}' has requested the {model.RequestType.GetString()?.ToLower()} '{model.Title}'! Please log in to approve this request. Request Date: {model.DateTime.ToString("f")}" };
var message = new MimeMessage
{
Body = body.ToMessageBody(),
Subject = $"Plex Requests: New {model.RequestType.GetString()?.ToLower()} request for {model.Title}!"
};
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
await Send(message, settings);
}
private async Task EmailIssue(NotificationModel model, EmailNotificationSettings settings)
{
var email = new EmailBasicTemplate();
var html = email.LoadTemplate(
$"Plex Requests: New issue for {model.Title}!",
$"Hello! The user '{model.User}' has reported a new issue {model.Body} for the title {model.Title}!",
model.ImgSrc);
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! The user '{model.User}' has reported a new issue {model.Body} for the title {model.Title}!"};
var message = new MimeMessage
{
Body = body.ToMessageBody(),
Subject = $"Plex Requests: New issue for {model.Title}!"
};
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
await Send(message, settings);
}
private async Task EmailAddedToRequestQueue(NotificationModel model, EmailNotificationSettings settings)
{
var email = new EmailBasicTemplate();
var html = email.LoadTemplate(
"Plex Requests: A request could not be added.",
$"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying",
model.ImgSrc);
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying" };
var message = new MimeMessage
{
Body = body.ToMessageBody(),
Subject = $"Plex Requests: A request could not be added"
};
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
await Send(message, settings);
}
private async Task EmailRequestDeclined(NotificationModel model, EmailNotificationSettings settings)
{
var email = new EmailBasicTemplate();
var html = email.LoadTemplate(
"Plex Requests: Your request has been declined",
$"Hello! Your request for {model.Title} has been declined, Sorry!",
model.ImgSrc);
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! Your request for {model.Title} has been declined, Sorry!", };
var message = new MimeMessage
{
Body = body.ToMessageBody(),
Subject = $"Plex Requests: Your request has been declined"
};
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
message.To.Add(new MailboxAddress(model.UserEmail, model.UserEmail));
await Send(message, settings);
}
private async Task EmailRequestApproved(NotificationModel model, EmailNotificationSettings settings)
{
var email = new EmailBasicTemplate();
var html = email.LoadTemplate(
"Plex Requests: Your request has been approved!",
$"Hello! Your request for {model.Title} has been approved!",
model.ImgSrc);
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! Your request for {model.Title} has been approved!", };
var message = new MimeMessage
{
Body = body.ToMessageBody(),
Subject = $"Plex Requests: Your request has been approved!"
};
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
message.To.Add(new MailboxAddress(model.UserEmail, model.UserEmail));
await Send(message, settings);
}
private async Task EmailAvailableRequest(NotificationModel model, EmailNotificationSettings settings)
{
if (!settings.EnableUserEmailNotifications)
{
await Task.FromResult(false);
}
var email = new EmailBasicTemplate();
var html = email.LoadTemplate(
$"Plex Requests: {model.Title} is now available!",
$"Hello! You requested {model.Title} on PlexRequests! This is now available on Plex! :)",
model.ImgSrc);
var body = new BodyBuilder { HtmlBody = html, TextBody = $"Hello! You requested {model.Title} on PlexRequests! This is now available on Plex! :)" };
var message = new MimeMessage
{
Body = body.ToMessageBody(),
Subject = $"Plex Requests: {model.Title} is now available!"
};
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
message.To.Add(new MailboxAddress(model.UserEmail, model.UserEmail));
await Send(message, settings);
}
private async Task Send(MimeMessage message, EmailNotificationSettings settings)
{
try
{
using (var client = new SmtpClient())
{
client.Connect(settings.EmailHost, settings.EmailPort); // Let MailKit figure out the correct SecureSocketOptions.
// Note: since we don't have an OAuth2 token, disable
// the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
if (settings.Authentication)
{
client.Authenticate(settings.EmailUsername, settings.EmailPassword);
}
Log.Info("sending message to {0} \r\n from: {1}\r\n Are we authenticated: {2}", message.To, message.From, client.IsAuthenticated);
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
}
catch (Exception e)
{
Log.Error(e);
}
}
private async Task EmailTest(NotificationModel model, EmailNotificationSettings settings)
{
var email = new EmailBasicTemplate();
var html = email.LoadTemplate(
"Test Message",
"This is just a test! Success!",
model.ImgSrc);
var body = new BodyBuilder { HtmlBody = html, };
var message = new MimeMessage
{
Body = body.ToMessageBody()
};
message.From.Add(new MailboxAddress(settings.EmailSender, settings.EmailSender));
message.To.Add(new MailboxAddress(settings.RecipientEmail, settings.RecipientEmail));
await Send(message, settings);
}
}
}

View file

@ -0,0 +1,173 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: NotificationEngine.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 System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NLog;
using Ombi.Api.Interfaces;
using Ombi.Core.Models;
using Ombi.Core.Users;
using Ombi.Helpers.Permissions;
using Ombi.Services.Interfaces;
using Ombi.Store;
using Ombi.Store.Models;
using Ombi.Store.Repository;
namespace Ombi.Services.Notification
{
public class NotificationEngine : INotificationEngine
{
public NotificationEngine(IPlexApi p, IRepository<UsersToNotify> repo, INotificationService service, IUserHelper userHelper)
{
PlexApi = p;
UserNotifyRepo = repo;
Notification = service;
UserHelper = userHelper;
}
private IPlexApi PlexApi { get; }
private IRepository<UsersToNotify> UserNotifyRepo { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
private INotificationService Notification { get; }
private IUserHelper UserHelper { get; }
public async Task NotifyUsers(IEnumerable<RequestedModel> modelChanged, string apiKey, NotificationType type)
{
try
{
var plexUser = PlexApi.GetUsers(apiKey);
var userAccount = PlexApi.GetAccount(apiKey);
var adminUsername = userAccount.Username ?? string.Empty;
var users = UserHelper.GetUsersWithFeature(Features.RequestAddedNotification).ToList();
Log.Debug("Notifying Users Count {0}", users.Count);
foreach (var model in modelChanged)
{
var selectedUsers = new List<string>();
foreach (var u in users)
{
var requestUser = model.RequestedUsers.FirstOrDefault(
x => x.Equals(u.Username, StringComparison.CurrentCultureIgnoreCase) || x.Equals(u.UserAlias, StringComparison.CurrentCultureIgnoreCase));
if (string.IsNullOrEmpty(requestUser))
{
continue;
}
selectedUsers.Add(requestUser);
}
//var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers, StringComparer.CurrentCultureIgnoreCase);
foreach (var user in selectedUsers)
{
Log.Info("Notifying user {0}", user);
if (user.Equals(adminUsername, StringComparison.CurrentCultureIgnoreCase))
{
Log.Info("This user is the Plex server owner");
await PublishUserNotification(userAccount.Username, userAccount.Email, model.Title, model.PosterPath, type);
return;
}
var email = plexUser.User.FirstOrDefault(x => x.Username.Equals(user, StringComparison.CurrentCultureIgnoreCase));
if (string.IsNullOrEmpty(email?.Email))
{
Log.Info("There is no email address for this Plex user, cannot send notification");
// We do not have a plex user that requested this!
continue;
}
Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Username, email.Email, model.Title);
await PublishUserNotification(email.Username, email.Email, model.Title, model.PosterPath, type);
}
}
}
catch (Exception e)
{
Log.Error(e);
}
}
public async Task NotifyUsers(RequestedModel model, string apiKey, NotificationType type)
{
try
{
var plexUser = PlexApi.GetUsers(apiKey);
var userAccount = PlexApi.GetAccount(apiKey);
var adminUsername = userAccount.Username ?? string.Empty;
var users = UserHelper.GetUsersWithFeature(Features.RequestAddedNotification).ToList();
Log.Debug("Notifying Users Count {0}", users.Count);
var selectedUsers = users.Select(x => x.Username).Intersect(model.RequestedUsers, StringComparer.CurrentCultureIgnoreCase);
foreach (var user in selectedUsers)
{
Log.Info("Notifying user {0}", user);
if (user.Equals(adminUsername, StringComparison.CurrentCultureIgnoreCase))
{
Log.Info("This user is the Plex server owner");
await PublishUserNotification(userAccount.Username, userAccount.Email, model.Title, model.PosterPath, type);
return;
}
var email = plexUser.User.FirstOrDefault(x => x.Username.Equals(user, StringComparison.CurrentCultureIgnoreCase));
if (email == null)
{
Log.Info("There is no email address for this Plex user, cannot send notification");
// We do not have a plex user that requested this!
continue;
}
Log.Info("Sending notification to: {0} at: {1}, for title: {2}", email.Username, email.Email, model.Title);
await PublishUserNotification(email.Username, email.Email, model.Title, model.PosterPath, type);
}
}
catch (Exception e)
{
Log.Error(e);
}
}
private async Task PublishUserNotification(string username, string email, string title, string img, NotificationType type)
{
var notificationModel = new NotificationModel
{
User = username,
UserEmail = email,
NotificationType = type,
Title = title,
ImgSrc = img
};
// Send the notification to the user.
await Notification.Publish(notificationModel);
}
}
}

View file

@ -0,0 +1,45 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: NotificationModel.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 System;
using Ombi.Core.Models;
using Ombi.Store;
namespace Ombi.Services.Notification
{
public class NotificationModel
{
public string Title { get; set; }
public string Body { get; set; }
public DateTime DateTime { get; set; }
public NotificationType NotificationType { get; set; }
public string User { get; set; }
public string UserEmail { get; set; }
public RequestType RequestType { get; set; }
public string ImgSrc { get; set; }
}
}

View file

@ -0,0 +1,103 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: NotificationService.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 System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;
using NLog;
using Ombi.Core.SettingModels;
using Ombi.Services.Interfaces;
namespace Ombi.Services.Notification
{
public class NotificationService : INotificationService
{
private static Logger Log = LogManager.GetCurrentClassLogger();
public ConcurrentDictionary<string, INotification> Observers { get; } = new ConcurrentDictionary<string, INotification>();
/// <summary>
/// Sends a notification to the user. This one is used in normal notification scenarios
/// </summary>
/// <param name="model">The model.</param>
/// <returns></returns>
public async Task Publish(NotificationModel model)
{
var notificationTasks = Observers.Values.Select(notification => NotifyAsync(notification, model));
await Task.WhenAll(notificationTasks).ConfigureAwait(false);
}
/// <summary>
/// Sends a notification to the user, this is usually for testing the settings.
/// </summary>
/// <param name="model">The model.</param>
/// <param name="settings">The settings.</param>
/// <returns></returns>
public async Task Publish(NotificationModel model, Settings settings)
{
var notificationTasks = Observers.Values.Select(notification => NotifyAsync(notification, model, settings));
await Task.WhenAll(notificationTasks).ConfigureAwait(false);
}
public void Subscribe(INotification notification)
{
Observers.TryAdd(notification.NotificationName, notification);
}
public void UnSubscribe(INotification notification)
{
Observers.TryRemove(notification.NotificationName, out notification);
}
private async Task NotifyAsync(INotification notification, NotificationModel model)
{
try
{
await notification.NotifyAsync(model).ConfigureAwait(false);
}
catch (Exception ex)
{
Log.Error(ex, $"Notification '{notification.NotificationName}' failed with exception");
}
}
private async Task NotifyAsync(INotification notification, NotificationModel model, Settings settings)
{
try
{
await notification.NotifyAsync(model, settings).ConfigureAwait(false);
}
catch (Exception ex)
{
Log.Error(ex, $"Notification '{notification.NotificationName}' failed with exception");
}
}
}
}

View file

@ -0,0 +1,155 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: PushbulletNotification.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 System;
using System.Threading.Tasks;
using NLog;
using Ombi.Api.Interfaces;
using Ombi.Core;
using Ombi.Core.Models;
using Ombi.Core.SettingModels;
using Ombi.Services.Interfaces;
using Ombi.Store;
namespace Ombi.Services.Notification
{
public class PushbulletNotification : INotification
{
public PushbulletNotification(IPushbulletApi pushbulletApi, ISettingsService<PushbulletNotificationSettings> settings)
{
PushbulletApi = pushbulletApi;
SettingsService = settings;
}
private IPushbulletApi PushbulletApi { get; }
private ISettingsService<PushbulletNotificationSettings> SettingsService { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
public string NotificationName => "PushbulletNotification";
public async Task NotifyAsync(NotificationModel model)
{
var configuration = GetSettings();
await NotifyAsync(model, configuration);
}
public async Task NotifyAsync(NotificationModel model, Settings settings)
{
if (settings == null) await NotifyAsync(model);
var pushSettings = (PushbulletNotificationSettings)settings;
if (!ValidateConfiguration(pushSettings)) return;
switch (model.NotificationType)
{
case NotificationType.NewRequest:
await PushNewRequestAsync(model, pushSettings);
break;
case NotificationType.Issue:
await PushIssueAsync(model, pushSettings);
break;
case NotificationType.RequestAvailable:
break;
case NotificationType.RequestApproved:
break;
case NotificationType.AdminNote:
break;
case NotificationType.Test:
await PushTestAsync(pushSettings);
break;
case NotificationType.RequestDeclined:
break;
case NotificationType.ItemAddedToFaultQueue:
await PushFaultQueue(model, pushSettings);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private bool ValidateConfiguration(PushbulletNotificationSettings settings)
{
if (!settings.Enabled)
{
return false;
}
if (string.IsNullOrEmpty(settings.AccessToken))
{
return false;
}
return true;
}
private PushbulletNotificationSettings GetSettings()
{
return SettingsService.GetSettings();
}
private async Task PushNewRequestAsync(NotificationModel model, PushbulletNotificationSettings settings)
{
var message = $"The {model.RequestType.GetString()?.ToLower()} '{model.Title}' has been requested by user: {model.User}";
var pushTitle = $"Plex Requests: The {model.RequestType.GetString()?.ToLower()} {model.Title} has been requested!";
await Push(settings, message, pushTitle);
}
private async Task PushIssueAsync(NotificationModel model, PushbulletNotificationSettings settings)
{
var message = $"A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
var pushTitle = $"Plex Requests: A new issue has been reported for {model.Title}";
await Push(settings, message, pushTitle);
}
private async Task PushTestAsync(PushbulletNotificationSettings settings)
{
var message = "This is just a test! Success!";
var pushTitle = "Plex Requests: Test Message!";
await Push(settings, message, pushTitle);
}
private async Task PushFaultQueue(NotificationModel model, PushbulletNotificationSettings settings)
{
var message = $"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying";
var pushTitle = $"Plex Requests: The {model.RequestType.GetString()?.ToLower()} {model.Title} has been requested but could not be added!";
await Push(settings, message, pushTitle);
}
private async Task Push(PushbulletNotificationSettings settings, string message, string title)
{
try
{
var result = await PushbulletApi.PushAsync(settings.AccessToken, title, message, settings.DeviceIdentifier);
if (result != null)
{
Log.Error("Pushbullet api returned a null value, the notification did not get pushed");
}
}
catch (Exception e)
{
Log.Error(e);
}
}
}
}

View file

@ -0,0 +1,151 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: PushbulletNotification.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 System;
using System.Threading.Tasks;
using NLog;
using Ombi.Api.Interfaces;
using Ombi.Core;
using Ombi.Core.Models;
using Ombi.Core.SettingModels;
using Ombi.Services.Interfaces;
using Ombi.Store;
namespace Ombi.Services.Notification
{
public class PushoverNotification : INotification
{
public PushoverNotification(IPushoverApi pushoverApi, ISettingsService<PushoverNotificationSettings> settings)
{
PushoverApi = pushoverApi;
SettingsService = settings;
}
private IPushoverApi PushoverApi { get; }
private ISettingsService<PushoverNotificationSettings> SettingsService { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
public string NotificationName => "PushoverNotification";
public async Task NotifyAsync(NotificationModel model)
{
var configuration = GetSettings();
await NotifyAsync(model, configuration);
}
public async Task NotifyAsync(NotificationModel model, Settings settings)
{
if (settings == null) await NotifyAsync(model);
var pushSettings = (PushoverNotificationSettings)settings;
if (!ValidateConfiguration(pushSettings)) return;
switch (model.NotificationType)
{
case NotificationType.NewRequest:
await PushNewRequestAsync(model, pushSettings);
break;
case NotificationType.Issue:
await PushIssueAsync(model, pushSettings);
break;
case NotificationType.RequestAvailable:
break;
case NotificationType.RequestApproved:
break;
case NotificationType.AdminNote:
break;
case NotificationType.Test:
await PushTestAsync(model, pushSettings);
break;
case NotificationType.RequestDeclined:
break;
case NotificationType.ItemAddedToFaultQueue:
await PushFaultQueue(model, pushSettings);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private bool ValidateConfiguration(PushoverNotificationSettings settings)
{
if (!settings.Enabled)
{
return false;
}
if (string.IsNullOrEmpty(settings.AccessToken) || string.IsNullOrEmpty(settings.UserToken))
{
return false;
}
return true;
}
private PushoverNotificationSettings GetSettings()
{
return SettingsService.GetSettings();
}
private async Task PushNewRequestAsync(NotificationModel model, PushoverNotificationSettings settings)
{
var message = $"Plex Requests: The {model.RequestType.GetString()?.ToLower()} '{model.Title}' has been requested by user: {model.User}";
await Push(settings, message);
}
private async Task PushIssueAsync(NotificationModel model, PushoverNotificationSettings settings)
{
var message = $"Plex Requests: A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
await Push(settings, message);
}
private async Task PushTestAsync(NotificationModel model, PushoverNotificationSettings settings)
{
var message = $"Plex Requests: Test Message!";
await Push(settings, message);
}
private async Task PushFaultQueue(NotificationModel model, PushoverNotificationSettings settings)
{
var message = $"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying";
await Push(settings, message);
}
private async Task Push(PushoverNotificationSettings settings, string message)
{
try
{
var result = await PushoverApi.PushAsync(settings.AccessToken, message, settings.UserToken);
if (result?.status != 1)
{
Log.Error("Pushover api returned a status that was not 1, the notification did not get pushed");
}
}
catch (Exception e)
{
Log.Error(e);
}
}
}
}

View file

@ -0,0 +1,166 @@
#region Copyright
// /************************************************************************
// Copyright (c) 2016 Jamie Rees
// File: SlackNotification.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 System;
using System.Threading.Tasks;
using NLog;
using Ombi.Api.Interfaces;
using Ombi.Api.Models.Notifications;
using Ombi.Core;
using Ombi.Core.Models;
using Ombi.Core.SettingModels;
using Ombi.Services.Interfaces;
namespace Ombi.Services.Notification
{
public class SlackNotification : INotification
{
public SlackNotification(ISlackApi api, ISettingsService<SlackNotificationSettings> sn)
{
Api = api;
Settings = sn;
}
public string NotificationName => "SlackNotification";
private ISlackApi Api { get; }
private ISettingsService<SlackNotificationSettings> Settings { get; }
private static Logger Log = LogManager.GetCurrentClassLogger();
public async Task NotifyAsync(NotificationModel model)
{
var settings = Settings.GetSettings();
await NotifyAsync(model, settings);
}
public async Task NotifyAsync(NotificationModel model, Settings settings)
{
if (settings == null) await NotifyAsync(model);
var pushSettings = (SlackNotificationSettings)settings;
if (!ValidateConfiguration(pushSettings))
{
Log.Error("Settings for Slack was not correct, we cannot push a notification");
return;
}
switch (model.NotificationType)
{
case NotificationType.NewRequest:
await PushNewRequestAsync(model, pushSettings);
break;
case NotificationType.Issue:
await PushIssueAsync(model, pushSettings);
break;
case NotificationType.RequestAvailable:
break;
case NotificationType.RequestApproved:
break;
case NotificationType.AdminNote:
break;
case NotificationType.Test:
await PushTest(pushSettings);
break;
case NotificationType.RequestDeclined:
break;
case NotificationType.ItemAddedToFaultQueue:
await PushFaultQueue(model, pushSettings);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private async Task PushNewRequestAsync(NotificationModel model, SlackNotificationSettings settings)
{
var message = $"{model.Title} has been requested by user: {model.User}";
await Push(settings, message);
}
private async Task PushIssueAsync(NotificationModel model, SlackNotificationSettings settings)
{
var message = $"A new issue: {model.Body} has been reported by user: {model.User} for the title: {model.Title}";
await Push(settings, message);
}
private async Task PushTest(SlackNotificationSettings settings)
{
var message = $"This is a test from Plex Requests, if you can see this then we have successfully pushed a notification!";
await Push(settings, message);
}
private async Task PushFaultQueue(NotificationModel model, SlackNotificationSettings settings)
{
var message = $"Hello! The user '{model.User}' has requested {model.Title} but it could not be added. This has been added into the requests queue and will keep retrying";
await Push(settings, message);
}
private async Task Push(SlackNotificationSettings config, string message)
{
try
{
var notification = new SlackNotificationBody { username = config.Username, channel = config.Channel ?? string.Empty, text = message };
var result = await Api.PushAsync(config.Team, config.Token, config.Service, notification);
if (!result.Equals("ok"))
{
Log.Error("Slack returned a message that was not 'ok', the notification did not get pushed");
Log.Error($"Message that slack returned: {result}");
}
}
catch (Exception e)
{
Log.Error(e);
}
}
private bool ValidateConfiguration(SlackNotificationSettings settings)
{
if (!settings.Enabled)
{
return false;
}
if (string.IsNullOrEmpty(settings.WebhookUrl))
{
return false;
}
try
{
var a = settings.Team;
var b = settings.Service;
var c = settings.Token;
}
catch (IndexOutOfRangeException)
{
return false;
}
return true;
}
}
}