| | | 1 | | using Microsoft.Extensions.Configuration; |
| | | 2 | | using Microsoft.Extensions.Logging; |
| | | 3 | | |
| | | 4 | | namespace FAU.Logica.Services; |
| | | 5 | | |
| | | 6 | | public class FilesystemStorageService : IStorageService |
| | | 7 | | { |
| | | 8 | | private readonly string _basePath; |
| | | 9 | | private readonly ILogger<FilesystemStorageService> _logger; |
| | | 10 | | |
| | 1 | 11 | | private static readonly HashSet<string> _allowedMimeTypes = new(StringComparer.OrdinalIgnoreCase) |
| | 1 | 12 | | { |
| | 1 | 13 | | "application/pdf", |
| | 1 | 14 | | "image/jpeg", |
| | 1 | 15 | | "image/jpg", |
| | 1 | 16 | | "image/png", |
| | 1 | 17 | | "image/tiff" |
| | 1 | 18 | | }; |
| | | 19 | | |
| | 8 | 20 | | public FilesystemStorageService(IConfiguration config, ILogger<FilesystemStorageService> logger) |
| | | 21 | | { |
| | 8 | 22 | | _basePath = config["Storage:BasePath"] |
| | 8 | 23 | | ?? throw new InvalidOperationException("Storage:BasePath no está configurado."); |
| | 8 | 24 | | _logger = logger; |
| | 8 | 25 | | } |
| | | 26 | | |
| | | 27 | | public async Task<string> GuardarAsync(Stream contenido, string rutaRelativa, string contentType) |
| | | 28 | | { |
| | 6 | 29 | | if (!_allowedMimeTypes.Contains(contentType)) |
| | 1 | 30 | | throw new ArgumentException($"Tipo de archivo no permitido: {contentType}. Tipos permitidos: PDF, JPG, PNG, |
| | | 31 | | |
| | 5 | 32 | | var rutaCompleta = Path.Combine(_basePath, rutaRelativa); |
| | 5 | 33 | | var directorio = Path.GetDirectoryName(rutaCompleta)!; |
| | | 34 | | |
| | 5 | 35 | | Directory.CreateDirectory(directorio); |
| | | 36 | | |
| | 5 | 37 | | await using var fs = new FileStream(rutaCompleta, FileMode.Create, FileAccess.Write); |
| | 5 | 38 | | await contenido.CopyToAsync(fs); |
| | | 39 | | |
| | 5 | 40 | | _logger.LogInformation("Archivo guardado: {Ruta}", rutaRelativa); |
| | 5 | 41 | | return rutaRelativa; |
| | 5 | 42 | | } |
| | | 43 | | |
| | | 44 | | public Task EliminarAsync(string rutaRelativa) |
| | | 45 | | { |
| | 3 | 46 | | var rutaCompleta = Path.Combine(_basePath, rutaRelativa); |
| | | 47 | | |
| | 3 | 48 | | if (File.Exists(rutaCompleta)) |
| | | 49 | | { |
| | 2 | 50 | | File.Delete(rutaCompleta); |
| | 2 | 51 | | _logger.LogInformation("Archivo eliminado: {Ruta}", rutaRelativa); |
| | | 52 | | |
| | 2 | 53 | | var directorio = Path.GetDirectoryName(rutaCompleta)!; |
| | 2 | 54 | | if (Directory.Exists(directorio) && !Directory.EnumerateFileSystemEntries(directorio).Any()) |
| | 2 | 55 | | Directory.Delete(directorio); |
| | | 56 | | } |
| | | 57 | | |
| | 3 | 58 | | return Task.CompletedTask; |
| | | 59 | | } |
| | | 60 | | |
| | | 61 | | public Task<Stream> ObtenerAsync(string rutaRelativa) |
| | | 62 | | { |
| | 2 | 63 | | var rutaCompleta = Path.Combine(_basePath, rutaRelativa); |
| | | 64 | | |
| | 2 | 65 | | if (!File.Exists(rutaCompleta)) |
| | 1 | 66 | | throw new StorageFileNotFoundException($"Archivo no encontrado: {rutaRelativa}"); |
| | | 67 | | |
| | 1 | 68 | | Stream stream = new FileStream(rutaCompleta, FileMode.Open, FileAccess.Read, FileShare.Read); |
| | 1 | 69 | | return Task.FromResult(stream); |
| | | 70 | | } |
| | | 71 | | } |