✨ Some drive service changes
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Drive.Billing;
|
||||
|
||||
@@ -28,15 +29,21 @@ public class UsageService(AppDatabase db)
|
||||
{
|
||||
public async Task<TotalUsageDetails> GetTotalUsage()
|
||||
{
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
var fileQuery = db.Files
|
||||
.Where(f => !f.IsMarkedRecycle)
|
||||
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
|
||||
.AsQueryable();
|
||||
|
||||
var poolUsages = await db.Pools
|
||||
.Select(p => new UsageDetails
|
||||
{
|
||||
PoolId = p.Id,
|
||||
PoolName = p.Name,
|
||||
UsageBytes = db.Files
|
||||
UsageBytes = fileQuery
|
||||
.Where(f => f.PoolId == p.Id)
|
||||
.Sum(f => f.Size),
|
||||
Cost = db.Files
|
||||
Cost = fileQuery
|
||||
.Where(f => f.PoolId == p.Id)
|
||||
.Sum(f => f.Size) / 1024.0 / 1024.0 *
|
||||
(p.BillingConfig.CostMultiplier ?? 1.0),
|
||||
@@ -75,13 +82,17 @@ public class UsageService(AppDatabase db)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
var fileQuery = db.Files
|
||||
.Where(f => !f.IsMarkedRecycle)
|
||||
.Where(f => f.ExpiredAt.HasValue && f.ExpiredAt > now)
|
||||
.AsQueryable();
|
||||
|
||||
var usageBytes = await db.Files
|
||||
.Where(f => f.PoolId == poolId)
|
||||
var usageBytes = await fileQuery
|
||||
.SumAsync(f => f.Size);
|
||||
|
||||
var fileCount = await db.Files
|
||||
.Where(f => f.PoolId == poolId)
|
||||
var fileCount = await fileQuery
|
||||
.CountAsync();
|
||||
|
||||
var cost = usageBytes / 1024.0 / 1024.0 *
|
||||
|
@@ -35,6 +35,7 @@ public class FileController(
|
||||
|
||||
var file = await fs.GetFileAsync(id);
|
||||
if (file is null) return NotFound();
|
||||
if (file.IsMarkedRecycle) return StatusCode(StatusCodes.Status410Gone, "The file has been recycled.");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(file.StorageUrl)) return Redirect(file.StorageUrl);
|
||||
|
||||
@@ -149,7 +150,7 @@ public class FileController(
|
||||
.AsQueryable();
|
||||
|
||||
if (pool.HasValue) query = query.Where(e => e.PoolId == pool);
|
||||
|
||||
|
||||
var total = await query.CountAsync();
|
||||
Response.Headers.Append("X-Total", total.ToString());
|
||||
|
||||
|
@@ -153,25 +153,26 @@ public class FileService(
|
||||
IsEncrypted = !string.IsNullOrWhiteSpace(encryptPassword) && pool.PolicyConfig.AllowEncryption
|
||||
};
|
||||
|
||||
var existingFile = await db.Files.AsNoTracking().FirstOrDefaultAsync(f => f.Hash == hash);
|
||||
file.StorageId = existingFile?.StorageId ?? file.Id;
|
||||
|
||||
if (existingFile is not null)
|
||||
{
|
||||
file.FileMeta = existingFile.FileMeta;
|
||||
file.HasCompression = existingFile.HasCompression;
|
||||
file.SensitiveMarks = existingFile.SensitiveMarks;
|
||||
file.MimeType = existingFile.MimeType;
|
||||
file.UploadedAt = existingFile.UploadedAt;
|
||||
file.PoolId = existingFile.PoolId;
|
||||
|
||||
db.Files.Add(file);
|
||||
await db.SaveChangesAsync();
|
||||
// Since the file content is a duplicate, we can delete the new upload and we are done.
|
||||
await stream.DisposeAsync();
|
||||
await store.DeleteFileAsync(file.Id, CancellationToken.None);
|
||||
return file;
|
||||
}
|
||||
// TODO: Enable the feature later
|
||||
// var existingFile = await db.Files.AsNoTracking().FirstOrDefaultAsync(f => f.Hash == hash);
|
||||
// file.StorageId = existingFile?.StorageId ?? file.Id;
|
||||
//
|
||||
// if (existingFile is not null)
|
||||
// {
|
||||
// file.FileMeta = existingFile.FileMeta;
|
||||
// file.HasCompression = existingFile.HasCompression;
|
||||
// file.SensitiveMarks = existingFile.SensitiveMarks;
|
||||
// file.MimeType = existingFile.MimeType;
|
||||
// file.UploadedAt = existingFile.UploadedAt;
|
||||
// file.PoolId = existingFile.PoolId;
|
||||
//
|
||||
// db.Files.Add(file);
|
||||
// await db.SaveChangesAsync();
|
||||
// // Since the file content is a duplicate, we can delete the new upload and we are done.
|
||||
// await stream.DisposeAsync();
|
||||
// await store.DeleteFileAsync(file.Id, CancellationToken.None);
|
||||
// return file;
|
||||
// }
|
||||
|
||||
// Extract metadata on the current thread for a faster initial response
|
||||
if (!pool.PolicyConfig.NoMetadata)
|
||||
@@ -540,11 +541,11 @@ public class FileService(
|
||||
|
||||
public async Task DeleteFileAsync(CloudFile file)
|
||||
{
|
||||
await DeleteFileDataAsync(file);
|
||||
|
||||
db.Remove(file);
|
||||
await db.SaveChangesAsync();
|
||||
await _PurgeCacheAsync(file.Id);
|
||||
|
||||
await DeleteFileDataAsync(file);
|
||||
}
|
||||
|
||||
public async Task DeleteFileDataAsync(CloudFile file)
|
||||
@@ -559,17 +560,10 @@ public class FileService(
|
||||
.ToListAsync();
|
||||
|
||||
// Check if any of these files are referenced
|
||||
var anyReferenced = false;
|
||||
if (sameOriginFiles.Count != 0)
|
||||
{
|
||||
anyReferenced = await db.FileReferences
|
||||
.Where(r => sameOriginFiles.Contains(r.FileId))
|
||||
.AnyAsync();
|
||||
}
|
||||
return;
|
||||
|
||||
// If any other file with the same storage ID is referenced, don't delete the actual file data
|
||||
if (anyReferenced) return;
|
||||
|
||||
var dest = await GetRemoteStorageConfig(file.PoolId.Value);
|
||||
if (dest is null) throw new InvalidOperationException($"No remote storage configured for pool {file.PoolId}");
|
||||
var client = CreateMinioClient(dest);
|
||||
|
Reference in New Issue
Block a user