gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

common.go (3880B)


      1 // GoToSocial
      2 // Copyright (C) GoToSocial Authors admin@gotosocial.org
      3 // SPDX-License-Identifier: AGPL-3.0-or-later
      4 //
      5 // This program is free software: you can redistribute it and/or modify
      6 // it under the terms of the GNU Affero General Public License as published by
      7 // the Free Software Foundation, either version 3 of the License, or
      8 // (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU Affero General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU Affero General Public License
     16 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 package status
     19 
     20 import (
     21 	"context"
     22 	"fmt"
     23 
     24 	"codeberg.org/gruf/go-kv"
     25 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     26 	"github.com/superseriousbusiness/gotosocial/internal/gtserror"
     27 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
     28 	"github.com/superseriousbusiness/gotosocial/internal/log"
     29 )
     30 
     31 func (p *Processor) apiStatus(ctx context.Context, targetStatus *gtsmodel.Status, requestingAccount *gtsmodel.Account) (*apimodel.Status, gtserror.WithCode) {
     32 	apiStatus, err := p.tc.StatusToAPIStatus(ctx, targetStatus, requestingAccount)
     33 	if err != nil {
     34 		err = gtserror.Newf("error converting status %s to frontend representation: %w", targetStatus.ID, err)
     35 		return nil, gtserror.NewErrorInternalError(err)
     36 	}
     37 
     38 	return apiStatus, nil
     39 }
     40 
     41 func (p *Processor) getVisibleStatus(ctx context.Context, requestingAccount *gtsmodel.Account, targetStatusID string) (*gtsmodel.Status, gtserror.WithCode) {
     42 	targetStatus, err := p.state.DB.GetStatusByID(ctx, targetStatusID)
     43 	if err != nil {
     44 		err = fmt.Errorf("getVisibleStatus: db error fetching status %s: %w", targetStatusID, err)
     45 		return nil, gtserror.NewErrorNotFound(err)
     46 	}
     47 
     48 	if requestingAccount != nil {
     49 		// Ensure the status is up-to-date.
     50 		p.federator.RefreshStatusAsync(ctx,
     51 			requestingAccount.Username,
     52 			targetStatus,
     53 			nil,
     54 			false,
     55 		)
     56 	}
     57 
     58 	visible, err := p.filter.StatusVisible(ctx, requestingAccount, targetStatus)
     59 	if err != nil {
     60 		err = fmt.Errorf("getVisibleStatus: error seeing if status %s is visible: %w", targetStatus.ID, err)
     61 		return nil, gtserror.NewErrorNotFound(err)
     62 	}
     63 
     64 	if !visible {
     65 		err = fmt.Errorf("getVisibleStatus: status %s is not visible to requesting account", targetStatusID)
     66 		return nil, gtserror.NewErrorNotFound(err)
     67 	}
     68 
     69 	return targetStatus, nil
     70 }
     71 
     72 // invalidateStatus is a shortcut function for invalidating the prepared/cached
     73 // representation one status in the home timeline and all list timelines of the
     74 // given accountID. It should only be called in cases where a status update
     75 // does *not* need to be passed into the processor via the worker queue, since
     76 // such invalidation will, in that case, be handled by the processor instead.
     77 func (p *Processor) invalidateStatus(ctx context.Context, accountID string, statusID string) error {
     78 	// Get lists first + bail if this fails.
     79 	lists, err := p.state.DB.GetListsForAccountID(ctx, accountID)
     80 	if err != nil {
     81 		return gtserror.Newf("db error getting lists for account %s: %w", accountID, err)
     82 	}
     83 
     84 	l := log.WithContext(ctx).WithFields(kv.Fields{
     85 		{"accountID", accountID},
     86 		{"statusID", statusID},
     87 	}...)
     88 
     89 	// Unprepare item from home + list timelines, just log
     90 	// if something goes wrong since this is not a showstopper.
     91 
     92 	if err := p.state.Timelines.Home.UnprepareItem(ctx, accountID, statusID); err != nil {
     93 		l.Errorf("error unpreparing item from home timeline: %v", err)
     94 	}
     95 
     96 	for _, list := range lists {
     97 		if err := p.state.Timelines.List.UnprepareItem(ctx, list.ID, statusID); err != nil {
     98 			l.Errorf("error unpreparing item from list timeline %s: %v", list.ID, err)
     99 		}
    100 	}
    101 
    102 	return nil
    103 }