From 1bf4b6110d072568aa2775b9c7630e9fed576a0a Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 5 Apr 2013 13:10:55 -0400 Subject: [PATCH] Get/Set DisplayPreferences separately through the api --- MediaBrowser.Api/DisplayPreferencesService.cs | 100 ++++++++++++++++++ MediaBrowser.Api/MediaBrowser.Api.csproj | 1 + .../UserLibrary/BaseItemsRequest.cs | 2 +- .../UserLibrary/UserLibraryService.cs | 76 +++---------- MediaBrowser.Controller/Library/DtoBuilder.cs | 6 +- .../Library/IUserManager.cs | 3 +- MediaBrowser.Model/DTO/BaseItemDto.cs | 6 +- MediaBrowser.Model/Querying/ItemFields.cs | 2 +- 8 files changed, 124 insertions(+), 72 deletions(-) create mode 100644 MediaBrowser.Api/DisplayPreferencesService.cs diff --git a/MediaBrowser.Api/DisplayPreferencesService.cs b/MediaBrowser.Api/DisplayPreferencesService.cs new file mode 100644 index 0000000000..1ea71c545e --- /dev/null +++ b/MediaBrowser.Api/DisplayPreferencesService.cs @@ -0,0 +1,100 @@ +using MediaBrowser.Controller.Library; +using MediaBrowser.Model.Entities; +using MediaBrowser.Model.Serialization; +using ServiceStack.ServiceHost; +using ServiceStack.Text.Controller; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace MediaBrowser.Api +{ + /// + /// Class UpdateDisplayPreferences + /// + [Route("/Users/{UserId}/DisplayPreferences/{Id}", "POST")] + [Api(("Updates a user's display preferences for an item"))] + public class UpdateDisplayPreferences : DisplayPreferences, IReturnVoid + { + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public Guid Id { get; set; } + } + + [Route("/Users/{UserId}/DisplayPreferences/{Id}", "GET")] + [Api(("Gets a user's display preferences for an item"))] + public class GetDisplayPreferences : IReturn + { + [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public Guid UserId { get; set; } + + /// + /// Gets or sets the id. + /// + /// The id. + [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] + public Guid Id { get; set; } + } + + /// + /// Class DisplayPreferencesService + /// + public class DisplayPreferencesService : BaseApiService + { + /// + /// The _user manager + /// + private readonly IUserManager _userManager; + /// + /// The _json serializer + /// + private readonly IJsonSerializer _jsonSerializer; + + /// + /// Initializes a new instance of the class. + /// + /// The user manager. + /// The json serializer. + public DisplayPreferencesService(IUserManager userManager, IJsonSerializer jsonSerializer) + { + _userManager = userManager; + _jsonSerializer = jsonSerializer; + } + + /// + /// Gets the specified request. + /// + /// The request. + public object Get(GetDisplayPreferences request) + { + var task = _userManager.GetDisplayPreferences(request.UserId, request.Id); + + return ToOptimizedResult(task.Result); + } + + /// + /// Posts the specified request. + /// + /// The request. + public void Post(UpdateDisplayPreferences request) + { + // We need to parse this manually because we told service stack not to with IRequiresRequestStream + // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs + var pathInfo = PathInfo.Parse(RequestContext.PathInfo); + var userId = new Guid(pathInfo.GetArgumentValue(1)); + var displayPreferencesId = new Guid(pathInfo.GetArgumentValue(3)); + + var user = _userManager.GetUserById(userId); + + // Serialize to json and then back so that the core doesn't see the request dto type + var displayPreferences = _jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(request)); + + var task = _userManager.SaveDisplayPreferences(user.Id, displayPreferencesId, displayPreferences, CancellationToken.None); + + Task.WaitAll(task); + } + } +} diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 792a4e3090..c7593d9e93 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -62,6 +62,7 @@ Properties\SharedVersion.cs + diff --git a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs index a15da715f4..c348bf5f51 100644 --- a/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs +++ b/MediaBrowser.Api/UserLibrary/BaseItemsRequest.cs @@ -52,7 +52,7 @@ namespace MediaBrowser.Api.UserLibrary /// Fields to return within the items, in addition to basic information /// /// The fields. - [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: AudioInfo, Chapters, DateCreated, DisplayMediaType, DisplayPreferences, Genres, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, Publishers, SeriesInfo, SortName, Studios, Taglines, TrailerUrls, UserData", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] + [ApiMember(Name = "Fields", Description = "Optional. Specify additional fields of information to return in the output. This allows multiple, comma delimeted. Options: AudioInfo, Chapters, DateCreated, DisplayMediaType, DisplayPreferences, Genres, ItemCounts, IndexOptions, MediaStreams, Overview, OverviewHtml, ParentId, Path, People, ProviderIds, PrimaryImageAspectRatio, SeriesInfo, SortName, Studios, Taglines, TrailerUrls, UserData", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)] public string Fields { get; set; } } } diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs index d1f963a9ee..e24e638196 100644 --- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs +++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs @@ -1,17 +1,13 @@ -using System.Threading; -using MediaBrowser.Controller.Entities; +using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Library; -using MediaBrowser.Model.Connectivity; using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Querying; -using MediaBrowser.Model.Serialization; using ServiceStack.ServiceHost; -using ServiceStack.Text.Controller; using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Api.UserLibrary @@ -20,7 +16,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class GetItem /// [Route("/Users/{UserId}/Items/{Id}", "GET")] - [ServiceStack.ServiceHost.Api(Description = "Gets an item from a user's library")] + [Api(Description = "Gets an item from a user's library")] public class GetItem : IReturn { /// @@ -42,7 +38,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class GetItem /// [Route("/Users/{UserId}/Items/Root", "GET")] - [ServiceStack.ServiceHost.Api(Description = "Gets the root folder from a user's library")] + [Api(Description = "Gets the root folder from a user's library")] public class GetRootFolder : IReturn { /// @@ -57,7 +53,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class GetIntros /// [Route("/Users/{UserId}/Items/{Id}/Intros", "GET")] - [ServiceStack.ServiceHost.Api(("Gets intros to play before the main media item plays"))] + [Api(("Gets intros to play before the main media item plays"))] public class GetIntros : IReturn> { /// @@ -75,21 +71,6 @@ namespace MediaBrowser.Api.UserLibrary public string Id { get; set; } } - /// - /// Class UpdateDisplayPreferences - /// - [Route("/Users/{UserId}/Items/{Id}/DisplayPreferences", "POST")] - [Api(("Updates a user's display preferences for an item"))] - public class UpdateDisplayPreferences : DisplayPreferences, IReturnVoid - { - /// - /// Gets or sets the id. - /// - /// The id. - [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")] - public string Id { get; set; } - } - /// /// Class MarkFavoriteItem /// @@ -138,7 +119,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class ClearUserItemRating /// [Route("/Users/{UserId}/Items/{Id}/Rating", "DELETE")] - [ServiceStack.ServiceHost.Api(Description = "Deletes a user's saved personal rating for an item")] + [Api(Description = "Deletes a user's saved personal rating for an item")] public class DeleteUserItemRating : IReturnVoid { /// @@ -160,7 +141,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class UpdateUserItemRating /// [Route("/Users/{UserId}/Items/{Id}/Rating", "POST")] - [ServiceStack.ServiceHost.Api(Description = "Updates a user's rating for an item")] + [Api(Description = "Updates a user's rating for an item")] public class UpdateUserItemRating : IReturnVoid { /// @@ -189,7 +170,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class MarkPlayedItem /// [Route("/Users/{UserId}/PlayedItems/{Id}", "POST")] - [ServiceStack.ServiceHost.Api(Description = "Marks an item as played")] + [Api(Description = "Marks an item as played")] public class MarkPlayedItem : IReturnVoid { /// @@ -211,7 +192,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class MarkUnplayedItem /// [Route("/Users/{UserId}/PlayedItems/{Id}", "DELETE")] - [ServiceStack.ServiceHost.Api(Description = "Marks an item as unplayed")] + [Api(Description = "Marks an item as unplayed")] public class MarkUnplayedItem : IReturnVoid { /// @@ -230,7 +211,7 @@ namespace MediaBrowser.Api.UserLibrary } [Route("/Users/{UserId}/PlayingItems/{Id}", "POST")] - [ServiceStack.ServiceHost.Api(Description = "Reports that a user has begun playing an item")] + [Api(Description = "Reports that a user has begun playing an item")] public class OnPlaybackStart : IReturnVoid { /// @@ -249,7 +230,7 @@ namespace MediaBrowser.Api.UserLibrary } [Route("/Users/{UserId}/PlayingItems/{Id}/Progress", "POST")] - [ServiceStack.ServiceHost.Api(Description = "Reports a user's playback progress")] + [Api(Description = "Reports a user's playback progress")] public class OnPlaybackProgress : IReturnVoid { /// @@ -275,7 +256,7 @@ namespace MediaBrowser.Api.UserLibrary } [Route("/Users/{UserId}/PlayingItems/{Id}", "DELETE")] - [ServiceStack.ServiceHost.Api(Description = "Reports that a user has stopped playing an item")] + [Api(Description = "Reports that a user has stopped playing an item")] public class OnPlaybackStopped : IReturnVoid { /// @@ -304,7 +285,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class GetLocalTrailers /// [Route("/Users/{UserId}/Items/{Id}/LocalTrailers", "GET")] - [ServiceStack.ServiceHost.Api(Description = "Gets local trailers for an item")] + [Api(Description = "Gets local trailers for an item")] public class GetLocalTrailers : IReturn> { /// @@ -326,7 +307,7 @@ namespace MediaBrowser.Api.UserLibrary /// Class GetSpecialFeatures /// [Route("/Users/{UserId}/Items/{Id}/SpecialFeatures", "GET")] - [ServiceStack.ServiceHost.Api(Description = "Gets special features for a movie")] + [Api(Description = "Gets special features for a movie")] public class GetSpecialFeatures : IReturn> { /// @@ -356,18 +337,16 @@ namespace MediaBrowser.Api.UserLibrary private readonly IUserManager _userManager; private readonly ILibraryManager _libraryManager; - private readonly IJsonSerializer _jsonSerializer; /// /// Initializes a new instance of the class. /// /// jsonSerializer - public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager, IJsonSerializer jsonSerializer) + public UserLibraryService(IUserManager userManager, ILibraryManager libraryManager) : base() { _userManager = userManager; _libraryManager = libraryManager; - _jsonSerializer = jsonSerializer; } /// @@ -467,31 +446,6 @@ namespace MediaBrowser.Api.UserLibrary return ToOptimizedResult(result); } - /// - /// Posts the specified request. - /// - /// The request. - public void Post(UpdateDisplayPreferences request) - { - // We need to parse this manually because we told service stack not to with IRequiresRequestStream - // https://code.google.com/p/servicestack/source/browse/trunk/Common/ServiceStack.Text/ServiceStack.Text/Controller/PathInfo.cs - var pathInfo = PathInfo.Parse(RequestContext.PathInfo); - var userId = new Guid(pathInfo.GetArgumentValue(1)); - var itemId = pathInfo.GetArgumentValue(3); - - var user = _userManager.GetUserById(userId); - - var item = string.IsNullOrEmpty(itemId) ? user.RootFolder : DtoBuilder.GetItemByClientId(itemId, _userManager, _libraryManager, user.Id); - var folder = (Folder)item; - - // Serialize to json and then back so that the core doesn't see the request dto type - var displayPreferences = _jsonSerializer.DeserializeFromString(_jsonSerializer.SerializeToString(request)); - - var task = _userManager.SaveDisplayPreferences(user.Id, folder.DisplayPreferencesId, displayPreferences, CancellationToken.None); - - Task.WaitAll(task); - } - /// /// Posts the specified request. /// diff --git a/MediaBrowser.Controller/Library/DtoBuilder.cs b/MediaBrowser.Controller/Library/DtoBuilder.cs index 4dfe78faf7..fbaa59f34f 100644 --- a/MediaBrowser.Controller/Library/DtoBuilder.cs +++ b/MediaBrowser.Controller/Library/DtoBuilder.cs @@ -172,11 +172,9 @@ namespace MediaBrowser.Controller.Library dto.UserData = GetUserItemDataDto(userData); } - if (item.IsFolder && fields.Contains(ItemFields.DisplayPreferences)) + if (item.IsFolder && fields.Contains(ItemFields.DisplayPreferencesId)) { - var displayPreferencesId = ((Folder) item).DisplayPreferencesId; - - dto.DisplayPreferences = await _userManager.GetDisplayPreferences(user.Id, displayPreferencesId).ConfigureAwait(false); + dto.DisplayPreferencesId = ((Folder)item).DisplayPreferencesId.ToString(); } if (item.IsFolder) diff --git a/MediaBrowser.Controller/Library/IUserManager.cs b/MediaBrowser.Controller/Library/IUserManager.cs index 8374c6880b..8eee8e447c 100644 --- a/MediaBrowser.Controller/Library/IUserManager.cs +++ b/MediaBrowser.Controller/Library/IUserManager.cs @@ -207,7 +207,6 @@ namespace MediaBrowser.Controller.Library /// The display preferences. /// The cancellation token. /// Task. - Task SaveDisplayPreferences(Guid userId, Guid displayPreferencesId, DisplayPreferences displayPreferences, - CancellationToken cancellationToken); + Task SaveDisplayPreferences(Guid userId, Guid displayPreferencesId, DisplayPreferences displayPreferences, CancellationToken cancellationToken); } } diff --git a/MediaBrowser.Model/DTO/BaseItemDto.cs b/MediaBrowser.Model/DTO/BaseItemDto.cs index b4d6aecd9b..6b5103b5bc 100644 --- a/MediaBrowser.Model/DTO/BaseItemDto.cs +++ b/MediaBrowser.Model/DTO/BaseItemDto.cs @@ -267,11 +267,11 @@ namespace MediaBrowser.Model.Dto public int? SpecialFeatureCount { get; set; } /// - /// Gets or sets the display preferences. + /// Gets or sets the display preferences id. /// - /// The display preferences. + /// The display preferences id. [ProtoMember(49)] - public DisplayPreferences DisplayPreferences { get; set; } + public string DisplayPreferencesId { get; set; } /// /// Gets or sets the status. diff --git a/MediaBrowser.Model/Querying/ItemFields.cs b/MediaBrowser.Model/Querying/ItemFields.cs index 30f62bf8f2..d9902d6d41 100644 --- a/MediaBrowser.Model/Querying/ItemFields.cs +++ b/MediaBrowser.Model/Querying/ItemFields.cs @@ -29,7 +29,7 @@ namespace MediaBrowser.Model.Querying /// /// Item display preferences /// - DisplayPreferences, + DisplayPreferencesId, /// /// Genres