DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/FileService.cs

255 lines
9.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using AsbCloudApp.Data;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services
{
public class FileService : IFileService
{
public string RootPath { get; private set; }
private readonly IQueryable<AsbCloudDb.Model.FileInfo> dbSetConfigured;
private readonly IAsbCloudDbContext db;
private readonly IGoogleDriveService googleDriveService;
public FileService(IAsbCloudDbContext db, IGoogleDriveService googleDriveService)
{
RootPath = "files";
this.db = db;
dbSetConfigured = db.Files
.Include(f => f.Author)
.ThenInclude(u => u.Company)
.ThenInclude(c => c.CompanyType);
this.googleDriveService = googleDriveService;
}
public string CreateGoogleDriveWebLink(string filePath, string originalName)
{ // TODO: Сделать проверку, есть ли уже такой файл на гугл диске. Если есть, то удалить и пересоздать.
// Без этого они будут копиться там с одинаковыми названиями. Или в найстроках гугл диска мож есть перезапись файлов с одинаковыми названиями.
using var fileStream = File.Open(filePath, FileMode.Open);
var uploadedFileId = googleDriveService.UploadFile(fileStream, originalName,
"", "uploaded");
googleDriveService.CreatePublicPermissionForFile(uploadedFileId);
var webLink = googleDriveService.GetFileWebLink(uploadedFileId);
return webLink;
}
public async Task<int> SaveWeblinkToFileInfo(int idFileInfo, string weblink,
CancellationToken token = default)
{
var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFileInfo)
.ConfigureAwait(false);
fileInfo.WebStorageUrl = weblink;
return await db.SaveChangesAsync(token).ConfigureAwait(false);
}
public async Task<FileInfoDto> MoveAsync(int idWell, int? idUser, int idCategory, string destinationFileName, string srcFilePath, CancellationToken token = default)
{
destinationFileName = Path.GetFileName(destinationFileName);
srcFilePath = Path.GetFullPath(srcFilePath);
if (!File.Exists(srcFilePath))
throw new ArgumentException($"file {srcFilePath} doesn't exist", nameof(srcFilePath));
var sysFileInfo = new System.IO.FileInfo(srcFilePath);
//save info to db
var fileInfo = new AsbCloudDb.Model.FileInfo()
{
IdWell = idWell,
IdAuthor = idUser,
IdCategory = idCategory,
Name = destinationFileName,
UploadDate = DateTime.Now,
IsDeleted = false,
Size = sysFileInfo.Length,
};
var entry = db.Files.Add(fileInfo);
await db.SaveChangesAsync(token).ConfigureAwait(false);
var fileId = entry.Entity.Id;
string filePath = MakeFilePath(idWell, idCategory, destinationFileName, fileId);
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.Move(srcFilePath, filePath);
var dto = entry.Entity.Adapt<FileInfoDto>();
return dto;
}
public async Task<FileInfoDto> SaveAsync(int idWell, int? idUser, int idCategory, string fileFullName, Stream fileStream, CancellationToken token = default)
{
//save info to db
var fileInfo = new AsbCloudDb.Model.FileInfo()
{
IdWell = idWell,
IdAuthor = idUser,
IdCategory = idCategory,
Name = Path.GetFileName(fileFullName),
UploadDate = DateTime.Now,
IsDeleted = false,
Size = fileStream?.Length ?? 0
};
var entry = db.Files.Add(fileInfo);
await db.SaveChangesAsync(token).ConfigureAwait(false);
var fileId = entry.Entity.Id;
//save stream to disk
string filePath = MakeFilePath(idWell, idCategory, fileFullName, fileId);
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
using var newfileStream = new FileStream(filePath, FileMode.Create);
await fileStream.CopyToAsync(newfileStream, token).ConfigureAwait(false);
await fileStream.CopyToAsync(newfileStream);
var dto = entry.Entity.Adapt<FileInfoDto>();
return dto;
}
private string MakeFilePath(int idWell, int idCategory, string fileFullName, int fileId)
{
return Path.Combine(RootPath, $"{idWell}",
$"{idCategory}", $"{fileId}" + $"{Path.GetExtension(fileFullName)}");
}
public async Task<IEnumerable<FileInfoDto>> GetInfosByCategoryAsync(int idWell,
int idCategory, CancellationToken token = default)
{
var entities = await dbSetConfigured
.Where(e => e.IdWell == idWell && e.IdCategory == idCategory && e.IsDeleted == false)
.AsNoTracking()
.ToListAsync(token)
.ConfigureAwait(false);
var dtos = entities.Adapt<FileInfoDto>();
return dtos;
}
public async Task<PaginationContainer<FileInfoDto>> GetInfosAsync(int idWell,
int idCategory, string companyName = default, string fileName = default, DateTime begin = default,
DateTime end = default, int skip = 0, int take = 32, CancellationToken token = default)
{
var query = dbSetConfigured
.Where(e => e.IdWell == idWell &&
e.IdCategory == idCategory);
query = query.Where(e => !e.IsDeleted);
if (!string.IsNullOrEmpty(companyName))
query = query
.Include(file => file.Author)
.ThenInclude(a => a.Company)
.Where(e => (e.Author == null) || (e.Author.Company == null) || e.Author.Company.Caption.Contains(companyName));
if (!string.IsNullOrEmpty(fileName))
query = query.Where(e => e.Name.ToLower().Contains(fileName.ToLower()));
if (begin != default)
query = query.Where(e => e.UploadDate >= begin);
if (end != default)
query = query.Where(e => e.UploadDate <= end);
var count = await query.CountAsync(token).ConfigureAwait(false);
var result = new PaginationContainer<FileInfoDto>(count)
{
Skip = skip,
Take = take,
Count = count,
};
if (count <= skip)
return result;
query = query.OrderBy(e => e.UploadDate);
if (skip > 0)
query = query.Skip(skip);
query = query.Take(take);
var entities = await query
.Take(take).AsNoTracking().ToListAsync(token)
.ConfigureAwait(false);
var dtos = entities.Adapt<FileInfoDto>();
result.Items.AddRange(dtos);
return result;
}
public async Task<FileInfoDto> GetInfoAsync(int fileId,
CancellationToken token = default)
{
var entity = await dbSetConfigured
.AsNoTracking()
.FirstOrDefaultAsync(f => f.Id == fileId, token)
.ConfigureAwait(false);
if (entity is null)
return null;
var dto = entity.Adapt<FileInfoDto>();
return dto;
}
public async Task<int> MarkAsDeletedAsync(int idFile,
CancellationToken token = default)
{
var fileInfo = await db.Files.FirstOrDefaultAsync(f => f.Id == idFile, token).ConfigureAwait(false);
if (fileInfo is null)
return 0;
fileInfo.IsDeleted = true;
return await db.SaveChangesAsync(token).ConfigureAwait(false);
}
public async Task<int> DeleteAsync(int idFile, CancellationToken token)
{
var fileInfo = await db.Files
.FirstOrDefaultAsync(f => f.Id == idFile, token)
.ConfigureAwait(false);
if (fileInfo is null)
return 0;
var fileName = GetUrl(fileInfo.Adapt<FileInfoDto>());
if (File.Exists(fileName))
File.Delete(fileName);
db.Files.Remove(fileInfo);
return await db.SaveChangesAsync(token).ConfigureAwait(false);
}
public string GetUrl(FileInfoDto fileInfo) =>
GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name));
public string GetUrl(int idFile)
{
var fileInfo = db.Files
.FirstOrDefault(f => f.Id == idFile);
if (fileInfo is null)
return null;
return GetUrl(fileInfo.IdWell, fileInfo.IdCategory, fileInfo.Id, Path.GetExtension(fileInfo.Name));
}
public string GetUrl(int idWell, int idCategory, int idFile, string dotExtention) =>
Path.Combine(RootPath, idWell.ToString(), idCategory.ToString(), $"{idFile}{dotExtention}");
}
}