270 lines
9.2 KiB
C#
270 lines
9.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security;
|
|
using Kreta.Core.FileService.Configuration;
|
|
|
|
namespace Kreta.Core.FileService
|
|
{
|
|
public class FileService : IFileService
|
|
{
|
|
private readonly IFileServiceConfiguration FileServiceConfiguration;
|
|
|
|
public FileService(IFileServiceConfiguration fileServiceConfiguration)
|
|
{
|
|
FileServiceConfiguration = fileServiceConfiguration ?? throw new ArgumentNullException(nameof(fileServiceConfiguration));
|
|
}
|
|
|
|
//konfigból jobb lenne
|
|
private readonly Dictionary<string, string> _allowedFileTypes =
|
|
new Dictionary<string, string>() {
|
|
{ ".txt", "text/plain" },
|
|
{ ".pdf", "application/pdf" },
|
|
{ ".png", "image/png" },
|
|
{ ".bmp", "image/bmp" },
|
|
{ ".jpg", "image/jpeg" },
|
|
{ ".jpeg", "image/jpeg" },
|
|
{ ".xls", "application/vnd.ms-excel" },
|
|
{ ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" },
|
|
{ ".doc", "application/msword" },
|
|
{ ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document" },
|
|
{ ".xml", "text/xml" },
|
|
{ ".roz", "application/roz" },
|
|
{".rar", "application/octet-stream"},
|
|
{".zip", "application/x-zip-compressed"}
|
|
};
|
|
|
|
private Storage GetStorage(string storageName)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(storageName))
|
|
{
|
|
throw new ArgumentException(nameof(storageName));
|
|
}
|
|
|
|
Storage storage = null;
|
|
|
|
foreach (Storage storageElement in FileServiceConfiguration.Storages)
|
|
{
|
|
if (storageElement.Key.Equals(storageName, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
storage = storageElement;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (storage == null)
|
|
{
|
|
throw new Exception("Nem létező storage name van megadva!");
|
|
}
|
|
|
|
return storage;
|
|
}
|
|
|
|
public string WriteToFile(string base64EncodedContent, string storageName)
|
|
{
|
|
Storage storage = GetStorage(storageName);
|
|
|
|
string newFileName = Guid.NewGuid().ToString();
|
|
string directoryPath = System.IO.Path.Combine(GetFileSharePath(storage), System.IO.Path.Combine(newFileName.Split('-')[0].Substring(0, 4).Select(x => x.ToString()).ToArray()));
|
|
|
|
try
|
|
{
|
|
Directory.CreateDirectory(directoryPath);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new Exception($"Hiba történt a mappa létrehozása során!", exception);
|
|
}
|
|
|
|
string filePath = System.IO.Path.Combine(directoryPath, newFileName);
|
|
string[] parts = base64EncodedContent.Split(new string[] { ";", ":", "," }, StringSplitOptions.None);
|
|
byte[] binaryFile = Convert.FromBase64String(parts[3]);
|
|
|
|
AttachmentValidation(binaryFile.Length, storage.MaxFileSizeInBytes, _allowedFileTypes.FirstOrDefault(x => x.Value == parts[1]).Key);
|
|
|
|
try
|
|
{
|
|
File.WriteAllBytes(filePath, binaryFile);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new Exception($"Hiba történt a fájl írása közben: {exception.Message}", exception);
|
|
}
|
|
|
|
return filePath;
|
|
}
|
|
|
|
public byte[] ReadFromFile(string filePath)
|
|
{
|
|
try
|
|
{
|
|
return File.ReadAllBytes(filePath);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
throw new Exception($"Hiba történt a fájl olvasása közben: {exception.Message}", exception);
|
|
}
|
|
}
|
|
|
|
public string ReadImage(string filePath, string fileExtension)
|
|
{
|
|
byte[] imageContent = ReadFromFile(filePath);
|
|
|
|
if (imageContent != null)
|
|
{
|
|
return $"data:image/{fileExtension};base64,{Convert.ToBase64String(imageContent)}";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public string ReadAndResizeImage(string filePath, int width, int height)
|
|
{
|
|
byte[] imageContent = ReadFromFile(filePath);
|
|
|
|
if (imageContent != null)
|
|
{
|
|
Image image = CreateImage(imageContent);
|
|
|
|
return $"data:image/jpeg;base64,{Convert.ToBase64String(ResizeImage(image, width, height))}";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private Image CreateImage(byte[] pictureByteArray)
|
|
{
|
|
using (var memoryStream = new MemoryStream(pictureByteArray, 0, pictureByteArray.Length))
|
|
{
|
|
return Image.FromStream(memoryStream, true, true);
|
|
}
|
|
}
|
|
|
|
private byte[] ResizeImage(Image image, int width, int height)
|
|
{
|
|
var destRect = new Rectangle(0, 0, width, height);
|
|
|
|
using (var destImage = new Bitmap(width, height))
|
|
{
|
|
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
|
|
|
|
using (var graphics = Graphics.FromImage(destImage))
|
|
{
|
|
graphics.CompositingMode = CompositingMode.SourceCopy;
|
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
|
|
using (var wrapMode = new ImageAttributes())
|
|
{
|
|
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
|
|
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
|
|
}
|
|
}
|
|
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
destImage.Save(memoryStream, ImageFormat.Jpeg);
|
|
|
|
return memoryStream.ToArray();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AttachmentValidation(long contentLength, int maxFileSizeInBytes, string contentType)
|
|
{
|
|
if (contentType == null)
|
|
{
|
|
throw new Exception("Nem tölthető fel a fájl, mert nincs kiterjesztése");
|
|
}
|
|
|
|
if (!_allowedFileTypes.ContainsKey(contentType))
|
|
{
|
|
throw new Exception("Nem megengedett a fájl formátuma!");
|
|
}
|
|
|
|
if (contentLength > maxFileSizeInBytes)
|
|
{
|
|
throw new Exception("Nem tölthető fel a fájl, mert túl nagy a mérete");
|
|
}
|
|
}
|
|
|
|
private string GetFileSharePath(Storage storageElement)
|
|
{
|
|
string root = string.Empty;
|
|
|
|
foreach (Configuration.Path path in storageElement.Paths)
|
|
{
|
|
root = path.Value;
|
|
|
|
if (!HasEnoughFreeSpaceOnDisk(storageElement.MinimumRequiredFreeSpaceInBytes, root))
|
|
{
|
|
throw new Exception("Nincs elég hely a tárolón!");
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(root))
|
|
{
|
|
throw new Exception("A megosztott meghajtó nincs megadva!");
|
|
}
|
|
|
|
return root;
|
|
}
|
|
|
|
private bool HasEnoughFreeSpaceOnDisk(int minimumRequiredFreeSpaceInBytes, string path)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(path))
|
|
{
|
|
throw new ArgumentException(nameof(path));
|
|
}
|
|
|
|
//Nem működik a megosztott mappával
|
|
//TODO Imi: ellenőrizni, h létezik-e a megadott megosztott mappa
|
|
/*if (!Directory.Exists(path))
|
|
{
|
|
throw new ArgumentNullException("Nem létezik a file share!");
|
|
}*/
|
|
|
|
long freeSpaceInBytes = 0, dummy1 = 0, dummy2 = 0;
|
|
|
|
if (!GetDiskFreeSpaceEx(path, ref freeSpaceInBytes, ref dummy1, ref dummy2))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return freeSpaceInBytes > minimumRequiredFreeSpaceInBytes;
|
|
}
|
|
|
|
[SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage"), SuppressUnmanagedCodeSecurity]
|
|
[DllImport("Kernel32", SetLastError = true, CharSet = CharSet.Auto)]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
private static extern bool GetDiskFreeSpaceEx
|
|
(
|
|
string lpszPath,
|
|
ref long lpFreeBytesAvailable,
|
|
ref long lpTotalNumberOfBytes,
|
|
ref long lpTotalNumberOfFreeBytes
|
|
);
|
|
|
|
public void DeleteFile(string filePath)
|
|
{
|
|
try
|
|
{
|
|
File.Delete(filePath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new Exception("A fájl törlése sikertelen!", ex);
|
|
}
|
|
}
|
|
}
|
|
}
|