2018-06-29 19:52:40 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Threading.Tasks;
|
2018-09-02 22:56:55 +02:00
|
|
|
|
using Umbraco.Core.Composing;
|
2018-06-29 19:52:40 +02:00
|
|
|
|
using Umbraco.Core.Configuration.UmbracoSettings;
|
|
|
|
|
|
using Umbraco.Core.Exceptions;
|
|
|
|
|
|
using Umbraco.Core.Logging;
|
|
|
|
|
|
using Umbraco.Core.Media;
|
|
|
|
|
|
using Umbraco.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Core.IO
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// A custom file system provider for media
|
|
|
|
|
|
/// </summary>
|
2018-10-26 15:06:53 +02:00
|
|
|
|
public class MediaFileSystem : FileSystemWrapper, IMediaFileSystem
|
2018-06-29 19:52:40 +02:00
|
|
|
|
{
|
2018-10-26 15:06:53 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Initializes a new instance of the <see cref="MediaFileSystem"/> class.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public MediaFileSystem(IFileSystem innerFileSystem)
|
|
|
|
|
|
: base(innerFileSystem)
|
2018-06-29 19:52:40 +02:00
|
|
|
|
{
|
2018-09-02 22:56:55 +02:00
|
|
|
|
ContentConfig = Current.Container.GetInstance<IContentSection>();
|
|
|
|
|
|
Logger = Current.Container.GetInstance<ILogger>();
|
|
|
|
|
|
MediaPathScheme = Current.Container.GetInstance<IMediaPathScheme>();
|
2018-06-29 19:52:40 +02:00
|
|
|
|
MediaPathScheme.Initialize(this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-07-06 17:36:33 +02:00
|
|
|
|
private IMediaPathScheme MediaPathScheme { get; }
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
2018-07-06 17:36:33 +02:00
|
|
|
|
private IContentSection ContentConfig { get; }
|
2018-06-29 19:52:40 +02:00
|
|
|
|
|
2018-07-06 17:36:33 +02:00
|
|
|
|
private ILogger Logger { get; }
|
2018-06-20 10:49:12 +02:00
|
|
|
|
|
2018-10-26 15:06:53 +02:00
|
|
|
|
/// <inheritoc />
|
2018-06-29 19:52:40 +02:00
|
|
|
|
public void DeleteMediaFiles(IEnumerable<string> files)
|
|
|
|
|
|
{
|
|
|
|
|
|
files = files.Distinct();
|
|
|
|
|
|
|
2018-10-26 15:06:53 +02:00
|
|
|
|
// kinda try to keep things under control
|
|
|
|
|
|
var options = new ParallelOptions { MaxDegreeOfParallelism = 20 };
|
|
|
|
|
|
|
|
|
|
|
|
Parallel.ForEach(files, options, file =>
|
2018-06-29 19:52:40 +02:00
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
if (file.IsNullOrWhiteSpace()) return;
|
|
|
|
|
|
if (FileExists(file) == false) return;
|
|
|
|
|
|
DeleteFile(file);
|
|
|
|
|
|
|
2018-06-20 10:49:12 +02:00
|
|
|
|
var directory = MediaPathScheme.GetDeleteDirectory(file);
|
|
|
|
|
|
if (!directory.IsNullOrWhiteSpace())
|
2018-06-29 19:52:40 +02:00
|
|
|
|
DeleteDirectory(directory, true);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
|
{
|
2018-10-26 15:06:53 +02:00
|
|
|
|
Logger.Error<MediaFileSystem>(e, "Failed to delete media file '{File}'.", file);
|
2018-06-29 19:52:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region Media Path
|
|
|
|
|
|
|
2018-10-26 15:06:53 +02:00
|
|
|
|
/// <inheritoc />
|
2018-06-29 19:52:40 +02:00
|
|
|
|
public string GetMediaPath(string filename, Guid cuid, Guid puid)
|
|
|
|
|
|
{
|
|
|
|
|
|
filename = Path.GetFileName(filename);
|
|
|
|
|
|
if (filename == null) throw new ArgumentException("Cannot become a safe filename.", nameof(filename));
|
|
|
|
|
|
filename = IOHelper.SafeFileName(filename.ToLowerInvariant());
|
|
|
|
|
|
|
|
|
|
|
|
return MediaPathScheme.GetFilePath(cuid, puid, filename);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-26 15:06:53 +02:00
|
|
|
|
/// <inheritoc />
|
2018-06-29 19:52:40 +02:00
|
|
|
|
public string GetMediaPath(string filename, string prevpath, Guid cuid, Guid puid)
|
|
|
|
|
|
{
|
|
|
|
|
|
filename = Path.GetFileName(filename);
|
|
|
|
|
|
if (filename == null) throw new ArgumentException("Cannot become a safe filename.", nameof(filename));
|
|
|
|
|
|
filename = IOHelper.SafeFileName(filename.ToLowerInvariant());
|
|
|
|
|
|
|
|
|
|
|
|
return MediaPathScheme.GetFilePath(cuid, puid, filename, prevpath);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region Associated Media Files
|
|
|
|
|
|
|
2018-10-26 15:06:53 +02:00
|
|
|
|
/// <inheritoc />
|
2018-06-29 19:52:40 +02:00
|
|
|
|
public string StoreFile(IContentBase content, PropertyType propertyType, string filename, Stream filestream, string oldpath)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (content == null) throw new ArgumentNullException(nameof(content));
|
|
|
|
|
|
if (propertyType == null) throw new ArgumentNullException(nameof(propertyType));
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(filename)) throw new ArgumentNullOrEmptyException(nameof(filename));
|
|
|
|
|
|
if (filestream == null) throw new ArgumentNullException(nameof(filestream));
|
|
|
|
|
|
|
|
|
|
|
|
// clear the old file, if any
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(oldpath) == false)
|
|
|
|
|
|
DeleteFile(oldpath);
|
|
|
|
|
|
|
|
|
|
|
|
// get the filepath, store the data
|
|
|
|
|
|
// use oldpath as "prevpath" to try and reuse the folder, in original number-based scheme
|
|
|
|
|
|
var filepath = GetMediaPath(filename, oldpath, content.Key, propertyType.Key);
|
|
|
|
|
|
AddFile(filepath, filestream);
|
|
|
|
|
|
return filepath;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-26 15:06:53 +02:00
|
|
|
|
/// <inheritoc />
|
2018-06-29 19:52:40 +02:00
|
|
|
|
public string CopyFile(IContentBase content, PropertyType propertyType, string sourcepath)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (content == null) throw new ArgumentNullException(nameof(content));
|
|
|
|
|
|
if (propertyType == null) throw new ArgumentNullException(nameof(propertyType));
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(sourcepath)) throw new ArgumentNullOrEmptyException(nameof(sourcepath));
|
|
|
|
|
|
|
|
|
|
|
|
// ensure we have a file to copy
|
|
|
|
|
|
if (FileExists(sourcepath) == false) return null;
|
|
|
|
|
|
|
|
|
|
|
|
// get the filepath
|
|
|
|
|
|
var filename = Path.GetFileName(sourcepath);
|
|
|
|
|
|
var filepath = GetMediaPath(filename, content.Key, propertyType.Key);
|
|
|
|
|
|
this.CopyFile(sourcepath, filepath);
|
|
|
|
|
|
return filepath;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-26 15:06:53 +02:00
|
|
|
|
#endregion
|
2018-06-29 19:52:40 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|