diff options
author | 2021-08-10 13:32:39 +0200 | |
---|---|---|
committer | 2021-08-10 13:32:39 +0200 | |
commit | 0f2de6394a1c52d47e326bb7d7d129a217ae4f6f (patch) | |
tree | e2709bdbbbbcf5e12d6da62b653b67f1789ab1c5 /internal/typeutils/internaltoas.go | |
parent | Frodo swaggins (#126) (diff) | |
download | gotosocial-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.go | 145 |
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 +} |