Files
SteUP_Dotnet/SteUp.Maui/Core/Services/AttachedService.cs
2026-02-24 11:33:36 +01:00

228 lines
7.2 KiB
C#

using Microsoft.Extensions.Logging.Abstractions;
using SteUp.Shared.Core.Dto;
using SteUp.Shared.Core.Entities;
using SteUp.Shared.Core.Helpers;
using SteUp.Shared.Core.Interface.System;
namespace SteUp.Maui.Core.Services;
public class AttachedService : IAttachedService
{
private static string AttachedRoot =>
Path.Combine(FileSystem.CacheDirectory, "attached");
public async Task<AttachedDto?> SelectImageFromCamera()
{
var cameraPerm = await Permissions.RequestAsync<Permissions.Camera>();
var storagePerm = await Permissions.RequestAsync<Permissions.StorageWrite>();
if (cameraPerm != PermissionStatus.Granted || storagePerm != PermissionStatus.Granted)
return null;
FileResult? result;
try
{
result = await MediaPicker.Default.CapturePhotoAsync();
result?.FileName = $"img_{DateTime.Now:ddMMyyy_hhmmss}{result.FileName[result.FileName.IndexOf('.')..]}";
}
catch (Exception ex)
{
Console.WriteLine($"Errore cattura foto: {ex.Message}");
SentrySdk.CaptureException(ex);
return null;
}
return result is null ? null : await ConvertToDto(result, AttachedDto.TypeAttached.Image);
}
public async Task<List<AttachedDto>?> SelectImageFromGallery()
{
List<FileResult>? resultList;
var storagePerm = await Permissions.RequestAsync<Permissions.StorageRead>();
if (storagePerm != PermissionStatus.Granted)
return null;
try
{
resultList = await MediaPicker.Default.PickPhotosAsync();
}
catch (Exception ex)
{
Console.WriteLine($"Errore selezione galleria: {ex.Message}");
SentrySdk.CaptureException(ex);
return null;
}
if (resultList.IsNullOrEmpty()) return null;
List<AttachedDto> returnList = [];
foreach (var fileResult in resultList)
{
returnList.Add(await ConvertToDto(fileResult, AttachedDto.TypeAttached.Image));
}
return returnList;
}
private static async Task<AttachedDto> ConvertToDto(FileResult file, AttachedDto.TypeAttached type)
{
var stream = await file.OpenReadAsync();
using var ms = new MemoryStream();
await stream.CopyToAsync(ms);
return new AttachedDto
{
Name = file.FileName,
Path = file.FullPath,
MimeType = file.ContentType,
DimensionBytes = ms.Length,
FileBytes = ms.ToArray(),
Type = type
};
}
private async Task<AttachedDto> ConvertToDto(FileInfo file, AttachedDto.TypeAttached type)
{
var (origUrl, thumbUrl) = await SaveAndCreateThumbAsync(
await File.ReadAllBytesAsync(file.FullName),
file.Name
);
return new AttachedDto
{
Name = file.Name,
Path = file.FullName,
TempPath = origUrl,
ThumbPath = thumbUrl,
Type = type,
SavedOnAppData = true
};
}
public async Task<List<AttachedDto>?> GetInspectionFiles(Ispezione ispezione)
{
var baseDir = FileSystem.AppDataDirectory;
var inspectionDir = Path.Combine(baseDir, $"attached_{GetInspectionKey(ispezione)}");
var directory = new DirectoryInfo(inspectionDir);
if (!directory.Exists) return null;
var fileList = directory.GetFiles().ToList();
var returnList = new List<AttachedDto>();
foreach (var file in fileList)
{
returnList.Add(await ConvertToDto(file, AttachedDto.TypeAttached.Image));
}
return returnList;
}
public async Task<string?> SaveInspectionFile(Ispezione ispezione, byte[] file, string fileName,
CancellationToken ct)
{
ArgumentNullException.ThrowIfNull(ispezione);
ArgumentNullException.ThrowIfNull(file);
ArgumentException.ThrowIfNullOrWhiteSpace(fileName);
var baseDir = FileSystem.AppDataDirectory;
var inspectionDir = Path.Combine(baseDir, $"attached_{GetInspectionKey(ispezione)}");
if (!Directory.Exists(inspectionDir)) Directory.CreateDirectory(inspectionDir);
var filePath = Path.Combine(inspectionDir, fileName);
await File.WriteAllBytesAsync(filePath, file, ct);
return filePath;
}
public bool RemoveInspectionFile(Ispezione ispezione, string fileName)
{
var baseDir = FileSystem.AppDataDirectory;
var inspectionDir = Path.Combine(baseDir, $"attached_{GetInspectionKey(ispezione)}");
if (!Directory.Exists(inspectionDir)) return false;
if (string.IsNullOrWhiteSpace(fileName)) return false;
var filePath = Path.Combine(inspectionDir, fileName);
if (!File.Exists(filePath)) return false;
File.Delete(filePath);
if (!Directory.EnumerateFileSystemEntries(inspectionDir).Any())
Directory.Delete(inspectionDir);
return true;
}
public async Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default)
{
ArgumentNullException.ThrowIfNull(file);
if (file.CanSeek)
file.Position = 0;
fileName = Path.GetFileName(fileName);
var dir = FileSystem.CacheDirectory;
var filePath = Path.Combine(dir, fileName);
await using var fileStream = File.Create(filePath);
await file.CopyToAsync(fileStream, ct);
return filePath;
}
public Task CleanTempStorageAsync(CancellationToken ct = default)
{
return Task.Run(() =>
{
if (Directory.Exists(AttachedRoot))
Directory.Delete(AttachedRoot, true);
}, ct);
}
public Task OpenFile(string fileName, string filePath)
{
#if IOS
throw new NotImplementedException();
#else
return Launcher.OpenAsync(new OpenFileRequest
{
Title = "Apri file",
File = new ReadOnlyFile(filePath)
});
#endif
}
public async Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync(
byte[] bytes, string fileName, CancellationToken ct = default)
{
Directory.CreateDirectory(AttachedRoot);
var id = Guid.NewGuid().ToString("N");
var safeName = SanitizeFileName(fileName);
var originalFile = $"{id}_{safeName}";
var thumbFile = $"{id}_thumb.jpg";
var originalPath = Path.Combine(AttachedRoot, originalFile);
await File.WriteAllBytesAsync(originalPath, bytes, ct);
var thumbPath = Path.Combine(AttachedRoot, thumbFile);
await ImageThumb.CreateThumbnailAsync(originalPath, thumbPath, maxSide: 320, quality: 70, ct);
return ($"https://localfiles/attached/{originalFile}",
$"https://localfiles/attached/{thumbFile}");
}
private static string SanitizeFileName(string fileName)
{
var name = Path.GetFileName(fileName);
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, '_'));
}
private static string GetInspectionKey(Ispezione ispezione) =>
$"{ispezione.CodMdep}_{ispezione.Data:ddMMyyyy}_{ispezione.Rilevatore.ToLower()}";
}