This commit is contained in:
Kieran
2023-11-20 15:22:12 +00:00
parent 3f373e6ca3
commit 992ea50aba
16 changed files with 1063 additions and 218 deletions

View File

@@ -15,6 +15,13 @@ public interface IFileMetadataStore
/// <returns></returns>
ValueTask<File?> Get(Guid id);
/// <summary>
/// Get metadata for a single file by its hash
/// </summary>
/// <param name="digest"></param>
/// <returns></returns>
ValueTask<File?> GetHash(string digest);
/// <summary>
/// Get metadata for multiple files
/// </summary>

View File

@@ -26,6 +26,11 @@ public class LocalDiskFileMetadataStore : IFileMetadataStore
{
return GetMeta<Database.File>(id);
}
public ValueTask<Database.File?> GetHash(string digest)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public async ValueTask<IReadOnlyList<Database.File>> Get(Guid[] ids)

View File

@@ -50,6 +50,8 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
if (payload.ShouldStripMetadata && payload.Segment == payload.TotalSegments)
{
fsTemp.Seek(0, SeekOrigin.Begin);
var originalHash = await SHA256.Create().ComputeHashAsync(fsTemp, cts);
fsTemp.Close();
var ext = Path.GetExtension(vf.Name);
var srcPath = $"{finalPath}_orig{ext}";
@@ -60,6 +62,7 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
if (res.Success)
{
File.Move(res.OutPath, finalPath);
File.Delete(srcPath);
// recompute metadata
@@ -69,7 +72,8 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
{
Size = (ulong)fInfo.Length,
Digest = hash.ToHex(),
MimeType = res.MimeType ?? vf.MimeType
MimeType = res.MimeType ?? vf.MimeType,
OriginalDigest = originalHash.ToHex()
};
}
else
@@ -125,7 +129,7 @@ public class LocalDiskFileStore : StreamFileStore, IFileStore
return path;
}
private string MapPath(Guid id) =>
Path.Join(_settings.DataDirectory, "files-v2", id.ToString()[..2], id.ToString()[2..4], id.ToString());
}

View File

@@ -1,10 +1,10 @@
using Microsoft.EntityFrameworkCore;
using VoidCat.Model;
using VoidCat.Services.Abstractions;
using File = VoidCat.Database.File;
namespace VoidCat.Services.Files;
/// <inheritdoc />
public class PostgresFileMetadataStore : IFileMetadataStore
{
private readonly VoidContext _db;
@@ -18,8 +18,7 @@ public class PostgresFileMetadataStore : IFileMetadataStore
public string? Key => "postgres";
/// <inheritdoc />
public async ValueTask<Database.File?> Get(Guid id)
public async ValueTask<File?> Get(Guid id)
{
return await _db.Files
.AsNoTracking()
@@ -27,13 +26,20 @@ public class PostgresFileMetadataStore : IFileMetadataStore
.SingleOrDefaultAsync(a => a.Id == id);
}
public async ValueTask Add(Database.File f)
public async ValueTask<File?> GetHash(string digest)
{
return await _db.Files
.AsNoTracking()
.Include(a => a.Paywall)
.SingleOrDefaultAsync(a => a.Digest == digest || a.OriginalDigest == digest);
}
public async ValueTask Add(File f)
{
_db.Files.Add(f);
await _db.SaveChangesAsync();
}
/// <inheritdoc />
public async ValueTask Delete(Guid id)
{
await _db.Files
@@ -41,8 +47,7 @@ public class PostgresFileMetadataStore : IFileMetadataStore
.ExecuteDeleteAsync();
}
/// <inheritdoc />
public async ValueTask<IReadOnlyList<Database.File>> Get(Guid[] ids)
public async ValueTask<IReadOnlyList<File>> Get(Guid[] ids)
{
return await _db.Files
.Include(a => a.Paywall)
@@ -50,8 +55,7 @@ public class PostgresFileMetadataStore : IFileMetadataStore
.ToArrayAsync();
}
/// <inheritdoc />
public async ValueTask Update(Guid id, Database.File obj)
public async ValueTask Update(Guid id, File obj)
{
var existing = await _db.Files.FindAsync(id);
if (existing == default)
@@ -63,10 +67,9 @@ public class PostgresFileMetadataStore : IFileMetadataStore
await _db.SaveChangesAsync();
}
/// <inheritdoc />
public async ValueTask<PagedResult<Database.File>> ListFiles(PagedRequest request)
public async ValueTask<PagedResult<File>> ListFiles(PagedRequest request)
{
IQueryable<Database.File> MakeQuery(VoidContext db)
IQueryable<File> MakeQuery(VoidContext db)
{
var q = db.Files.AsNoTracking().AsQueryable();
switch (request.SortBy, request.SortOrder)
@@ -99,12 +102,12 @@ public class PostgresFileMetadataStore : IFileMetadataStore
return q.Skip(request.Page * request.PageSize).Take(request.PageSize);
}
async IAsyncEnumerable<Database.File> Enumerate()
async IAsyncEnumerable<File> Enumerate()
{
using var scope = _scopeFactory.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<VoidContext>();
await foreach (var r in MakeQuery(db).AsAsyncEnumerable())
{
yield return r;
@@ -121,7 +124,6 @@ public class PostgresFileMetadataStore : IFileMetadataStore
};
}
/// <inheritdoc />
public async ValueTask<IFileMetadataStore.StoreStats> Stats()
{
var size = await _db.Files

View File

@@ -2,6 +2,7 @@
using Newtonsoft.Json;
using VoidCat.Model;
using VoidCat.Services.Abstractions;
using File = VoidCat.Database.File;
namespace VoidCat.Services.Files;
@@ -40,6 +41,11 @@ public class S3FileMetadataStore : IFileMetadataStore
return default;
}
public ValueTask<File?> GetHash(string digest)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public async ValueTask<IReadOnlyList<Database.File>> Get(Guid[] ids)