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
}