using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; using DysonNetwork.Shared.Models.Embed; using DysonNetwork.Shared.Proto; using Google.Protobuf.WellKnownTypes; using NodaTime; using EmbedLinkEmbed = DysonNetwork.Shared.Models.Embed.LinkEmbed; namespace DysonNetwork.Shared.Models; public class SnWebArticle : ModelBase { public Guid Id { get; set; } = Guid.NewGuid(); [MaxLength(4096)] public string Title { get; set; } = null!; [MaxLength(8192)] public string Url { get; set; } = null!; [MaxLength(4096)] public string? Author { get; set; } [Column(TypeName = "jsonb")] public Dictionary? Meta { get; set; } [Column(TypeName = "jsonb")] public EmbedLinkEmbed? Preview { get; set; } // ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength public string? Content { get; set; } public DateTime? PublishedAt { get; set; } public Guid FeedId { get; set; } public SnWebFeed Feed { get; set; } = null!; public WebArticle ToProtoValue() { var proto = new WebArticle { Id = Id.ToString(), Title = Title, Url = Url, FeedId = FeedId.ToString(), CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()), UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()) }; if (!string.IsNullOrEmpty(Author)) proto.Author = Author; if (Meta != null) proto.Meta = GrpcTypeHelper.ConvertObjectToByteString(Meta); if (Preview != null) proto.Preview = Preview.ToProtoValue(); if (!string.IsNullOrEmpty(Content)) proto.Content = Content; if (PublishedAt.HasValue) proto.PublishedAt = Timestamp.FromDateTime(PublishedAt.Value.ToUniversalTime()); if (DeletedAt.HasValue) proto.DeletedAt = Timestamp.FromDateTimeOffset(DeletedAt.Value.ToDateTimeOffset()); return proto; } public static SnWebArticle FromProtoValue(WebArticle proto) { return new SnWebArticle { Id = Guid.Parse(proto.Id), Title = proto.Title, Url = proto.Url, FeedId = Guid.Parse(proto.FeedId), Author = proto.Author == "" ? null : proto.Author, Meta = proto.Meta != null ? GrpcTypeHelper.ConvertByteStringToObject>(proto.Meta) : null, Preview = proto.Preview != null ? EmbedLinkEmbed.FromProtoValue(proto.Preview) : null, Content = proto.Content == "" ? null : proto.Content, PublishedAt = proto.PublishedAt != null ? proto.PublishedAt.ToDateTime() : null, CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()), UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()), DeletedAt = proto.DeletedAt != null ? Instant.FromDateTimeOffset(proto.DeletedAt.ToDateTimeOffset()) : null }; } } public class WebFeedConfig { public bool ScrapPage { get; set; } public Proto.WebFeedConfig ToProtoValue() { return new Proto.WebFeedConfig { ScrapPage = ScrapPage }; } public static WebFeedConfig FromProtoValue(Proto.WebFeedConfig proto) { return new WebFeedConfig { ScrapPage = proto.ScrapPage }; } } public class SnWebFeed : ModelBase { public Guid Id { get; set; } = Guid.NewGuid(); [MaxLength(8192)] public string Url { get; set; } = null!; [MaxLength(4096)] public string Title { get; set; } = null!; [MaxLength(8192)] public string? Description { get; set; } public Instant? VerifiedAt { get; set; } [JsonIgnore] [MaxLength(8192)] public string? VerificationKey { get; set; } [Column(TypeName = "jsonb")] public EmbedLinkEmbed? Preview { get; set; } [Column(TypeName = "jsonb")] public WebFeedConfig Config { get; set; } = new(); public Guid PublisherId { get; set; } [NotMapped] public SnPublisher Publisher { get; set; } = null!; [JsonIgnore] public List Articles { get; set; } = new(); public WebFeed ToProtoValue() { var proto = new WebFeed { Id = Id.ToString(), Url = Url, Title = Title, Config = Config.ToProtoValue(), PublisherId = PublisherId.ToString(), CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()), UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()) }; if (!string.IsNullOrEmpty(Description)) proto.Description = Description; if (VerifiedAt.HasValue) proto.VerifiedAt = Timestamp.FromDateTimeOffset(VerifiedAt.Value.ToDateTimeOffset()); if (Preview != null) proto.Preview = Preview.ToProtoValue(); if (Publisher != null) proto.Publisher = Publisher.ToProtoValue(); if (DeletedAt.HasValue) proto.DeletedAt = Timestamp.FromDateTimeOffset(DeletedAt.Value.ToDateTimeOffset()); return proto; } public static SnWebFeed FromProtoValue(WebFeed proto) { return new SnWebFeed { Id = Guid.Parse(proto.Id), Url = proto.Url, Title = proto.Title, Description = proto.Description == "" ? null : proto.Description, VerifiedAt = proto.VerifiedAt != null ? Instant.FromDateTimeOffset(proto.VerifiedAt.ToDateTimeOffset()) : null, Preview = proto.Preview != null ? EmbedLinkEmbed.FromProtoValue(proto.Preview) : null, Config = WebFeedConfig.FromProtoValue(proto.Config), PublisherId = Guid.Parse(proto.PublisherId), Publisher = proto.Publisher != null ? SnPublisher.FromProtoValue(proto.Publisher) : null, CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()), UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()), DeletedAt = proto.DeletedAt != null ? Instant.FromDateTimeOffset(proto.DeletedAt.ToDateTimeOffset()) : null }; } } public class SnWebFeedSubscription : ModelBase { public Guid Id { get; set; } = Guid.NewGuid(); public Guid FeedId { get; set; } public SnWebFeed Feed { get; set; } = null!; public Guid AccountId { get; set; } [NotMapped] public SnAccount Account { get; set; } = null!; public WebFeedSubscription ToProtoValue() { var proto = new WebFeedSubscription { Id = Id.ToString(), FeedId = FeedId.ToString(), AccountId = AccountId.ToString(), CreatedAt = Timestamp.FromDateTimeOffset(CreatedAt.ToDateTimeOffset()), UpdatedAt = Timestamp.FromDateTimeOffset(UpdatedAt.ToDateTimeOffset()) }; if (Feed != null) proto.Feed = Feed.ToProtoValue(); return proto; } public static SnWebFeedSubscription FromProtoValue(WebFeedSubscription proto) { return new SnWebFeedSubscription { Id = Guid.Parse(proto.Id), FeedId = Guid.Parse(proto.FeedId), Feed = proto.Feed != null ? SnWebFeed.FromProtoValue(proto.Feed) : null, AccountId = Guid.Parse(proto.AccountId), CreatedAt = Instant.FromDateTimeOffset(proto.CreatedAt.ToDateTimeOffset()), UpdatedAt = Instant.FromDateTimeOffset(proto.UpdatedAt.ToDateTimeOffset()) }; } }