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
}
}