using AsbCloudApp.Data; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudApp.Services { #nullable enable /// /// Сервис доступа к файлам /// public class FileService { private readonly IFileRepository fileRepository; private readonly IFileStorageRepository fileStorageRepository; /// /// Сервис доступа к файлам /// /// /// public FileService(IFileRepository fileRepository, IFileStorageRepository fileStorageRepository) { this.fileRepository = fileRepository; this.fileStorageRepository = fileStorageRepository; } /// /// переместить файл /// /// /// /// /// /// /// /// public async Task MoveAsync(int idWell, int? idUser, int idCategory, string destinationFileName, string srcFilePath, CancellationToken token = default) { destinationFileName = Path.GetFileName(destinationFileName); srcFilePath = Path.GetFullPath(srcFilePath); var fileSize = fileStorageRepository.GetLengthFile(srcFilePath); //save info to db var dto = new FileInfoDto { IdWell = idWell, IdAuthor = idUser, IdCategory = idCategory, Name = destinationFileName, Size = fileSize }; var fileId = await fileRepository.InsertAsync(dto, token) .ConfigureAwait(false); string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, destinationFileName, fileId); fileStorageRepository.MoveFile(srcFilePath, filePath); return await GetInfoAsync(fileId, token); } /// /// Сохранить файл /// /// /// /// /// /// /// /// public async Task SaveAsync(int idWell, int? idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token) { //save info to db var dto = new FileInfoDto { IdWell = idWell, IdAuthor = idUser, IdCategory = idCategory, Name = Path.GetFileName(fileFullName), Size = fileStream?.Length ?? 0 }; var fileId = await fileRepository.InsertAsync(dto, token) .ConfigureAwait(false); //save stream to disk string filePath = fileStorageRepository.MakeFilePath(idWell, idCategory, fileFullName, fileId); await fileStorageRepository.CopyFileAsync(filePath, fileStream, token); return await GetInfoAsync(fileId, token); } /// /// Инфо о файле /// /// /// /// public async Task GetInfoAsync(int idFile, CancellationToken token) { var dto = await fileRepository.GetOrDefaultAsync(idFile, token).ConfigureAwait(false); var ext = Path.GetExtension(dto.Name); var relativePath = GetUrl(dto.IdWell, dto.IdCategory, dto.Id, ext); var fullPath = Path.GetFullPath(relativePath); fileStorageRepository.FileExists(fullPath, relativePath); return dto; } /// /// удалить файл /// /// /// /// public Task DeleteAsync(int idFile, CancellationToken token) => DeleteAsync(new int[] { idFile }, token); /// /// удалить файлы /// /// /// /// public async Task DeleteAsync(IEnumerable ids, CancellationToken token) { if (ids is null || !ids.Any()) return 0; var files = await fileRepository.DeleteAsync(ids, token).ConfigureAwait(false); if (files is null || !files.Any()) return 0; foreach (var file in files) { var fileName = GetUrl(file.IdWell, file.IdCategory, file.Id, Path.GetExtension(file.Name)); fileStorageRepository.DeleteFile(fileName); } return files.Any() ? 1 : 0; } /// /// получить путь для скачивания /// /// /// public async Task GetUrl(int idFile) { var fileInfo = await fileRepository.GetOrDefaultAsync(idFile, CancellationToken.None).ConfigureAwait(false); return GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); } /// /// получить путь для скачивания /// /// /// public string GetUrl(FileInfoDto fileInfo) => GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name)); /// /// получить путь для скачивания /// /// /// /// /// /// public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) => Path.Combine(fileStorageRepository.RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}"); /// /// пометить метку файла как удаленную /// /// /// /// public Task MarkFileMarkAsDeletedAsync(int idMark, CancellationToken token) => fileRepository.MarkFileMarkAsDeletedAsync(new int[] { idMark }, token); /// /// Инфо о файле /// /// /// /// public async Task> GetInfoByIdsAsync(IEnumerable idsFile, CancellationToken token) { var result = await fileRepository.GetInfoByIdsAsync(idsFile, token).ConfigureAwait(false); foreach (var entity in result) { var ext = Path.GetExtension(entity.Name); var relativePath = GetUrl(entity.IdWell, entity.IdCategory, entity.Id, ext); var fullPath = Path.GetFullPath(relativePath); fileStorageRepository.FileExists(fullPath, relativePath); } return result; } /// /// Получить список файлов в контейнере /// /// /// /// public async Task> GetInfosAsync(FileServiceRequest request, CancellationToken token) => await fileRepository.GetInfosAsync(request, token) .ConfigureAwait(false); /// /// Пометить файл как удаленный /// /// /// /// public async Task MarkAsDeletedAsync(int idFile, CancellationToken token = default) => await fileRepository.MarkAsDeletedAsync(idFile, token) .ConfigureAwait(false); /// /// добавить метку на файл /// /// /// /// /// public async Task CreateFileMarkAsync(FileMarkDto fileMarkDto, int idUser, CancellationToken token) => await fileRepository.CreateFileMarkAsync(fileMarkDto, idUser, token) .ConfigureAwait(false); /// /// Получить запись по id /// /// /// /// public async Task GetOrDefaultAsync(int id, CancellationToken token) => await fileRepository.GetOrDefaultAsync(id, token) .ConfigureAwait(false); /// /// получить инфо о файле по метке /// /// /// /// public async Task GetByMarkId(int idMark, CancellationToken token) => await fileRepository.GetByMarkId(idMark, token) .ConfigureAwait(false); /// /// получить инфо о файле по метке /// /// /// /// public async Task MarkFileMarkAsDeletedAsync(IEnumerable idsMarks, CancellationToken token) => await fileRepository.MarkFileMarkAsDeletedAsync(idsMarks, token) .ConfigureAwait(false); /// /// Получение файлов по скважине /// /// /// /// public async Task> GetInfosByWellIdAsync(int idWell, CancellationToken token) => await fileRepository.GetInfosByWellIdAsync(new FileServiceRequest { IdWell = idWell, IsDeleted = false }, token) .ConfigureAwait(false); /// /// Получить файлы определенной категории /// /// /// /// /// public async Task> GetInfosByCategoryAsync(int idWell, int idCategory, CancellationToken token) => await fileRepository.GetInfosByCategoryAsync(idWell, idCategory, token) .ConfigureAwait(false); /// /// Удаление всех файлов по скважине помеченных как удаленные /// /// /// /// public async Task DeleteFilesFromDbMarkedDeletionByIdWell(int idWell, CancellationToken token) { var files = await fileRepository.GetInfosByWellIdAsync( new FileServiceRequest { IdWell = idWell, IsDeleted = true }, token); var result = await DeleteAsync(files.Select(x => x.Id), token); return result; } /// /// Удаление всех файлов с диска о которых нет информации в базе /// /// /// public async Task DeleteFilesNotExistStorage(int idWell, CancellationToken token) { var files = await fileRepository.GetInfosByWellIdAsync( new FileServiceRequest { IdWell = idWell }, token); var result = await Task.FromResult(fileStorageRepository.DeleteFilesNotExistStorage(idWell, files.Select(x => x.Id))); return result; } /// /// Вывод списка всех файлов из базы, для которых нет файла на диске /// /// /// public async Task> GetListFilesNotDisc(int idWell, CancellationToken token) { var files = await fileRepository.GetInfosByWellIdAsync( new FileServiceRequest { IdWell = idWell }, token); var result = fileStorageRepository.GetListFilesNotDisc(idWell, files); return result; } } #nullable disable }