From e65b8d6ad563a4009ee2f493af056f3df5a066d9 Mon Sep 17 00:00:00 2001 From: mStar aka a person <12024604-mstarongitlab@users.noreply.gitlab.com> Date: Wed, 31 Jan 2024 16:56:07 +0000 Subject: [PATCH] I think that's all AP things relevant --- ap/accept-action.go | 12 +++++++++++ ap/announce-action.go | 14 ++++++++++++ ap/attachment.go | 1 + ap/create-action.go | 16 ++++++++------ ap/delete-action.go | 16 ++++++++++++++ ap/emote.go | 15 +++++++++++++ ap/follow-action.go | 12 +++++++++++ ap/like-action.go | 12 +++++++++++ ap/media.go | 7 +++--- ap/mention.go | 10 +++++++++ ap/note-object.go | 15 +++++++------ ap/ordered-collection.go | 30 ++++++++++++++------------ ap/person.go | 46 +++++++++++++++++++++++----------------- ap/public_key.go | 1 + ap/question-entry.go | 1 + ap/question-object.go | 3 ++- ap/raw-note-content.go | 1 + ap/reject-action.go | 12 +++++++++++ ap/tag.go | 3 ++- ap/tombstone-object.go | 10 +++++++++ ap/undo-action.go | 12 +++++++++++ 21 files changed, 197 insertions(+), 52 deletions(-) create mode 100644 ap/accept-action.go create mode 100644 ap/announce-action.go create mode 100644 ap/delete-action.go create mode 100644 ap/emote.go create mode 100644 ap/follow-action.go create mode 100644 ap/like-action.go create mode 100644 ap/mention.go create mode 100644 ap/reject-action.go create mode 100644 ap/tombstone-object.go create mode 100644 ap/undo-action.go diff --git a/ap/accept-action.go b/ap/accept-action.go new file mode 100644 index 0000000..7132a49 --- /dev/null +++ b/ap/accept-action.go @@ -0,0 +1,12 @@ +package ap + +import "net/url" + +// Sent when a follow request is approved, manually or automatically +type AcceptAction struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Url to this action + Type string `json:"type"` // Should always be "Accept" + Actor url.URL `json:"actor"` // Who is accepting what + Object FollowAction `json:"object"` // Action that is being accepted +} diff --git a/ap/announce-action.go b/ap/announce-action.go new file mode 100644 index 0000000..2591896 --- /dev/null +++ b/ap/announce-action.go @@ -0,0 +1,14 @@ +package ap + +import "net/url" + +// Announce == boost/share/retweet +type AnnounceAction struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Url to this action + Type string `json:"type"` // Should always be "Announce" + Actor url.URL `json:"actor"` // Who is announcing something + To []url.URL `json:"to"` // Targets to share to + Cc []url.URL `json:"cc"` // More targets to send to + Object url.URL `json:"object"` // Url to announced object +} diff --git a/ap/attachment.go b/ap/attachment.go index 961e166..eca2a2a 100644 --- a/ap/attachment.go +++ b/ap/attachment.go @@ -1,5 +1,6 @@ package ap +// An info field on an account page type PersonInfoField struct { Type string `json:"type"` // Type of the attachment. Probably should always be "PropertyValue" Name string `json:"name"` // Name of the property. Example: Source diff --git a/ap/create-action.go b/ap/create-action.go index be21d89..dfc3748 100644 --- a/ap/create-action.go +++ b/ap/create-action.go @@ -5,12 +5,14 @@ import ( "time" ) +// Sent when posting something type CreateAction struct { - ID url.URL `json:"id"` // URL to this resource - Actor url.URL `json:"actor"` // Account that created this action, links to the AP url - Type string `json:"type"` // Should always be "Create" - Published time.Time `json:"published"` // When this action was created - Object map[string]any `json:"object"` // Content of the action, is an AP object, like notes or questions (survey) - To []url.URL `json:"to"` // Array of url targets to deliver it to? - Cc []url.URL `json:"cc"` // More targets to deliver to? + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + ID url.URL `json:"id"` // URL to this resource + Actor url.URL `json:"actor"` // Account that created this action, links to the AP url + Type string `json:"type"` // Should always be "Create" + Published time.Time `json:"published"` // When this action was created + Object any `json:"object"` // Content of the action, is an AP object, like notes or questions (survey) + To []url.URL `json:"to"` // Array of url targets to deliver it to. With dms, oonly includes target accounts. Followers only goes to followers url of posting account + Cc []url.URL `json:"cc"` // More targets to deliver to? } diff --git a/ap/delete-action.go b/ap/delete-action.go new file mode 100644 index 0000000..978007e --- /dev/null +++ b/ap/delete-action.go @@ -0,0 +1,16 @@ +package ap + +import ( + "net/url" + "time" +) + +// When a message is deleted +type DeleteAction struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Location of this resource + Type string `json:"type"` // Should always be "Delete" + Actor url.URL `json:"actor"` // Account deleting something + Target url.URL `json:"object"` // Account that the actor wants to follow + Published time.Time `json:"published"` // When this was done +} diff --git a/ap/emote.go b/ap/emote.go new file mode 100644 index 0000000..d261cb1 --- /dev/null +++ b/ap/emote.go @@ -0,0 +1,15 @@ +package ap + +import ( + "net/url" + "time" +) + +// Custom emote information +type Emote struct { + Icon Media `json:"icon"` // Emote source file + ID url.URL `json:"id"` // Url of the image + Name string `json:"name"` // Name of the emote, example: ":neocat_heart:" + Type string `json:"type"` // Should always be "Emoji" + Updated time.Time `json:"updated"` // When this was last updated. Akkoma seems to set this to unix epoch +} diff --git a/ap/follow-action.go b/ap/follow-action.go new file mode 100644 index 0000000..f517a84 --- /dev/null +++ b/ap/follow-action.go @@ -0,0 +1,12 @@ +package ap + +import "net/url" + +// A follow request +type FollowAction struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Location of this resource + Type string `json:"type"` // Should always be "Follow" + Actor url.URL `json:"actor"` // Account instanciating the follow request + Target url.URL `json:"object"` // Account that the actor wants to follow +} diff --git a/ap/like-action.go b/ap/like-action.go new file mode 100644 index 0000000..ebfb569 --- /dev/null +++ b/ap/like-action.go @@ -0,0 +1,12 @@ +package ap + +import "net/url" + +// Action to like a post +type LikeAction struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Url to this action + Type string `json:"type"` // Should always be "Like" + Actor url.URL `json:"actor"` // Who is liking something + Object url.URL `json:"object"` // What is being liked +} diff --git a/ap/media.go b/ap/media.go index a8fd27f..30532ed 100644 --- a/ap/media.go +++ b/ap/media.go @@ -2,8 +2,9 @@ package ap import "net/url" +// Media content (video files, images, audio) type Media struct { - Type string `json:"type"` // Should probably always be "Image", "Video" or similar. Dunno if "Video" is correct - MediaType string `json:"mediaType"` // What media type the linked resource is. Something like "image/png" - Url url.URL `json:"url"` // Where to find the media file + Type string `json:"type"` // Should probably always be "Image", "Video" or similar. Dunno if "Video" is correct + MediaType *string `json:"mediaType,omitempty"` // What media type the linked resource is. Something like "image/png" + Url url.URL `json:"url"` // Where to find the media file } diff --git a/ap/mention.go b/ap/mention.go new file mode 100644 index 0000000..92aae0c --- /dev/null +++ b/ap/mention.go @@ -0,0 +1,10 @@ +package ap + +import "net/url" + +// Tag type for mentions +type Mention struct { + Type string `json:"type"` // Should always be "Mention" + Href url.URL `json:"href"` // Url to mentioned account + Name string `json:"name"` // Name of the account ("@foo@example.com") +} diff --git a/ap/note-object.go b/ap/note-object.go index cf632bc..7e7a384 100644 --- a/ap/note-object.go +++ b/ap/note-object.go @@ -5,17 +5,17 @@ import ( "time" ) +// A post type Note struct { - Context map[string]any `json:"@context,omitempty"` // Lots of something. Not included if note is embedded as object in another object + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if note is embedded as object in another object ID url.URL `json:"id"` // Url to this resource Type string `json:"type"` // Should always be "Note" AttributedTo url.URL `json:"attributedTo"` // Author of this note Content string `json:"content"` // Content of this note - MkContent string `json:"_misskey_content"` // Misskey version of content - Source RawNoteContent `json:"source"` // Raw content + Source *RawNoteContent `json:"source"` // Raw content InReplyTo *url.URL `json:"inReplyTo,omitempty"` // Note this is a reply to. Empty if not a reply Attachment []map[string]string `json:"attachment"` // Media attachments - TODO: Make proper type for this - Tag []Tag `json:"tag"` // List of hashtags + Tag []any `json:"tag"` // List of hashtags, mentions & custom emotes Published time.Time `json:"published"` // When this note was created To []url.URL `json:"to"` // Where this note should get sent to Cc []url.URL `json:"cc"` // More where this note should get sent to @@ -23,7 +23,8 @@ type Note struct { Summary *string `json:"summary"` // Summary of a post (also known as content warning) Sensitive bool `json:"sensitive"` // Does this note have a content warning? - MkQuote *url.URL `json:"_misskey_quote,omitempty"` // Misskey link to note this quotes - QuoteUrl *url.URL `json:"quoteUrl,omitempty"` // Link to quoted note object - QuoteUri *url.URL `json:"quoteUri,omitempty"` // Same as Quote Url? + MkContent *string `json:"_misskey_content,omitempty"` // Misskey version of content + MkQuote *url.URL `json:"_misskey_quote,omitempty"` // Misskey link to note this quotes + QuoteUrl *url.URL `json:"quoteUrl,omitempty"` // Link to quoted note object + QuoteUri *url.URL `json:"quoteUri,omitempty"` // Same as Quote Url? } diff --git a/ap/ordered-collection.go b/ap/ordered-collection.go index 1581337..4fbcdb6 100644 --- a/ap/ordered-collection.go +++ b/ap/ordered-collection.go @@ -2,22 +2,24 @@ package ap import "net/url" +// Ordered collection of things (paged) type OrderedCollection struct { - Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck - ID url.URL `json:"id"` // URL to this resource - Type string `json:"type"` // Should always be "OrderedCollection" - TotalItems int `json:"totalItems"` // Number of resources in this collection - First url.URL `json:"first"` // Link to the first resource in this collection, an OrderedCollectionPage object - Last url.URL `json:"last"` // Link to the last resource in this collection, an OrderedCollectionPage object + Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck + ID url.URL `json:"id"` // URL to this resource + Type string `json:"type"` // Should always be "OrderedCollection" + TotalItems *int `json:"totalItems,omitempty"` // Number of resources in this collection, Akoma doesn't include this + First url.URL `json:"first"` // Link to the first resource in this collection, an OrderedCollectionPage object + Last url.URL `json:"last"` // Link to the last resource in this collection, an OrderedCollectionPage object } +// One page of an ordered collection type OrderedCollectionPage struct { - Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck - ID url.URL `json:"id"` // URL to this resource - PartOf url.URL `json:"partOf"` // URL to the collection this is a part of - Type string `json:"type"` // Should always be "OrderedCollectionPage" - TotalItems int `json:"totalItems"` // Number of resources in this collection - OrderedItems []map[string]any `json:"orderedItems"` // Items in this list. Should all be AP objects/actions - Previous *url.URL `json:"prev"` // Previous page - Next *url.URL `json:"next"` // Next page + Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck + ID url.URL `json:"id"` // URL to this resource + PartOf url.URL `json:"partOf"` // URL to the collection this is a part of + Type string `json:"type"` // Should always be "OrderedCollectionPage" + TotalItems *int `json:"totalItems,omitempty"` // Number of resources in this collection. Mk yes, Masto no, Akoma no + OrderedItems []map[string]any `json:"orderedItems"` // Items in this list. Should all be AP objects/actions + Previous *url.URL `json:"prev"` // Previous page, empty if no items? I think? + Next *url.URL `json:"next"` // Next page } diff --git a/ap/person.go b/ap/person.go index 9da9df8..37b0114 100644 --- a/ap/person.go +++ b/ap/person.go @@ -5,39 +5,47 @@ import ( "time" ) +// An account type Person struct { Context map[string]any `json:"@context"` // Big chunk of hopefully don't give a fuck ID url.URL `json:"id"` // URL to this resource - Type string `json:"type"` // Should always be of content "Person" + Type string `json:"type"` // Should always be of content "Person" (or "Service", if a bot) Following url.URL `json:"following"` // Ordered collection of accounts this account follows Followers url.URL `json:"followers"` // Ordered collection of accounts following this account Inbox url.URL `json:"inbox"` // Where others send activities to (posts, follow requests, reactions, etc) Outbox url.URL `json:"outbox"` // Where others can read this account's activities from - Featured url.URL `json:"featured"` // Ordered collection of something featured - TODO: Find out what this is - FeaturedTags *url.URL `json:"featuredTags"` // Collection of something, not ordered - TODO: Find out what this is + Featured url.URL `json:"featured"` // Ordered collection of something featured - TODO: Find out what this is PreferredUsername string `json:"preferredUsername"` // Username Name string `json:"name"` // Vanity name Summary string `json:"summary"` // Description of the account. Could contain html or maybe mfm for *key Url url.URL `json:"url"` // Public location of the account - Locked bool `json:"manuallyApprovesFollowers"` // Does this account have to approve of follows before they are actual follows? + ManualApproval bool `json:"manuallyApprovesFollowers"` // Does this account have to approve of follows before they are actual follows? Discoverable bool `json:"discoverable"` // If this account can be found via search things? I guess? - Indexable *bool `json:"indexable"` // Probably if this account will be shown to search engines and crawlers? - Published *time.Time `json:"published"` // When this account was created I guess? - Memorial *bool `json:"memorial"` // If this account is closed? Or moved? Probably closed - Devices *url.URL `json:"devices"` // Collection of something - TODO: Find out what this is PublicKey PublicKey `json:"publicKey"` // public key of that account. For verifying that that account is actually them - Tag []any `json:"tag"` // Array of something. Probably urls or strings + Tag []Emote `json:"tag"` // Contains custom emote info - TODO: Add proper type Attachment PersonInfoField `json:"attachment"` // Additional profile information (fields below the description, like "Source: https://gitlab.com/mstarongitlab/linstrom") Endpoints map[string]string `json:"endpoints"` // Stores at least the shared inbox of the server this account is on in "sharedInbox", which is an url - Icon *Media `json:"icon"` // Profile image of the account - Image *Media `json:"image"` // Header image of the account + Icon *Media `json:"icon"` // Profile image of the account, null if not set + Image *Media `json:"image"` // Header image of the account, null if not set - SharedInbox *url.URL `json:"sharedInbox"` // Replicates the shared inbox url here I guess - MkSummary *string `json:"_misskey_summary"` // Misskey's version of the summary - Background *url.URL `json:"backgroundUrl"` // Background image - IsCat *bool `json:"isCat"` // Is the user a cat (apply cat ears in that case) - NoIndex *bool `json:"noindex"` // probably the same as Indexable, just reversed? - SpeakAsCat *bool `json:"speakAsCat"` // Does the account speak like a cat - Birthday *string `json:"vcard:bday"` // Birthday date, but doesn't quite follow normalised datetime - Location *string `json:"vcard:Address"` // Where the user of the account lives, could technically be anything as just a string + // Section: Mastodon only + Indexable *bool `json:"indexable,omitempty"` // Probably if this account will be shown to search engines and crawlers? + FeaturedTags *url.URL `json:"featuredTags,omitempty"` // Collection of something, not ordered - TODO: Find out what this is + Published *time.Time `json:"published,omitempty"` // When this account was created I guess? + Memorial *bool `json:"memorial,omitempty"` // If this account is closed? Or moved? Probably closed + Devices *url.URL `json:"devices,omitempty"` // Collection of something - TODO: Find out what this is + + // Section: Misskey only + SharedInbox *url.URL `json:"sharedInbox,omitempty"` // Replicates the shared inbox url here I guess + MkSummary *string `json:"_misskey_summary,omitempty"` // Misskey's version of the summary + Background *url.URL `json:"backgroundUrl,omitempty"` // Background image + IsCat *bool `json:"isCat,omitempty"` // Is the user a cat (apply cat ears in that case) + NoIndex *bool `json:"noindex,omitempty"` // probably the same as Indexable, just reversed? + SpeakAsCat *bool `json:"speakAsCat,omitempty"` // Does the account speak like a cat + Birthday *string `json:"vcard:bday,omitempty"` // Birthday date, but doesn't quite follow normalised datetime + Location *string `json:"vcard:Address,omitempty"` // Where the user of the account lives, could technically be anything as just a string + + // Section: Akkoma things + AlsoKnownAs *[]any `json:"alsoKnownAs"` // Meaning unknown + Capabilities *map[string]any `json:"capabilities"` // Meaning unknown } diff --git a/ap/public_key.go b/ap/public_key.go index 528c783..22f3c4d 100644 --- a/ap/public_key.go +++ b/ap/public_key.go @@ -2,6 +2,7 @@ package ap import "net/url" +// The public key associated with an account type PublicKey struct { ID url.URL `json:"id"` // ID of the key Owner url.URL `json:"owner"` // Who this key belongs to diff --git a/ap/question-entry.go b/ap/question-entry.go index 250a8ab..603a3db 100644 --- a/ap/question-entry.go +++ b/ap/question-entry.go @@ -1,5 +1,6 @@ package ap +// One option for a survey type QuestionEntry struct { Type string `json:"type"` // Should always be "Note" Name string `json:"name"` // Name of the entry diff --git a/ap/question-object.go b/ap/question-object.go index 611741b..d9090fd 100644 --- a/ap/question-object.go +++ b/ap/question-object.go @@ -5,6 +5,7 @@ import ( "time" ) +// A survey. Options are in the field OneOf if it's single choice, AnyOf if multipleChoice type Question struct { Context map[string]any `json:"@context,omitempty"` // Lots of something. Not included if note is embedded as object in another object ID url.URL `json:"id"` // Url to this object @@ -20,7 +21,7 @@ type Question struct { Attachment []map[string]string `json:"attachment"` // File attachments - TODO: Move to concrete type Sensitive bool `json:"sensitive"` // Whether this post has a content warning Summary *string `json:"summary"` // Summary of a post (also known as content warning) - Tag []Tag `json:"tag"` // Hashtags + Tag []Hashtag `json:"tag"` // Hashtags EndTime *time.Time `json:"endTime"` // Timestamp of when the question ends OneOf []QuestionEntry `json:"oneOf,omitempty"` // All available options to vote for. Used if single choice vote AnyOf []QuestionEntry `json:"anyOf,omitempty"` // All available options to vote for. Used if multiple choice vote diff --git a/ap/raw-note-content.go b/ap/raw-note-content.go index 06fc613..39a025c 100644 --- a/ap/raw-note-content.go +++ b/ap/raw-note-content.go @@ -1,5 +1,6 @@ package ap +// Raw content of a note I think. Added by Misskey and Akkoma type RawNoteContent struct { Content string `json:"content"` MediaType string `json:"mediaType"` diff --git a/ap/reject-action.go b/ap/reject-action.go new file mode 100644 index 0000000..144e38f --- /dev/null +++ b/ap/reject-action.go @@ -0,0 +1,12 @@ +package ap + +import "net/url" + +// Follow request rejected (or maybe I think "confirmation" on unfollow) +type RejectAction struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Location of this resource + Type string `json:"type"` // Should always be "Reject" + Actor url.URL `json:"actor"` // Account rejecting the follow request + Request FollowAction `json:"object"` // Request that's being rejected +} diff --git a/ap/tag.go b/ap/tag.go index 2e05cdd..773c720 100644 --- a/ap/tag.go +++ b/ap/tag.go @@ -2,7 +2,8 @@ package ap import "net/url" -type Tag struct { +// Describes a hashtag's data +type Hashtag struct { Type string `json:"type"` // Should always be "Hashtag" Href url.URL `json:"href"` // Url to that hashtag Name string `json:"name"` // Name of the hashtag, example: "#some-hashtag" diff --git a/ap/tombstone-object.go b/ap/tombstone-object.go new file mode 100644 index 0000000..3a06bc4 --- /dev/null +++ b/ap/tombstone-object.go @@ -0,0 +1,10 @@ +package ap + +import "net/url" + +// The tombstone of a message +type Tombstone struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Location of this resource + Type string `json:"type"` // Should always be "Tombstone" +} diff --git a/ap/undo-action.go b/ap/undo-action.go new file mode 100644 index 0000000..039f559 --- /dev/null +++ b/ap/undo-action.go @@ -0,0 +1,12 @@ +package ap + +import "net/url" + +// Undo == unfollow +type UndoAction struct { + Context *map[string]any `json:"@context,omitempty"` // Lots of something. Not included if action is embedded as object in another object + Id url.URL `json:"id"` // Location of this resource + Type string `json:"type"` // Should always be "Undo" + Actor url.URL `json:"actor"` // Account instanciating the follow request + Target FollowAction `json:"object"` // Follow to undo +}