A remote post's canReply, canLike and canAnnounce (with the older always and approvalRequired) are kept beside canQuote and judged for each persona: let in at once when the rule names the public, the persona, the author's followers while it follows the author, or the accounts the author follows while the author follows it; asked first when only the manual list names it; refused (422) otherwise. Asked first, a ReplyRequest, LikeRequest or AnnounceRequest with the interaction as its instrument goes to the author alone, and the interaction waits (privapub.approval: pending). The author's Accept brings an authorization, verified on the author's origin as naming the interaction and the post; the reply then goes out with replyAuthorization, the boost with announceAuthorization, the like with likeAuthorization. A Reject leaves the reply ours alone and takes a like or a boost back. As a third party, a reply a policy does not let in at once is kept only with an authorization that verifies. Clients see the rules as GoToSocial's interaction_policy. Checked live against GoToSocial 0.22.1: the scenario's nine new checks pass (64 in all), a reply and a like approved through its interaction requests and a boost refused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
134 lines
3.9 KiB
C#
134 lines
3.9 KiB
C#
namespace PrivaPub.Models.Post
|
|
{
|
|
public class CustomEmoji
|
|
{
|
|
public string Shortcode { get; set; }//without the colons
|
|
public string URL { get; set; }
|
|
public DateTime? Updated { get; set; }
|
|
}
|
|
|
|
public class PostPoll
|
|
{
|
|
public List<PollOption> Options { get; set; } = new();
|
|
public bool Multiple { get; set; }
|
|
public DateTime? ExpiresAt { get; set; }
|
|
public DateTime? ClosedAt { get; set; }
|
|
public int? VotersCount { get; set; }//null when the origin does not say (Misskey)
|
|
public bool HideTotals { get; set; }
|
|
}
|
|
|
|
public class PollOption
|
|
{
|
|
public string Title { get; set; }
|
|
public int Votes { get; set; }
|
|
}
|
|
|
|
// an interaction of ours with a remote post whose interaction policy asks its author first
|
|
public enum ApprovalState
|
|
{
|
|
None,
|
|
Pending,
|
|
Accepted,
|
|
Rejected
|
|
}
|
|
|
|
public class InteractionRule
|
|
{
|
|
public List<string> Automatic { get; set; } = new();//actor or collection URIs; Public for anyone
|
|
public List<string> Manual { get; set; } = new();
|
|
}
|
|
|
|
public class PostSource
|
|
{
|
|
public string Content { get; set; }
|
|
public string MediaType { get; set; }//text/markdown, text/x.misskeymarkdown (MFM), text/bbcode…
|
|
}
|
|
|
|
public class PostLink
|
|
{
|
|
public string Href { get; set; }
|
|
public string MediaType { get; set; }
|
|
public string Title { get; set; }
|
|
public string Description { get; set; }
|
|
public string ImageURL { get; set; }
|
|
public bool FromPublisher { get; set; }//title, description and image came with the post (FEP-8967 preview), nothing was fetched
|
|
}
|
|
|
|
public class MediaVariant
|
|
{
|
|
public string Url { get; set; }
|
|
public string MediaType { get; set; }
|
|
public int? Width { get; set; }
|
|
public int? Height { get; set; }
|
|
public double? Fps { get; set; }
|
|
public long? Size { get; set; }
|
|
public List<string> Streams { get; set; } = new();//"audio", "video", from PeerTube's ffprobe_codec_type
|
|
}
|
|
|
|
public class VideoDetails
|
|
{
|
|
public double? DurationSeconds { get; set; }
|
|
public List<MediaVariant> Variants { get; set; } = new();
|
|
public string PlaylistURL { get; set; }//HLS
|
|
public bool IsLive { get; set; }
|
|
public int? State { get; set; }//PeerTube: 1 published, 4 waiting for live, 5 live ended
|
|
public long? Views { get; set; }
|
|
public int? CommentsPolicy { get; set; }//PeerTube: 1 open, 2 closed, 3 needs approval
|
|
public bool? DownloadEnabled { get; set; }
|
|
public string Licence { get; set; }
|
|
public string Category { get; set; }
|
|
public string ChannelURI { get; set; }
|
|
public string EmbedURL { get; set; }
|
|
public string ChaptersURL { get; set; }
|
|
public List<Caption> Captions { get; set; } = new();
|
|
}
|
|
|
|
public class Caption
|
|
{
|
|
public string Language { get; set; }
|
|
public string Url { get; set; }
|
|
}
|
|
|
|
public class AudioDetails
|
|
{
|
|
public double? DurationSeconds { get; set; }
|
|
public List<MediaVariant> Variants { get; set; } = new();
|
|
public string Album { get; set; }
|
|
public int? Position { get; set; }
|
|
public string Licence { get; set; }
|
|
}
|
|
|
|
public class EventDetails
|
|
{
|
|
public DateTime? Start { get; set; }
|
|
public DateTime? End { get; set; }
|
|
public string TimeZone { get; set; }
|
|
public bool FloatingTime { get; set; }//"-00:00": a local time with no zone (Hubzilla)
|
|
public List<EventPlace> Places { get; set; } = new();
|
|
public string OnlineURL { get; set; }
|
|
public string JoinMode { get; set; }
|
|
public int? ParticipantCount { get; set; }
|
|
public int? Capacity { get; set; }
|
|
public string Status { get; set; }
|
|
public string Category { get; set; }
|
|
}
|
|
|
|
//a remote post's own place (Pixelfed's location): shown, never federated again
|
|
public class PostPlace
|
|
{
|
|
public string Name { get; set; }
|
|
public double Latitude { get; set; }
|
|
public double Longitude { get; set; }
|
|
public string Country { get; set; }
|
|
}
|
|
|
|
public class EventPlace
|
|
{
|
|
public string Name { get; set; }
|
|
public string Address { get; set; }
|
|
public double? Latitude { get; set; }
|
|
public double? Longitude { get; set; }
|
|
public string Url { get; set; }//a VirtualLocation
|
|
}
|
|
}
|