diff options
Diffstat (limited to 'internal/processing/fromfederator.go')
-rw-r--r-- | internal/processing/fromfederator.go | 120 |
1 files changed, 85 insertions, 35 deletions
diff --git a/internal/processing/fromfederator.go b/internal/processing/fromfederator.go index f165b2835..335b1a102 100644 --- a/internal/processing/fromfederator.go +++ b/internal/processing/fromfederator.go @@ -107,53 +107,32 @@ func (p *Processor) ProcessFromFederator(ctx context.Context, federatorMsg messa return nil } -// processCreateStatusFromFederator handles Activity Create and Object Note +// processCreateStatusFromFederator handles Activity Create and Object Note. func (p *Processor) processCreateStatusFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { - // check for either an IRI that we still need to dereference, OR an already dereferenced - // and converted status pinned to the message. + // Check the federatorMsg for either an already + // dereferenced and converted status pinned to + // the message, or an AP IRI that we need to deref. var ( status *gtsmodel.Status err error ) if federatorMsg.GTSModel != nil { - var ok bool - - // there's a gts model already pinned to the message, it should be a status - if status, ok = federatorMsg.GTSModel.(*gtsmodel.Status); !ok { - return gtserror.New("Note was not parseable as *gtsmodel.Status") - } - - // Since this was a create originating AP object - // statusable may have been set on message (no problem if not). - statusable, _ := federatorMsg.APObjectModel.(ap.Statusable) - - // Call refresh on status to deref if necessary etc. - status, _, err = p.federator.RefreshStatus(ctx, - federatorMsg.ReceivingAccount.Username, - status, - statusable, - false, - ) - if err != nil { - return err - } + // Model is set, use that. + status, err = p.statusFromGTSModel(ctx, federatorMsg) } else { - // no model pinned, we need to dereference based on the IRI - if federatorMsg.APIri == nil { - return gtserror.New("status was not pinned to federatorMsg, and neither was an IRI for us to dereference") - } + // Model is not set, use IRI. + status, err = p.statusFromAPIRI(ctx, federatorMsg) + } - status, _, err = p.federator.GetStatusByURI(ctx, federatorMsg.ReceivingAccount.Username, federatorMsg.APIri) - if err != nil { - return err - } + if err != nil { + return gtserror.Newf("error extracting status from federatorMsg: %w", err) } if status.Account == nil || status.Account.IsRemote() { // Either no account attached yet, or a remote account. // Both situations we need to parse account URI to fetch it. - remoteAccURI, err := url.Parse(status.AccountURI) + accountURI, err := url.Parse(status.AccountURI) if err != nil { return err } @@ -161,13 +140,22 @@ func (p *Processor) processCreateStatusFromFederator(ctx context.Context, federa // Ensure that account for this status has been deref'd. status.Account, _, err = p.federator.GetAccountByURI(ctx, federatorMsg.ReceivingAccount.Username, - remoteAccURI, + accountURI, ) if err != nil { return err } } + // Ensure status ancestors dereferenced. We need at least the + // immediate parent (if present) to ascertain timelineability. + if err := p.federator.DereferenceStatusAncestors(ctx, + federatorMsg.ReceivingAccount.Username, + status, + ); err != nil { + return err + } + if status.InReplyToID != "" { // Interaction counts changed on the replied status; // uncache the prepared version from all timelines. @@ -181,6 +169,58 @@ func (p *Processor) processCreateStatusFromFederator(ctx context.Context, federa return nil } +func (p *Processor) statusFromGTSModel(ctx context.Context, federatorMsg messages.FromFederator) (*gtsmodel.Status, error) { + // There should be a status pinned to the federatorMsg + // (we've already checked to ensure this is not nil). + status, ok := federatorMsg.GTSModel.(*gtsmodel.Status) + if !ok { + err := gtserror.New("Note was not parseable as *gtsmodel.Status") + return nil, err + } + + // AP statusable representation may have also + // been set on message (no problem if not). + statusable, _ := federatorMsg.APObjectModel.(ap.Statusable) + + // Call refresh on status to update + // it (deref remote) if necessary. + var err error + status, _, err = p.federator.RefreshStatus( + ctx, + federatorMsg.ReceivingAccount.Username, + status, + statusable, + false, + ) + if err != nil { + return nil, gtserror.Newf("%w", err) + } + + return status, nil +} + +func (p *Processor) statusFromAPIRI(ctx context.Context, federatorMsg messages.FromFederator) (*gtsmodel.Status, error) { + // There should be a status IRI pinned to + // the federatorMsg for us to dereference. + if federatorMsg.APIri == nil { + err := gtserror.New("status was not pinned to federatorMsg, and neither was an IRI for us to dereference") + return nil, err + } + + // Get the status + ensure we have + // the most up-to-date version. + status, _, err := p.federator.GetStatusByURI( + ctx, + federatorMsg.ReceivingAccount.Username, + federatorMsg.APIri, + ) + if err != nil { + return nil, gtserror.Newf("%w", err) + } + + return status, nil +} + // processCreateFaveFromFederator handles Activity Create with Object Like. func (p *Processor) processCreateFaveFromFederator(ctx context.Context, federatorMsg messages.FromFederator) error { statusFave, ok := federatorMsg.GTSModel.(*gtsmodel.StatusFave) @@ -278,11 +318,21 @@ func (p *Processor) processCreateAnnounceFromFederator(ctx context.Context, fede } status.ID = statusID - // Store, timeline, and notify. + // Store the boost wrapper status. if err := p.state.DB.PutStatus(ctx, status); err != nil { return gtserror.Newf("db error inserting status: %w", err) } + // Ensure boosted status ancestors dereferenced. We need at least + // the immediate parent (if present) to ascertain timelineability. + if err := p.federator.DereferenceStatusAncestors(ctx, + federatorMsg.ReceivingAccount.Username, + status.BoostOf, + ); err != nil { + return err + } + + // Timeline and notify the announce. if err := p.timelineAndNotifyStatus(ctx, status); err != nil { return gtserror.Newf("error timelining status: %w", err) } |