NotificationManager.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using MediaBrowser.Common.Configuration;
  8. using MediaBrowser.Common.Extensions;
  9. using MediaBrowser.Controller.Configuration;
  10. using MediaBrowser.Controller.Entities;
  11. using MediaBrowser.Controller.Library;
  12. using MediaBrowser.Controller.Notifications;
  13. using MediaBrowser.Model.Dto;
  14. using MediaBrowser.Model.Notifications;
  15. using Microsoft.Extensions.Logging;
  16. namespace Emby.Notifications
  17. {
  18. public class NotificationManager : INotificationManager
  19. {
  20. private readonly ILogger _logger;
  21. private readonly IUserManager _userManager;
  22. private readonly IServerConfigurationManager _config;
  23. private INotificationService[] _services;
  24. private INotificationTypeFactory[] _typeFactories;
  25. public NotificationManager(ILoggerFactory loggerFactory, IUserManager userManager, IServerConfigurationManager config)
  26. {
  27. _userManager = userManager;
  28. _config = config;
  29. _logger = loggerFactory.CreateLogger(GetType().Name);
  30. }
  31. private NotificationOptions GetConfiguration()
  32. {
  33. return _config.GetConfiguration<NotificationOptions>("notifications");
  34. }
  35. public Task SendNotification(NotificationRequest request, CancellationToken cancellationToken)
  36. {
  37. return SendNotification(request, null, cancellationToken);
  38. }
  39. public Task SendNotification(NotificationRequest request, BaseItem relatedItem, CancellationToken cancellationToken)
  40. {
  41. var notificationType = request.NotificationType;
  42. var options = string.IsNullOrEmpty(notificationType) ?
  43. null :
  44. GetConfiguration().GetOptions(notificationType);
  45. var users = GetUserIds(request, options)
  46. .Select(i => _userManager.GetUserById(i))
  47. .Where(i => relatedItem == null || relatedItem.IsVisibleStandalone(i))
  48. .ToArray();
  49. var title = request.Name;
  50. var description = request.Description;
  51. var tasks = _services.Where(i => IsEnabled(i, notificationType))
  52. .Select(i => SendNotification(request, i, users, title, description, cancellationToken));
  53. return Task.WhenAll(tasks);
  54. }
  55. private Task SendNotification(NotificationRequest request,
  56. INotificationService service,
  57. IEnumerable<User> users,
  58. string title,
  59. string description,
  60. CancellationToken cancellationToken)
  61. {
  62. users = users.Where(i => IsEnabledForUser(service, i))
  63. .ToList();
  64. var tasks = users.Select(i => SendNotification(request, service, title, description, i, cancellationToken));
  65. return Task.WhenAll(tasks);
  66. }
  67. private IEnumerable<Guid> GetUserIds(NotificationRequest request, NotificationOption options)
  68. {
  69. if (request.SendToUserMode.HasValue)
  70. {
  71. switch (request.SendToUserMode.Value)
  72. {
  73. case SendToUserType.Admins:
  74. return _userManager.Users.Where(i => i.Policy.IsAdministrator)
  75. .Select(i => i.Id);
  76. case SendToUserType.All:
  77. return _userManager.UsersIds;
  78. case SendToUserType.Custom:
  79. return request.UserIds;
  80. default:
  81. throw new ArgumentException("Unrecognized SendToUserMode: " + request.SendToUserMode.Value);
  82. }
  83. }
  84. if (options != null && !string.IsNullOrEmpty(request.NotificationType))
  85. {
  86. var config = GetConfiguration();
  87. return _userManager.Users
  88. .Where(i => config.IsEnabledToSendToUser(request.NotificationType, i.Id.ToString("N", CultureInfo.InvariantCulture), i.Policy))
  89. .Select(i => i.Id);
  90. }
  91. return request.UserIds;
  92. }
  93. private async Task SendNotification(NotificationRequest request,
  94. INotificationService service,
  95. string title,
  96. string description,
  97. User user,
  98. CancellationToken cancellationToken)
  99. {
  100. var notification = new UserNotification
  101. {
  102. Date = request.Date,
  103. Description = description,
  104. Level = request.Level,
  105. Name = title,
  106. Url = request.Url,
  107. User = user
  108. };
  109. _logger.LogDebug("Sending notification via {0} to user {1}", service.Name, user.Name);
  110. try
  111. {
  112. await service.SendNotification(notification, cancellationToken).ConfigureAwait(false);
  113. }
  114. catch (Exception ex)
  115. {
  116. _logger.LogError(ex, "Error sending notification to {0}", service.Name);
  117. }
  118. }
  119. private bool IsEnabledForUser(INotificationService service, User user)
  120. {
  121. try
  122. {
  123. return service.IsEnabledForUser(user);
  124. }
  125. catch (Exception ex)
  126. {
  127. _logger.LogError(ex, "Error in IsEnabledForUser");
  128. return false;
  129. }
  130. }
  131. private bool IsEnabled(INotificationService service, string notificationType)
  132. {
  133. if (string.IsNullOrEmpty(notificationType))
  134. {
  135. return true;
  136. }
  137. return GetConfiguration().IsServiceEnabled(service.Name, notificationType);
  138. }
  139. public void AddParts(IEnumerable<INotificationService> services, IEnumerable<INotificationTypeFactory> notificationTypeFactories)
  140. {
  141. _services = services.ToArray();
  142. _typeFactories = notificationTypeFactories.ToArray();
  143. }
  144. public List<NotificationTypeInfo> GetNotificationTypes()
  145. {
  146. var list = _typeFactories.Select(i =>
  147. {
  148. try
  149. {
  150. return i.GetNotificationTypes().ToList();
  151. }
  152. catch (Exception ex)
  153. {
  154. _logger.LogError(ex, "Error in GetNotificationTypes");
  155. return new List<NotificationTypeInfo>();
  156. }
  157. }).SelectMany(i => i).ToList();
  158. var config = GetConfiguration();
  159. foreach (var i in list)
  160. {
  161. i.Enabled = config.IsEnabled(i.Type);
  162. }
  163. return list;
  164. }
  165. public IEnumerable<NameIdPair> GetNotificationServices()
  166. {
  167. return _services.Select(i => new NameIdPair
  168. {
  169. Name = i.Name,
  170. Id = i.Name.GetMD5().ToString("N", CultureInfo.InvariantCulture)
  171. }).OrderBy(i => i.Name);
  172. }
  173. }
  174. }