1800 lines
52 KiB
Plaintext
1800 lines
52 KiB
Plaintext
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Constants\ConfigurationNodeNames.cs
|
|
|
|
namespace xStorageService.Constants {
|
|
public partial struct ConfigurationNodeNames {
|
|
public const string STORAGE_SERVICE_NODE_NAME = "StorageConfiguration";
|
|
}
|
|
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Constants\FileExtensions.cs
|
|
|
|
using xExceptions.Attributes;
|
|
|
|
namespace xStorageService.Constants {
|
|
public enum FileExtensions {
|
|
//
|
|
// Document
|
|
[StringValue (".txt")]
|
|
TEXT = 100,
|
|
|
|
[StringValue (".pdf")]
|
|
PDF = 101,
|
|
|
|
[StringValue (".ppt")]
|
|
PPT = 102,
|
|
|
|
[StringValue (".pptx")]
|
|
PPTX = 103,
|
|
|
|
[StringValue (".odp")]
|
|
ODP = 104,
|
|
|
|
[StringValue (".pps")]
|
|
PPS = 105,
|
|
|
|
[StringValue (".ods")]
|
|
ODS = 106,
|
|
|
|
[StringValue (".xlr")]
|
|
XLR = 107,
|
|
|
|
[StringValue (".xls")]
|
|
XLS = 108,
|
|
|
|
[StringValue (".xlsx")]
|
|
XLSX = 109,
|
|
|
|
[StringValue (".xml")]
|
|
XML = 110,
|
|
|
|
[StringValue (".doc")]
|
|
DOC = 111,
|
|
|
|
[StringValue (".docx")]
|
|
DOCX = 112,
|
|
|
|
[StringValue (".odt")]
|
|
ODT = 113,
|
|
|
|
[StringValue (".rtf")]
|
|
RTF = 114,
|
|
|
|
[StringValue (".tex")]
|
|
TEX = 115,
|
|
|
|
[StringValue (".wpd")]
|
|
WPD = 116,
|
|
|
|
[StringValue (".md")]
|
|
MD = 117,
|
|
|
|
//
|
|
// Archive
|
|
[StringValue (".zip")]
|
|
ZIP = 200,
|
|
|
|
//
|
|
// Internal Supports
|
|
[StringValue (".ttf")]
|
|
TTF = 300,
|
|
|
|
[StringValue (".js")]
|
|
JAVASCRIPT = 301,
|
|
|
|
[StringValue (".css")]
|
|
CSS = 302,
|
|
|
|
[StringValue (".htm")]
|
|
HTM = 303,
|
|
|
|
[StringValue (".html")]
|
|
HTML = 304,
|
|
|
|
[StringValue (".sdw")]
|
|
SAHER_DASHBOARD_WIDGET = 305,
|
|
|
|
[StringValue (".sdwmanifest")]
|
|
SAHER_DASHBOARD_WIDGET_MANIFEST = 306,
|
|
|
|
//
|
|
// Video
|
|
[StringValue (".mp4")]
|
|
MP4 = 400,
|
|
|
|
[StringValue (".avi")]
|
|
AVI = 401,
|
|
|
|
[StringValue (".mpg")]
|
|
MPG = 402,
|
|
|
|
[StringValue (".mpeg")]
|
|
MPEG = 403,
|
|
|
|
[StringValue (".wmv")]
|
|
WMV = 404,
|
|
|
|
//
|
|
// Audio
|
|
[StringValue (".mp3")]
|
|
MP3 = 500,
|
|
|
|
[StringValue (".ogg")]
|
|
OGG = 501,
|
|
|
|
[StringValue (".wav")]
|
|
WAV = 502,
|
|
|
|
[StringValue (".wma")]
|
|
WMA = 503,
|
|
|
|
//
|
|
// Image
|
|
[StringValue (".png")]
|
|
PNG = 600,
|
|
|
|
[StringValue (".jpeg")]
|
|
JPEG = 601,
|
|
|
|
[StringValue (".jpg")]
|
|
JPG = 602,
|
|
|
|
// [StringValue (".ico")]
|
|
// ICON = 603,
|
|
|
|
[StringValue (".gif")]
|
|
GIF = 604,
|
|
|
|
[StringValue (".bmp")]
|
|
BITMAP = 605,
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\DI\XDIHelperExtension.cs
|
|
|
|
using System.IO;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xStorageService.Constants;
|
|
using xStorageService.Helpers;
|
|
using xStorageService.Interfaces;
|
|
using xStorageService.Models;
|
|
using xStorageService.Providers;
|
|
|
|
namespace xStorageService.DI {
|
|
public static partial class XDIHelperExtension {
|
|
/// <summary>
|
|
/// Retrieve XStorage Configuration from AppSettings
|
|
/// </summary>
|
|
/// <param name="configuration"></param>
|
|
/// <returns></returns>
|
|
public static XStorageConfiguration GetXStorageConfiguration (this IConfiguration configuration) {
|
|
//
|
|
var storageConfigurationSection = configuration.GetSection (ConfigurationNodeNames.STORAGE_SERVICE_NODE_NAME);
|
|
return storageConfigurationSection.Get<XStorageConfiguration> ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XStorage Configuration
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="configuration"></param>
|
|
public static void AddXStorageConfiguration (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
// Check wwwroot Folder ...
|
|
if (!Directory.Exists ("wwwroot")) {
|
|
Directory.CreateDirectory ("wwwroot");
|
|
}
|
|
|
|
//
|
|
// Retrieve and Register XStorage Configurations ...
|
|
var xStorageConfiguration = configuration.GetXStorageConfiguration ();
|
|
if (xStorageConfiguration.IsNull ()) {
|
|
XException.InvalidConfiguration.Throw ();
|
|
}
|
|
|
|
//
|
|
xStorageConfiguration.BaseFolder = Path.Combine (Directory.GetCurrentDirectory (), "wwwroot");
|
|
xStorageConfiguration.RootFolder = Directory.GetDirectoryRoot (xStorageConfiguration.BaseFolder);
|
|
|
|
//
|
|
services.AddSingleton<XStorageConfiguration> (xStorageConfiguration);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Register XStorage Service
|
|
/// </summary>
|
|
/// <param name="services"></param>
|
|
/// <param name="config"></param>
|
|
public static void AddXStorageService (
|
|
this IServiceCollection services,
|
|
IConfiguration configuration
|
|
) {
|
|
//
|
|
// Register and Retrieve XStorage Configuration
|
|
services.AddXStorageConfiguration (configuration);
|
|
var xStorageConfiguration = services.GetRegisteredService<XStorageConfiguration> ();
|
|
|
|
//
|
|
// Add File Provider ...
|
|
services.AddSingleton<IFileProvider> (
|
|
new PhysicalFileProvider (xStorageConfiguration.BaseFolder)
|
|
);
|
|
|
|
//
|
|
// Register XStorageHelper Service ...
|
|
services.AddSingleton<XStorageHelper> ();
|
|
|
|
//
|
|
// Register ThumbnailHelper ...
|
|
services.AddSingleton<IXThumbnailProvider, XThumbnailProvider> ();
|
|
|
|
//
|
|
// Register Storage Provider ...
|
|
services.AddScoped<IXStorageProvider, XStorageProvider> ();
|
|
|
|
//
|
|
// StorageService Preperation...
|
|
var xStorageService = services.GetRegisteredService<IXStorageProvider> ();
|
|
xStorageService.Prepare ();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use XStorage Service
|
|
/// </summary>
|
|
/// <param name="app"></param>
|
|
public static void UseXStorageService (this IApplicationBuilder app) {
|
|
//
|
|
// Get Instance of Scope and Service and Prepare Folder Structure ...
|
|
using (var scope = app.ApplicationServices.CreateScope ()) {
|
|
//
|
|
var storageProvider = scope.ServiceProvider.GetService<IXStorageProvider> ();
|
|
|
|
//
|
|
storageProvider.Prepare ();
|
|
}
|
|
|
|
//
|
|
// available Static Files ...
|
|
app.UseStaticFiles ();
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Helpers\XStorageHelper.cs
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xStorageService.Constants;
|
|
|
|
namespace xStorageService.Helpers {
|
|
public partial class XStorageHelper {
|
|
|
|
private int[] DocumentTypeThreshold = new int[] { 99, 307 };
|
|
private int[] ImageTypeThreshold = new int[] { 599, 606 };
|
|
private int[] AudioTypeThreshold = new int[] { 499, 504 };
|
|
private int[] VideoTypeThreshold = new int[] { 399, 405 };
|
|
|
|
public XStorageHelper () { }
|
|
|
|
/// <summary>
|
|
/// Retrieve FileType
|
|
/// </summary>
|
|
/// <param name="fileExtension"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetType (int fileExtension) {
|
|
//
|
|
// Compare File Extension Integer Value and
|
|
// Find Propper Type for it ...
|
|
if (fileExtension > DocumentTypeThreshold[0] && fileExtension < DocumentTypeThreshold[1]) {
|
|
return XFileType.Document;
|
|
} else if (fileExtension > VideoTypeThreshold[0] && fileExtension < VideoTypeThreshold[1]) {
|
|
return XFileType.Video;
|
|
} else if (fileExtension > AudioTypeThreshold[0] && fileExtension < AudioTypeThreshold[1]) {
|
|
return XFileType.Audio;
|
|
} else if (fileExtension > ImageTypeThreshold[0] && fileExtension < ImageTypeThreshold[1]) {
|
|
return XFileType.Image;
|
|
} else {
|
|
//
|
|
// if not in case return Document Type
|
|
return XFileType.Document;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a File Type
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetType (string fileName) {
|
|
//
|
|
if (fileName.IsNullOrEmpty ()) {
|
|
XException.InavlidFile.Throw ();
|
|
}
|
|
|
|
//
|
|
var ext = GetFileExtension (fileName);
|
|
var extType = GetExtensionType (ext);
|
|
return GetType (extType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// used for validating Extension in Widget Upload ...
|
|
/// </summary>
|
|
/// <returns>an string array</returns>
|
|
public string[] GetAllowedExtensionsForWidgetUpload () {
|
|
return new [] {
|
|
FileExtensions.SAHER_DASHBOARD_WIDGET.GetStringValue ()
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a Files Extension string
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileExtension (string fileName) {
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var fileExt = "";
|
|
try {
|
|
fileExt = Path.GetExtension (fileName);
|
|
} catch { }
|
|
|
|
//
|
|
return fileExt;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a File Name Without it's Extension
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileNameWithoutExtension (string fileName) {
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty ()) {
|
|
return null;
|
|
}
|
|
|
|
//
|
|
var fileNameWithoutExt = "";
|
|
try {
|
|
fileNameWithoutExt = Path
|
|
.GetFileNameWithoutExtension (fileName);
|
|
} catch { }
|
|
|
|
//
|
|
return fileNameWithoutExt;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get File Extension Type
|
|
/// </summary>
|
|
/// <param name="fileExtension"></param>
|
|
/// <returns></returns>
|
|
public int GetExtensionType (string fileExtension) {
|
|
//
|
|
foreach (var extItem in Enum
|
|
.GetValues (typeof (FileExtensions))
|
|
.Cast<FileExtensions> ()) {
|
|
if (extItem.GetStringValue ()
|
|
.Contains (fileExtension.ToLower ())) {
|
|
return (int) extItem;
|
|
}
|
|
}
|
|
|
|
//
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Interfaces\IXStorageProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using xCommons.Constants;
|
|
using xModels.Dtos;
|
|
using xStorageService.Constants;
|
|
using xStorageService.Helpers;
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Interfaces
|
|
{
|
|
public partial interface IXStorageProvider
|
|
{
|
|
XStorageConfiguration Configuration { get; }
|
|
XStorageHelper StorageHelper { get; }
|
|
IFileProvider FileProvider { get; }
|
|
IXThumbnailProvider ThumbnailProvider { get; }
|
|
|
|
//
|
|
#region Special Folders Path Getter (s) ...
|
|
string GetStorageFolderPath();
|
|
string GetTempFolderPath();
|
|
string GetThumbFolderPath();
|
|
string GetUploadsFolderPath();
|
|
string GetWidgetsFolderPath();
|
|
string GetImageFolderPath();
|
|
string GetAudioFolderPath();
|
|
string GetVideoFolderPath();
|
|
string GetDocumentFolderPath();
|
|
string FilePathResolver(string fullPath);
|
|
string ConvertToFileUrl(string fullPath);
|
|
#endregion
|
|
|
|
//
|
|
#region Prepare Storage Structure ...
|
|
void Prepare();
|
|
#endregion
|
|
|
|
//
|
|
#region Validators ...
|
|
bool IsFolderExists(string path);
|
|
bool IsFileExists(string filePath);
|
|
bool IsSupportThumb(string fileName);
|
|
bool IsSupportThumb(XFileType type);
|
|
void ValidateFileExists(string filePath);
|
|
void ValidateFileModel(XFileDto file);
|
|
void ValidateFile(IFormFile file);
|
|
void ValidateProfileImage(IFormFile file);
|
|
#endregion
|
|
|
|
//
|
|
#region Generators ...
|
|
string NewFileName();
|
|
string GenerateThumbName(string fileName);
|
|
string GetNewFileName(string fileName);
|
|
#endregion
|
|
|
|
//
|
|
#region Tools Actions ...
|
|
|
|
string GetFileExtension(string fileName);
|
|
string GetFileNameWithoutExtension(string fileName);
|
|
FileExtensions GetFileExtensionType(string fileName);
|
|
XFileType GetFileType(string fileName);
|
|
XFileType GetFileType(FileExtensions fileExtension);
|
|
string GetThumbnailFileFullPath(string thumFileName);
|
|
string GetRelatedThumbnailFullPath(string fileName);
|
|
string GetFileTypeFolderPath(XFileType type);
|
|
string GetFileFolderPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
);
|
|
string GetFileFullPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
);
|
|
Task<string> SaveFileAsync(
|
|
IFormFile file,
|
|
bool isTemp = false,
|
|
bool isWidget = false,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
void DeleteFile(
|
|
string fileFullPath,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
);
|
|
ICollection<string> DeleteFiles(
|
|
ICollection<string> fileFullPaths,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
);
|
|
// Task CreateThumbnail (XFile file);
|
|
Task CreateThumbnail(
|
|
XFileDto file,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task CreateThumbnail(
|
|
string fileName,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task<XFileResult> HandleProfileImageSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task<XFileResult> HandleFileSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
Task<IEnumerable<XFileResult>> HandleFilesSave(
|
|
IFormFileCollection files,
|
|
CancellationToken cancellationToken = default
|
|
);
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Interfaces\IXThumbnailProvider.cs
|
|
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Interfaces {
|
|
public partial interface IXThumbnailProvider {
|
|
void SetTempFolder (string folder);
|
|
XImageInfo GetImageInfo (string filePath);
|
|
void ResizeImage (
|
|
string filePath,
|
|
string resizedFilePath,
|
|
int size,
|
|
int quality
|
|
);
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XFileResult.cs
|
|
|
|
namespace xStorageService.Models {
|
|
public partial class XFileResult {
|
|
public string Name { get; set; }
|
|
public string FileName { get; set; }
|
|
public string FilePath { get; set; }
|
|
public string Thmbnail { get; set; }
|
|
public string ThmbnailPath { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XImageInfo.cs
|
|
|
|
using ImageMagick;
|
|
|
|
namespace xStorageService.Models {
|
|
public partial class XImageInfo {
|
|
public Interlace Interlace { get; }
|
|
public int Height { get; }
|
|
public MagickFormat Format { get; }
|
|
public string FileName { get; }
|
|
public Density Density { get; }
|
|
public CompressionMethod Compression { get; }
|
|
public ColorSpace ColorSpace { get; }
|
|
public int Width { get; }
|
|
public int Quality { get; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Models\XStorageConfiguration.cs
|
|
|
|
namespace xStorageService.Models {
|
|
public partial class XStorageConfiguration {
|
|
/// <summary>
|
|
/// Base Path of Identity Host Server
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string IdentityAuthority { get; set; }
|
|
|
|
/// <summary>
|
|
/// Base Path of Host Server
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Authority { get; set; }
|
|
|
|
/// <summary>
|
|
/// Root Directory Of File Storage
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string RootFolder { get; set; }
|
|
|
|
/// <summary>
|
|
/// Base Root of Usable Folder for Files
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string BaseFolder { get; set; }
|
|
|
|
/// <summary>
|
|
/// Storage Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Storage { get; set; }
|
|
|
|
/// <summary>
|
|
/// Temp Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Temp { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumb Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Thumb { get; set; }
|
|
|
|
/// <summary>
|
|
/// Uploads Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Uploads { get; set; }
|
|
|
|
/// <summary>
|
|
/// Widgets Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Widgets { get; set; }
|
|
|
|
/// <summary>
|
|
/// Images Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Image { get; set; }
|
|
|
|
/// <summary>
|
|
/// Audios Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Audio { get; set; }
|
|
|
|
/// <summary>
|
|
/// Videos Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Video { get; set; }
|
|
|
|
/// <summary>
|
|
/// Documents Folder Label
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string Document { get; set; }
|
|
|
|
/// <summary>
|
|
/// new Files Prefix
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string FilePrefix { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumb Files Prefix
|
|
/// </summary>
|
|
/// <value></value>
|
|
public string ThumbPrefix { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumbnail File Sizes
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int ThumbSize { get; set; }
|
|
|
|
/// <summary>
|
|
/// Thumbnail File Quality
|
|
/// </summary>
|
|
/// <value></value>
|
|
public int ThumbQuality { get; set; }
|
|
|
|
/// <summary>
|
|
/// Max File Size
|
|
/// </summary>
|
|
/// <value></value>
|
|
public long MaxFileSize { get; set; }
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Providers\XStorageProvider.cs
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.ObjectModel;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.FileProviders;
|
|
using xCommons.Constants;
|
|
using xCommons.Extensions;
|
|
using xExceptions.Constants;
|
|
using xModels.Dtos;
|
|
using xStorageService.Constants;
|
|
using xStorageService.Helpers;
|
|
using xStorageService.Interfaces;
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Providers
|
|
{
|
|
public partial class XStorageProvider : IXStorageProvider
|
|
{
|
|
|
|
public readonly string BasePath;
|
|
private readonly XFileType[] ThumbSupprtedTypes = new XFileType[] {
|
|
XFileType.Image, XFileType.CoverImage, XFileType.ProfileImasge
|
|
};
|
|
|
|
public IFileProvider FileProvider { get; }
|
|
public XStorageHelper StorageHelper { get; }
|
|
public IXThumbnailProvider ThumbnailProvider { get; }
|
|
public XStorageConfiguration Configuration { get; }
|
|
|
|
public XStorageProvider(
|
|
IFileProvider fileProvider,
|
|
XStorageHelper storageHelper,
|
|
IXThumbnailProvider thumbnailProvider,
|
|
XStorageConfiguration configuration
|
|
)
|
|
{
|
|
//
|
|
FileProvider = fileProvider;
|
|
Configuration = configuration;
|
|
StorageHelper = storageHelper;
|
|
ThumbnailProvider = thumbnailProvider;
|
|
|
|
//
|
|
BasePath = Path
|
|
.Combine(Directory
|
|
.GetCurrentDirectory(), Configuration.BaseFolder);
|
|
}
|
|
|
|
//
|
|
#region Special Folders Path Getter (s) ...
|
|
/// <summary>
|
|
/// Get Storage Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetStorageFolderPath()
|
|
{
|
|
return Path.Combine(BasePath, Configuration.Storage);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Temp Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetTempFolderPath()
|
|
{
|
|
return Path.Combine(GetStorageFolderPath(), Configuration.Temp);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Uploads Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetUploadsFolderPath()
|
|
{
|
|
return Path.Combine(GetStorageFolderPath(), Configuration.Uploads);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Widgets Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetWidgetsFolderPath()
|
|
{
|
|
return Path.Combine(GetStorageFolderPath(), Configuration.Widgets);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Thumb Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetThumbFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Thumb);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Images Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetImageFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Image);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Audios Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetAudioFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Audio);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Videos Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetVideoFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Video);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get Documents Folder Path
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string GetDocumentFolderPath()
|
|
{
|
|
return Path.Combine(GetUploadsFolderPath(), Configuration.Document);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare Full Path to Use for Static Files
|
|
/// </summary>
|
|
/// <param name="fullPath"></param>
|
|
/// <returns></returns>
|
|
public string FilePathResolver(string fullPath)
|
|
{
|
|
return fullPath.Replace(BasePath, "");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a File Path to Url
|
|
/// </summary>
|
|
/// <param name="fullPath"></param>
|
|
/// <returns></returns>
|
|
public string ConvertToProfileImageUrl(string fullPath)
|
|
{
|
|
//
|
|
var authority = !Configuration.IdentityAuthority.IsNullOrEmpty() &&
|
|
Configuration.IdentityAuthority.EndsWith("/") ?
|
|
Configuration.IdentityAuthority.Substring(0, Configuration.IdentityAuthority.Length - 1) :
|
|
Configuration.IdentityAuthority;
|
|
|
|
//
|
|
return $"{authority}{FilePathResolver(fullPath)}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert a File Path to Url
|
|
/// </summary>
|
|
/// <param name="fullPath"></param>
|
|
/// <returns></returns>
|
|
public string ConvertToFileUrl(string fullPath)
|
|
{
|
|
//
|
|
var authority = !Configuration.Authority.IsNullOrEmpty() &&
|
|
Configuration.Authority.EndsWith("/") ?
|
|
Configuration.Authority.Substring(0, Configuration.Authority.Length - 1) :
|
|
Configuration.Authority;
|
|
|
|
//
|
|
return $"{authority}/{FilePathResolver(fullPath)}";
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Prepare Storage Structure ...
|
|
/// <summary>
|
|
/// Check Folder Structure of Storage Area
|
|
/// and Create them if not Exists
|
|
/// </summary>
|
|
public void Prepare()
|
|
{
|
|
//
|
|
try
|
|
{
|
|
//
|
|
// Storage Folder Path Check ...
|
|
if (!IsFolderExists(GetStorageFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetStorageFolderPath());
|
|
}
|
|
|
|
//
|
|
// Temp Folder Path Check ...
|
|
if (!IsFolderExists(GetTempFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetTempFolderPath());
|
|
}
|
|
|
|
//
|
|
// Temp Folder Path Check ...
|
|
if (!IsFolderExists(GetThumbFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetThumbFolderPath());
|
|
}
|
|
|
|
//
|
|
// Widgets Folder Path Chekc ...
|
|
if (!IsFolderExists(GetWidgetsFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetWidgetsFolderPath());
|
|
}
|
|
|
|
//
|
|
// Uploads Folder Path Chekc ...
|
|
if (!IsFolderExists(GetUploadsFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetUploadsFolderPath());
|
|
}
|
|
|
|
//
|
|
// Image Folder Path Chekc ...
|
|
if (!IsFolderExists(GetImageFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetImageFolderPath());
|
|
}
|
|
|
|
//
|
|
// Music Folder Path Chekc ...
|
|
if (!IsFolderExists(GetAudioFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetAudioFolderPath());
|
|
}
|
|
|
|
//
|
|
// Video Folder Path Chekc ...
|
|
if (!IsFolderExists(GetVideoFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetVideoFolderPath());
|
|
}
|
|
|
|
//
|
|
// Document Folder Path Chekc ...
|
|
if (!IsFolderExists(GetDocumentFolderPath()))
|
|
{
|
|
Directory.CreateDirectory(GetDocumentFolderPath());
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
XException.StorageServiceInitialFailed.Throw();
|
|
}
|
|
|
|
//
|
|
// Set Temp Folder for Actions ...
|
|
ThumbnailProvider.SetTempFolder(GetTempFolderPath());
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Validators ...
|
|
/// <summary>
|
|
/// Detrmines a Path Exists or not
|
|
/// </summary>
|
|
/// <param name="path"></param>
|
|
/// <returns></returns>
|
|
public bool IsFolderExists(string path)
|
|
{
|
|
return Directory.Exists(path);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a File Exists or not
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
/// <returns></returns>
|
|
public bool IsFileExists(string filePath)
|
|
{
|
|
return File.Exists(filePath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a File Name Support Thumbnail or not
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public bool IsSupportThumb(string fileName)
|
|
{
|
|
//
|
|
if (!fileName.StartsWith(Configuration.FilePrefix))
|
|
{
|
|
XException.InavlidFile.Throw();
|
|
}
|
|
|
|
//
|
|
var fileType = StorageHelper.GetType(fileName);
|
|
return IsSupportThumb(fileType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check a FileType Support Thumbnail or not
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public bool IsSupportThumb(XFileType type)
|
|
{
|
|
return ThumbSupprtedTypes.Contains(type);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a File Exists or not
|
|
/// </summary>
|
|
/// <param name="filePath"></param>
|
|
public void ValidateFileExists(string filePath)
|
|
{
|
|
//
|
|
if (!IsFileExists(filePath))
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a File Model with it's Related Physical File
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
public void ValidateFileModel(XFileDto file)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (file == null)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve Full File Path ...
|
|
var fileFullPath = file.Path;
|
|
if (fileFullPath.IsNullOrEmpty())
|
|
{
|
|
XException.InavlidFile.Throw();
|
|
}
|
|
|
|
//
|
|
// Retrieve is File Exists or not ...
|
|
var isPhysicalFileExists = IsFileExists(file.Path);
|
|
if (!isPhysicalFileExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate File for Upload
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
public void ValidateFile(IFormFile file)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (file == null)
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Check File Size not Zero ...
|
|
if (file.Length == 0)
|
|
{
|
|
XException.EmptyFile.Throw();
|
|
}
|
|
|
|
//
|
|
// Check File Max Size ...
|
|
if (file.Length > Configuration.MaxFileSize)
|
|
{
|
|
XException.MaxFileSizeExceeded.Throw();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate a Collection of IFormFile
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
public void ValidateFiles(IFormFileCollection files)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!files.HasChild())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
files.ToList()
|
|
.ForEach(f => ValidateFile(f));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Validate File for Profile Image
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
public void ValidateProfileImage(IFormFile file)
|
|
{
|
|
//
|
|
// Check File Validation ...
|
|
// since Args Checked in File Validation, there is no need to
|
|
// double check it ...
|
|
ValidateFile(file);
|
|
|
|
//
|
|
// Check File Type ...
|
|
var fileType = GetFileType(file.FileName);
|
|
if (fileType != XFileType.Image)
|
|
{
|
|
XException.UnsupportedFileType.Throw();
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Generators ...
|
|
/// <summary>
|
|
/// Generate New File
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public string NewFileName()
|
|
{
|
|
return Configuration.FilePrefix + Guid.NewGuid().ToString().ToLower();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Related Thumnail File
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GenerateThumbName(string fileName)
|
|
{
|
|
//
|
|
if (!IsSupportThumb(fileName))
|
|
{
|
|
XException.UnsupportedFileType.Throw();
|
|
}
|
|
|
|
//
|
|
return fileName.Replace(Configuration.FilePrefix, Configuration.ThumbPrefix);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a New FileName with Extension based on Given fileName
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetNewFileName(string fileName)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var fileExt = GetFileExtension(fileName);
|
|
var newFileNameWithoutExt = NewFileName();
|
|
|
|
//
|
|
// Generate New File Name ...
|
|
var newFileName = string.Format("{0}{1}", newFileNameWithoutExt, fileExt);
|
|
|
|
//
|
|
return newFileName;
|
|
}
|
|
#endregion
|
|
|
|
//
|
|
#region Tools Actions ...
|
|
/// <summary>
|
|
/// Extract a FileName's Extension
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileExtension(string fileName)
|
|
{
|
|
//
|
|
var result = StorageHelper.GetFileExtension(fileName);
|
|
if (result.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extract a FileName's Without it's Extension
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetFileNameWithoutExtension(string fileName)
|
|
{
|
|
//
|
|
var result = StorageHelper.GetFileNameWithoutExtension(fileName);
|
|
if (result.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get file Extension of Specified File Name
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public FileExtensions GetFileExtensionType(string fileName)
|
|
{
|
|
//
|
|
var fileExt = GetFileExtension(fileName);
|
|
if (fileExt.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
var result = StorageHelper.GetExtensionType(fileExt);
|
|
if (result == -1)
|
|
{
|
|
XException.UnsupportedFileType.Throw();
|
|
}
|
|
|
|
//
|
|
return (FileExtensions)result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return File Type of Specific File Name
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetFileType(string fileName)
|
|
{
|
|
//
|
|
var fileExtension = GetFileExtensionType(fileName);
|
|
return GetFileType(fileExtension);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Return File Type of Specific Extension
|
|
/// </summary>
|
|
/// <param name="fileExtension"></param>
|
|
/// <returns></returns>
|
|
public XFileType GetFileType(FileExtensions fileExtension)
|
|
{
|
|
return StorageHelper.GetType((int)fileExtension);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Full Path of thumbnail File
|
|
/// </summary>
|
|
/// <param name="thumFileName"></param>
|
|
/// <returns></returns>
|
|
public string GetThumbnailFileFullPath(string thumFileName)
|
|
{
|
|
//
|
|
if (!thumFileName.StartsWith(Configuration.ThumbPrefix))
|
|
{
|
|
XException.InavlidFile.Throw();
|
|
}
|
|
|
|
//
|
|
return Path.Combine(GetThumbFolderPath(), thumFileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a File Thumbnail Path if Supported
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <returns></returns>
|
|
public string GetRelatedThumbnailFullPath(string fileName)
|
|
{
|
|
//
|
|
var thumbName = GenerateThumbName(fileName);
|
|
return GetThumbnailFileFullPath(thumbName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve Special File Type's Folder Path
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <returns></returns>
|
|
public string GetFileTypeFolderPath(XFileType type)
|
|
{
|
|
//
|
|
// Retrieve Folder Path Based on file ...
|
|
switch (type)
|
|
{
|
|
case XFileType.Image:
|
|
case XFileType.CoverImage:
|
|
case XFileType.ProfileImasge:
|
|
return GetImageFolderPath();
|
|
|
|
case XFileType.Audio:
|
|
return GetAudioFolderPath();
|
|
|
|
case XFileType.Video:
|
|
return GetVideoFolderPath();
|
|
|
|
case XFileType.Document:
|
|
default:
|
|
return GetDocumentFolderPath();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a File's Folder path
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="isTemp"></param>
|
|
/// <param name="isWidget"></param>
|
|
/// <returns></returns>
|
|
public string GetFileFolderPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
var fileType = GetFileType(fileName);
|
|
|
|
//
|
|
var folderPath = "";
|
|
|
|
//
|
|
// if isTemp equals true
|
|
// ignore file type and return Temp Folder ...
|
|
if (isTemp)
|
|
{
|
|
folderPath = GetTempFolderPath();
|
|
}
|
|
|
|
//
|
|
// if isWidget equals true and isTemp equals false
|
|
// ignore file type and return Widget's Folder ...
|
|
if (isWidget && !isTemp)
|
|
{
|
|
folderPath = GetWidgetsFolderPath();
|
|
}
|
|
|
|
//
|
|
// if both isTemp and isWidget equals false
|
|
// which is the default state, retrieve proper folder path
|
|
// based on file type and return it ...
|
|
if (!isTemp && !isWidget)
|
|
{
|
|
folderPath = GetFileTypeFolderPath(fileType);
|
|
}
|
|
|
|
//
|
|
// Check folderPath restrict to have Value ...
|
|
if (folderPath.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidData.Throw();
|
|
}
|
|
|
|
//
|
|
// return result ...
|
|
return folderPath;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieve a Full path of a File
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="isTemp"></param>
|
|
/// <param name="isWidget"></param>
|
|
/// <returns></returns>
|
|
public string GetFileFullPath(
|
|
string fileName,
|
|
bool isTemp = false,
|
|
bool isWidget = false
|
|
)
|
|
{
|
|
//
|
|
var folderPath = GetFileFolderPath(
|
|
fileName,
|
|
isTemp: isTemp,
|
|
isWidget: isWidget
|
|
);
|
|
|
|
//
|
|
if (folderPath.IsNullOrEmpty())
|
|
{
|
|
XException.ActionFailed.Throw();
|
|
}
|
|
|
|
//
|
|
return Path.Combine(folderPath, fileName);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save a File into Storage Based on it's Type
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="isTemp"></param>
|
|
/// <param name="isWidget"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<string> SaveFileAsync(
|
|
IFormFile file,
|
|
bool isTemp = false,
|
|
bool isWidget = false,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
ValidateFile(file);
|
|
|
|
//
|
|
// Extract and Generate required Data ...
|
|
var fileName = GetNewFileName(file.FileName);
|
|
var folderPath = GetFileFolderPath(file.FileName, isTemp, isWidget);
|
|
var fileFullPath = Path.Combine(folderPath, fileName);
|
|
|
|
//
|
|
// Save File ...
|
|
using (var stream = new FileStream(fileFullPath, FileMode.Create))
|
|
{
|
|
//
|
|
await file.CopyToAsync(
|
|
stream,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
// Since all Required data can be Generated based on
|
|
// a simple file Name, there is no need to return additional
|
|
// data as result ...
|
|
return fileName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Delete a Physical File by Validate it's Exists
|
|
/// </summary>
|
|
/// <param name="fileFullPath"></param>
|
|
/// <param name="forceFileExists"></param>
|
|
/// <param name="exception"></param>
|
|
public void DeleteFile(
|
|
string fileFullPath,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
// Validate Args ...
|
|
if (!forceFileExists &&
|
|
fileFullPath.IsNullOrEmpty())
|
|
{
|
|
XException.InvalidArgs.Throw();
|
|
}
|
|
|
|
//
|
|
// Prepare Default Exception ...
|
|
if (exception == null)
|
|
{
|
|
exception = XException.NotFound.ToException();
|
|
}
|
|
|
|
//
|
|
// Check File Exists ...
|
|
var isFileExists = File.Exists(fileFullPath);
|
|
if (forceFileExists &&
|
|
!isFileExists)
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
// Handle Prevent Error when forceFileExists false
|
|
// and File doesn't Exists ...
|
|
if (!forceFileExists &&
|
|
!isFileExists)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
File.Delete(fileFullPath);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Remove a List of Physical Files Path
|
|
/// and return Un Removable Files ...
|
|
/// </summary>
|
|
/// <param name="fileFullPaths"></param>
|
|
/// <param name="forceFileExists"></param>
|
|
/// <param name="exception"></param>
|
|
/// <returns></returns>
|
|
public ICollection<string> DeleteFiles(
|
|
ICollection<string> fileFullPaths,
|
|
bool forceFileExists = true,
|
|
Exception exception = null
|
|
)
|
|
{
|
|
//
|
|
if (exception.IsNull())
|
|
{
|
|
exception = XException.NotFound.ToException();
|
|
}
|
|
|
|
//
|
|
var result = fileFullPaths.Where(f => !IsFileExists(GetFileFullPath(f))).ToList();
|
|
if (forceFileExists && result.HasChild())
|
|
{
|
|
throw exception;
|
|
}
|
|
|
|
//
|
|
var existsFile = fileFullPaths.Where(f => IsFileExists(f)).ToList();
|
|
existsFile.ForEach(f =>
|
|
{
|
|
DeleteFile(
|
|
f,
|
|
forceFileExists: forceFileExists,
|
|
exception: exception
|
|
);
|
|
});
|
|
|
|
//
|
|
return fileFullPaths.Except(existsFile).ToList();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create Thumbnail based on FileName.Ext
|
|
/// </summary>
|
|
/// <param name="fileName"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task CreateThumbnail(
|
|
string fileName,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
if (fileName.IsNullOrEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
await Task.Run(() =>
|
|
{
|
|
//
|
|
var fileFullPath = GetFileFullPath(fileName);
|
|
if (!IsFileExists(fileFullPath))
|
|
{
|
|
XException.NotFound.Throw();
|
|
}
|
|
|
|
//
|
|
var thumbFileName = GenerateThumbName(fileName);
|
|
var thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
ThumbnailProvider.ResizeImage(
|
|
fileFullPath,
|
|
thumbFullPath,
|
|
Configuration.ThumbSize,
|
|
Configuration.ThumbQuality
|
|
);
|
|
}, cancellationToken);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Create Thumbnail based on XFile model
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task CreateThumbnail(
|
|
XFileDto file,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
await CreateThumbnail(
|
|
file.Name,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Save and Create a Thumbnail For Profile Image
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XFileResult> HandleProfileImageSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
ValidateProfileImage(file);
|
|
|
|
//
|
|
var savedFileName = await SaveFileAsync(
|
|
file,
|
|
isTemp: false,
|
|
isWidget: false,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
var thumbFileName = GenerateThumbName(savedFileName);
|
|
|
|
//
|
|
var savedFileFullPath = GetFileFullPath(savedFileName);
|
|
var thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
await CreateThumbnail(
|
|
savedFileName,
|
|
cancellationToken
|
|
);
|
|
|
|
//
|
|
return new XFileResult
|
|
{
|
|
Name = file.Name,
|
|
FileName = savedFileName,
|
|
FilePath = ConvertToProfileImageUrl(savedFileFullPath),
|
|
Thmbnail = thumbFileName,
|
|
ThmbnailPath = ConvertToProfileImageUrl(thumbFullPath)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle File Upload with Support of Thumbnails ...
|
|
/// </summary>
|
|
/// <param name="file"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<XFileResult> HandleFileSave(
|
|
IFormFile file,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
ValidateFile(file);
|
|
|
|
//
|
|
var savedFileName = await SaveFileAsync(file, isTemp: false, isWidget: false);
|
|
|
|
//
|
|
var savedFileFullPath = GetFileFullPath(savedFileName);
|
|
|
|
//
|
|
var thumbFileName = "";
|
|
var thumbFullPath = "";
|
|
var fileType = GetFileType(savedFileName);
|
|
if (fileType.IsImageKind())
|
|
{
|
|
//
|
|
thumbFileName = GenerateThumbName(savedFileName);
|
|
thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
await CreateThumbnail(savedFileName);
|
|
}
|
|
|
|
//
|
|
var result =
|
|
new XFileResult
|
|
{
|
|
Name = file.FileName,
|
|
FileName = savedFileName,
|
|
FilePath = ConvertToFileUrl(savedFileFullPath),
|
|
Thmbnail = thumbFileName,
|
|
ThmbnailPath = ConvertToFileUrl(thumbFullPath),
|
|
};
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handle File Upload with Support of Thumbnails ...
|
|
/// </summary>
|
|
/// <param name="files"></param>
|
|
/// <param name="cancellationToken"></param>
|
|
/// <returns></returns>
|
|
public async Task<IEnumerable<XFileResult>> HandleFilesSave(
|
|
IFormFileCollection files,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
//
|
|
ValidateFiles(files);
|
|
|
|
//
|
|
var result = new Collection<XFileResult>();
|
|
foreach (var file in files)
|
|
{
|
|
//
|
|
var savedFileName = await SaveFileAsync(
|
|
file,
|
|
isTemp: false,
|
|
isWidget: false,
|
|
cancellationToken: cancellationToken
|
|
);
|
|
|
|
//
|
|
var savedFileFullPath = GetFileFullPath(savedFileName);
|
|
|
|
//
|
|
var thumbFileName = "";
|
|
var thumbFullPath = "";
|
|
var fileType = GetFileType(savedFileName);
|
|
if (fileType.IsImageKind())
|
|
{
|
|
//
|
|
thumbFileName = GenerateThumbName(savedFileName);
|
|
thumbFullPath = GetThumbnailFileFullPath(thumbFileName);
|
|
|
|
//
|
|
await CreateThumbnail(
|
|
savedFileName,
|
|
cancellationToken
|
|
);
|
|
}
|
|
|
|
//
|
|
result.Add(
|
|
new XFileResult
|
|
{
|
|
Name = file.FileName,
|
|
FileName = savedFileName,
|
|
FilePath = ConvertToFileUrl(savedFileFullPath),
|
|
Thmbnail = thumbFileName,
|
|
ThmbnailPath = ConvertToFileUrl(thumbFullPath),
|
|
});
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xStorageService\Providers\XThumbnailProvider.cs
|
|
|
|
using ImageMagick;
|
|
using xCommons.Extensions;
|
|
using xStorageService.Interfaces;
|
|
using xStorageService.Models;
|
|
|
|
namespace xStorageService.Providers {
|
|
public partial class XThumbnailProvider : IXThumbnailProvider {
|
|
public void SetTempFolder (string folder) {
|
|
MagickNET.SetTempDirectory (folder);
|
|
}
|
|
|
|
public XImageInfo GetImageInfo (string filePath) {
|
|
//
|
|
MagickImageInfo info = new MagickImageInfo (filePath);
|
|
return info.MapConvert<XImageInfo, MagickImageInfo> ();
|
|
}
|
|
|
|
public void ResizeImage (
|
|
string filePath,
|
|
string resizedFilePath,
|
|
int size,
|
|
int quality
|
|
) {
|
|
//
|
|
using (var image = new MagickImage (filePath)) {
|
|
//
|
|
image.Resize (size, size);
|
|
image.Strip ();
|
|
image.Quality = quality;
|
|
image.Write (resizedFilePath);
|
|
}
|
|
}
|
|
}
|
|
}
|