#16987, #16527, #16785: Media file upload fixes.

--HG--
branch : dev
This commit is contained in:
Andre Rodrigues
2010-12-08 16:13:09 -08:00
parent 653bf6f14b
commit 98d759e7d4
9 changed files with 63 additions and 49 deletions

View File

@@ -189,7 +189,7 @@ namespace Orchard.Media.Controllers {
// then save them
foreach (string fileName in Request.Files) {
HttpPostedFileBase file = Request.Files[fileName];
_mediaService.UploadMediaFile(viewModel.MediaPath, file);
_mediaService.UploadMediaFile(viewModel.MediaPath, file, viewModel.ExtractZip);
}
Services.Notifier.Information(T("Media file(s) uploaded"));
@@ -222,7 +222,7 @@ namespace Orchard.Media.Controllers {
}
var file = Request.Files[0];
var publicUrl = _mediaService.UploadMediaFile(viewModel.MediaPath, file);
var publicUrl = _mediaService.UploadMediaFile(viewModel.MediaPath, file, viewModel.ExtractZip);
return Content(string.Format("<script type=\"text/javascript\">var result = {{ url: \"{0}\" }};</script>", publicUrl));
}

View File

@@ -12,7 +12,8 @@ namespace Orchard.Media.Services {
void RenameFolder(string path, string newName);
void DeleteFile(string name, string folderName);
void RenameFile(string name, string newName, string folderName);
string UploadMediaFile(string folderName, HttpPostedFileBase postedFile);
string UploadMediaFile(string folderName, string fileName, byte[] bytes, bool extractZip);
string UploadMediaFile(string folderName, HttpPostedFileBase postedFile, bool extractZip);
bool FileAllowed(HttpPostedFileBase postedFile);
}
}

View File

@@ -91,23 +91,43 @@ namespace Orchard.Media.Services {
_storageProvider.RenameFile(_storageProvider.Combine(folderName, name), _storageProvider.Combine(folderName, newName));
}
public string UploadMediaFile(string folderName, HttpPostedFileBase postedFile) {
if (postedFile.FileName.EndsWith(".zip")) {
UnzipMediaFileArchive(folderName, postedFile);
// Don't save the zip file.
return _storageProvider.GetPublicUrl(folderName);
}
if (FileAllowed(postedFile) && postedFile.ContentLength > 0) {
var filePath = Path.Combine(folderName, Path.GetFileName(postedFile.FileName));
var inputStream = postedFile.InputStream;
public string UploadMediaFile(string folderName, HttpPostedFileBase postedFile, bool extractZip) {
var postedFileLength = postedFile.ContentLength;
var postedFileStream = postedFile.InputStream;
var postedFileData = new byte[postedFileLength];
postedFileStream.Read(postedFileData, 0, postedFileLength);
return UploadMediaFile(folderName, postedFile.FileName, postedFileData, extractZip);
}
public string UploadMediaFile(string folderPath, string fileName, byte [] bytes, bool extractZip) {
if (extractZip && fileName.EndsWith(".zip")) {
UnzipMediaFileArchive(folderPath, bytes);
// Don't save the zip file.
return _storageProvider.GetPublicUrl(folderPath);
}
if (FileAllowed(fileName, true) && bytes.Length > 0) {
string filePath = Path.Combine(folderPath, Path.GetFileName(fileName));
_storageProvider.TryCreateFolder(folderPath);
IStorageFile file = _storageProvider.CreateFile(filePath);
using(var stream = file.OpenWrite()) {
stream.Write(bytes, 0, bytes.Length);
}
SaveStream(filePath, inputStream);
return _storageProvider.GetPublicUrl(filePath);
}
return null;
}
public bool FileAllowed(HttpPostedFileBase postedFile) {
if (postedFile == null) {
return false;
}
return FileAllowed(postedFile.FileName, true);
}
private bool FileAllowed(string name, bool allowZip) {
if (string.IsNullOrWhiteSpace(name)) {
return false;
@@ -138,13 +158,6 @@ namespace Orchard.Media.Services {
return true;
}
public bool FileAllowed(HttpPostedFileBase postedFile) {
if (postedFile == null) {
return false;
}
return FileAllowed(postedFile.FileName, true);
}
private void SaveStream(string filePath, Stream inputStream) {
var file = _storageProvider.CreateFile(filePath);
var outputStream = file.OpenWrite();
@@ -165,6 +178,10 @@ namespace Orchard.Media.Services {
var postedFileData = new byte[postedFileLength];
postedFileStream.Read(postedFileData, 0, postedFileLength);
UnzipMediaFileArchive(targetFolder, postedFileData);
}
private void UnzipMediaFileArchive(string targetFolder, byte [] postedFileData) {
using (var memoryStream = new MemoryStream(postedFileData)) {
var fileInflater = new ZipInputStream(memoryStream);
ZipEntry entry;
@@ -182,13 +199,7 @@ namespace Orchard.Media.Services {
// skip disallowed files
if (FileAllowed(entry.Name, false)) {
try {
_storageProvider.CreateFolder(directoryName);
}
catch {
// no handling needed - this is to force the folder to exist if it doesn't
}
_storageProvider.TryCreateFolder(directoryName);
SaveStream(entryName, fileInflater);
}
}

View File

@@ -1,22 +1,25 @@
using System;
using System.IO;
using System.Web;
using System.Xml.Linq;
using JetBrains.Annotations;
using Orchard.Core.XmlRpc;
using Orchard.Core.XmlRpc.Models;
using Orchard.Security;
using Orchard.Utility.Extensions;
namespace Orchard.Media.Services {
[UsedImplicitly]
public class XmlRpcHandler : IXmlRpcHandler {
private readonly IMembershipService _membershipService;
private readonly IAuthorizationService _authorizationService;
private readonly IMediaService _mediaService;
public XmlRpcHandler(IMembershipService membershipService, IAuthorizationService authorizationService) {
public XmlRpcHandler(
IMembershipService membershipService,
IAuthorizationService authorizationService,
IMediaService mediaService) {
_membershipService = membershipService;
_authorizationService = authorizationService;
_mediaService = mediaService;
}
public void SetCapabilities(XElement options) {
@@ -25,15 +28,8 @@ namespace Orchard.Media.Services {
}
public void Process(XmlRpcContext context) {
var uriBuilder = new UriBuilder(context.HttpContext.Request.ToUrlString()) {
Path = context.HttpContext.Request.ApplicationPath,
Query = string.Empty
};
if (context.Request.MethodName == "metaWeblog.newMediaObject") {
var result = MetaWeblogNewMediaObject(
uriBuilder,
Convert.ToString(context.Request.Params[0].Value),
Convert.ToString(context.Request.Params[1].Value),
Convert.ToString(context.Request.Params[2].Value),
(XRpcStruct)context.Request.Params[3].Value);
@@ -42,8 +38,6 @@ namespace Orchard.Media.Services {
}
private XRpcStruct MetaWeblogNewMediaObject(
UriBuilder uriBuilder,
string blogId,
string userName,
string password,
XRpcStruct file) {
@@ -57,14 +51,8 @@ namespace Orchard.Media.Services {
var name = file.Optional<string>("name");
var bits = file.Optional<byte[]>("bits");
var target = HttpContext.Current.Server.MapPath("~/Media/" + name);
Directory.CreateDirectory(Path.GetDirectoryName(target));
using (var stream = new FileStream(target, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) {
stream.Write(bits, 0, bits.Length);
}
uriBuilder.Path = uriBuilder.Path.TrimEnd('/') + "/Media/" + name.TrimStart('/');
return new XRpcStruct().Set("url", uriBuilder.Uri.AbsoluteUri);
string publicUrl = _mediaService.UploadMediaFile(Path.GetDirectoryName(name), Path.GetFileName(name), bits, true);
return new XRpcStruct().Set("url", publicUrl);
}
}
}

View File

@@ -1,6 +1,11 @@
namespace Orchard.Media.ViewModels {
public class MediaItemAddViewModel {
public MediaItemAddViewModel() {
ExtractZip = true;
}
public string FolderName { get; set; }
public string MediaPath { get; set; }
public bool ExtractZip { get; set; }
}
}

View File

@@ -17,6 +17,10 @@
<fieldset>
<label for="pageTitle">@T("File Path <span> - multiple files must be in a zipped folder</span>")</label>
<input id="MediaItemPath" name="MediaItemPath" type="file" value="@T("Browse")" size="64"/>
@Html.LabelFor(m => m.ExtractZip, T("Extract Zip"))
@Html.CheckBoxFor(m => m.ExtractZip)
<span class="hint">@T("After your files have been uploaded, you can edit the titles and descriptions.")</span>
<input type="hidden" id="FolderName" name="FolderName" value="@Model.FolderName" />
<input type="hidden" id="MediaPath" name="MediaPath" value="@Model.MediaPath" />

View File

@@ -94,12 +94,16 @@ namespace Orchard.FileSystems.Media {
return (di.Attributes & FileAttributes.Hidden) != 0;
}
public void TryCreateFolder(string path) {
Directory.CreateDirectory(Map(path));
}
public void CreateFolder(string path) {
if (Directory.Exists(Map(path))) {
throw new ArgumentException(T("Directory {0} already exists", path).ToString());
}
Directory.CreateDirectory(Map(path));
TryCreateFolder(Map(path));
}
public void DeleteFolder(string path) {

View File

@@ -6,6 +6,7 @@ namespace Orchard.FileSystems.Media {
IStorageFile GetFile(string path);
IEnumerable<IStorageFile> ListFiles(string path);
IEnumerable<IStorageFolder> ListFolders(string path);
void TryCreateFolder(string path);
void CreateFolder(string path);
void DeleteFolder(string path);
void RenameFolder(string path, string newPath);