Merge with 6.0.1

This commit is contained in:
Shannon Deminick
2013-02-19 20:19:43 +06:00
6 changed files with 132 additions and 166 deletions

View File

@@ -1,8 +1,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Umbraco.Core.CodeAnnotations;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.IO
@@ -27,6 +25,15 @@ namespace Umbraco.Core.IO
return propertyId.ToString() + seperator + fileName;
}
public string GetRelativePath(string subfolder, string fileName)
{
var seperator = UmbracoSettings.UploadAllowDirectories
? Path.DirectorySeparatorChar
: '-';
return subfolder + seperator + fileName;
}
public IEnumerable<string> GetThumbnails(string path)
{
var parentDirectory = System.IO.Path.GetDirectoryName(path);

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Umbraco.Core.IO;
namespace Umbraco.Core.Media
{
/// <summary>
/// Internal singleton to handle the numbering of subfolders within the Media-folder.
/// When this class is initiated it will look for numbered subfolders and select the highest number,
/// which will be the start point for the naming of the next subfolders. If no subfolders exists
/// then the starting point will be 1000, ie. /media/1000/koala.jpg
/// </summary>
internal class MediaSubfolderCounter
{
#region Singleton
private long _numberedFolder = 1000;//Default starting point
private static readonly ReaderWriterLockSlim ClearLock = new ReaderWriterLockSlim();
private static readonly Lazy<MediaSubfolderCounter> Lazy = new Lazy<MediaSubfolderCounter>(() => new MediaSubfolderCounter());
public static MediaSubfolderCounter Current { get { return Lazy.Value; } }
private MediaSubfolderCounter()
{
var folders = new List<long>();
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
var directories = fs.GetDirectories("");
foreach (var directory in directories)
{
long dirNum;
if (long.TryParse(directory, out dirNum))
{
folders.Add(dirNum);
}
}
var last = folders.OrderBy(x => x).LastOrDefault();
if(last != default(long))
_numberedFolder = last;
}
#endregion
/// <summary>
/// Returns an increment of the numbered media subfolders.
/// </summary>
/// <returns>A <see cref="System.Int64"/> value</returns>
public long Increment()
{
using (new ReadLock(ClearLock))
{
_numberedFolder = _numberedFolder + 1;
return _numberedFolder;
}
}
}
}

View File

@@ -11,6 +11,7 @@ using System.Xml;
using System.Xml.Linq;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Media;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.UnitOfWork;
@@ -142,16 +143,22 @@ namespace Umbraco.Core.Models
/// <summary>
/// Sets and uploads the file from a HttpPostedFileBase object as the property value
/// </summary>
/// <param name="content"><see cref="IContent"/> to add property value to</param>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFileBase"/> containing the file that will be uploaded</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileBase value)
{
// Ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
var fileName = value.FileName;
if (fileName.LastIndexOf(@"\") > 0)
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
var name =
IOHelper.SafeFileName(
value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1,
value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
fileName.Substring(fileName.LastIndexOf(IOHelper.DirSepChar) + 1,
fileName.Length - fileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
if (string.IsNullOrEmpty(name) == false)
SetFileOnContent(content, propertyTypeAlias, name, value.InputStream);
@@ -160,16 +167,22 @@ namespace Umbraco.Core.Models
/// <summary>
/// Sets and uploads the file from a HttpPostedFile object as the property value
/// </summary>
/// <param name="content"><see cref="IContent"/> to add property value to</param>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFile"/> containing the file that will be uploaded</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFile value)
{
// Ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
var fileName = value.FileName;
if (fileName.LastIndexOf(@"\") > 0)
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
var name =
IOHelper.SafeFileName(
value.FileName.Substring(value.FileName.LastIndexOf(IOHelper.DirSepChar) + 1,
value.FileName.Length - value.FileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
fileName.Substring(fileName.LastIndexOf(IOHelper.DirSepChar) + 1,
fileName.Length - fileName.LastIndexOf(IOHelper.DirSepChar) - 1)
.ToLower());
if (string.IsNullOrEmpty(name) == false)
SetFileOnContent(content, propertyTypeAlias, name, value.InputStream);
@@ -178,13 +191,33 @@ namespace Umbraco.Core.Models
/// <summary>
/// Sets and uploads the file from a HttpPostedFileWrapper object as the property value
/// </summary>
/// <param name="content"><see cref="IContent"/> to add property value to</param>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="value">The <see cref="HttpPostedFileWrapper"/> containing the file that will be uploaded</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, HttpPostedFileWrapper value)
{
if (string.IsNullOrEmpty(value.FileName) == false)
SetFileOnContent(content, propertyTypeAlias, value.FileName, value.InputStream);
// Ensure we get the filename without the path in IE in intranet mode
// http://stackoverflow.com/questions/382464/httppostedfile-filename-different-from-ie
var fileName = value.FileName;
if (fileName.LastIndexOf(@"\") > 0)
fileName = fileName.Substring(fileName.LastIndexOf(@"\") + 1);
if (string.IsNullOrEmpty(fileName) == false)
SetFileOnContent(content, propertyTypeAlias, fileName, value.InputStream);
}
/// <summary>
/// Sets and uploads the file from a <see cref="Stream"/> as the property value
/// </summary>
/// <param name="content"><see cref="IContentBase"/> to add property value to</param>
/// <param name="propertyTypeAlias">Alias of the property to save the value on</param>
/// <param name="fileName">Name of the file</param>
/// <param name="fileStream"><see cref="Stream"/> to save to disk</param>
public static void SetValue(this IContentBase content, string propertyTypeAlias, string fileName,
Stream fileStream)
{
if (string.IsNullOrEmpty(fileName) == false && fileStream != null)
SetFileOnContent(content, propertyTypeAlias, fileName, fileStream);
}
private static void SetFileOnContent(IContentBase content, string propertyTypeAlias, string name, Stream fileStream)
@@ -194,10 +227,12 @@ namespace Umbraco.Core.Models
return;
bool supportsResizing = false;
var numberedFolder = MediaSubfolderCounter.Current.Increment();
string fileName = UmbracoSettings.UploadAllowDirectories
? Path.Combine(property.Id.ToString(), name)
: property.Id + "-" + name;
string extension = Path.GetExtension(name);
? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), name)
: numberedFolder + "-" + name;
string extension = Path.GetExtension(name).Substring(1).ToLowerInvariant();
var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
fs.AddFile(fileName, fileStream);

View File

@@ -143,6 +143,7 @@
<Compile Include="Events\SendToPublishEventArgs.cs" />
<Compile Include="IApplicationEventHandler.cs" />
<Compile Include="MacroPropertyTypeResolver.cs" />
<Compile Include="Media\MediaSubfolderCounter.cs" />
<Compile Include="Models\ContentBase.cs" />
<Compile Include="Models\ContentExtensions.cs" />
<Compile Include="Enum.cs" />

View File

@@ -1,8 +1,10 @@
using System;
using System.Globalization;
using System.IO;
using System.Web;
using System.Xml;
using Umbraco.Core.IO;
using Umbraco.Core.Media;
using umbraco.cms.businesslogic.Files;
using umbraco.cms.businesslogic.property;
@@ -55,9 +57,10 @@ namespace umbraco.cms.businesslogic.datatype
// handle upload
if (name != String.Empty)
{
var numberedFolder = MediaSubfolderCounter.Current.Increment();
string fileName = UmbracoSettings.UploadAllowDirectories
? Path.Combine(PropertyId.ToString(), name)
: PropertyId + "-" + name;
? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), name)
: numberedFolder + "-" + name;
//fileName = Path.Combine(SystemDirectories.Media, fileName);
UmbracoFile um = UmbracoFile.Save(fileStream, fileName);

View File

@@ -1,15 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Web;
using Umbraco.Core.Logging;
using umbraco.BasePages;
using System.Collections.Generic;
using Umbraco.Core.Models;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.datatype;
namespace umbraco.cms.businesslogic.media
{
@@ -27,146 +18,17 @@ namespace umbraco.cms.businesslogic.media
public override void DoHandleMedia(Media media, PostedMediaFile postedFile, User user)
{
// Get Image object, width and height
var image = Image.FromStream(postedFile.InputStream);
var fileWidth = image.Width;
var fileHeight = image.Height;
// Set media property to upload the file as well as set all related properties
media.MediaItem.SetValue("umbracoFile", postedFile.FileName, postedFile.InputStream);
// Get umbracoFile property
var propertyId = media.getProperty("umbracoFile").Id;
// Copy back the values from the internal IMedia to ensure that the values are persisted when saved
foreach (var property in media.MediaItem.Properties)
{
media.getProperty(property.Alias).Value = property.Value;
}
// Get paths
var destFilePath = FileSystem.GetRelativePath(propertyId, postedFile.FileName);
var ext = Path.GetExtension(destFilePath).Substring(1);
// Set media properties
media.getProperty("umbracoFile").Value = FileSystem.GetUrl(destFilePath);
if (media.getProperty("umbracoWidth") != null)
media.getProperty("umbracoWidth").Value = fileWidth;
if (media.getProperty("umbracoHeight") != null)
media.getProperty("umbracoHeight").Value = fileHeight;
if (media.getProperty("umbracoBytes") != null)
media.getProperty("umbracoBytes").Value = postedFile.ContentLength;
if (media.getProperty("umbracoExtension") != null)
media.getProperty("umbracoExtension").Value = ext;
if (media.getProperty("umbracoExtensio") != null)
media.getProperty("umbracoExtensio").Value = ext;
// Generate thumbnail
var thumbDestFilePath = Path.Combine(Path.GetDirectoryName(destFilePath), Path.GetFileNameWithoutExtension(destFilePath) + "_thumb");
GenerateThumbnail(image, 100, fileWidth, fileHeight, ext, thumbDestFilePath + ".jpg");
// Generate additional thumbnails based on PreValues set in DataTypeDefinition uploadField
GenerateAdditionalThumbnails(image, fileWidth, fileHeight, ext, thumbDestFilePath);
image.Dispose();
FileSystem.AddFile(destFilePath, postedFile.InputStream, postedFile.ReplaceExisting);
// Save media
// Save media (using legacy media object to ensure the usage of the legacy events).
media.Save();
}
private void GenerateAdditionalThumbnails(Image image, int fileWidth, int fileHeight, string ext, string destFilePath)
{
var uploadFieldDataTypeId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c");
DataTypeDefinition dataTypeDef = null;
try
{
// Get DataTypeDefinition of upload field
dataTypeDef = DataTypeDefinition.GetByDataTypeId(uploadFieldDataTypeId);
}
catch (Exception e)
{
LogHelper.Error<UmbracoImageMediaFactory>("Could get Upload Field datatype definition", e);
}
if (dataTypeDef != null)
{
// Get PreValues
var preValues = PreValues.GetPreValues(dataTypeDef.Id);
var thumbnails = "";
if (preValues.Count > 0)
thumbnails = ((PreValue)preValues[0]).Value;
if (thumbnails != "")
{
var thumbnailSizes = thumbnails.Split(";".ToCharArray());
foreach (var thumb in thumbnailSizes.Where(thumb => thumb != ""))
{
GenerateThumbnail(image, int.Parse(thumb), fileWidth, fileHeight, ext, destFilePath + "_" + thumb + ".jpg");
}
}
}
}
private void GenerateThumbnail(Image image, int maxWidthHeight, int fileWidth, int fileHeight, string ext, string thumbnailFileName)
{
// Generate thumbnailee
var fx = (float)fileWidth / maxWidthHeight;
var fy = (float)fileHeight / maxWidthHeight;
// must fit in thumbnail size
var f = Math.Max(fx, fy); //if (f < 1) f = 1;
var widthTh = (int)Math.Round(fileWidth / f);
var heightTh = (int)Math.Round(fileHeight / f);
// fixes for empty width or height
if (widthTh == 0)
widthTh = 1;
if (heightTh == 0)
heightTh = 1;
// Create new image with best quality settings
var bp = new Bitmap(widthTh, heightTh);
var g = Graphics.FromImage(bp);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
// Copy the old image to the new and resized
var rect = new Rectangle(0, 0, widthTh, heightTh);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel);
// Copy metadata
var codecs = ImageCodecInfo.GetImageEncoders();
var codec = ext.ToLower() == "png" || ext.ToLower() == "gif"
? codecs.Single(t => t.MimeType.Equals("image/png"))
: codecs.Single(t => t.MimeType.Equals("image/jpeg"));
// Set compresion ratio to 90%
var ep = new EncoderParameters();
ep.Param[0] = new EncoderParameter(Encoder.Quality, 90L);
// Save the new image
if (codec != null)
{
var ms = new MemoryStream();
bp.Save(ms, codec, ep);
ms.Seek(0, 0);
FileSystem.AddFile(thumbnailFileName, ms);
ms.Close();
}
else
{
// Log error
LogHelper.Warn<UmbracoImageMediaFactory>("Multiple file upload: Can't find appropriate codec");
}
bp.Dispose();
g.Dispose();
}
}
}