kopia lustrzana https://github.com/reiver/greatape
feat(activitypub): 🧑💻 protocol objects and helpers
rodzic
5e3fa111e0
commit
cc4926684b
|
@ -0,0 +1,16 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Activity struct {
|
||||||
|
Context interface{} `json:"@context"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
Actor string `json:"actor,omitempty"`
|
||||||
|
Object interface{} `json:"object,omitempty"`
|
||||||
|
From string `json:"from,omitempty"`
|
||||||
|
To interface{} `json:"to,omitempty"`
|
||||||
|
InReplyTo string `json:"inReplyTo,omitempty"`
|
||||||
|
Content string `json:"content,omitempty"`
|
||||||
|
Published time.Time `json:"published,omitempty"`
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Actor struct {
|
||||||
|
Context []interface{} `json:"@context"`
|
||||||
|
Followers string `json:"followers"`
|
||||||
|
Following string `json:"following"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
PreferredUsername string `json:"preferredUsername"`
|
||||||
|
Inbox string `json:"inbox"`
|
||||||
|
Outbox string `json:"outbox"`
|
||||||
|
Playlists string `json:"playlists"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
PublicKey PublicKey `json:"publicKey"`
|
||||||
|
Url string `json:"url"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
Published time.Time `json:"published"`
|
||||||
|
Icon Icon `json:"icon,omitempty"`
|
||||||
|
Image Icon `json:"image,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Icon struct {
|
||||||
|
Height int64 `json:"height,omitempty"`
|
||||||
|
MediaType string `json:"mediaType,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Width int64 `json:"width,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PublicKey struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Owner string `json:"owner"`
|
||||||
|
PublicKeyPem string `json:"publicKeyPem"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalActor(data []byte) (Actor, error) {
|
||||||
|
var r Actor
|
||||||
|
err := json.Unmarshal(data, &r)
|
||||||
|
return r, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Actor) Marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(r)
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
type OrderedCollection struct {
|
||||||
|
Context string `json:"@context"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
TotalItems int `json:"totalItems"`
|
||||||
|
OrderedItems interface{} `json:"orderedItems,omitempty"`
|
||||||
|
First string `json:"first,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOrderedCollection(id string, items interface{}, length int) *OrderedCollection {
|
||||||
|
return &OrderedCollection{
|
||||||
|
Context: ActivityStreams,
|
||||||
|
ID: id,
|
||||||
|
Type: TypeOrderedCollection,
|
||||||
|
TotalItems: length,
|
||||||
|
OrderedItems: items,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalOrderedCollection(data []byte) (OrderedCollection, error) {
|
||||||
|
var o OrderedCollection
|
||||||
|
err := json.Unmarshal(data, &o)
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OrderedCollection) Marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(o)
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
type Create struct {
|
||||||
|
Context string `json:"@context"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Id string `json:"id"`
|
||||||
|
To []string `json:"to"`
|
||||||
|
Actor string `json:"actor"`
|
||||||
|
Object interface{} `json:"object"`
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
type Followers struct {
|
||||||
|
Context string `json:"@context"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
TotalItems int `json:"totalItems"`
|
||||||
|
OrderedItems interface{} `json:"orderedItems,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalFollowers(data []byte) (Followers, error) {
|
||||||
|
var o Followers
|
||||||
|
err := json.Unmarshal(data, &o)
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Followers) Marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(o)
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Note struct {
|
||||||
|
Context string `json:"@context" validate:"activitystream"`
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
To []string `json:"to"`
|
||||||
|
AttributedTo string `json:"attributedTo"`
|
||||||
|
InReplyTo string `json:"inReplyTo,omitempty"`
|
||||||
|
Content string `json:"content"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNote(from, to, content string) *Note {
|
||||||
|
return &Note{
|
||||||
|
Context: ActivityStreams,
|
||||||
|
To: []string{to},
|
||||||
|
Content: content,
|
||||||
|
Type: TypeNote,
|
||||||
|
AttributedTo: from,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPublicNote(from, content string) *Note {
|
||||||
|
return NewNote(from, Public, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (note *Note) Wrap(username, publicUrl, uniqueIdentifier string) *Activity {
|
||||||
|
return &Activity{
|
||||||
|
Context: ActivityStreams,
|
||||||
|
Type: TypeCreate,
|
||||||
|
ID: fmt.Sprintf("%s/u/%s/posts/%s", publicUrl, username, uniqueIdentifier),
|
||||||
|
To: note.To,
|
||||||
|
Actor: fmt.Sprintf("%s/u/%s", publicUrl, username),
|
||||||
|
Published: time.Now(),
|
||||||
|
Object: note,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalNote(data []byte) (Note, error) {
|
||||||
|
var note Note
|
||||||
|
err := json.Unmarshal(data, ¬e)
|
||||||
|
return note, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (note *Note) Marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(note)
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
type Object struct {
|
||||||
|
Context interface{} `json:"@context"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalObject(data []byte) (Object, error) {
|
||||||
|
var object Object
|
||||||
|
err := json.Unmarshal(data, &object)
|
||||||
|
return object, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (object *Object) Marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(object)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
type Outbox struct {
|
||||||
|
Context string `json:"@context"`
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
TotalItems int `json:"totalItems"`
|
||||||
|
OrderedItems interface{} `json:"orderedItems,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnmarshalOutbox(data []byte) (Outbox, error) {
|
||||||
|
var o Outbox
|
||||||
|
err := json.Unmarshal(data, &o)
|
||||||
|
return o, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *Outbox) Marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(o)
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActivityStreams = "https://www.w3.org/ns/activitystreams"
|
||||||
|
|
||||||
|
TypeCreate = "Create"
|
||||||
|
TypeFollow = "Follow"
|
||||||
|
TypeAccept = "Accept"
|
||||||
|
TypeNote = "Note"
|
||||||
|
TypeOrderedCollection = "OrderedCollection"
|
||||||
|
|
||||||
|
Public = ActivityStreams + "#Public"
|
||||||
|
)
|
|
@ -0,0 +1,38 @@
|
||||||
|
package activitypub
|
||||||
|
|
||||||
|
import "encoding/json"
|
||||||
|
|
||||||
|
func UnmarshalWebfinger(data []byte) (Webfinger, error) {
|
||||||
|
var r Webfinger
|
||||||
|
err := json.Unmarshal(data, &r)
|
||||||
|
return r, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Webfinger) Marshal() ([]byte, error) {
|
||||||
|
return json.Marshal(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Webfinger struct {
|
||||||
|
Aliases []string `json:"aliases"`
|
||||||
|
Links []Link `json:"links"`
|
||||||
|
Subject string `json:"subject"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Link struct {
|
||||||
|
Href *string `json:"href,omitempty"`
|
||||||
|
Rel string `json:"rel"`
|
||||||
|
Type *string `json:"type,omitempty"`
|
||||||
|
Template *string `json:"template,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (webfinger *Webfinger) Self() string {
|
||||||
|
self := ""
|
||||||
|
for _, link := range webfinger.Links {
|
||||||
|
if link.Rel == "self" && link.Type != nil && *link.Type == "application/activity+json" {
|
||||||
|
self = *link.Href
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
Ładowanie…
Reference in New Issue