jellyfin/Emby.Notifications/NotificationManager.cs

225 lines
7.6 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
2020-05-20 19:07:53 +02:00
using Jellyfin.Data.Entities;
2020-05-13 04:10:35 +02:00
using Jellyfin.Data.Enums;
using MediaBrowser.Common.Configuration;
2014-07-02 20:34:08 +02:00
using MediaBrowser.Common.Extensions;
2014-04-27 05:42:05 +02:00
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
2014-04-25 22:15:50 +02:00
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Notifications;
2018-09-12 19:26:21 +02:00
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Notifications;
using Microsoft.Extensions.Logging;
2014-04-25 22:15:50 +02:00
2018-09-12 19:26:21 +02:00
namespace Emby.Notifications
2014-04-25 22:15:50 +02:00
{
/// <summary>
/// NotificationManager class.
/// </summary>
2014-04-25 22:15:50 +02:00
public class NotificationManager : INotificationManager
{
2020-06-06 02:15:56 +02:00
private readonly ILogger<NotificationManager> _logger;
2014-04-25 22:15:50 +02:00
private readonly IUserManager _userManager;
2014-04-27 05:42:05 +02:00
private readonly IServerConfigurationManager _config;
private INotificationService[] _services = Array.Empty<INotificationService>();
private INotificationTypeFactory[] _typeFactories = Array.Empty<INotificationTypeFactory>();
/// <summary>
/// Initializes a new instance of the <see cref="NotificationManager" /> class.
/// </summary>
/// <param name="logger">The logger.</param>
2020-02-08 22:25:44 +01:00
/// <param name="userManager">The user manager.</param>
/// <param name="config">The server configuration manager.</param>
public NotificationManager(
ILogger<NotificationManager> logger,
IUserManager userManager,
IServerConfigurationManager config)
2014-04-25 22:15:50 +02:00
{
_logger = logger;
2014-04-25 22:15:50 +02:00
_userManager = userManager;
2014-04-27 05:42:05 +02:00
_config = config;
2014-04-25 22:15:50 +02:00
}
2014-07-02 20:34:08 +02:00
private NotificationOptions GetConfiguration()
{
return _config.GetConfiguration<NotificationOptions>("notifications");
}
/// <inheritdoc />
2014-04-25 22:15:50 +02:00
public Task SendNotification(NotificationRequest request, CancellationToken cancellationToken)
{
return SendNotification(request, null, cancellationToken);
}
/// <inheritdoc />
public Task SendNotification(NotificationRequest request, BaseItem? relatedItem, CancellationToken cancellationToken)
2014-04-25 22:15:50 +02:00
{
2014-04-27 05:42:05 +02:00
var notificationType = request.NotificationType;
2018-09-12 19:26:21 +02:00
var options = string.IsNullOrEmpty(notificationType) ?
2014-04-27 19:54:43 +02:00
null :
2014-07-02 20:34:08 +02:00
GetConfiguration().GetOptions(notificationType);
2014-04-27 19:54:43 +02:00
2014-04-27 21:30:12 +02:00
var users = GetUserIds(request, options)
.Select(i => _userManager.GetUserById(i))
2022-12-05 15:00:20 +01:00
.Where(i => relatedItem is null || relatedItem.IsVisibleStandalone(i))
.ToArray();
2014-04-27 19:54:43 +02:00
2018-09-12 19:26:21 +02:00
var title = request.Name;
var description = request.Description;
2014-04-27 05:42:05 +02:00
var tasks = _services.Where(i => IsEnabled(i, notificationType))
2014-05-01 05:24:55 +02:00
.Select(i => SendNotification(request, i, users, title, description, cancellationToken));
2014-04-25 22:15:50 +02:00
return Task.WhenAll(tasks);
}
private Task SendNotification(
NotificationRequest request,
2014-04-25 22:15:50 +02:00
INotificationService service,
2020-05-20 19:07:53 +02:00
IEnumerable<User> users,
2014-04-27 05:42:05 +02:00
string title,
2014-04-30 17:07:02 +02:00
string description,
2014-04-25 22:15:50 +02:00
CancellationToken cancellationToken)
{
2022-01-04 17:05:36 +01:00
users = users.Where(i => IsEnabledForUser(service, i));
2014-04-25 22:15:50 +02:00
2014-04-30 17:07:02 +02:00
var tasks = users.Select(i => SendNotification(request, service, title, description, i, cancellationToken));
2014-04-25 22:15:50 +02:00
return Task.WhenAll(tasks);
}
private IEnumerable<Guid> GetUserIds(NotificationRequest request, NotificationOption? options)
2014-04-27 19:54:43 +02:00
{
if (request.SendToUserMode.HasValue)
{
switch (request.SendToUserMode.Value)
{
case SendToUserType.Admins:
2020-05-13 04:10:35 +02:00
return _userManager.Users.Where(i => i.HasPermission(PermissionKind.IsAdministrator))
2018-09-12 19:26:21 +02:00
.Select(i => i.Id);
2014-04-27 19:54:43 +02:00
case SendToUserType.All:
2019-06-09 22:08:01 +02:00
return _userManager.UsersIds;
2014-04-27 19:54:43 +02:00
case SendToUserType.Custom:
return request.UserIds;
default:
throw new ArgumentException("Unrecognized SendToUserMode: " + request.SendToUserMode.Value);
}
}
2022-12-05 15:01:13 +01:00
if (options is not null && !string.IsNullOrEmpty(request.NotificationType))
2014-04-27 19:54:43 +02:00
{
var config = GetConfiguration();
2014-07-18 02:39:07 +02:00
return _userManager.Users
2020-05-13 04:10:35 +02:00
.Where(i => config.IsEnabledToSendToUser(request.NotificationType, i.Id.ToString("N", CultureInfo.InvariantCulture), i))
2018-09-12 19:26:21 +02:00
.Select(i => i.Id);
2014-04-27 19:54:43 +02:00
}
2014-04-30 17:07:02 +02:00
return request.UserIds;
2014-04-27 19:54:43 +02:00
}
private async Task SendNotification(
NotificationRequest request,
2014-04-25 22:15:50 +02:00
INotificationService service,
2014-04-27 05:42:05 +02:00
string title,
2014-04-30 17:07:02 +02:00
string description,
2020-05-20 19:07:53 +02:00
User user,
2014-04-25 22:15:50 +02:00
CancellationToken cancellationToken)
{
var notification = new UserNotification
{
Date = request.Date,
2014-04-30 17:07:02 +02:00
Description = description,
2014-04-25 22:15:50 +02:00
Level = request.Level,
2014-04-27 05:42:05 +02:00
Name = title,
2014-04-25 22:15:50 +02:00
Url = request.Url,
User = user
};
2020-05-13 04:10:35 +02:00
_logger.LogDebug("Sending notification via {0} to user {1}", service.Name, user.Username);
2014-04-27 05:42:05 +02:00
2014-04-25 22:15:50 +02:00
try
{
await service.SendNotification(notification, cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
2018-12-20 13:11:26 +01:00
_logger.LogError(ex, "Error sending notification to {0}", service.Name);
2014-04-25 22:15:50 +02:00
}
}
2020-05-20 19:07:53 +02:00
private bool IsEnabledForUser(INotificationService service, User user)
2014-04-25 22:15:50 +02:00
{
try
{
return service.IsEnabledForUser(user);
}
catch (Exception ex)
{
2018-12-20 13:11:26 +01:00
_logger.LogError(ex, "Error in IsEnabledForUser");
2014-04-25 22:15:50 +02:00
return false;
}
}
2014-04-27 05:42:05 +02:00
private bool IsEnabled(INotificationService service, string notificationType)
{
2015-09-20 04:06:56 +02:00
if (string.IsNullOrEmpty(notificationType))
{
return true;
}
return GetConfiguration().IsServiceEnabled(service.Name, notificationType);
2014-04-27 05:42:05 +02:00
}
/// <inheritdoc />
2014-04-27 05:42:05 +02:00
public void AddParts(IEnumerable<INotificationService> services, IEnumerable<INotificationTypeFactory> notificationTypeFactories)
2014-04-25 22:15:50 +02:00
{
_services = services.ToArray();
2014-04-27 05:42:05 +02:00
_typeFactories = notificationTypeFactories.ToArray();
}
/// <inheritdoc />
2017-08-19 21:43:35 +02:00
public List<NotificationTypeInfo> GetNotificationTypes()
2014-04-27 05:42:05 +02:00
{
var list = _typeFactories.Select(i =>
{
try
{
return i.GetNotificationTypes().ToList();
}
catch (Exception ex)
{
2018-12-20 13:11:26 +01:00
_logger.LogError(ex, "Error in GetNotificationTypes");
2014-04-27 05:42:05 +02:00
return new List<NotificationTypeInfo>();
}
}).SelectMany(i => i).ToList();
2014-07-02 20:34:08 +02:00
var config = GetConfiguration();
2014-04-27 05:42:05 +02:00
foreach (var i in list)
{
2014-07-02 20:34:08 +02:00
i.Enabled = config.IsEnabled(i.Type);
2014-04-27 05:42:05 +02:00
}
return list;
}
/// <inheritdoc />
2018-09-12 19:26:21 +02:00
public IEnumerable<NameIdPair> GetNotificationServices()
2014-04-27 05:42:05 +02:00
{
2018-09-12 19:26:21 +02:00
return _services.Select(i => new NameIdPair
2014-04-27 05:42:05 +02:00
{
Name = i.Name,
Id = i.Name.GetMD5().ToString("N", CultureInfo.InvariantCulture)
2014-04-27 05:42:05 +02:00
}).OrderBy(i => i.Name);
2014-04-25 22:15:50 +02:00
}
}
}