diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 2b5b278041..15fe4a1771 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -37,7 +37,6 @@ namespace MediaBrowser.Api.Library } [Route("/Videos/{Id}/Subtitles/{Index}", "GET")] - [Route("/Videos/{Id}/Subtitles/{Index}/stream.srt", "GET")] [Api(Description = "Gets an external subtitle file")] public class GetSubtitle { diff --git a/MediaBrowser.Model/Configuration/NotificationOptions.cs b/MediaBrowser.Model/Configuration/NotificationOptions.cs index 4c0c092fe3..84352e7fd5 100644 --- a/MediaBrowser.Model/Configuration/NotificationOptions.cs +++ b/MediaBrowser.Model/Configuration/NotificationOptions.cs @@ -14,42 +14,50 @@ namespace MediaBrowser.Model.Configuration new NotificationOption { Type = NotificationType.TaskFailed.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins }, new NotificationOption { Type = NotificationType.ServerRestartRequired.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins }, new NotificationOption { Type = NotificationType.ApplicationUpdateAvailable.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins }, new NotificationOption { Type = NotificationType.ApplicationUpdateInstalled.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins }, new NotificationOption { Type = NotificationType.PluginUpdateInstalled.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins }, new NotificationOption { Type = NotificationType.PluginUninstalled.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins }, new NotificationOption { Type = NotificationType.InstallationFailed.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins }, new NotificationOption { Type = NotificationType.PluginInstalled.ToString(), - Enabled = true + Enabled = true, + SendToUserMode = SendToUserType.Admins } }; } @@ -82,12 +90,26 @@ namespace MediaBrowser.Model.Configuration !opt.DisabledMonitorUsers.Contains(userId, StringComparer.OrdinalIgnoreCase); } - public bool IsEnabledToSendToUser(string type, string userId) + public bool IsEnabledToSendToUser(string type, string userId, UserConfiguration userConfig) { var opt = GetOptions(type); - return opt != null && opt.Enabled && - !opt.DisabledSendToUsers.Contains(userId, StringComparer.OrdinalIgnoreCase); + if (opt != null && opt.Enabled) + { + if (opt.SendToUserMode == SendToUserType.All) + { + return true; + } + + if (opt.SendToUserMode == SendToUserType.Admins && userConfig.IsAdministrator) + { + return true; + } + + return opt.SendToUsers.Contains(userId, StringComparer.OrdinalIgnoreCase); + } + + return false; } } @@ -101,9 +123,9 @@ namespace MediaBrowser.Model.Configuration public string[] DisabledMonitorUsers { get; set; } /// - /// User Ids to not send to (it's opt out) + /// User Ids to send to (if SendToUserMode == Custom) /// - public string[] DisabledSendToUsers { get; set; } + public string[] SendToUsers { get; set; } /// /// Gets or sets a value indicating whether this is enabled. @@ -122,28 +144,41 @@ namespace MediaBrowser.Model.Configuration /// /// The disabled services. public string[] DisabledServices { get; set; } - + + /// + /// Gets or sets the send to user mode. + /// + /// The send to user mode. + public SendToUserType SendToUserMode { get; set; } + public NotificationOption() { DisabledServices = new string[] { }; DisabledMonitorUsers = new string[] { }; - DisabledSendToUsers = new string[] { }; + SendToUsers = new string[] { }; } } public enum NotificationType { - TaskFailed, - InstallationFailed, - NewLibraryContent, - ServerRestartRequired, ApplicationUpdateAvailable, ApplicationUpdateInstalled, + AudioPlayback, + GamePlayback, + InstallationFailed, PluginInstalled, PluginUpdateInstalled, PluginUninstalled, - AudioPlayback, - GamePlayback, + NewLibraryContent, + ServerRestartRequired, + TaskFailed, VideoPlayback } + + public enum SendToUserType + { + All = 0, + Admins = 1, + Custom = 2 + } } diff --git a/MediaBrowser.Model/Notifications/Notification.cs b/MediaBrowser.Model/Notifications/Notification.cs index 9b42d8a748..e69875a68a 100644 --- a/MediaBrowser.Model/Notifications/Notification.cs +++ b/MediaBrowser.Model/Notifications/Notification.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using MediaBrowser.Model.Configuration; namespace MediaBrowser.Model.Notifications { @@ -48,6 +49,8 @@ namespace MediaBrowser.Model.Notifications public Dictionary Variables { get; set; } + public SendToUserType? SendToUserMode { get; set; } + public NotificationRequest() { UserIds = new List(); diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs index dd2c5bf854..06dcf92ff8 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs @@ -75,15 +75,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications var installationInfo = e.Argument.Item1; - var userIds = _userManager - .Users - .Where(i => i.Configuration.IsAdministrator && _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var notification = new NotificationRequest { - UserIds = userIds, Description = installationInfo.Description, NotificationType = type }; @@ -100,15 +93,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications var installationInfo = e.Argument; - var userIds = _userManager - .Users - .Where(i => i.Configuration.IsAdministrator && _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var notification = new NotificationRequest { - UserIds = userIds, Description = installationInfo.description, NotificationType = type }; @@ -129,15 +115,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications var type = NotificationType.ApplicationUpdateAvailable.ToString(); - var userIds = _userManager - .Users - .Where(i => i.Configuration.IsAdministrator && _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var notification = new NotificationRequest { - UserIds = userIds, Description = "Please see mediabrowser3.com for details.", NotificationType = type }; @@ -154,15 +133,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications var type = NotificationType.ServerRestartRequired.ToString(); - var userIds = _userManager - .Users - .Where(i => i.Configuration.IsAdministrator && _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var notification = new NotificationRequest { - UserIds = userIds, NotificationType = type }; @@ -173,17 +145,11 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { var user = e.Users.FirstOrDefault(); - var userIds = _userManager - .Users - .Where(i => NotifyOnPlayback(e.MediaInfo.MediaType, user, i)) - .Select(i => i.Id.ToString("N")) - .ToList(); - var item = e.MediaInfo; var notification = new NotificationRequest { - UserIds = userIds + NotificationType = GetPlaybackNotificationType(item.MediaType) }; notification.Variables["ItemName"] = item.Name; @@ -193,71 +159,23 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications await SendNotification(notification).ConfigureAwait(false); } - - private bool NotifyOnPlayback(string mediaType, User playingUser, User notifiedUser) + + private string GetPlaybackNotificationType(string mediaType) { if (string.Equals(mediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)) { - var type = NotificationType.AudioPlayback.ToString(); - - if (playingUser != null) - { - if (!_config.Configuration.NotificationOptions.IsEnabledToMonitorUser( - type, playingUser.Id.ToString("N"))) - { - return false; - } - - if (playingUser.Id == notifiedUser.Id) - { - return false; - } - } - - return _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, notifiedUser.Id.ToString("N")); + return NotificationType.AudioPlayback.ToString(); } if (string.Equals(mediaType, MediaType.Game, StringComparison.OrdinalIgnoreCase)) { - var type = NotificationType.GamePlayback.ToString(); - - if (playingUser != null) - { - if (!_config.Configuration.NotificationOptions.IsEnabledToMonitorUser( - type, playingUser.Id.ToString("N"))) - { - return false; - } - - if (playingUser.Id == notifiedUser.Id) - { - return false; - } - } - - return _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, notifiedUser.Id.ToString("N")); + return NotificationType.GamePlayback.ToString(); } if (string.Equals(mediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase)) { - var type = NotificationType.VideoPlayback.ToString(); - - if (playingUser != null) - { - if (!_config.Configuration.NotificationOptions.IsEnabledToMonitorUser( - type, playingUser.Id.ToString("N"))) - { - return false; - } - - if (playingUser.Id == notifiedUser.Id) - { - return false; - } - } - - return _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, notifiedUser.Id.ToString("N")); + return NotificationType.VideoPlayback.ToString(); } - return false; + return null; } async void _libraryManager_ItemAdded(object sender, ItemChangeEventArgs e) @@ -266,17 +184,10 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { var type = NotificationType.NewLibraryContent.ToString(); - var userIds = _userManager - .Users - .Where(i => _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var item = e.Item; var notification = new NotificationRequest { - UserIds = userIds, NotificationType = type }; @@ -306,15 +217,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { var type = NotificationType.TaskFailed.ToString(); - var userIds = _userManager - .Users - .Where(i => i.Configuration.IsAdministrator && _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var notification = new NotificationRequest { - UserIds = userIds, Description = result.ErrorMessage, Level = NotificationLevel.Error, NotificationType = type @@ -332,15 +236,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications var plugin = e.Argument; - var userIds = _userManager - .Users - .Where(i => i.Configuration.IsAdministrator && _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var notification = new NotificationRequest { - UserIds = userIds, NotificationType = type }; @@ -356,15 +253,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications var type = NotificationType.InstallationFailed.ToString(); - var userIds = _userManager - .Users - .Where(i => i.Configuration.IsAdministrator && _config.Configuration.NotificationOptions.IsEnabledToSendToUser(type, i.Id.ToString("N"))) - .Select(i => i.Id.ToString("N")) - .ToList(); - var notification = new NotificationRequest { - UserIds = userIds, Level = NotificationLevel.Error, Description = e.Exception.Message, NotificationType = type diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json index 18c2ca577d..37d4f27447 100644 --- a/MediaBrowser.Server.Implementations/Localization/Server/server.json +++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json @@ -77,6 +77,7 @@ "MaxParentalRatingHelp": "Content with a higher rating will be hidden from this user.", "LibraryAccessHelp": "Select the media folders to share with this user. Administrators will be able to edit all folders using the metadata manager.", "ButtonDeleteImage": "Delete Image", + "LabelSelectUsers": "Select users:", "ButtonUpload": "Upload", "HeaderUploadNewImage": "Upload New Image", "LabelDropImageHere": "Drop Image Here", @@ -579,5 +580,8 @@ "CategorySystem": "System", "LabelMessageTitle": "Message title:", "LabelAvailableTokens": "Available tokens:", - "AdditionalNotificationServices": "Browse the plugin catalog to install additional notification services." + "AdditionalNotificationServices": "Browse the plugin catalog to install additional notification services.", + "OptionAllUsers": "All users", + "OptionAdminUsers": "Administrators", + "OptionCustomUsers": "Custom" } \ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs b/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs index bf5228dd99..cfda23a654 100644 --- a/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs +++ b/MediaBrowser.Server.Implementations/Notifications/CoreNotificationTypes.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller.Localization; +using MediaBrowser.Controller; +using MediaBrowser.Controller.Localization; using MediaBrowser.Controller.Notifications; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Notifications; @@ -11,22 +12,18 @@ namespace MediaBrowser.Server.Implementations.Notifications public class CoreNotificationTypes : INotificationTypeFactory { private readonly ILocalizationManager _localization; + private readonly IServerApplicationHost _appHost; - public CoreNotificationTypes(ILocalizationManager localization) + public CoreNotificationTypes(ILocalizationManager localization, IServerApplicationHost appHost) { _localization = localization; + _appHost = appHost; } public IEnumerable GetNotificationTypes() { var knownTypes = new List { - new NotificationTypeInfo - { - Type = NotificationType.ApplicationUpdateAvailable.ToString(), - DefaultTitle = "A new version of Media Browser Server is available for download." - }, - new NotificationTypeInfo { Type = NotificationType.ApplicationUpdateInstalled.ToString(), @@ -104,6 +101,15 @@ namespace MediaBrowser.Server.Implementations.Notifications } }; + if (!_appHost.CanSelfUpdate) + { + knownTypes.Add(new NotificationTypeInfo + { + Type = NotificationType.ApplicationUpdateAvailable.ToString(), + DefaultTitle = "A new version of Media Browser Server is available for download." + }); + } + foreach (var type in knownTypes) { Update(type); diff --git a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs index ff8d35e284..300d2c351e 100644 --- a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs +++ b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Notifications; +using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Notifications; using System; @@ -31,11 +32,15 @@ namespace MediaBrowser.Server.Implementations.Notifications public Task SendNotification(NotificationRequest request, CancellationToken cancellationToken) { - var users = request.UserIds.Select(i => _userManager.GetUserById(new Guid(i))); - var notificationType = request.NotificationType; - var title = GetTitle(request); + var options = string.IsNullOrWhiteSpace(notificationType) ? + null : + _config.Configuration.NotificationOptions.GetOptions(notificationType); + + var users = GetUserIds(request, options).Select(i => _userManager.GetUserById(new Guid(i))); + + var title = GetTitle(request, options); var tasks = _services.Where(i => IsEnabled(i, notificationType)) .Select(i => SendNotification(request, i, users, title, cancellationToken)); @@ -58,6 +63,43 @@ namespace MediaBrowser.Server.Implementations.Notifications } + private IEnumerable GetUserIds(NotificationRequest request, NotificationOption options) + { + if (request.SendToUserMode.HasValue) + { + switch (request.SendToUserMode.Value) + { + case SendToUserType.Admins: + return _userManager.Users.Where(i => i.Configuration.IsAdministrator) + .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); + } + } + + if (options != null) + { + switch (options.SendToUserMode) + { + case SendToUserType.Admins: + return _userManager.Users.Where(i => i.Configuration.IsAdministrator) + .Select(i => i.Id.ToString("N")); + case SendToUserType.All: + return _userManager.Users.Select(i => i.Id.ToString("N")); + case SendToUserType.Custom: + return options.SendToUsers; + default: + throw new ArgumentException("Unrecognized SendToUserMode: " + options.SendToUserMode); + } + } + + return new List(); + } + private async Task SendNotification(NotificationRequest request, INotificationService service, string title, @@ -86,7 +128,7 @@ namespace MediaBrowser.Server.Implementations.Notifications } } - private string GetTitle(NotificationRequest request) + private string GetTitle(NotificationRequest request, NotificationOption options) { var title = request.Name; @@ -95,8 +137,6 @@ namespace MediaBrowser.Server.Implementations.Notifications { if (!string.IsNullOrEmpty(request.NotificationType)) { - var options = _config.Configuration.NotificationOptions.GetOptions(request.NotificationType); - if (options != null) { title = options.Title;