jellyfin/Emby.Server.Implementations/Notifications/NotificationManager.cs

303 lines
10 KiB
C#
Raw Normal View History

2014-07-02 18:34:08 +00:00
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
2014-04-27 03:42:05 +00:00
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
2014-04-25 20:15:50 +00:00
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Notifications;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Notifications;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
2015-01-17 20:12:02 +00:00
using MediaBrowser.Model.Extensions;
2014-04-25 20:15:50 +00:00
2016-11-03 07:35:00 +00:00
namespace Emby.Server.Implementations.Notifications
2014-04-25 20:15:50 +00:00
{
public class NotificationManager : INotificationManager
{
private readonly ILogger _logger;
private readonly IUserManager _userManager;
2014-04-27 03:42:05 +00:00
private readonly IServerConfigurationManager _config;
2014-04-25 20:15:50 +00:00
private INotificationService[] _services;
2014-04-27 03:42:05 +00:00
private INotificationTypeFactory[] _typeFactories;
2014-04-25 20:15:50 +00:00
2014-04-27 03:42:05 +00:00
public NotificationManager(ILogManager logManager, IUserManager userManager, IServerConfigurationManager config)
2014-04-25 20:15:50 +00:00
{
_userManager = userManager;
2014-04-27 03:42:05 +00:00
_config = config;
2014-04-25 20:15:50 +00:00
_logger = logManager.GetLogger(GetType().Name);
}
2014-07-02 18:34:08 +00:00
private NotificationOptions GetConfiguration()
{
return _config.GetConfiguration<NotificationOptions>("notifications");
}
2014-04-25 20:15:50 +00:00
public Task SendNotification(NotificationRequest request, CancellationToken cancellationToken)
{
return SendNotification(request, null, cancellationToken);
}
public Task SendNotification(NotificationRequest request, BaseItem relatedItem, CancellationToken cancellationToken)
2014-04-25 20:15:50 +00:00
{
2014-04-27 03:42:05 +00:00
var notificationType = request.NotificationType;
2014-04-27 17:54:43 +00:00
var options = string.IsNullOrWhiteSpace(notificationType) ?
null :
2014-07-02 18:34:08 +00:00
GetConfiguration().GetOptions(notificationType);
2014-04-27 17:54:43 +00:00
2014-04-27 19:30:12 +00:00
var users = GetUserIds(request, options)
.Select(i => _userManager.GetUserById(i))
.Where(i => relatedItem == null || relatedItem.IsVisibleStandalone(i))
.ToArray();
2014-04-27 17:54:43 +00:00
var title = GetTitle(request, options);
2014-04-30 15:07:02 +00:00
var description = GetDescription(request, options);
2014-04-27 03:42:05 +00:00
var tasks = _services.Where(i => IsEnabled(i, notificationType))
2014-05-01 03:24:55 +00:00
.Select(i => SendNotification(request, i, users, title, description, cancellationToken));
2014-04-25 20:15:50 +00:00
return Task.WhenAll(tasks);
}
2014-04-27 03:42:05 +00:00
private Task SendNotification(NotificationRequest request,
2014-04-25 20:15:50 +00:00
INotificationService service,
IEnumerable<User> users,
2014-04-27 03:42:05 +00:00
string title,
2014-04-30 15:07:02 +00:00
string description,
2014-04-25 20:15:50 +00:00
CancellationToken cancellationToken)
{
users = users.Where(i => IsEnabledForUser(service, i))
.ToList();
2014-04-30 15:07:02 +00:00
var tasks = users.Select(i => SendNotification(request, service, title, description, i, cancellationToken));
2014-04-25 20:15:50 +00:00
return Task.WhenAll(tasks);
}
2014-04-27 17:54:43 +00:00
private IEnumerable<string> GetUserIds(NotificationRequest request, NotificationOption options)
{
if (request.SendToUserMode.HasValue)
{
switch (request.SendToUserMode.Value)
{
case SendToUserType.Admins:
2014-12-20 06:06:27 +00:00
return _userManager.Users.Where(i => i.Policy.IsAdministrator)
2014-04-27 17:54:43 +00:00
.Select(i => i.Id.ToString("N"));
case SendToUserType.All:
return _userManager.Users.Select(i => i.Id.ToString("N"));
case SendToUserType.Custom:
return request.UserIds;
default:
throw new ArgumentException("Unrecognized SendToUserMode: " + request.SendToUserMode.Value);
}
}
2014-04-27 19:30:12 +00:00
if (options != null && !string.IsNullOrWhiteSpace(request.NotificationType))
2014-04-27 17:54:43 +00:00
{
var config = GetConfiguration();
2014-07-18 00:39:07 +00:00
return _userManager.Users
2015-04-01 04:23:34 +00:00
.Where(i => config.IsEnabledToSendToUser(request.NotificationType, i.Id.ToString("N"), i.Policy))
2014-07-18 00:39:07 +00:00
.Select(i => i.Id.ToString("N"));
2014-04-27 17:54:43 +00:00
}
2014-04-30 15:07:02 +00:00
return request.UserIds;
2014-04-27 17:54:43 +00:00
}
2014-04-27 03:42:05 +00:00
private async Task SendNotification(NotificationRequest request,
2014-04-25 20:15:50 +00:00
INotificationService service,
2014-04-27 03:42:05 +00:00
string title,
2014-04-30 15:07:02 +00:00
string description,
2014-04-25 20:15:50 +00:00
User user,
CancellationToken cancellationToken)
{
var notification = new UserNotification
{
Date = request.Date,
2014-04-30 15:07:02 +00:00
Description = description,
2014-04-25 20:15:50 +00:00
Level = request.Level,
2014-04-27 03:42:05 +00:00
Name = title,
2014-04-25 20:15:50 +00:00
Url = request.Url,
User = user
};
_logger.Debug("Sending notification via {0} to user {1}", service.Name, user.Name);
2014-04-27 03:42:05 +00:00
2014-04-25 20:15:50 +00:00
try
{
await service.SendNotification(notification, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.ErrorException("Error sending notification to {0}", ex, service.Name);
}
}
2014-04-27 17:54:43 +00:00
private string GetTitle(NotificationRequest request, NotificationOption options)
2014-04-27 03:42:05 +00:00
{
var title = request.Name;
// If empty, grab from options
if (string.IsNullOrEmpty(title))
{
if (!string.IsNullOrEmpty(request.NotificationType))
{
if (options != null)
{
title = options.Title;
}
}
}
// If still empty, grab default
if (string.IsNullOrEmpty(title))
{
if (!string.IsNullOrEmpty(request.NotificationType))
{
var info = GetNotificationTypes().FirstOrDefault(i => string.Equals(i.Type, request.NotificationType, StringComparison.OrdinalIgnoreCase));
if (info != null)
{
title = info.DefaultTitle;
}
}
}
title = title ?? string.Empty;
foreach (var pair in request.Variables)
{
var token = "{" + pair.Key + "}";
title = title.Replace(token, pair.Value, StringComparison.OrdinalIgnoreCase);
}
return title;
}
2014-04-30 15:07:02 +00:00
private string GetDescription(NotificationRequest request, NotificationOption options)
{
var text = request.Description;
// If empty, grab from options
if (string.IsNullOrEmpty(text))
{
if (!string.IsNullOrEmpty(request.NotificationType))
{
if (options != null)
{
2014-05-01 03:24:55 +00:00
text = options.Description;
2014-04-30 15:07:02 +00:00
}
}
}
// If still empty, grab default
if (string.IsNullOrEmpty(text))
{
if (!string.IsNullOrEmpty(request.NotificationType))
{
var info = GetNotificationTypes().FirstOrDefault(i => string.Equals(i.Type, request.NotificationType, StringComparison.OrdinalIgnoreCase));
if (info != null)
{
text = info.DefaultDescription;
}
}
}
text = text ?? string.Empty;
foreach (var pair in request.Variables)
{
var token = "{" + pair.Key + "}";
text = text.Replace(token, pair.Value, StringComparison.OrdinalIgnoreCase);
}
return text;
}
2014-04-25 20:15:50 +00:00
private bool IsEnabledForUser(INotificationService service, User user)
{
try
{
return service.IsEnabledForUser(user);
}
catch (Exception ex)
{
_logger.ErrorException("Error in IsEnabledForUser", ex);
return false;
}
}
2014-04-27 03:42:05 +00:00
private bool IsEnabled(INotificationService service, string notificationType)
{
2015-09-20 02:06:56 +00:00
if (string.IsNullOrEmpty(notificationType))
{
return true;
}
var configurable = service as IConfigurableNotificationService;
if (configurable != null)
{
return configurable.IsEnabled(notificationType);
}
return GetConfiguration().IsServiceEnabled(service.Name, notificationType);
2014-04-27 03:42:05 +00:00
}
public void AddParts(IEnumerable<INotificationService> services, IEnumerable<INotificationTypeFactory> notificationTypeFactories)
2014-04-25 20:15:50 +00:00
{
_services = services.ToArray();
2014-04-27 03:42:05 +00:00
_typeFactories = notificationTypeFactories.ToArray();
}
2017-08-19 19:43:35 +00:00
public List<NotificationTypeInfo> GetNotificationTypes()
2014-04-27 03:42:05 +00:00
{
var list = _typeFactories.Select(i =>
{
try
{
return i.GetNotificationTypes().ToList();
}
catch (Exception ex)
{
_logger.ErrorException("Error in GetNotificationTypes", ex);
return new List<NotificationTypeInfo>();
}
}).SelectMany(i => i).ToList();
2014-07-02 18:34:08 +00:00
var config = GetConfiguration();
2014-04-27 03:42:05 +00:00
foreach (var i in list)
{
2014-07-02 18:34:08 +00:00
i.Enabled = config.IsEnabled(i.Type);
2014-04-27 03:42:05 +00:00
}
return list;
}
public IEnumerable<NotificationServiceInfo> GetNotificationServices()
{
2015-09-20 02:06:56 +00:00
return _services.Where(i =>
{
var configurable = i as IConfigurableNotificationService;
return configurable == null || !configurable.IsHidden;
}).Select(i => new NotificationServiceInfo
2014-04-27 03:42:05 +00:00
{
Name = i.Name,
Id = i.Name.GetMD5().ToString("N")
}).OrderBy(i => i.Name);
2014-04-25 20:15:50 +00:00
}
}
}