diff options
34 files changed, 451 insertions, 319 deletions
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs index 562da40ee..e85a5a680 100644 --- a/MediaBrowser.Api/Images/ImageService.cs +++ b/MediaBrowser.Api/Images/ImageService.cs @@ -358,7 +358,7 @@ namespace MediaBrowser.Api.Images /// <returns>System.Object.</returns> public object Get(GetItemImageInfos request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var result = GetItemImageInfos(item); @@ -493,7 +493,9 @@ namespace MediaBrowser.Api.Images /// <returns>System.Object.</returns> public object Get(GetItemImage request) { - var item = string.IsNullOrEmpty(request.Id) ? _libraryManager.RootFolder : _dtoService.GetItemByDtoId(request.Id); + var item = string.IsNullOrEmpty(request.Id) ? + _libraryManager.RootFolder : + _libraryManager.GetItemById(request.Id); return GetImage(request, item); } diff --git a/MediaBrowser.Api/Images/RemoteImageService.cs b/MediaBrowser.Api/Images/RemoteImageService.cs index 36b509c74..c76506357 100644 --- a/MediaBrowser.Api/Images/RemoteImageService.cs +++ b/MediaBrowser.Api/Images/RemoteImageService.cs @@ -175,7 +175,7 @@ namespace MediaBrowser.Api.Images public object Get(GetRemoteImageProviders request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var result = GetImageProviders(item); @@ -201,7 +201,7 @@ namespace MediaBrowser.Api.Images public object Get(GetRemoteImages request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var result = GetRemoteImageResult(item, request); @@ -269,7 +269,7 @@ namespace MediaBrowser.Api.Images /// <param name="request">The request.</param> public void Post(DownloadRemoteImage request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var task = DownloadRemoteImage(item, request); diff --git a/MediaBrowser.Api/ItemLookupService.cs b/MediaBrowser.Api/ItemLookupService.cs index 62596287e..b600c3b46 100644 --- a/MediaBrowser.Api/ItemLookupService.cs +++ b/MediaBrowser.Api/ItemLookupService.cs @@ -124,7 +124,7 @@ namespace MediaBrowser.Api public object Get(GetExternalIdInfos request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var infos = _providerManager.GetExternalIdInfos(item).ToList(); diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs index 97e43f018..3816332b2 100644 --- a/MediaBrowser.Api/ItemRefreshService.cs +++ b/MediaBrowser.Api/ItemRefreshService.cs @@ -250,7 +250,7 @@ namespace MediaBrowser.Api /// <returns>Task.</returns> private async Task RefreshItem(RefreshItem request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var options = GetRefreshOptions(request); diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs index 8bc06b657..5f05fdc3f 100644 --- a/MediaBrowser.Api/ItemUpdateService.cs +++ b/MediaBrowser.Api/ItemUpdateService.cs @@ -91,7 +91,7 @@ namespace MediaBrowser.Api private async Task UpdateItem(UpdateItem request) { - var item = _dtoService.GetItemByDtoId(request.ItemId); + var item = _libraryManager.GetItemById(request.ItemId); var newLockData = request.LockData ?? false; var dontFetchMetaChanged = item.IsLocked != newLockData; diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs index 967bc1fba..0599b45d5 100644 --- a/MediaBrowser.Api/Library/LibraryService.cs +++ b/MediaBrowser.Api/Library/LibraryService.cs @@ -284,7 +284,7 @@ namespace MediaBrowser.Api.Library public object Get(GetFile request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var locationType = item.LocationType; if (locationType == LocationType.Remote || locationType == LocationType.Virtual) { @@ -350,7 +350,7 @@ namespace MediaBrowser.Api.Library /// <returns>Task{BaseItemDto[]}.</returns> public List<BaseItemDto> GetAncestors(GetAncestors request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var baseItemDtos = new List<BaseItemDto>(); @@ -504,7 +504,7 @@ namespace MediaBrowser.Api.Library private Task DeleteItem(DeleteItem request) { - var item = _dtoService.GetItemByDtoId(request.Id); + var item = _libraryManager.GetItemById(request.Id); var session = GetSession(_sessionManager); @@ -593,7 +593,7 @@ namespace MediaBrowser.Api.Library ? (request.UserId.HasValue ? user.RootFolder : (Folder)_libraryManager.RootFolder) - : _dtoService.GetItemByDtoId(request.Id, request.UserId); + : _libraryManager.GetItemById(request.Id); var originalItem = item; @@ -661,7 +661,7 @@ namespace MediaBrowser.Api.Library ? (request.UserId.HasValue ? user.RootFolder : (Folder)_libraryManager.RootFolder) - : _dtoService.GetItemByDtoId(request.Id, request.UserId); + : _libraryManager.GetItemById(request.Id); var originalItem = item; @@ -771,7 +771,7 @@ namespace MediaBrowser.Api.Library ? (userId.HasValue ? user.RootFolder : (Folder)_libraryManager.RootFolder) - : _dtoService.GetItemByDtoId(id, userId); + : _libraryManager.GetItemById(id); // Get everything var fields = Enum.GetNames(typeof(ItemFields)) diff --git a/MediaBrowser.Api/Music/InstantMixService.cs b/MediaBrowser.Api/Music/InstantMixService.cs index c39811bb6..f50c87f47 100644 --- a/MediaBrowser.Api/Music/InstantMixService.cs +++ b/MediaBrowser.Api/Music/InstantMixService.cs @@ -38,18 +38,20 @@ namespace MediaBrowser.Api.Music private readonly IUserManager _userManager; private readonly IDtoService _dtoService; + private readonly ILibraryManager _libraryManager; private readonly IMusicManager _musicManager; - public InstantMixService(IUserManager userManager, IDtoService dtoService, IMusicManager musicManager) + public InstantMixService(IUserManager userManager, IDtoService dtoService, IMusicManager musicManager, ILibraryManager libraryManager) { _userManager = userManager; _dtoService = dtoService; _musicManager = musicManager; + _libraryManager = libraryManager; } public object Get(GetInstantMixFromSong request) { - var item = (Audio)_dtoService.GetItemByDtoId(request.Id); + var item = (Audio)_libraryManager.GetItemById(request.Id); var user = _userManager.GetUserById(request.UserId.Value); @@ -60,7 +62,7 @@ namespace MediaBrowser.Api.Music public object Get(GetInstantMixFromAlbum request) { - var album = (MusicAlbum)_dtoService.GetItemByDtoId(request.Id); + var album = (MusicAlbum)_libraryManager.GetItemById(request.Id); var user = _userManager.GetUserById(request.UserId.Value); diff --git a/MediaBrowser.Api/NotificationsService.cs b/MediaBrowser.Api/NotificationsService.cs index a71a85395..796fcdab1 100644 --- a/MediaBrowser.Api/NotificationsService.cs +++ b/MediaBrowser.Api/NotificationsService.cs @@ -2,7 +2,7 @@ using MediaBrowser.Model.Notifications; using ServiceStack; using System; -using System.Linq; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -28,17 +28,17 @@ namespace MediaBrowser.Api public class GetNotificationsSummary : IReturn<NotificationsSummary> { [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] - public Guid UserId { get; set; } + public string UserId { get; set; } } [Route("/Notifications/{UserId}", "POST", Summary = "Adds a notifications")] - public class AddUserNotification : IReturn<Notification> + public class AddUserNotification : IReturnVoid { [ApiMember(Name = "Id", Description = "The Id of the new notification. If unspecified one will be provided.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] - public Guid? Id { get; set; } + public string Id { get; set; } [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public Guid UserId { get; set; } + public string UserId { get; set; } [ApiMember(Name = "Name", Description = "The notification's name", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] public string Name { get; set; } @@ -49,12 +49,6 @@ namespace MediaBrowser.Api [ApiMember(Name = "Url", Description = "The notification's info url", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public string Url { get; set; } - [ApiMember(Name = "Category", Description = "The notification's category", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")] - public string Category { get; set; } - - [ApiMember(Name = "RelatedId", Description = "The notification's related id (item)", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] - public string RelatedId { get; set; } - [ApiMember(Name = "Level", Description = "The notification level", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] public NotificationLevel Level { get; set; } } @@ -63,7 +57,7 @@ namespace MediaBrowser.Api public class MarkRead : IReturnVoid { [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public Guid UserId { get; set; } + public string UserId { get; set; } [ApiMember(Name = "Ids", Description = "A list of notification ids, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)] public string Ids { get; set; } @@ -73,7 +67,7 @@ namespace MediaBrowser.Api public class MarkUnread : IReturnVoid { [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public Guid UserId { get; set; } + public string UserId { get; set; } [ApiMember(Name = "Ids", Description = "A list of notification ids, comma delimited", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST", AllowMultiple = true)] public string Ids { get; set; } @@ -82,17 +76,19 @@ namespace MediaBrowser.Api public class NotificationsService : BaseApiService { private readonly INotificationsRepository _notificationsRepo; + private readonly INotificationManager _notificationManager; - public NotificationsService(INotificationsRepository notificationsRepo) + public NotificationsService(INotificationsRepository notificationsRepo, INotificationManager notificationManager) { _notificationsRepo = notificationsRepo; + _notificationManager = notificationManager; } - public object Post(AddUserNotification request) + public void Post(AddUserNotification request) { var task = AddNotification(request); - return ToOptimizedResult(task.Result); + Task.WaitAll(task); } public object Get(GetNotificationsSummary request) @@ -102,24 +98,19 @@ namespace MediaBrowser.Api return result; } - private async Task<Notification> AddNotification(AddUserNotification request) + private async Task AddNotification(AddUserNotification request) { - var notification = new Notification + var notification = new NotificationRequest { - Id = request.Id ?? Guid.NewGuid(), Date = DateTime.UtcNow, Description = request.Description, Level = request.Level, Name = request.Name, Url = request.Url, - UserId = request.UserId, - Category = request.Category, - RelatedId = request.RelatedId + UserIds = new List<string> { request.UserId } }; - await _notificationsRepo.AddNotification(notification, CancellationToken.None).ConfigureAwait(false); - - return notification; + await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); } public void Post(MarkRead request) @@ -136,9 +127,9 @@ namespace MediaBrowser.Api Task.WaitAll(task); } - private Task MarkRead(string idList, Guid userId, bool read) + private Task MarkRead(string idList, string userId, bool read) { - var ids = idList.Split(',').Select(i => new Guid(i)); + var ids = idList.Split(','); return _notificationsRepo.MarkRead(ids, userId, read, CancellationToken.None); } diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index aafda7812..3fd171416 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1336,8 +1336,8 @@ namespace MediaBrowser.Api.Playback } var item = string.IsNullOrEmpty(request.MediaSourceId) ? - DtoService.GetItemByDtoId(request.Id) : - DtoService.GetItemByDtoId(request.MediaSourceId); + LibraryManager.GetItemById(request.Id) : + LibraryManager.GetItemById(request.MediaSourceId); if (user != null && item.GetPlayAccess(user) != PlayAccess.Full) { diff --git a/MediaBrowser.Api/SimilarItemsHelper.cs b/MediaBrowser.Api/SimilarItemsHelper.cs index 1f02a63a0..664a344ce 100644 --- a/MediaBrowser.Api/SimilarItemsHelper.cs +++ b/MediaBrowser.Api/SimilarItemsHelper.cs @@ -73,7 +73,7 @@ namespace MediaBrowser.Api var item = string.IsNullOrEmpty(request.Id) ? (request.UserId.HasValue ? user.RootFolder : - libraryManager.RootFolder) : dtoService.GetItemByDtoId(request.Id, request.UserId); + libraryManager.RootFolder) : libraryManager.GetItemById(request.Id); var fields = request.GetItemFields().ToList(); diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs index d21014dfe..c2b8069cb 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsByNameService.cs @@ -61,14 +61,14 @@ namespace MediaBrowser.Api.UserLibrary if (request.UserId.HasValue) { user = UserManager.GetUserById(request.UserId.Value); - item = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : DtoService.GetItemByDtoId(request.ParentId, user.Id); + item = string.IsNullOrEmpty(request.ParentId) ? user.RootFolder : LibraryManager.GetItemById(request.ParentId); libraryItems = user.RootFolder.GetRecursiveChildren(user).ToList(); } else { - item = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : DtoService.GetItemByDtoId(request.ParentId); + item = string.IsNullOrEmpty(request.ParentId) ? LibraryManager.RootFolder : LibraryManager.GetItemById(request.ParentId); libraryItems = LibraryManager.RootFolder.RecursiveChildren.ToList(); } diff --git a/MediaBrowser.Api/UserLibrary/ItemsService.cs b/MediaBrowser.Api/UserLibrary/ItemsService.cs index 74ce4a0a7..f1b8b2d52 100644 --- a/MediaBrowser.Api/UserLibrary/ItemsService.cs +++ b/MediaBrowser.Api/UserLibrary/ItemsService.cs @@ -373,11 +373,9 @@ namespace MediaBrowser.Api.UserLibrary /// <exception cref="System.InvalidOperationException"></exception> private IEnumerable<BaseItem> GetItemsToSerialize(GetItems request, User user) { - var userId = user == null ? (Guid?)null : user.Id; - var item = string.IsNullOrEmpty(request.ParentId) ? user == null ? _libraryManager.RootFolder : user.RootFolder : - _dtoService.GetItemByDtoId(request.ParentId, userId); + _libraryManager.GetItemById(request.ParentId); // Default list type = children IEnumerable<BaseItem> items; @@ -386,7 +384,7 @@ namespace MediaBrowser.Api.UserLibrary { var idList = request.Ids.Split(',').ToList(); - items = idList.Select(i => _dtoService.GetItemByDtoId(i, userId)); + items = idList.Select(i => _libraryManager.GetItemById(i)); } else if (request.Recursive) diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index 649f2ae02..d145dd054 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -463,7 +463,9 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(request.UserId); - var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _dtoService.GetItemByDtoId(request.Id, user.Id); + var item = string.IsNullOrEmpty(request.Id) ? + user.RootFolder : + _libraryManager.GetItemById(request.Id); // Get everything var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList(); @@ -529,7 +531,7 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(request.UserId); - var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _dtoService.GetItemByDtoId(request.Id, user.Id); + var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id); // Get everything var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList(); @@ -559,7 +561,7 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(request.UserId); - var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _dtoService.GetItemByDtoId(request.Id, user.Id); + var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id); // Get everything var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList(); @@ -597,7 +599,7 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(request.UserId); - var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _dtoService.GetItemByDtoId(request.Id, user.Id); + var item = string.IsNullOrEmpty(request.Id) ? user.RootFolder : _libraryManager.GetItemById(request.Id); var items = _libraryManager.GetIntros(item, user); @@ -651,7 +653,7 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(userId); - var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _dtoService.GetItemByDtoId(itemId, user.Id); + var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId); var key = item.GetUserDataKey(); @@ -701,7 +703,7 @@ namespace MediaBrowser.Api.UserLibrary { var user = _userManager.GetUserById(userId); - var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _dtoService.GetItemByDtoId(itemId, user.Id); + var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : _libraryManager.GetItemById(itemId); var key = item.GetUserDataKey(); @@ -871,7 +873,7 @@ namespace MediaBrowser.Api.UserLibrary /// <returns>Task.</returns> private async Task<UserItemDataDto> UpdatePlayedStatus(User user, string itemId, bool wasPlayed, DateTime? datePlayed) { - var item = _dtoService.GetItemByDtoId(itemId, user.Id); + var item = _libraryManager.GetItemById(itemId); if (wasPlayed) { diff --git a/MediaBrowser.Api/VideosService.cs b/MediaBrowser.Api/VideosService.cs index 940c82540..f62e37f79 100644 --- a/MediaBrowser.Api/VideosService.cs +++ b/MediaBrowser.Api/VideosService.cs @@ -73,7 +73,7 @@ namespace MediaBrowser.Api ? (request.UserId.HasValue ? user.RootFolder : _libraryManager.RootFolder) - : _dtoService.GetItemByDtoId(request.Id, request.UserId); + : _libraryManager.GetItemById(request.Id); // Get everything var fields = Enum.GetNames(typeof(ItemFields)) @@ -104,7 +104,7 @@ namespace MediaBrowser.Api private async Task RemoveAlternateVersions(DeleteAlternateSources request) { - var video = (Video)_dtoService.GetItemByDtoId(request.Id); + var video = (Video)_libraryManager.GetItemById(request.Id); foreach (var link in video.GetLinkedAlternateVersions()) { diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index d07deaf23..b2081fe6b 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -2,7 +2,6 @@ using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; -using System; using System.Collections.Generic; namespace MediaBrowser.Controller.Dto @@ -34,14 +33,6 @@ namespace MediaBrowser.Controller.Dto UserItemDataDto GetUserItemDataDto(UserItemData data); /// <summary> - /// Gets the item by dto id. - /// </summary> - /// <param name="id">The id.</param> - /// <param name="userId">The user id.</param> - /// <returns>BaseItem.</returns> - BaseItem GetItemByDtoId(string id, Guid? userId = null); - - /// <summary> /// Attaches the primary image aspect ratio. /// </summary> /// <param name="dto">The dto.</param> diff --git a/MediaBrowser.Controller/Library/ILibraryManager.cs b/MediaBrowser.Controller/Library/ILibraryManager.cs index 680317237..9e18dc9b0 100644 --- a/MediaBrowser.Controller/Library/ILibraryManager.cs +++ b/MediaBrowser.Controller/Library/ILibraryManager.cs @@ -342,5 +342,10 @@ namespace MediaBrowser.Controller.Library DeleteFileLocation = true }); } + + public static BaseItem GetItemById(this ILibraryManager manager, string id) + { + return manager.GetItemById(new Guid(id)); + } } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj index cc3f3d08b..417c03f27 100644 --- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj +++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj @@ -167,8 +167,10 @@ <Compile Include="Net\IHttpServer.cs" /> <Compile Include="Net\IRestfulService.cs" /> <Compile Include="News\INewsService.cs" /> + <Compile Include="Notifications\INotificationManager.cs" /> <Compile Include="Notifications\INotificationsRepository.cs" /> <Compile Include="Notifications\NotificationUpdateEventArgs.cs" /> + <Compile Include="Notifications\UserNotification.cs" /> <Compile Include="Persistence\IFileOrganizationRepository.cs" /> <Compile Include="Persistence\MediaStreamQuery.cs" /> <Compile Include="Providers\DirectoryService.cs" /> diff --git a/MediaBrowser.Controller/Notifications/INotificationManager.cs b/MediaBrowser.Controller/Notifications/INotificationManager.cs new file mode 100644 index 000000000..8ed62f59f --- /dev/null +++ b/MediaBrowser.Controller/Notifications/INotificationManager.cs @@ -0,0 +1,49 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Notifications; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Controller.Notifications +{ + public interface INotificationManager + { + /// <summary> + /// Sends the notification. + /// </summary> + /// <param name="request">The request.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task SendNotification(NotificationRequest request, CancellationToken cancellationToken); + + /// <summary> + /// Adds the parts. + /// </summary> + /// <param name="services">The services.</param> + void AddParts(IEnumerable<INotificationService> services); + } + + public interface INotificationService + { + /// <summary> + /// Gets the name. + /// </summary> + /// <value>The name.</value> + string Name { get; } + + /// <summary> + /// Sends the notification. + /// </summary> + /// <param name="request">The request.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task.</returns> + Task SendNotification(UserNotification request, CancellationToken cancellationToken); + + /// <summary> + /// Determines whether [is enabled for user] [the specified user identifier]. + /// </summary> + /// <param name="user">The user.</param> + /// <returns><c>true</c> if [is enabled for user] [the specified user identifier]; otherwise, <c>false</c>.</returns> + bool IsEnabledForUser(User user); + } +} diff --git a/MediaBrowser.Controller/Notifications/INotificationsRepository.cs b/MediaBrowser.Controller/Notifications/INotificationsRepository.cs index 7a4b69b52..87b89e79c 100644 --- a/MediaBrowser.Controller/Notifications/INotificationsRepository.cs +++ b/MediaBrowser.Controller/Notifications/INotificationsRepository.cs @@ -1,8 +1,7 @@ -using System.Threading; -using MediaBrowser.Controller.Persistence; -using MediaBrowser.Model.Notifications; +using MediaBrowser.Model.Notifications; using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Notifications @@ -44,7 +43,7 @@ namespace MediaBrowser.Controller.Notifications /// <param name="id">The id.</param> /// <param name="userId">The user id.</param> /// <returns>Notification.</returns> - Notification GetNotification(Guid id, Guid userId); + Notification GetNotification(string id, string userId); /// <summary> /// Adds the notification. @@ -55,14 +54,6 @@ namespace MediaBrowser.Controller.Notifications Task AddNotification(Notification notification, CancellationToken cancellationToken); /// <summary> - /// Updates the notification. - /// </summary> - /// <param name="notification">The notification.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - Task UpdateNotification(Notification notification, CancellationToken cancellationToken); - - /// <summary> /// Marks the read. /// </summary> /// <param name="notificationIdList">The notification id list.</param> @@ -70,13 +61,13 @@ namespace MediaBrowser.Controller.Notifications /// <param name="isRead">if set to <c>true</c> [is read].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - Task MarkRead(IEnumerable<Guid> notificationIdList, Guid userId, bool isRead, CancellationToken cancellationToken); + Task MarkRead(IEnumerable<string> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken); /// <summary> /// Gets the notifications summary. /// </summary> /// <param name="userId">The user id.</param> /// <returns>NotificationsSummary.</returns> - NotificationsSummary GetNotificationsSummary(Guid userId); + NotificationsSummary GetNotificationsSummary(string userId); } } diff --git a/MediaBrowser.Controller/Notifications/NotificationUpdateEventArgs.cs b/MediaBrowser.Controller/Notifications/NotificationUpdateEventArgs.cs index e156ca26a..d8a6634df 100644 --- a/MediaBrowser.Controller/Notifications/NotificationUpdateEventArgs.cs +++ b/MediaBrowser.Controller/Notifications/NotificationUpdateEventArgs.cs @@ -10,8 +10,8 @@ namespace MediaBrowser.Controller.Notifications public class NotificationReadEventArgs : EventArgs { - public Guid[] IdList { get; set; } - public Guid UserId { get; set; } + public string[] IdList { get; set; } + public string UserId { get; set; } public bool IsRead { get; set; } } } diff --git a/MediaBrowser.Controller/Notifications/UserNotification.cs b/MediaBrowser.Controller/Notifications/UserNotification.cs new file mode 100644 index 000000000..d035a3995 --- /dev/null +++ b/MediaBrowser.Controller/Notifications/UserNotification.cs @@ -0,0 +1,21 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Model.Notifications; +using System; + +namespace MediaBrowser.Controller.Notifications +{ + public class UserNotification + { + public string Name { get; set; } + + public string Description { get; set; } + + public string Url { get; set; } + + public NotificationLevel Level { get; set; } + + public DateTime Date { get; set; } + + public User User { get; set; } + } +} diff --git a/MediaBrowser.Dlna/Server/ContentDirectory.cs b/MediaBrowser.Dlna/Server/ContentDirectory.cs index e657a2ff6..93c5cdec8 100644 --- a/MediaBrowser.Dlna/Server/ContentDirectory.cs +++ b/MediaBrowser.Dlna/Server/ContentDirectory.cs @@ -8,9 +8,7 @@ using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; -using System.Threading; namespace MediaBrowser.Dlna.Server { @@ -27,9 +25,6 @@ namespace MediaBrowser.Dlna.Server private readonly IEventManager _eventManager; - private int _systemUpdateId; - private Timer _systemUpdateTimer; - public ContentDirectory(IDlnaManager dlna, IUserDataManager userDataManager, IImageProcessor imageProcessor, @@ -49,9 +44,16 @@ namespace MediaBrowser.Dlna.Server _userManager = userManager; _eventManager = eventManager; _logger = logManager.GetLogger("DlnaContentDirectory"); + } + + private int SystemUpdateId + { + get + { + var now = DateTime.UtcNow; - _systemUpdateTimer = new Timer(SystemUdpateTimerCallback, null, Timeout.Infinite, - Convert.ToInt64(TimeSpan.FromMinutes(60).TotalMilliseconds)); + return now.Year + now.DayOfYear + now.Hour; + } } public string GetContentDirectoryXml(IDictionary<string, string> headers) @@ -80,7 +82,7 @@ namespace MediaBrowser.Dlna.Server _imageProcessor, _userDataManager, user, - _systemUpdateId) + SystemUpdateId) .ProcessControlRequest(request); } @@ -110,40 +112,9 @@ namespace MediaBrowser.Dlna.Server return _userManager.Users.First(); } - private readonly CultureInfo _usCulture = new CultureInfo("en-US"); - private async void SystemUdpateTimerCallback(object state) - { - var values = new Dictionary<string, string>(); - - _systemUpdateId++; - values["SystemUpdateID"] = _systemUpdateId.ToString(_usCulture); - - try - { - await _eventManager.TriggerEvent("upnp:event", values).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error sending system update notification", ex); - } - } - - private readonly object _disposeLock = new object(); public void Dispose() { - lock (_disposeLock) - { - DisposeUpdateTimer(); - } - } - private void DisposeUpdateTimer() - { - if (_systemUpdateTimer != null) - { - _systemUpdateTimer.Dispose(); - _systemUpdateTimer = null; - } } } } diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs index 323373106..bbd07817c 100644 --- a/MediaBrowser.Model/ApiClient/IApiClient.cs +++ b/MediaBrowser.Model/ApiClient/IApiClient.cs @@ -141,18 +141,11 @@ namespace MediaBrowser.Model.ApiClient Task MarkNotificationsRead(string userId, IEnumerable<Guid> notificationIdList, bool isRead); /// <summary> - /// Updates the notification. - /// </summary> - /// <param name="notification">The notification.</param> - /// <returns>Task.</returns> - Task UpdateNotification(Notification notification); - - /// <summary> /// Adds the notification. /// </summary> /// <param name="notification">The notification.</param> /// <returns>Task{Notification}.</returns> - Task<Notification> AddNotification(Notification notification); + Task SendNotification(NotificationRequest notification); /// <summary> /// Gets the notifications summary. diff --git a/MediaBrowser.Model/Notifications/Notification.cs b/MediaBrowser.Model/Notifications/Notification.cs index 14f55b6e1..511227cbf 100644 --- a/MediaBrowser.Model/Notifications/Notification.cs +++ b/MediaBrowser.Model/Notifications/Notification.cs @@ -1,12 +1,13 @@ using System; +using System.Collections.Generic; namespace MediaBrowser.Model.Notifications { public class Notification { - public Guid Id { get; set; } + public string Id { get; set; } - public Guid UserId { get; set; } + public string UserId { get; set; } public DateTime Date { get; set; } @@ -17,16 +18,32 @@ namespace MediaBrowser.Model.Notifications public string Description { get; set; } public string Url { get; set; } - - public string Category { get; set; } - - public string RelatedId { get; set; } public NotificationLevel Level { get; set; } public Notification() { - Id = Guid.NewGuid(); + Date = DateTime.UtcNow; + } + } + + public class NotificationRequest + { + public string Name { get; set; } + + public string Description { get; set; } + + public string Url { get; set; } + + public NotificationLevel Level { get; set; } + + public List<string> UserIds { get; set; } + + public DateTime Date { get; set; } + + public NotificationRequest() + { + UserIds = new List<string>(); Date = DateTime.UtcNow; } } diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index ee6bbb04f..480cb39db 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -556,44 +556,6 @@ namespace MediaBrowser.Server.Implementations.Dto return dto; } - - /// <summary> - /// Gets a BaseItem based upon it's client-side item id - /// </summary> - /// <param name="id">The id.</param> - /// <param name="userId">The user id.</param> - /// <returns>BaseItem.</returns> - public BaseItem GetItemByDtoId(string id, Guid? userId = null) - { - if (string.IsNullOrEmpty(id)) - { - throw new ArgumentNullException("id"); - } - - BaseItem item = null; - - if (userId.HasValue) - { - item = _libraryManager.GetItemById(new Guid(id)); - } - - // If we still don't find it, look within individual user views - if (item == null && !userId.HasValue) - { - foreach (var user in _userManager.Users) - { - item = GetItemByDtoId(id, user.Id); - - if (item != null) - { - break; - } - } - } - - return item; - } - /// <summary> /// Sets simple property values on a DTOBaseItem /// </summary> diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs index fcb4406ab..2a3668dfa 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/Notifier.cs @@ -20,20 +20,20 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications /// </summary> public class Notifications : IServerEntryPoint { - private readonly INotificationsRepository _notificationsRepo; private readonly IInstallationManager _installationManager; private readonly IUserManager _userManager; private readonly ILogger _logger; private readonly ITaskManager _taskManager; + private readonly INotificationManager _notificationManager; - public Notifications(IInstallationManager installationManager, INotificationsRepository notificationsRepo, IUserManager userManager, ILogger logger, ITaskManager taskManager) + public Notifications(IInstallationManager installationManager, IUserManager userManager, ILogger logger, ITaskManager taskManager, INotificationManager notificationManager) { _installationManager = installationManager; - _notificationsRepo = notificationsRepo; _userManager = userManager; _logger = logger; _taskManager = taskManager; + _notificationManager = notificationManager; } public void Run() @@ -49,21 +49,25 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications async void _userManager_UserCreated(object sender, GenericEventArgs<User> e) { - var notification = new Notification + var userIds = _userManager + .Users + .Select(i => i.Id.ToString("N")) + .ToList(); + + var notification = new NotificationRequest { - UserId = e.Argument.Id, - Category = "UserCreated", + UserIds = userIds, Name = "Welcome to Media Browser!", Description = "Check back here for more notifications." }; try { - await _notificationsRepo.AddNotification(notification, CancellationToken.None).ConfigureAwait(false); + await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { - _logger.ErrorException("Error adding notification", ex); + _logger.ErrorException("Error sending notification", ex); } } @@ -73,29 +77,27 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications if (result.Status == TaskCompletionStatus.Failed) { - foreach (var user in _userManager - .Users - .Where(i => i.Configuration.IsAdministrator) - .ToList()) + var userIds = _userManager + .Users + .Where(i => i.Configuration.IsAdministrator) + .Select(i => i.Id.ToString("N")) + .ToList(); + + var notification = new NotificationRequest + { + UserIds = userIds, + Name = result.Name + " failed", + Description = result.ErrorMessage, + Level = NotificationLevel.Error + }; + + try { - var notification = new Notification - { - UserId = user.Id, - Category = "ScheduledTaskFailed", - Name = result.Name + " failed", - RelatedId = result.Name, - Description = result.ErrorMessage, - Level = NotificationLevel.Error - }; - - try - { - await _notificationsRepo.AddNotification(notification, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error adding notification", ex); - } + await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending notification", ex); } } } @@ -104,27 +106,25 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { var plugin = e.Argument; - foreach (var user in _userManager - .Users - .Where(i => i.Configuration.IsAdministrator) - .ToList()) + var userIds = _userManager + .Users + .Where(i => i.Configuration.IsAdministrator) + .Select(i => i.Id.ToString("N")) + .ToList(); + + var notification = new NotificationRequest { - var notification = new Notification - { - UserId = user.Id, - Category = "PluginUninstalled", - Name = plugin.Name + " has been uninstalled", - RelatedId = plugin.Id.ToString() - }; + UserIds = userIds, + Name = plugin.Name + " has been uninstalled" + }; - try - { - await _notificationsRepo.AddNotification(notification, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error adding notification", ex); - } + try + { + await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending notification", ex); } } @@ -132,28 +132,26 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { var installationInfo = e.InstallationInfo; - foreach (var user in _userManager - .Users - .Where(i => i.Configuration.IsAdministrator) - .ToList()) + var userIds = _userManager + .Users + .Where(i => i.Configuration.IsAdministrator) + .Select(i => i.Id.ToString("N")) + .ToList(); + + var notification = new NotificationRequest { - var notification = new Notification - { - UserId = user.Id, - Category = "PackageInstallationCompleted", - Name = installationInfo.Name + " " + installationInfo.Version + " was installed", - RelatedId = installationInfo.Name, - Description = e.PackageVersionInfo.description - }; + UserIds = userIds, + Name = installationInfo.Name + " " + installationInfo.Version + " was installed", + Description = e.PackageVersionInfo.description + }; - try - { - await _notificationsRepo.AddNotification(notification, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error adding notification", ex); - } + try + { + await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending notification", ex); } } @@ -161,29 +159,27 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications { var installationInfo = e.InstallationInfo; - foreach (var user in _userManager + var userIds = _userManager .Users .Where(i => i.Configuration.IsAdministrator) - .ToList()) + .Select(i => i.Id.ToString("N")) + .ToList(); + + var notification = new NotificationRequest { - var notification = new Notification - { - UserId = user.Id, - Category = "PackageInstallationFailed", - Level = NotificationLevel.Error, - Name = installationInfo.Name + " " + installationInfo.Version + " installation failed", - RelatedId = installationInfo.Name, - Description = e.Exception.Message - }; + UserIds = userIds, + Level = NotificationLevel.Error, + Name = installationInfo.Name + " " + installationInfo.Version + " installation failed", + Description = e.Exception.Message + }; - try - { - await _notificationsRepo.AddNotification(notification, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.ErrorException("Error adding notification", ex); - } + try + { + await _notificationManager.SendNotification(notification, CancellationToken.None).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending notification", ex); } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs index 723e4fdd3..d5b7f5b36 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/RemoteNotifications.cs @@ -1,7 +1,6 @@ using MediaBrowser.Common.Configuration; using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; -using MediaBrowser.Controller.IO; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Notifications; using MediaBrowser.Controller.Plugins; @@ -26,22 +25,23 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications private readonly IApplicationPaths _appPaths; private readonly ILogger _logger; private readonly IJsonSerializer _json; - private readonly INotificationsRepository _notificationsRepo; private readonly IUserManager _userManager; private readonly IFileSystem _fileSystem; private readonly TimeSpan _frequency = TimeSpan.FromHours(6); private readonly TimeSpan _maxAge = TimeSpan.FromDays(31); - public RemoteNotifications(IApplicationPaths appPaths, ILogger logger, IHttpClient httpClient, IJsonSerializer json, INotificationsRepository notificationsRepo, IUserManager userManager, IFileSystem fileSystem) + private readonly INotificationManager _notificationManager; + + public RemoteNotifications(IApplicationPaths appPaths, ILogger logger, IHttpClient httpClient, IJsonSerializer json, IUserManager userManager, IFileSystem fileSystem, INotificationManager notificationManager) { _appPaths = appPaths; _logger = logger; _httpClient = httpClient; _json = json; - _notificationsRepo = notificationsRepo; _userManager = userManager; _fileSystem = fileSystem; + _notificationManager = notificationManager; } /// <summary> @@ -107,21 +107,19 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications .Where(i => string.Equals(i.active, "1") && i.date.ToUniversalTime() > lastRunTime && (DateTime.UtcNow - i.date.ToUniversalTime()) <= _maxAge) .ToList(); - foreach (var user in _userManager.Users.ToList()) + var userIds = _userManager.Users.Select(i => i.Id.ToString("N")).ToList(); + + foreach (var notification in notificationList) { - foreach (var notification in notificationList) + await _notificationManager.SendNotification(new NotificationRequest { - await _notificationsRepo.AddNotification(new Notification - { - Category = notification.category, - Date = notification.date, - Name = notification.name, - Description = notification.description, - Url = notification.url, - UserId = user.Id - - }, CancellationToken.None).ConfigureAwait(false); - } + Date = notification.date, + Name = notification.name, + Description = notification.description, + Url = notification.url, + UserIds = userIds + + }, CancellationToken.None).ConfigureAwait(false); } } diff --git a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs index c5a93720c..42aadf62e 100644 --- a/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs +++ b/MediaBrowser.Server.Implementations/EntryPoints/Notifications/WebSocketNotifier.cs @@ -30,9 +30,9 @@ namespace MediaBrowser.Server.Implementations.EntryPoints.Notifications void _notificationsRepo_NotificationsMarkedRead(object sender, NotificationReadEventArgs e) { - var list = e.IdList.Select(i => i.ToString("N")).ToList(); + var list = e.IdList.ToList(); - list.Add(e.UserId.ToString("N")); + list.Add(e.UserId); list.Add(e.IsRead.ToString().ToLower()); var msg = string.Join("|", list.ToArray()); diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs index ac1927931..28d476971 100644 --- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs +++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs @@ -117,7 +117,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio /// </summary> /// <param name="list">The list.</param> /// <returns><c>true</c> if the specified list contains music; otherwise, <c>false</c>.</returns> - public static bool ContainsMusic(IEnumerable<FileSystemInfo> list) + private static bool ContainsMusic(IEnumerable<FileSystemInfo> list) { // If list contains at least 2 audio files or at least one and no video files consider it to contain music var foundAudio = 0; diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj index 505325812..7d6ddbb6e 100644 --- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj +++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj @@ -185,11 +185,13 @@ <Compile Include="MediaEncoder\EncodingManager.cs" /> <Compile Include="News\NewsEntryPoint.cs" /> <Compile Include="News\NewsService.cs" /> + <Compile Include="Notifications\InternalNotificationService.cs" /> + <Compile Include="Notifications\NotificationManager.cs" /> <Compile Include="Persistence\SqliteChapterRepository.cs" /> <Compile Include="Persistence\SqliteExtensions.cs" /> <Compile Include="Persistence\SqliteFileOrganizationRepository.cs" /> <Compile Include="Persistence\SqliteMediaStreamsRepository.cs" /> - <Compile Include="Persistence\SqliteNotificationsRepository.cs" /> + <Compile Include="Notifications\SqliteNotificationsRepository.cs" /> <Compile Include="Persistence\SqliteProviderInfoRepository.cs" /> <Compile Include="Persistence\SqliteShrinkMemoryTimer.cs" /> <Compile Include="Persistence\TypeMapper.cs" /> diff --git a/MediaBrowser.Server.Implementations/Notifications/InternalNotificationService.cs b/MediaBrowser.Server.Implementations/Notifications/InternalNotificationService.cs new file mode 100644 index 000000000..56cb52f10 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Notifications/InternalNotificationService.cs @@ -0,0 +1,42 @@ +using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Notifications; +using MediaBrowser.Model.Notifications; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Server.Implementations.Notifications +{ + public class InternalNotificationService : INotificationService + { + private readonly INotificationsRepository _repo; + + public InternalNotificationService(INotificationsRepository repo) + { + _repo = repo; + } + + public string Name + { + get { return "Dashboard Notifications"; } + } + + public Task SendNotification(UserNotification request, CancellationToken cancellationToken) + { + return _repo.AddNotification(new Notification + { + Date = request.Date, + Description = request.Description, + Level = request.Level, + Name = request.Name, + Url = request.Url, + UserId = request.User.Id.ToString("N") + + }, cancellationToken); + } + + public bool IsEnabledForUser(User user) + { + return true; + } + } +} diff --git a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs new file mode 100644 index 000000000..d6caa5b68 --- /dev/null +++ b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs @@ -0,0 +1,94 @@ +using MediaBrowser.Controller.Entities; +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; + +namespace MediaBrowser.Server.Implementations.Notifications +{ + public class NotificationManager : INotificationManager + { + private readonly ILogger _logger; + private readonly IUserManager _userManager; + private INotificationService[] _services; + + public NotificationManager(ILogManager logManager, IUserManager userManager) + { + _userManager = userManager; + _logger = logManager.GetLogger(GetType().Name); + } + + public Task SendNotification(NotificationRequest request, CancellationToken cancellationToken) + { + var users = request.UserIds.Select(i => _userManager.GetUserById(new Guid(i))); + + var tasks = _services.Select(i => SendNotification(request, i, users, cancellationToken)); + + return Task.WhenAll(tasks); + } + + public Task SendNotification(NotificationRequest request, + INotificationService service, + IEnumerable<User> users, + CancellationToken cancellationToken) + { + users = users.Where(i => IsEnabledForUser(service, i)) + .ToList(); + + var tasks = users.Select(i => SendNotification(request, service, i, cancellationToken)); + + return Task.WhenAll(tasks); + + } + + public async Task SendNotification(NotificationRequest request, + INotificationService service, + User user, + CancellationToken cancellationToken) + { + var notification = new UserNotification + { + Date = request.Date, + Description = request.Description, + Level = request.Level, + Name = request.Name, + Url = request.Url, + User = user + }; + + _logger.Debug("Sending notification via {0} to user {1}", service.Name, user.Name); + + try + { + await service.SendNotification(notification, cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.ErrorException("Error sending notification to {0}", ex, service.Name); + } + } + + private bool IsEnabledForUser(INotificationService service, User user) + { + try + { + return service.IsEnabledForUser(user); + } + catch (Exception ex) + { + _logger.ErrorException("Error in IsEnabledForUser", ex); + return false; + } + } + + public void AddParts(IEnumerable<INotificationService> services) + { + _services = services.ToArray(); + } + } +} diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteNotificationsRepository.cs b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs index 0f9b4295e..2424a6652 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteNotificationsRepository.cs +++ b/MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs @@ -1,16 +1,17 @@ -using System.IO; -using MediaBrowser.Controller; +using MediaBrowser.Controller; using MediaBrowser.Controller.Notifications; using MediaBrowser.Model.Logging; using MediaBrowser.Model.Notifications; +using MediaBrowser.Server.Implementations.Persistence; using System; using System.Collections.Generic; using System.Data; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; -namespace MediaBrowser.Server.Implementations.Persistence +namespace MediaBrowser.Server.Implementations.Notifications { public class SqliteNotificationsRepository : INotificationsRepository { @@ -134,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - public NotificationsSummary GetNotificationsSummary(Guid userId) + public NotificationsSummary GetNotificationsSummary(string userId) { var result = new NotificationsSummary(); @@ -142,7 +143,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { cmd.CommandText = "select Level from Notifications where UserId=@UserId and IsRead=@IsRead"; - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = userId; + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(userId); cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = false; using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess)) @@ -183,8 +184,8 @@ namespace MediaBrowser.Server.Implementations.Persistence { var notification = new Notification { - Id = reader.GetGuid(0), - UserId = reader.GetGuid(1), + Id = reader.GetGuid(0).ToString("N"), + UserId = reader.GetGuid(1).ToString("N"), Date = reader.GetDateTime(2).ToUniversalTime(), Name = reader.GetString(3) }; @@ -202,13 +203,6 @@ namespace MediaBrowser.Server.Implementations.Persistence notification.Level = GetLevel(reader, 6); notification.IsRead = reader.GetBoolean(7); - notification.Category = reader.GetString(8); - - if (!reader.IsDBNull(9)) - { - notification.RelatedId = reader.GetString(9); - } - return notification; } @@ -223,13 +217,13 @@ namespace MediaBrowser.Server.Implementations.Persistence /// or /// userId /// </exception> - public Notification GetNotification(Guid id, Guid userId) + public Notification GetNotification(string id, string userId) { - if (id == Guid.Empty) + if (string.IsNullOrEmpty(id)) { throw new ArgumentNullException("id"); } - if (userId == Guid.Empty) + if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException("userId"); } @@ -238,8 +232,8 @@ namespace MediaBrowser.Server.Implementations.Persistence { cmd.CommandText = "select Id,UserId,Date,Name,Description,Url,Level,IsRead,Category,RelatedId where Id=@Id And UserId = @UserId"; - cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = id; - cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = userId; + cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = new Guid(id); + cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(userId); using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) { @@ -329,11 +323,11 @@ namespace MediaBrowser.Server.Implementations.Persistence /// <returns>Task.</returns> private async Task ReplaceNotification(Notification notification, CancellationToken cancellationToken) { - if (notification.Id == Guid.Empty) + if (string.IsNullOrEmpty(notification.Id)) { - throw new ArgumentException("The notification must have an id"); + notification.Id = Guid.NewGuid().ToString("N"); } - if (notification.UserId == Guid.Empty) + if (string.IsNullOrEmpty(notification.UserId)) { throw new ArgumentException("The notification must have a user id"); } @@ -348,16 +342,16 @@ namespace MediaBrowser.Server.Implementations.Persistence { transaction = _connection.BeginTransaction(); - _replaceNotificationCommand.GetParameter(0).Value = notification.Id; - _replaceNotificationCommand.GetParameter(1).Value = notification.UserId; + _replaceNotificationCommand.GetParameter(0).Value = new Guid(notification.Id); + _replaceNotificationCommand.GetParameter(1).Value = new Guid(notification.UserId); _replaceNotificationCommand.GetParameter(2).Value = notification.Date.ToUniversalTime(); _replaceNotificationCommand.GetParameter(3).Value = notification.Name; _replaceNotificationCommand.GetParameter(4).Value = notification.Description; _replaceNotificationCommand.GetParameter(5).Value = notification.Url; _replaceNotificationCommand.GetParameter(6).Value = notification.Level.ToString(); _replaceNotificationCommand.GetParameter(7).Value = notification.IsRead; - _replaceNotificationCommand.GetParameter(8).Value = notification.Category; - _replaceNotificationCommand.GetParameter(9).Value = notification.RelatedId; + _replaceNotificationCommand.GetParameter(8).Value = string.Empty; + _replaceNotificationCommand.GetParameter(9).Value = string.Empty; _replaceNotificationCommand.Transaction = transaction; @@ -404,9 +398,10 @@ namespace MediaBrowser.Server.Implementations.Persistence /// <param name="isRead">if set to <c>true</c> [is read].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public async Task MarkRead(IEnumerable<Guid> notificationIdList, Guid userId, bool isRead, CancellationToken cancellationToken) + public async Task MarkRead(IEnumerable<string> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken) { - var idArray = notificationIdList.ToArray(); + var list = notificationIdList.ToList(); + var idArray = list.Select(i => new Guid(i)).ToArray(); await MarkReadInternal(idArray, userId, isRead, cancellationToken).ConfigureAwait(false); @@ -416,7 +411,7 @@ namespace MediaBrowser.Server.Implementations.Persistence { NotificationsMarkedRead(this, new NotificationReadEventArgs { - IdList = idArray.ToArray(), + IdList = list.ToArray(), IsRead = isRead, UserId = userId }); @@ -428,7 +423,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } } - private async Task MarkReadInternal(IEnumerable<Guid> notificationIdList, Guid userId, bool isRead, CancellationToken cancellationToken) + private async Task MarkReadInternal(IEnumerable<Guid> notificationIdList, string userId, bool isRead, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); @@ -442,7 +437,7 @@ namespace MediaBrowser.Server.Implementations.Persistence transaction = _connection.BeginTransaction(); - _markReadCommand.GetParameter(0).Value = userId; + _markReadCommand.GetParameter(0).Value = new Guid(userId); _markReadCommand.GetParameter(1).Value = isRead; foreach (var id in notificationIdList) diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 8ee060c3c..2eeb075ee 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -56,6 +56,7 @@ using MediaBrowser.Server.Implementations.Library; using MediaBrowser.Server.Implementations.LiveTv; using MediaBrowser.Server.Implementations.Localization; using MediaBrowser.Server.Implementations.MediaEncoder; +using MediaBrowser.Server.Implementations.Notifications; using MediaBrowser.Server.Implementations.Persistence; using MediaBrowser.Server.Implementations.ServerManager; using MediaBrowser.Server.Implementations.Session; @@ -189,6 +190,8 @@ namespace MediaBrowser.ServerApplication private IFileOrganizationRepository FileOrganizationRepository { get; set; } private IProviderRepository ProviderRepository { get; set; } + private INotificationManager NotificationManager { get; set; } + /// <summary> /// Initializes a new instance of the <see cref="ApplicationHost"/> class. /// </summary> @@ -523,6 +526,9 @@ namespace MediaBrowser.ServerApplication LiveTvManager = new LiveTvManager(ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager); RegisterSingleInstance(LiveTvManager); + NotificationManager = new NotificationManager(LogManager, UserManager); + RegisterSingleInstance(NotificationManager); + var displayPreferencesTask = Task.Run(async () => await ConfigureDisplayPreferencesRepositories().ConfigureAwait(false)); var itemsTask = Task.Run(async () => await ConfigureItemRepositories().ConfigureAwait(false)); var userdataTask = Task.Run(async () => await ConfigureUserDataRepositories().ConfigureAwait(false)); @@ -705,6 +711,8 @@ namespace MediaBrowser.ServerApplication SessionManager.AddParts(GetExports<ISessionControllerFactory>()); ChannelManager.AddParts(GetExports<IChannel>()); + + NotificationManager.AddParts(GetExports<INotificationService>()); } /// <summary> |
