From 935ad134ece471bb4aa031642219d47ff5523417 Mon Sep 17 00:00:00 2001 From: mStar aka a person <12024604-mstarongitlab@users.noreply.gitlab.com> Date: Tue, 30 Jan 2024 11:26:41 +0000 Subject: [PATCH] Progress on adding AP objects --- ap/attachment.go | 7 +++++++ ap/create-action.go | 16 +++++++++++++++ ap/media.go | 9 +++++++++ ap/note-object.go | 29 +++++++++++++++++++++++++++ ap/ordered-collection.go | 23 +++++++++++++++++++++ ap/person.go | 43 ++++++++++++++++++++++++++++++++++++++++ ap/public_key.go | 21 ++++++++++++++++++++ ap/question-entry.go | 10 ++++++++++ ap/question-object.go | 27 +++++++++++++++++++++++++ ap/raw-note-content.go | 6 ++++++ ap/tag.go | 9 +++++++++ 11 files changed, 200 insertions(+) create mode 100644 ap/attachment.go create mode 100644 ap/create-action.go create mode 100644 ap/media.go create mode 100644 ap/note-object.go create mode 100644 ap/ordered-collection.go create mode 100644 ap/person.go create mode 100644 ap/public_key.go create mode 100644 ap/question-entry.go create mode 100644 ap/question-object.go create mode 100644 ap/raw-note-content.go create mode 100644 ap/tag.go diff --git a/ap/attachment.go b/ap/attachment.go new file mode 100644 index 0000000..961e166 --- /dev/null +++ b/ap/attachment.go @@ -0,0 +1,7 @@ +package ap + +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 + Value string `json:"value"` // Value of the property. Link or html or just some text. Example: https://gitlab.com/mstarongitlab/Linstrom +} diff --git a/ap/create-action.go b/ap/create-action.go new file mode 100644 index 0000000..be21d89 --- /dev/null +++ b/ap/create-action.go @@ -0,0 +1,16 @@ +package ap + +import ( + "net/url" + "time" +) + +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? +} diff --git a/ap/media.go b/ap/media.go new file mode 100644 index 0000000..a8fd27f --- /dev/null +++ b/ap/media.go @@ -0,0 +1,9 @@ +package ap + +import "net/url" + +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 +} diff --git a/ap/note-object.go b/ap/note-object.go new file mode 100644 index 0000000..cf632bc --- /dev/null +++ b/ap/note-object.go @@ -0,0 +1,29 @@ +package ap + +import ( + "net/url" + "time" +) + +type Note 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 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 + 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 + 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 + + 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? +} diff --git a/ap/ordered-collection.go b/ap/ordered-collection.go new file mode 100644 index 0000000..1581337 --- /dev/null +++ b/ap/ordered-collection.go @@ -0,0 +1,23 @@ +package ap + +import "net/url" + +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 +} + +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 +} diff --git a/ap/person.go b/ap/person.go new file mode 100644 index 0000000..9da9df8 --- /dev/null +++ b/ap/person.go @@ -0,0 +1,43 @@ +package ap + +import ( + "net/url" + "time" +) + +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" + 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 + 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? + 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 + 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 + + 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 +} diff --git a/ap/public_key.go b/ap/public_key.go new file mode 100644 index 0000000..528c783 --- /dev/null +++ b/ap/public_key.go @@ -0,0 +1,21 @@ +package ap + +import "net/url" + +type PublicKey struct { + ID url.URL `json:"id"` // ID of the key + Owner url.URL `json:"owner"` // Who this key belongs to + Content string `json:"publicKeyPem"` // Actual content of the key, example below +} + +/* + +Example for a public key + +""" +-----BEGIN PUBLIC KEY----- +Big blob of random characters +-----END PUBLIC KEY----- + +""" +*/ diff --git a/ap/question-entry.go b/ap/question-entry.go new file mode 100644 index 0000000..250a8ab --- /dev/null +++ b/ap/question-entry.go @@ -0,0 +1,10 @@ +package ap + +type QuestionEntry struct { + Type string `json:"type"` // Should always be "Note" + Name string `json:"name"` // Name of the entry + Replies struct { + Type string `json:"type"` // Should always be "Collection" + TotalItems int // Nr of people that selected this + } `json:"replies"` // Nr of people that selected this option +} diff --git a/ap/question-object.go b/ap/question-object.go new file mode 100644 index 0000000..611741b --- /dev/null +++ b/ap/question-object.go @@ -0,0 +1,27 @@ +package ap + +import ( + "net/url" + "time" +) + +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 + Type string `json:"type"` // Should always be "Question" + AttributedTo url.URL `json:"attributedTo"` // Creator of this object + Content string `json:"content"` // Preformated text content + MkContent string `json:"_misskey_content"` // Misskey version of the content + Source RawNoteContent `json:"source"` // Raw version of the content + Published time.Time `json:"published"` // When this object was published + To []url.URL `json:"to"` // Who to send this to + Cc []url.URL `json:"cc"` // More targets to send to + InReplyTo *url.URL `json:"inReplyTo"` // Object this post replies to + 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 + 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 new file mode 100644 index 0000000..06fc613 --- /dev/null +++ b/ap/raw-note-content.go @@ -0,0 +1,6 @@ +package ap + +type RawNoteContent struct { + Content string `json:"content"` + MediaType string `json:"mediaType"` +} diff --git a/ap/tag.go b/ap/tag.go new file mode 100644 index 0000000..2e05cdd --- /dev/null +++ b/ap/tag.go @@ -0,0 +1,9 @@ +package ap + +import "net/url" + +type Tag 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" +}