summaryrefslogtreecommitdiff
path: root/internal/typeutils/internaltoas.go
diff options
context:
space:
mode:
authorLibravatar Tobi Smethurst <31960611+tsmethurst@users.noreply.github.com>2021-08-10 13:32:39 +0200
committerLibravatar GitHub <noreply@github.com>2021-08-10 13:32:39 +0200
commit0f2de6394a1c52d47e326bb7d7d129a217ae4f6f (patch)
treee2709bdbbbbcf5e12d6da62b653b67f1789ab1c5 /internal/typeutils/internaltoas.go
parentFrodo swaggins (#126) (diff)
downloadgotosocial-0f2de6394a1c52d47e326bb7d7d129a217ae4f6f.tar.xz
Dereference remote replies (#132)
* decided where to put reply dereferencing * fiddling with dereferencing threads * further adventures * tidy up some stuff * move dereferencing functionality * a bunch of refactoring * go fmt * more refactoring * bleep bloop * docs and linting * start implementing replies collection on gts side * fiddling around * allow dereferencing our replies * lint, fmt
Diffstat (limited to 'internal/typeutils/internaltoas.go')
-rw-r--r--internal/typeutils/internaltoas.go145
1 files changed, 144 insertions, 1 deletions
diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go
index b24b07e13..333f131d4 100644
--- a/internal/typeutils/internaltoas.go
+++ b/internal/typeutils/internaltoas.go
@@ -27,6 +27,7 @@ import (
"github.com/go-fed/activity/streams"
"github.com/go-fed/activity/streams/vocab"
"github.com/superseriousbusiness/gotosocial/internal/db"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
@@ -505,7 +506,14 @@ func (c *converter) StatusToAS(s *gtsmodel.Status) (vocab.ActivityStreamsNote, e
status.SetActivityStreamsAttachment(attachmentProp)
// replies
- // TODO
+ repliesCollection, err := c.StatusToASRepliesCollection(s, false)
+ if err != nil {
+ return nil, fmt.Errorf("error creating repliesCollection: %s", err)
+ }
+
+ repliesProp := streams.NewActivityStreamsRepliesProperty()
+ repliesProp.SetActivityStreamsCollection(repliesCollection)
+ status.SetActivityStreamsReplies(repliesProp)
return status, nil
}
@@ -850,3 +858,138 @@ func (c *converter) BlockToAS(b *gtsmodel.Block) (vocab.ActivityStreamsBlock, er
return block, nil
}
+
+/*
+ the goal is to end up with something like this:
+
+ {
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
+ "type": "Collection",
+ "first": {
+ "id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?page=true",
+ "type": "CollectionPage",
+ "next": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?only_other_accounts=true&page=true",
+ "partOf": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
+ "items": []
+ }
+ }
+*/
+func (c *converter) StatusToASRepliesCollection(status *gtsmodel.Status, onlyOtherAccounts bool) (vocab.ActivityStreamsCollection, error) {
+ collectionID := fmt.Sprintf("%s/replies", status.URI)
+ collectionIDURI, err := url.Parse(collectionID)
+ if err != nil {
+ return nil, err
+ }
+
+ collection := streams.NewActivityStreamsCollection()
+
+ // collection.id
+ collectionIDProp := streams.NewJSONLDIdProperty()
+ collectionIDProp.SetIRI(collectionIDURI)
+ collection.SetJSONLDId(collectionIDProp)
+
+ // first
+ first := streams.NewActivityStreamsFirstProperty()
+ firstPage := streams.NewActivityStreamsCollectionPage()
+
+ // first.id
+ firstPageIDProp := streams.NewJSONLDIdProperty()
+ firstPageID, err := url.Parse(fmt.Sprintf("%s?page=true", collectionID))
+ if err != nil {
+ return nil, gtserror.NewErrorInternalError(err)
+ }
+ firstPageIDProp.SetIRI(firstPageID)
+ firstPage.SetJSONLDId(firstPageIDProp)
+
+ // first.next
+ nextProp := streams.NewActivityStreamsNextProperty()
+ nextPropID, err := url.Parse(fmt.Sprintf("%s?only_other_accounts=%t&page=true", collectionID, onlyOtherAccounts))
+ if err != nil {
+ return nil, gtserror.NewErrorInternalError(err)
+ }
+ nextProp.SetIRI(nextPropID)
+ firstPage.SetActivityStreamsNext(nextProp)
+
+ // first.partOf
+ partOfProp := streams.NewActivityStreamsPartOfProperty()
+ partOfProp.SetIRI(collectionIDURI)
+ firstPage.SetActivityStreamsPartOf(partOfProp)
+
+ first.SetActivityStreamsCollectionPage(firstPage)
+
+ // collection.first
+ collection.SetActivityStreamsFirst(first)
+
+ return collection, nil
+}
+
+/*
+ the goal is to end up with something like this:
+ {
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?only_other_accounts=true&page=true",
+ "type": "CollectionPage",
+ "next": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?min_id=106720870266901180&only_other_accounts=true&page=true",
+ "partOf": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
+ "items": [
+ "https://example.com/users/someone/statuses/106720752853216226",
+ "https://somewhere.online/users/eeeeeeeeeep/statuses/106720870163727231"
+ ]
+ }
+*/
+func (c *converter) StatusURIsToASRepliesPage(status *gtsmodel.Status, onlyOtherAccounts bool, minID string, replies map[string]*url.URL) (vocab.ActivityStreamsCollectionPage, error) {
+ collectionID := fmt.Sprintf("%s/replies", status.URI)
+
+ page := streams.NewActivityStreamsCollectionPage()
+
+ // .id
+ pageIDProp := streams.NewJSONLDIdProperty()
+ pageIDString := fmt.Sprintf("%s?page=true&only_other_accounts=%t", collectionID, onlyOtherAccounts)
+ if minID != "" {
+ pageIDString = fmt.Sprintf("%s&min_id=%s", pageIDString, minID)
+ }
+
+ pageID, err := url.Parse(pageIDString)
+ if err != nil {
+ return nil, gtserror.NewErrorInternalError(err)
+ }
+ pageIDProp.SetIRI(pageID)
+ page.SetJSONLDId(pageIDProp)
+
+ // .partOf
+ collectionIDURI, err := url.Parse(collectionID)
+ if err != nil {
+ return nil, err
+ }
+ partOfProp := streams.NewActivityStreamsPartOfProperty()
+ partOfProp.SetIRI(collectionIDURI)
+ page.SetActivityStreamsPartOf(partOfProp)
+
+ // .items
+ items := streams.NewActivityStreamsItemsProperty()
+ var highestID string
+ for k, v := range replies {
+ items.AppendIRI(v)
+ if k > highestID {
+ highestID = k
+ }
+ }
+ page.SetActivityStreamsItems(items)
+
+ // .next
+ nextProp := streams.NewActivityStreamsNextProperty()
+ nextPropIDString := fmt.Sprintf("%s?only_other_accounts=%t&page=true", collectionID, onlyOtherAccounts)
+ if highestID != "" {
+ nextPropIDString = fmt.Sprintf("%s&min_id=%s", nextPropIDString, highestID)
+ }
+
+ nextPropID, err := url.Parse(nextPropIDString)
+ if err != nil {
+ return nil, gtserror.NewErrorInternalError(err)
+ }
+ nextProp.SetIRI(nextPropID)
+ page.SetActivityStreamsNext(nextProp)
+
+ return page, nil
+}