summaryrefslogtreecommitdiff
path: root/internal/processing/workers
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2023-10-04 13:09:42 +0100
committerLibravatar GitHub <noreply@github.com>2023-10-04 13:09:42 +0100
commitc6e00afc7c23df994b70eee89d2d392718e6a321 (patch)
treecee98c1a78e36ba6a0e8183afa0b2796765fe7f6 /internal/processing/workers
parent[chore] internal/ap: add pollable AS types, code reformatting, general niceti... (diff)
downloadgotosocial-c6e00afc7c23df994b70eee89d2d392718e6a321.tar.xz
[feature] tentatively start adding polls support (#2249)
Diffstat (limited to 'internal/processing/workers')
-rw-r--r--internal/processing/workers/federate.go64
-rw-r--r--internal/processing/workers/fromclientapi.go21
-rw-r--r--internal/processing/workers/fromfediapi.go36
-rw-r--r--internal/processing/workers/wipestatus.go17
4 files changed, 117 insertions, 21 deletions
diff --git a/internal/processing/workers/federate.go b/internal/processing/workers/federate.go
index 4b2ca4de1..a87a89fd2 100644
--- a/internal/processing/workers/federate.go
+++ b/internal/processing/workers/federate.go
@@ -147,27 +147,27 @@ func (f *federate) CreateStatus(ctx context.Context, status *gtsmodel.Status) er
return nil
}
- // Populate model.
+ // Ensure the status model is fully populated.
if err := f.state.DB.PopulateStatus(ctx, status); err != nil {
return gtserror.Newf("error populating status: %w", err)
}
- // Parse relevant URI(s).
+ // Parse the outbox URI of the status author.
outboxIRI, err := parseURI(status.Account.OutboxURI)
if err != nil {
return err
}
- // Convert status to an ActivityStreams
- // Note, wrapped in a Create activity.
- asStatus, err := f.converter.StatusToAS(ctx, status)
+ // Convert status to ActivityStreams Statusable implementing type.
+ statusable, err := f.converter.StatusToAS(ctx, status)
if err != nil {
- return gtserror.Newf("error converting status to AS: %w", err)
+ return gtserror.Newf("error converting status to Statusable: %w", err)
}
- create, err := f.converter.WrapNoteInCreate(asStatus, false)
+ // Use ActivityStreams Statusable type as Object of Create.
+ create, err := f.converter.WrapStatusableInCreate(statusable, false)
if err != nil {
- return gtserror.Newf("error wrapping status in create: %w", err)
+ return gtserror.Newf("error wrapping Statusable in Create: %w", err)
}
// Send the Create via the Actor's outbox.
@@ -196,12 +196,12 @@ func (f *federate) DeleteStatus(ctx context.Context, status *gtsmodel.Status) er
return nil
}
- // Populate model.
+ // Ensure the status model is fully populated.
if err := f.state.DB.PopulateStatus(ctx, status); err != nil {
return gtserror.Newf("error populating status: %w", err)
}
- // Parse relevant URI(s).
+ // Parse the outbox URI of the status author.
outboxIRI, err := parseURI(status.Account.OutboxURI)
if err != nil {
return err
@@ -226,6 +226,50 @@ func (f *federate) DeleteStatus(ctx context.Context, status *gtsmodel.Status) er
return nil
}
+func (f *federate) UpdateStatus(ctx context.Context, status *gtsmodel.Status) error {
+ // Do nothing if the status
+ // shouldn't be federated.
+ if !*status.Federated {
+ return nil
+ }
+
+ // Do nothing if this
+ // isn't our status.
+ if !*status.Local {
+ return nil
+ }
+
+ // Ensure the status model is fully populated.
+ if err := f.state.DB.PopulateStatus(ctx, status); err != nil {
+ return gtserror.Newf("error populating status: %w", err)
+ }
+
+ // Parse the outbox URI of the status author.
+ outboxIRI, err := parseURI(status.Account.OutboxURI)
+ if err != nil {
+ return err
+ }
+
+ // Convert status to ActivityStreams Statusable implementing type.
+ statusable, err := f.converter.StatusToAS(ctx, status)
+ if err != nil {
+ return gtserror.Newf("error converting status to Statusable: %w", err)
+ }
+
+ // Use ActivityStreams Statusable type as Object of Update.
+ update, err := f.converter.WrapStatusableInUpdate(statusable, false)
+ if err != nil {
+ return gtserror.Newf("error wrapping Statusable in Update: %w", err)
+ }
+
+ // Send the Update activity with Statusable via the Actor's outbox.
+ if _, err := f.FederatingActor().Send(ctx, outboxIRI, update); err != nil {
+ return gtserror.Newf("error sending Update activity via outbox %s: %w", outboxIRI, err)
+ }
+
+ return nil
+}
+
func (f *federate) Follow(ctx context.Context, follow *gtsmodel.Follow) error {
// Populate model.
if err := f.state.DB.PopulateFollow(ctx, follow); err != nil {
diff --git a/internal/processing/workers/fromclientapi.go b/internal/processing/workers/fromclientapi.go
index 1c668db71..ff316b1f4 100644
--- a/internal/processing/workers/fromclientapi.go
+++ b/internal/processing/workers/fromclientapi.go
@@ -114,6 +114,10 @@ func (p *Processor) ProcessFromClientAPI(ctx context.Context, cMsg messages.From
case ap.ActivityUpdate:
switch cMsg.APObjectType {
+ // UPDATE NOTE/STATUS
+ case ap.ObjectNote:
+ return p.clientAPI.UpdateStatus(ctx, cMsg)
+
// UPDATE PROFILE/ACCOUNT
case ap.ObjectProfile, ap.ActorPerson:
return p.clientAPI.UpdateAccount(ctx, cMsg)
@@ -332,10 +336,25 @@ func (p *clientAPI) CreateBlock(ctx context.Context, cMsg messages.FromClientAPI
return nil
}
+func (p *clientAPI) UpdateStatus(ctx context.Context, cMsg messages.FromClientAPI) error {
+ // Cast the updated Status model attached to msg.
+ status, ok := cMsg.GTSModel.(*gtsmodel.Status)
+ if !ok {
+ return gtserror.Newf("cannot cast %T -> *gtsmodel.Status", cMsg.GTSModel)
+ }
+
+ // Federate the updated status changes out remotely.
+ if err := p.federate.UpdateStatus(ctx, status); err != nil {
+ return gtserror.Newf("error federating status update: %w", err)
+ }
+
+ return nil
+}
+
func (p *clientAPI) UpdateAccount(ctx context.Context, cMsg messages.FromClientAPI) error {
account, ok := cMsg.GTSModel.(*gtsmodel.Account)
if !ok {
- return gtserror.Newf("%T not parseable as *gtsmodel.Account", cMsg.GTSModel)
+ return gtserror.Newf("cannot cast %T -> *gtsmodel.Account", cMsg.GTSModel)
}
if err := p.federate.UpdateAccount(ctx, account); err != nil {
diff --git a/internal/processing/workers/fromfediapi.go b/internal/processing/workers/fromfediapi.go
index 57e087499..598480cfb 100644
--- a/internal/processing/workers/fromfediapi.go
+++ b/internal/processing/workers/fromfediapi.go
@@ -119,6 +119,10 @@ func (p *Processor) ProcessFromFediAPI(ctx context.Context, fMsg messages.FromFe
case ap.ActivityUpdate:
switch fMsg.APObjectType { //nolint:gocritic
+ // UPDATE NOTE/STATUS
+ case ap.ObjectNote:
+ return p.fediAPI.UpdateStatus(ctx, fMsg)
+
// UPDATE PROFILE/ACCOUNT
case ap.ObjectProfile:
return p.fediAPI.UpdateAccount(ctx, fMsg)
@@ -485,13 +489,13 @@ func (p *fediAPI) UpdateAccount(ctx context.Context, fMsg messages.FromFediAPI)
// Parse the old/existing account model.
account, ok := fMsg.GTSModel.(*gtsmodel.Account)
if !ok {
- return gtserror.Newf("%T not parseable as *gtsmodel.Account", fMsg.GTSModel)
+ return gtserror.Newf("cannot cast %T -> *gtsmodel.Account", fMsg.GTSModel)
}
// Because this was an Update, the new Accountable should be set on the message.
apubAcc, ok := fMsg.APObjectModel.(ap.Accountable)
if !ok {
- return gtserror.Newf("%T not parseable as ap.Accountable", fMsg.APObjectModel)
+ return gtserror.Newf("cannot cast %T -> ap.Accountable", fMsg.APObjectModel)
}
// Fetch up-to-date bio, avatar, header, etc.
@@ -509,6 +513,34 @@ func (p *fediAPI) UpdateAccount(ctx context.Context, fMsg messages.FromFediAPI)
return nil
}
+func (p *fediAPI) UpdateStatus(ctx context.Context, fMsg messages.FromFediAPI) error {
+ // Cast the existing Status model attached to msg.
+ existing, ok := fMsg.GTSModel.(*gtsmodel.Status)
+ if !ok {
+ return gtserror.Newf("cannot cast %T -> *gtsmodel.Status", fMsg.GTSModel)
+ }
+
+ // Cast the updated ActivityPub statusable object .
+ apStatus, ok := fMsg.APObjectModel.(ap.Statusable)
+ if !ok {
+ return gtserror.Newf("cannot cast %T -> ap.Statusable", fMsg.APObjectModel)
+ }
+
+ // Fetch up-to-date attach status attachments, etc.
+ _, _, err := p.federate.RefreshStatus(
+ ctx,
+ fMsg.ReceivingAccount.Username,
+ existing,
+ apStatus,
+ false,
+ )
+ if err != nil {
+ return gtserror.Newf("error refreshing updated status: %w", err)
+ }
+
+ return nil
+}
+
func (p *fediAPI) DeleteStatus(ctx context.Context, fMsg messages.FromFediAPI) error {
// Delete attachments from this status, since this request
// comes from the federating API, and there's no way the
diff --git a/internal/processing/workers/wipestatus.go b/internal/processing/workers/wipestatus.go
index 0891d9e24..ab59f14be 100644
--- a/internal/processing/workers/wipestatus.go
+++ b/internal/processing/workers/wipestatus.go
@@ -38,7 +38,7 @@ func wipeStatusF(state *state.State, media *media.Processor, surface *surface) w
statusToDelete *gtsmodel.Status,
deleteAttachments bool,
) error {
- errs := new(gtserror.MultiError)
+ var errs gtserror.MultiError
// Either delete all attachments for this status,
// or simply unattach + clean them separately later.
@@ -48,15 +48,15 @@ func wipeStatusF(state *state.State, media *media.Processor, surface *surface) w
// status immediately (in case of delete + redraft)
if deleteAttachments {
// todo:state.DB.DeleteAttachmentsForStatus
- for _, a := range statusToDelete.AttachmentIDs {
- if err := media.Delete(ctx, a); err != nil {
+ for _, id := range statusToDelete.AttachmentIDs {
+ if err := media.Delete(ctx, id); err != nil {
errs.Appendf("error deleting media: %w", err)
}
}
} else {
// todo:state.DB.UnattachAttachmentsForStatus
- for _, a := range statusToDelete.AttachmentIDs {
- if _, err := media.Unattach(ctx, statusToDelete.Account, a); err != nil {
+ for _, id := range statusToDelete.AttachmentIDs {
+ if _, err := media.Unattach(ctx, statusToDelete.Account, id); err != nil {
errs.Appendf("error unattaching media: %w", err)
}
}
@@ -95,11 +95,12 @@ func wipeStatusF(state *state.State, media *media.Processor, surface *surface) w
if err != nil {
errs.Appendf("error fetching status boosts: %w", err)
}
- for _, b := range boosts {
- if err := surface.deleteStatusFromTimelines(ctx, b.ID); err != nil {
+
+ for _, boost := range boosts {
+ if err := surface.deleteStatusFromTimelines(ctx, boost.ID); err != nil {
errs.Appendf("error deleting boost from timelines: %w", err)
}
- if err := state.DB.DeleteStatusByID(ctx, b.ID); err != nil {
+ if err := state.DB.DeleteStatusByID(ctx, boost.ID); err != nil {
errs.Appendf("error deleting boost: %w", err)
}
}