🐛 Fix issues cause by new data structure between services of drive

This commit is contained in:
2026-01-12 23:45:32 +08:00
parent c11bf579c4
commit 87d9267285
4 changed files with 118 additions and 8 deletions

View File

@@ -1,4 +1,3 @@
using DysonNetwork.Shared.Models;
using DysonNetwork.Shared.Proto; using DysonNetwork.Shared.Proto;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
using Grpc.Core; using Grpc.Core;
@@ -7,7 +6,7 @@ namespace DysonNetwork.Drive.Storage
{ {
public class FileServiceGrpc(FileService fileService) : Shared.Proto.FileService.FileServiceBase public class FileServiceGrpc(FileService fileService) : Shared.Proto.FileService.FileServiceBase
{ {
public override async Task<Shared.Proto.CloudFile> GetFile(GetFileRequest request, ServerCallContext context) public override async Task<CloudFile> GetFile(GetFileRequest request, ServerCallContext context)
{ {
var file = await fileService.GetFileAsync(request.Id); var file = await fileService.GetFileAsync(request.Id);
return file?.ToProtoValue() ?? throw new RpcException(new Status(StatusCode.NotFound, "File not found")); return file?.ToProtoValue() ?? throw new RpcException(new Status(StatusCode.NotFound, "File not found"));
@@ -19,7 +18,7 @@ namespace DysonNetwork.Drive.Storage
return new GetFileBatchResponse { Files = { files.Select(f => f.ToProtoValue()) } }; return new GetFileBatchResponse { Files = { files.Select(f => f.ToProtoValue()) } };
} }
public override async Task<Shared.Proto.CloudFile> UpdateFile(UpdateFileRequest request, public override async Task<CloudFile> UpdateFile(UpdateFileRequest request,
ServerCallContext context) ServerCallContext context)
{ {
var file = await fileService.GetFileAsync(request.File.Id); var file = await fileService.GetFileAsync(request.File.Id);

View File

@@ -73,7 +73,7 @@ public class SnCloudFile : ModelBase, ICloudFile, IIdentifiedResource
DeletedAt = DeletedAt, DeletedAt = DeletedAt,
Id = Id, Id = Id,
Name = Name, Name = Name,
FileMeta = FileMeta ?? [], FileMeta = FileMeta,
UserMeta = UserMeta ?? [], UserMeta = UserMeta ?? [],
SensitiveMarks = SensitiveMarks, SensitiveMarks = SensitiveMarks,
MimeType = MimeType, MimeType = MimeType,
@@ -102,13 +102,32 @@ public class SnCloudFile : ModelBase, ICloudFile, IIdentifiedResource
Url = StorageUrl ?? string.Empty, Url = StorageUrl ?? string.Empty,
ContentType = MimeType ?? string.Empty, ContentType = MimeType ?? string.Empty,
UploadedAt = UploadedAt?.ToTimestamp(), UploadedAt = UploadedAt?.ToTimestamp(),
// Convert file metadata
FileMeta = GrpcTypeHelper.ConvertObjectToByteString(FileMeta), FileMeta = GrpcTypeHelper.ConvertObjectToByteString(FileMeta),
// Convert user metadata
UserMeta = GrpcTypeHelper.ConvertObjectToByteString(UserMeta), UserMeta = GrpcTypeHelper.ConvertObjectToByteString(UserMeta),
SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks) SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks)
}; };
if (FileMeta.TryGetValue("width", out var width) && width is int w)
proto.Width = w;
if (FileMeta.TryGetValue("height", out var height) && height is int h)
proto.Height = h;
if (FileMeta.TryGetValue("blurhash", out var blurhash) && blurhash is string bh && !string.IsNullOrEmpty(bh))
proto.Blurhash = bh;
if (Object != null)
{
proto.Object = new Proto.FileObject
{
Id = Object.Id,
Size = Object.Size,
Meta = GrpcTypeHelper.ConvertObjectToByteString(Object.Meta),
MimeType = Object.MimeType ?? string.Empty,
Hash = Object.Hash ?? string.Empty,
HasCompression = Object.HasCompression,
HasThumbnail = Object.HasThumbnail
};
}
return proto; return proto;
} }
} }

View File

@@ -1,4 +1,5 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using DysonNetwork.Shared.Proto; using DysonNetwork.Shared.Proto;
namespace DysonNetwork.Shared.Models; namespace DysonNetwork.Shared.Models;
@@ -44,12 +45,16 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
public static SnCloudFileReferenceObject FromProtoValue(Proto.CloudFile proto) public static SnCloudFileReferenceObject FromProtoValue(Proto.CloudFile proto)
{ {
var fileMeta = proto.Object != null
? ConvertObjectToDictionary(proto.Object.Meta)
: ConvertToDictionary(proto.FileMeta);
return new SnCloudFileReferenceObject return new SnCloudFileReferenceObject
{ {
Id = proto.Id, Id = proto.Id,
Name = proto.Name, Name = proto.Name,
FileMeta = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(proto.FileMeta) ?? [], FileMeta = fileMeta,
UserMeta = GrpcTypeHelper.ConvertByteStringToObject<Dictionary<string, object?>>(proto.UserMeta) ?? [], UserMeta = ConvertToDictionary(proto.UserMeta),
SensitiveMarks = proto.HasSensitiveMarks SensitiveMarks = proto.HasSensitiveMarks
? GrpcTypeHelper.ConvertByteStringToObject<List<ContentSensitiveMark>>(proto.SensitiveMarks) ? GrpcTypeHelper.ConvertByteStringToObject<List<ContentSensitiveMark>>(proto.SensitiveMarks)
: [], : [],
@@ -64,6 +69,65 @@ public class SnCloudFileReferenceObject : ModelBase, ICloudFile
}; };
} }
private static Dictionary<string, object?> ConvertObjectToDictionary(Google.Protobuf.ByteString byteString)
{
if (byteString.IsEmpty)
return [];
var jsonElement = GrpcTypeHelper.ConvertByteStringToObject<JsonElement>(byteString);
if (jsonElement.ValueKind != JsonValueKind.Object)
return [];
var result = new Dictionary<string, object?>();
foreach (var property in jsonElement.EnumerateObject())
{
result[property.Name] = ConvertJsonElement(property.Value);
}
return result;
}
private static Dictionary<string, object?> ConvertToDictionary(Google.Protobuf.ByteString byteString)
{
if (byteString.IsEmpty)
return [];
var jsonElement = GrpcTypeHelper.ConvertByteStringToObject<JsonElement>(byteString);
if (jsonElement.ValueKind != JsonValueKind.Object)
return [];
var result = new Dictionary<string, object?>();
foreach (var property in jsonElement.EnumerateObject())
{
result[property.Name] = ConvertJsonElement(property.Value);
}
return result;
}
private static object? ConvertJsonElement(JsonElement element)
{
return element.ValueKind switch
{
JsonValueKind.String => element.GetString(),
JsonValueKind.Number => element.TryGetInt64(out long l) ? l : element.GetDouble(),
JsonValueKind.True => true,
JsonValueKind.False => false,
JsonValueKind.Null => null,
JsonValueKind.Object => ConvertToDictionaryElement(element),
JsonValueKind.Array => element.EnumerateArray().Select(ConvertJsonElement).ToList(),
_ => null
};
}
private static Dictionary<string, object?> ConvertToDictionaryElement(JsonElement element)
{
var result = new Dictionary<string, object?>();
foreach (var property in element.EnumerateObject())
{
result[property.Name] = ConvertJsonElement(property.Value);
}
return result;
}
/// <summary> /// <summary>
/// Converts the current object to its protobuf representation /// Converts the current object to its protobuf representation
/// </summary> /// </summary>

View File

@@ -54,6 +54,34 @@ message CloudFile {
// Blurhash for placeholder (optional, for images) // Blurhash for placeholder (optional, for images)
optional string blurhash = 15; optional string blurhash = 15;
// Nested file object containing additional metadata
optional FileObject object = 16;
}
// FileObject represents the actual file data stored in cloud storage.
// It contains metadata about the file content that may be shared across multiple references.
message FileObject {
// Unique identifier for the file object
string id = 1;
// File size in bytes
int64 size = 2;
// File metadata (e.g., dimensions, duration, etc.) stored as JSON bytes
bytes meta = 3;
// MIME type of the file
string mime_type = 4;
// File content hash (e.g., MD5, SHA-256)
string hash = 5;
// Indicates if the file is stored with compression
bool has_compression = 6;
// Indicates if the file has a thumbnail
bool has_thumbnail = 7;
} }
// Service for file operations // Service for file operations