diff --git a/MediaBrowser.Api/ApiService.cs b/MediaBrowser.Api/ApiService.cs
index e6e4594c16..33ea492e05 100644
--- a/MediaBrowser.Api/ApiService.cs
+++ b/MediaBrowser.Api/ApiService.cs
@@ -1,6 +1,4 @@
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
-using System;
+using System;
using System.Net;
namespace MediaBrowser.Api
@@ -10,24 +8,6 @@ namespace MediaBrowser.Api
///
public static class ApiService
{
- ///
- /// Gets a User by Id
- ///
- /// The id of the user
- /// User.
- /// id
- public static User GetUserById(string id)
- {
- if (string.IsNullOrEmpty(id))
- {
- throw new ArgumentNullException("id");
- }
-
- var guid = new Guid(id);
-
- return Kernel.Instance.GetUserById(guid);
- }
-
///
/// Determines whether [is API URL match] [the specified URL].
///
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 113bad083d..d3d76f4f27 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -1,4 +1,6 @@
-using MediaBrowser.Common.Extensions;
+using System.Threading;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Entities;
@@ -9,6 +11,7 @@ using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using ServiceStack.Text.Controller;
namespace MediaBrowser.Api.Images
{
@@ -101,7 +104,7 @@ namespace MediaBrowser.Api.Images
///
[Route("/Users/{Id}/Images/{Type}", "DELETE")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "DELETE")]
- public class DeleteUserImage : DeleteImageRequest
+ public class DeleteUserImage : DeleteImageRequest, IReturnVoid
{
///
/// Gets or sets the id.
@@ -109,6 +112,23 @@ namespace MediaBrowser.Api.Images
/// The id.
public Guid Id { get; set; }
}
+
+ [Route("/Users/{Id}/Images/{Type}", "POST")]
+ [Route("/Users/{Id}/Images/{Type}/{Index}", "POST")]
+ public class PostUserImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid
+ {
+ ///
+ /// Gets or sets the id.
+ ///
+ /// The id.
+ public Guid Id { get; set; }
+
+ ///
+ /// The raw Http Request Input Stream
+ ///
+ /// The request stream.
+ public Stream RequestStream { get; set; }
+ }
///
/// Class ImageService
@@ -197,6 +217,26 @@ namespace MediaBrowser.Api.Images
return GetImage(request, item);
}
+ ///
+ /// Posts the specified request.
+ ///
+ /// The request.
+ public void Post(PostUserImage request)
+ {
+ var kernel = (Kernel)Kernel;
+
+ var pathInfo = PathInfo.Parse(Request.PathInfo);
+ var id = new Guid(pathInfo.GetArgumentValue(1));
+
+ request.Type = (ImageType)Enum.Parse(typeof(ImageType), pathInfo.GetArgumentValue(3), true);
+
+ var item = kernel.Users.First(i => i.Id == id);
+
+ var task = PostImage(item, request.RequestStream, request.Type, Request.ContentType);
+
+ Task.WaitAll(task);
+ }
+
///
/// Deletes the specified request.
///
@@ -280,5 +320,62 @@ namespace MediaBrowser.Api.Images
return kernel.ImageManager.GetImagePath(item, request.Type, index);
}
+
+ ///
+ /// Posts the image.
+ ///
+ /// The entity.
+ /// The input stream.
+ /// Type of the image.
+ /// Type of the MIME.
+ /// Task.
+ private async Task PostImage(BaseItem entity, Stream inputStream, ImageType imageType, string mimeType)
+ {
+ using (var reader = new StreamReader(inputStream))
+ {
+ var text = await reader.ReadToEndAsync().ConfigureAwait(false);
+
+ var bytes = Convert.FromBase64String(text);
+
+ string filename;
+
+ switch (imageType)
+ {
+ case ImageType.Art:
+ filename = "clearart";
+ break;
+ case ImageType.Primary:
+ filename = "folder";
+ break;
+ default:
+ filename = imageType.ToString().ToLower();
+ break;
+ }
+
+ var extension = mimeType.Substring(mimeType.IndexOf('/') + 1);
+
+ var oldImagePath = entity.GetImage(imageType);
+
+ var imagePath = Path.Combine(entity.MetaLocation, filename + "." + extension);
+
+ // Save to file system
+ using (var fs = new FileStream(imagePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
+ {
+ await fs.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
+ }
+
+ // Set the image
+ entity.SetImage(imageType, imagePath);
+
+ // If the new and old paths are different, delete the old one
+ if (!string.IsNullOrEmpty(oldImagePath) && !oldImagePath.Equals(imagePath, StringComparison.OrdinalIgnoreCase))
+ {
+ File.Delete(oldImagePath);
+ }
+
+ // Directory watchers should repeat this, but do a quick refresh first
+ await entity.RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false).ConfigureAwait(false);
+ }
+ }
}
}
diff --git a/MediaBrowser.Api/Images/UploadImageHandler.cs b/MediaBrowser.Api/Images/UploadImageHandler.cs
deleted file mode 100644
index 758e96d851..0000000000
--- a/MediaBrowser.Api/Images/UploadImageHandler.cs
+++ /dev/null
@@ -1,141 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net.Handlers;
-using MediaBrowser.Controller;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Entities;
-using System;
-using System.IO;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Api.Images
-{
- ///
- /// Class UploadImageHandler
- ///
- class UploadImageHandler : BaseActionHandler
- {
- ///
- /// The _source entity
- ///
- private BaseItem _sourceEntity;
-
- ///
- /// Gets the source entity.
- ///
- /// Task{BaseItem}.
- private async Task GetSourceEntity()
- {
- if (_sourceEntity == null)
- {
- if (!string.IsNullOrEmpty(QueryString["personname"]))
- {
- _sourceEntity =
- await Kernel.LibraryManager.GetPerson(QueryString["personname"]).ConfigureAwait(false);
- }
-
- else if (!string.IsNullOrEmpty(QueryString["genre"]))
- {
- _sourceEntity =
- await Kernel.LibraryManager.GetGenre(QueryString["genre"]).ConfigureAwait(false);
- }
-
- else if (!string.IsNullOrEmpty(QueryString["year"]))
- {
- _sourceEntity =
- await
- Kernel.LibraryManager.GetYear(int.Parse(QueryString["year"])).ConfigureAwait(false);
- }
-
- else if (!string.IsNullOrEmpty(QueryString["studio"]))
- {
- _sourceEntity =
- await Kernel.LibraryManager.GetStudio(QueryString["studio"]).ConfigureAwait(false);
- }
-
- else if (!string.IsNullOrEmpty(QueryString["userid"]))
- {
- _sourceEntity = ApiService.GetUserById(QueryString["userid"]);
- }
-
- else
- {
- _sourceEntity = DtoBuilder.GetItemByClientId(QueryString["id"]);
- }
- }
-
- return _sourceEntity;
- }
-
- ///
- /// Gets the type of the image.
- ///
- /// The type of the image.
- private ImageType ImageType
- {
- get
- {
- var imageType = QueryString["type"];
-
- return (ImageType)Enum.Parse(typeof(ImageType), imageType, true);
- }
- }
-
- ///
- /// Performs the action.
- ///
- /// Task.
- protected override async Task ExecuteAction()
- {
- var entity = await GetSourceEntity().ConfigureAwait(false);
-
- using (var reader = new StreamReader(HttpListenerContext.Request.InputStream))
- {
- var text = await reader.ReadToEndAsync().ConfigureAwait(false);
-
- var bytes = Convert.FromBase64String(text);
-
- string filename;
-
- switch (ImageType)
- {
- case ImageType.Art:
- filename = "clearart";
- break;
- case ImageType.Primary:
- filename = "folder";
- break;
- default:
- filename = ImageType.ToString().ToLower();
- break;
- }
-
- // Use the client filename to determine the original extension
- var clientFileName = QueryString["filename"];
-
- var oldImagePath = entity.GetImage(ImageType);
-
- var imagePath = Path.Combine(entity.MetaLocation, filename + Path.GetExtension(clientFileName));
-
- // Save to file system
- using (var fs = new FileStream(imagePath, FileMode.Create, FileAccess.Write, FileShare.Read, StreamDefaults.DefaultFileStreamBufferSize, true))
- {
- await fs.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
- }
-
- // Set the image
- entity.SetImage(ImageType, imagePath);
-
- // If the new and old paths are different, delete the old one
- if (!string.IsNullOrEmpty(oldImagePath) && !oldImagePath.Equals(imagePath, StringComparison.OrdinalIgnoreCase))
- {
- File.Delete(oldImagePath);
- }
-
- // Directory watchers should repeat this, but do a quick refresh first
- await entity.RefreshMetadata(CancellationToken.None, forceSave: true, allowSlowProviders: false).ConfigureAwait(false);
- }
- }
- }
-}
diff --git a/MediaBrowser.Api/Javascript/ApiClient.js b/MediaBrowser.Api/Javascript/ApiClient.js
index e82238d24c..84e54597b2 100644
--- a/MediaBrowser.Api/Javascript/ApiClient.js
+++ b/MediaBrowser.Api/Javascript/ApiClient.js
@@ -613,15 +613,15 @@ var ApiClient = {
var data = window.btoa(e.target.result);
- var params = {
- userId: userId,
- type: imageType,
- filename: file.name
- };
+ var url = ApiClient.getUrl("Users/" + userId + "/Images/" + imageType);
- var url = ApiClient.getUrl("UploadImage", params);
+ $.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ contentType: "image/" + file.name.substring(file.name.lastIndexOf('.') + 1)
- $.post(url, data).done(function (result) {
+ }).done(function (result) {
deferred.resolveWith(null, [result]);
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index 81ff1001be..896e1d438e 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -78,7 +78,6 @@
-