mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[feature] tentatively start adding polls support (#2249)
This commit is contained in:
@@ -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 {
|
||||
|
@@ -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 {
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user