summaryrefslogtreecommitdiff
path: root/internal/typeutils/wrap.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/typeutils/wrap.go')
-rw-r--r--internal/typeutils/wrap.go175
1 files changed, 65 insertions, 110 deletions
diff --git a/internal/typeutils/wrap.go b/internal/typeutils/wrap.go
index 128c4ef15..5deca0e5b 100644
--- a/internal/typeutils/wrap.go
+++ b/internal/typeutils/wrap.go
@@ -19,6 +19,7 @@ package typeutils
import (
"net/url"
+ "time"
"github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/activity/streams"
@@ -84,132 +85,86 @@ func (c *Converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, origi
return update, nil
}
-// WrapNoteInCreate wraps a Statusable with a Create activity.
-//
-// If objectIRIOnly is set to true, then the function won't put the *entire* note in the Object field of the Create,
-// but just the AP URI of the note. This is useful in cases where you want to give a remote server something to dereference,
-// and still have control over whether or not they're allowed to actually see the contents.
-func (c *Converter) WrapStatusableInCreate(status ap.Statusable, objectIRIOnly bool) (vocab.ActivityStreamsCreate, error) {
+func WrapStatusableInCreate(status ap.Statusable, iriOnly bool) vocab.ActivityStreamsCreate {
create := streams.NewActivityStreamsCreate()
+ wrapStatusableInActivity(create, status, iriOnly)
+ return create
+}
- // Object property
- objectProp := streams.NewActivityStreamsObjectProperty()
- if objectIRIOnly {
- // Only append the object IRI to objectProp.
- objectProp.AppendIRI(status.GetJSONLDId().GetIRI())
- } else {
- // Our statusable's are always note types.
- asNote := status.(vocab.ActivityStreamsNote)
- objectProp.AppendActivityStreamsNote(asNote)
+func WrapPollOptionablesInCreate(options ...ap.PollOptionable) vocab.ActivityStreamsCreate {
+ if len(options) == 0 {
+ panic("no options")
}
- create.SetActivityStreamsObject(objectProp)
- // ID property
- idProp := streams.NewJSONLDIdProperty()
- createID := status.GetJSONLDId().GetIRI().String() + "/activity"
- createIDIRI, err := url.Parse(createID)
- if err != nil {
- return nil, err
+ // Extract attributedTo IRI from any option.
+ attribTos := ap.GetAttributedTo(options[0])
+ if len(attribTos) != 1 {
+ panic("invalid attributedTo count")
}
- idProp.SetIRI(createIDIRI)
- create.SetJSONLDId(idProp)
- // Actor Property
- actorProp := streams.NewActivityStreamsActorProperty()
- actorIRI, err := ap.ExtractAttributedToURI(status)
- if err != nil {
- return nil, gtserror.Newf("couldn't extract AttributedTo: %w", err)
+ // Extract target status IRI from any option.
+ replyTos := ap.GetInReplyTo(options[0])
+ if len(replyTos) != 1 {
+ panic("invalid inReplyTo count")
}
- actorProp.AppendIRI(actorIRI)
- create.SetActivityStreamsActor(actorProp)
- // Published Property
- publishedProp := streams.NewActivityStreamsPublishedProperty()
- published, err := ap.ExtractPublished(status)
- if err != nil {
- return nil, gtserror.Newf("couldn't extract Published: %w", err)
- }
- publishedProp.Set(published)
- create.SetActivityStreamsPublished(publishedProp)
+ // Allocate create activity and copy over 'To' property.
+ create := streams.NewActivityStreamsCreate()
+ ap.AppendTo(create, ap.GetTo(options[0])...)
- // To Property
- toProp := streams.NewActivityStreamsToProperty()
- if toURIs := ap.ExtractToURIs(status); len(toURIs) != 0 {
- for _, toURI := range toURIs {
- toProp.AppendIRI(toURI)
- }
- create.SetActivityStreamsTo(toProp)
- }
+ // Activity ID formatted as: {$statusIRI}/activity#vote/{$voterIRI}.
+ id := replyTos[0].String() + "/activity#vote/" + attribTos[0].String()
+ ap.MustSet(ap.SetJSONLDIdStr, ap.WithJSONLDId(create), id)
+
+ // Set a current publish time for activity.
+ ap.SetPublished(create, time.Now())
- // Cc Property
- ccProp := streams.NewActivityStreamsCcProperty()
- if ccURIs := ap.ExtractCcURIs(status); len(ccURIs) != 0 {
- for _, ccURI := range ccURIs {
- ccProp.AppendIRI(ccURI)
- }
- create.SetActivityStreamsCc(ccProp)
+ // Append each poll option as object to activity.
+ for _, option := range options {
+ status, _ := ap.ToStatusable(option)
+ appendStatusableToActivity(create, status, false)
}
- return create, nil
+ return create
}
-// WrapStatusableInUpdate wraps a Statusable with an Update activity.
-//
-// If objectIRIOnly is set to true, then the function won't put the *entire* note in the Object field of the Create,
-// but just the AP URI of the note. This is useful in cases where you want to give a remote server something to dereference,
-// and still have control over whether or not they're allowed to actually see the contents.
-func (c *Converter) WrapStatusableInUpdate(status ap.Statusable, objectIRIOnly bool) (vocab.ActivityStreamsUpdate, error) {
+func WrapStatusableInUpdate(status ap.Statusable, iriOnly bool) vocab.ActivityStreamsUpdate {
update := streams.NewActivityStreamsUpdate()
+ wrapStatusableInActivity(update, status, iriOnly)
+ return update
+}
- // Object property
- objectProp := streams.NewActivityStreamsObjectProperty()
- if objectIRIOnly {
- objectProp.AppendIRI(status.GetJSONLDId().GetIRI())
- } else if _, ok := status.(ap.Pollable); ok {
- asQuestion := status.(vocab.ActivityStreamsQuestion)
- objectProp.AppendActivityStreamsQuestion(asQuestion)
- } else {
- asNote := status.(vocab.ActivityStreamsNote)
- objectProp.AppendActivityStreamsNote(asNote)
- }
- update.SetActivityStreamsObject(objectProp)
-
- // ID property
- idProp := streams.NewJSONLDIdProperty()
- createID := status.GetJSONLDId().GetIRI().String() + "/activity"
- createIDIRI, err := url.Parse(createID)
- if err != nil {
- return nil, err
- }
- idProp.SetIRI(createIDIRI)
- update.SetJSONLDId(idProp)
-
- // Actor Property
- actorProp := streams.NewActivityStreamsActorProperty()
- actorIRI, err := ap.ExtractAttributedToURI(status)
- if err != nil {
- return nil, gtserror.Newf("couldn't extract AttributedTo: %w", err)
- }
- actorProp.AppendIRI(actorIRI)
- update.SetActivityStreamsActor(actorProp)
-
- // To Property
- toProp := streams.NewActivityStreamsToProperty()
- if toURIs := ap.ExtractToURIs(status); len(toURIs) != 0 {
- for _, toURI := range toURIs {
- toProp.AppendIRI(toURI)
- }
- update.SetActivityStreamsTo(toProp)
- }
+// wrapStatusableInActivity adds the required ap.Statusable data to the given ap.Activityable.
+func wrapStatusableInActivity(activity ap.Activityable, status ap.Statusable, iriOnly bool) {
+ idIRI := ap.GetJSONLDId(status) // activity ID formatted as {$statusIRI}/activity#{$typeName}
+ ap.MustSet(ap.SetJSONLDIdStr, ap.WithJSONLDId(activity), idIRI.String()+"/activity#"+activity.GetTypeName())
+ appendStatusableToActivity(activity, status, iriOnly)
+ ap.AppendTo(activity, ap.GetTo(status)...)
+ ap.AppendCc(activity, ap.GetCc(status)...)
+ ap.AppendActor(activity, ap.GetAttributedTo(status)...)
+ ap.SetPublished(activity, ap.GetPublished(status))
+}
- // Cc Property
- ccProp := streams.NewActivityStreamsCcProperty()
- if ccURIs := ap.ExtractCcURIs(status); len(ccURIs) != 0 {
- for _, ccURI := range ccURIs {
- ccProp.AppendIRI(ccURI)
- }
- update.SetActivityStreamsCc(ccProp)
+// appendStatusableToActivity appends a Statusable type to an Activityable, handling case of Question, Note or just IRI type.
+func appendStatusableToActivity(activity ap.Activityable, status ap.Statusable, iriOnly bool) {
+ // Get existing object property or allocate new.
+ objProp := activity.GetActivityStreamsObject()
+ if objProp == nil {
+ objProp = streams.NewActivityStreamsObjectProperty()
+ activity.SetActivityStreamsObject(objProp)
+ }
+
+ if iriOnly {
+ // Only append status IRI.
+ idIRI := ap.GetJSONLDId(status)
+ objProp.AppendIRI(idIRI)
+ } else if poll, ok := ap.ToPollable(status); ok {
+ // Our Pollable implementer is an AS Question type.
+ question := poll.(vocab.ActivityStreamsQuestion)
+ objProp.AppendActivityStreamsQuestion(question)
+ } else {
+ // All of our other Statusable types are AS Note.
+ note := status.(vocab.ActivityStreamsNote)
+ objProp.AppendActivityStreamsNote(note)
}
-
- return update, nil
}