diff --git a/MediaBrowser.Api/HttpHandlers/UserItemRatingHandler.cs b/MediaBrowser.Api/HttpHandlers/UserItemRatingHandler.cs new file mode 100644 index 0000000000..6f3908d051 --- /dev/null +++ b/MediaBrowser.Api/HttpHandlers/UserItemRatingHandler.cs @@ -0,0 +1,59 @@ +using MediaBrowser.Common.Net.Handlers; +using MediaBrowser.Model.DTO; +using MediaBrowser.Model.Entities; +using System.ComponentModel.Composition; +using System.Net; +using System.Threading.Tasks; + +namespace MediaBrowser.Api.HttpHandlers +{ + /// + /// Provides a handler to set a user's rating for an item + /// + [Export(typeof(BaseHandler))] + public class UserItemRatingHandler : BaseSerializationHandler + { + public override bool HandlesRequest(HttpListenerRequest request) + { + return ApiService.IsApiUrlMatch("UserItemRating", request); + } + + protected override Task GetObjectToSerialize() + { + // Get the item + BaseItem item = ApiService.GetItemById(QueryString["id"]); + + // Get the user + User user = ApiService.GetUserById(QueryString["userid"], true); + + // Get the user data for this item + UserItemData data = item.GetUserData(user); + + if (data == null) + { + data = new UserItemData(); + item.AddUserData(user, data); + } + + // If clearing the rating, set it to null + if (QueryString["clear"] == "1") + { + data.Rating = null; + } + + // If the user's rating mode is set to like/dislike + else if (user.ItemRatingMode == ItemRatingMode.LikeOrDislike) + { + data.Likes = QueryString["likes"] == "1"; + } + + // If the user's rating mode is set to numeric + else if (user.ItemRatingMode == ItemRatingMode.Numeric) + { + data.Rating = float.Parse(QueryString["value"]); + } + + return Task.FromResult(ApiService.GetDTOUserItemData(data)); + } + } +} \ No newline at end of file diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj index 31bb8f7a7d..bedb8d62e1 100644 --- a/MediaBrowser.Api/MediaBrowser.Api.csproj +++ b/MediaBrowser.Api/MediaBrowser.Api.csproj @@ -75,6 +75,7 @@ + diff --git a/MediaBrowser.ApiInteraction.Portable/ApiClient.cs b/MediaBrowser.ApiInteraction.Portable/ApiClient.cs index f63847e5cd..d83c6b1a6e 100644 --- a/MediaBrowser.ApiInteraction.Portable/ApiClient.cs +++ b/MediaBrowser.ApiInteraction.Portable/ApiClient.cs @@ -398,7 +398,46 @@ namespace MediaBrowser.ApiInteraction.Portable GetDataAsync(url, callback); } - + + /// + /// Clears a user's rating for an item + /// + public void ClearUserItemRatingAsync(Guid itemId, Guid userId, Action callback) + { + string url = ApiUrl + "/UserItemRating?id=" + itemId; + + url += "&userid=" + userId; + url += "&clear=1"; + + GetDataAsync(url, callback); + } + + /// + /// Updates a user's rating for an item, based on a numeric scale + /// + public void UpdateUserItemRatingAsync(Guid itemId, Guid userId, float value, Action callback) + { + string url = ApiUrl + "/UserItemRating?id=" + itemId; + + url += "&userid=" + userId; + url += "&value=" + value; + + GetDataAsync(url, callback); + } + + /// + /// Updates a user's rating for an item, based on likes or dislikes + /// + public void UpdateUserItemRatingAsync(Guid itemId, Guid userId, bool likes, Action callback) + { + string url = ApiUrl + "/UserItemRating?id=" + itemId; + + url += "&userid=" + userId; + url += "&likes=" + (likes ? "1" : "0"); + + GetDataAsync(url, callback); + } + /// /// Performs a GET request, and deserializes the response stream to an object of Type T /// diff --git a/MediaBrowser.ApiInteraction/BaseHttpApiClient.cs b/MediaBrowser.ApiInteraction/BaseHttpApiClient.cs index 3c3daa2091..b6a4539ee2 100644 --- a/MediaBrowser.ApiInteraction/BaseHttpApiClient.cs +++ b/MediaBrowser.ApiInteraction/BaseHttpApiClient.cs @@ -454,6 +454,54 @@ namespace MediaBrowser.ApiInteraction } } + /// + /// Clears a user's rating for an item + /// + public async Task ClearUserItemRatingAsync(Guid itemId, Guid userId) + { + string url = ApiUrl + "/UserItemRating?id=" + itemId; + + url += "&userid=" + userId; + url += "&clear=1"; + + using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false)) + { + return DeserializeFromStream(stream); + } + } + + /// + /// Updates a user's rating for an item, based on a numeric scale + /// + public async Task UpdateUserItemRatingAsync(Guid itemId, Guid userId, float value) + { + string url = ApiUrl + "/UserItemRating?id=" + itemId; + + url += "&userid=" + userId; + url += "&value=" + value; + + using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false)) + { + return DeserializeFromStream(stream); + } + } + + /// + /// Updates a user's rating for an item, based on likes or dislikes + /// + public async Task UpdateUserItemRatingAsync(Guid itemId, Guid userId, bool likes) + { + string url = ApiUrl + "/UserItemRating?id=" + itemId; + + url += "&userid=" + userId; + url += "&likes=" + (likes ? "1" : "0"); + + using (Stream stream = await GetSerializedStreamAsync(url).ConfigureAwait(false)) + { + return DeserializeFromStream(stream); + } + } + /// /// Authenticates a user and returns the result /// diff --git a/MediaBrowser.Model/DTO/DTOUser.cs b/MediaBrowser.Model/DTO/DTOUser.cs index aa066a3bd8..802bc8d8d8 100644 --- a/MediaBrowser.Model/DTO/DTOUser.cs +++ b/MediaBrowser.Model/DTO/DTOUser.cs @@ -1,4 +1,5 @@ -using ProtoBuf; +using MediaBrowser.Model.Entities; +using ProtoBuf; using System; namespace MediaBrowser.Model.DTO @@ -23,5 +24,8 @@ namespace MediaBrowser.Model.DTO [ProtoMember(6)] public DateTime? LastActivityDate { get; set; } + + [ProtoMember(7)] + public ItemRatingMode ItemRatingMode { get; set; } } } diff --git a/MediaBrowser.Model/Entities/User.cs b/MediaBrowser.Model/Entities/User.cs index 3c6117fca8..68e130c7a3 100644 --- a/MediaBrowser.Model/Entities/User.cs +++ b/MediaBrowser.Model/Entities/User.cs @@ -17,5 +17,16 @@ namespace MediaBrowser.Model.Entities public DateTime? LastLoginDate { get; set; } public DateTime? LastActivityDate { get; set; } + + /// + /// This allows the user to configure how they want to rate items + /// + public ItemRatingMode ItemRatingMode { get; set; } + } + + public enum ItemRatingMode + { + LikeOrDislike, + Numeric } }