using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using DysonNetwork.Shared.Proto;
namespace DysonNetwork.Shared.Models;
public enum ContentSensitiveMark
{
Language,
SexualContent,
Violence,
Profanity,
HateSpeech,
Racism,
AdultContent,
DrugAbuse,
AlcoholAbuse,
Gambling,
SelfHarm,
ChildAbuse,
Other
}
///
/// The class that used in jsonb columns which referenced the cloud file.
/// The aim of this class is to store some properties that won't change to a file to reduce the database load.
/// Supports both local cloud files (with Id) and external/fediverse files (with Url).
///
public class SnCloudFileReferenceObject : ModelBase, ICloudFile
{
public string Id { get; set; } = null!;
public string Name { get; set; } = string.Empty;
public Dictionary FileMeta { get; set; } = null!;
public Dictionary UserMeta { get; set; } = null!;
public List? SensitiveMarks { get; set; }
public string? MimeType { get; set; }
public string? Hash { get; set; }
public long Size { get; set; }
public bool HasCompression { get; set; } = false;
[MaxLength(2048)] public string? Url { get; set; }
public int? Width { get; set; }
public int? Height { get; set; }
[MaxLength(64)] public string? Blurhash { get; set; }
public static SnCloudFileReferenceObject FromProtoValue(Proto.CloudFile proto)
{
var fileMeta = proto.Object != null
? ConvertObjectToDictionary(proto.Object.Meta)
: ConvertToDictionary(proto.FileMeta);
return new SnCloudFileReferenceObject
{
Id = proto.Id,
Name = proto.Name,
FileMeta = fileMeta,
UserMeta = ConvertToDictionary(proto.UserMeta),
SensitiveMarks = proto.HasSensitiveMarks
? GrpcTypeHelper.ConvertByteStringToObject>(proto.SensitiveMarks)
: [],
MimeType = proto.MimeType,
Hash = proto.Hash,
Size = proto.Size,
HasCompression = proto.HasCompression,
Url = string.IsNullOrEmpty(proto.Url) ? null : proto.Url,
Width = proto.HasWidth ? proto.Width : null,
Height = proto.HasHeight ? proto.Height : null,
Blurhash = proto.HasBlurhash ? proto.Blurhash : null
};
}
private static Dictionary ConvertObjectToDictionary(Google.Protobuf.ByteString byteString)
{
if (byteString.IsEmpty)
return [];
var jsonElement = GrpcTypeHelper.ConvertByteStringToObject(byteString);
if (jsonElement.ValueKind != JsonValueKind.Object)
return [];
var result = new Dictionary();
foreach (var property in jsonElement.EnumerateObject())
{
result[property.Name] = ConvertJsonElement(property.Value);
}
return result;
}
private static Dictionary ConvertToDictionary(Google.Protobuf.ByteString byteString)
{
if (byteString.IsEmpty)
return [];
var jsonElement = GrpcTypeHelper.ConvertByteStringToObject(byteString);
if (jsonElement.ValueKind != JsonValueKind.Object)
return [];
var result = new Dictionary();
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 ConvertToDictionaryElement(JsonElement element)
{
var result = new Dictionary();
foreach (var property in element.EnumerateObject())
{
result[property.Name] = ConvertJsonElement(property.Value);
}
return result;
}
///
/// Converts the current object to its protobuf representation
///
public CloudFile ToProtoValue()
{
var proto = new CloudFile
{
Id = Id,
Name = Name,
MimeType = MimeType ?? string.Empty,
Hash = Hash ?? string.Empty,
Size = Size,
HasCompression = HasCompression,
ContentType = MimeType ?? string.Empty,
Url = Url ?? string.Empty,
Width = Width ?? 0,
Height = Height ?? 0,
Blurhash = Blurhash ?? string.Empty,
FileMeta = GrpcTypeHelper.ConvertObjectToByteString(FileMeta),
UserMeta = GrpcTypeHelper.ConvertObjectToByteString(UserMeta),
SensitiveMarks = GrpcTypeHelper.ConvertObjectToByteString(SensitiveMarks)
};
return proto;
}
}