mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-24 04:03:33 -06:00
[chore] deinterface the typeutils.Converter and update to use state structure (#2217)
* update typeconverter to use state structure * deinterface the typeutils.TypeConverter -> typeutils.Converter * finish copying over old type converter code comments * fix cherry-pick merge issues, fix tests pointing to old typeutils interface type still
This commit is contained in:
parent
1b848aa1e5
commit
8f67dd583d
119 changed files with 611 additions and 742 deletions
|
|
@ -34,7 +34,10 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||
)
|
||||
|
||||
func (c *converter) ASRepresentationToAccount(ctx context.Context, accountable ap.Accountable, accountDomain string) (*gtsmodel.Account, error) {
|
||||
// ASRepresentationToAccount converts a remote account/person/application representation into a gts model account.
|
||||
//
|
||||
// If accountDomain is provided then this value will be used as the account's Domain, else the AP ID host.
|
||||
func (c *Converter) ASRepresentationToAccount(ctx context.Context, accountable ap.Accountable, accountDomain string) (*gtsmodel.Account, error) {
|
||||
// first check if we actually already know this account
|
||||
uriProp := accountable.GetJSONLDId()
|
||||
if uriProp == nil || !uriProp.IsIRI() {
|
||||
|
|
@ -213,7 +216,7 @@ func (c *converter) ASRepresentationToAccount(ctx context.Context, accountable a
|
|||
return acct, nil
|
||||
}
|
||||
|
||||
func (c *converter) extractAttachments(i ap.WithAttachment) []*gtsmodel.MediaAttachment {
|
||||
func (c *Converter) extractAttachments(i ap.WithAttachment) []*gtsmodel.MediaAttachment {
|
||||
attachmentProp := i.GetActivityStreamsAttachment()
|
||||
if attachmentProp == nil {
|
||||
return nil
|
||||
|
|
@ -245,7 +248,8 @@ func (c *converter) extractAttachments(i ap.WithAttachment) []*gtsmodel.MediaAtt
|
|||
return attachments
|
||||
}
|
||||
|
||||
func (c *converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusable) (*gtsmodel.Status, error) {
|
||||
// ASStatus converts a remote activitystreams 'status' representation into a gts model status.
|
||||
func (c *Converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusable) (*gtsmodel.Status, error) {
|
||||
status := new(gtsmodel.Status)
|
||||
|
||||
// status.URI
|
||||
|
|
@ -341,7 +345,7 @@ func (c *converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusab
|
|||
}
|
||||
accountURI := attributedTo.String()
|
||||
|
||||
account, err := c.db.GetAccountByURI(ctx, accountURI)
|
||||
account, err := c.state.DB.GetAccountByURI(ctx, accountURI)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("db error getting status author account %s: %w", accountURI, err)
|
||||
return nil, err
|
||||
|
|
@ -364,7 +368,7 @@ func (c *converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusab
|
|||
status.InReplyToURI = inReplyToURI
|
||||
|
||||
// Check if we already have the replied-to status.
|
||||
inReplyTo, err := c.db.GetStatusByURI(ctx, inReplyToURI)
|
||||
inReplyTo, err := c.state.DB.GetStatusByURI(ctx, inReplyToURI)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
// Real database error.
|
||||
err = gtserror.Newf("db error getting replied-to status %s: %w", inReplyToURI, err)
|
||||
|
|
@ -417,7 +421,8 @@ func (c *converter) ASStatusToStatus(ctx context.Context, statusable ap.Statusab
|
|||
return status, nil
|
||||
}
|
||||
|
||||
func (c *converter) ASFollowToFollowRequest(ctx context.Context, followable ap.Followable) (*gtsmodel.FollowRequest, error) {
|
||||
// ASFollowToFollowRequest converts a remote activitystreams `follow` representation into gts model follow request.
|
||||
func (c *Converter) ASFollowToFollowRequest(ctx context.Context, followable ap.Followable) (*gtsmodel.FollowRequest, error) {
|
||||
idProp := followable.GetJSONLDId()
|
||||
if idProp == nil || !idProp.IsIRI() {
|
||||
return nil, errors.New("no id property set on follow, or was not an iri")
|
||||
|
|
@ -428,7 +433,7 @@ func (c *converter) ASFollowToFollowRequest(ctx context.Context, followable ap.F
|
|||
if err != nil {
|
||||
return nil, errors.New("error extracting actor property from follow")
|
||||
}
|
||||
originAccount, err := c.db.GetAccountByURI(ctx, origin.String())
|
||||
originAccount, err := c.state.DB.GetAccountByURI(ctx, origin.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with uri %s from the database: %s", origin.String(), err)
|
||||
}
|
||||
|
|
@ -437,7 +442,7 @@ func (c *converter) ASFollowToFollowRequest(ctx context.Context, followable ap.F
|
|||
if err != nil {
|
||||
return nil, errors.New("error extracting object property from follow")
|
||||
}
|
||||
targetAccount, err := c.db.GetAccountByURI(ctx, target.String())
|
||||
targetAccount, err := c.state.DB.GetAccountByURI(ctx, target.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with uri %s from the database: %s", origin.String(), err)
|
||||
}
|
||||
|
|
@ -451,7 +456,8 @@ func (c *converter) ASFollowToFollowRequest(ctx context.Context, followable ap.F
|
|||
return followRequest, nil
|
||||
}
|
||||
|
||||
func (c *converter) ASFollowToFollow(ctx context.Context, followable ap.Followable) (*gtsmodel.Follow, error) {
|
||||
// ASFollowToFollowRequest converts a remote activitystreams `follow` representation into gts model follow.
|
||||
func (c *Converter) ASFollowToFollow(ctx context.Context, followable ap.Followable) (*gtsmodel.Follow, error) {
|
||||
idProp := followable.GetJSONLDId()
|
||||
if idProp == nil || !idProp.IsIRI() {
|
||||
return nil, errors.New("no id property set on follow, or was not an iri")
|
||||
|
|
@ -462,7 +468,7 @@ func (c *converter) ASFollowToFollow(ctx context.Context, followable ap.Followab
|
|||
if err != nil {
|
||||
return nil, errors.New("error extracting actor property from follow")
|
||||
}
|
||||
originAccount, err := c.db.GetAccountByURI(ctx, origin.String())
|
||||
originAccount, err := c.state.DB.GetAccountByURI(ctx, origin.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with uri %s from the database: %s", origin.String(), err)
|
||||
}
|
||||
|
|
@ -471,7 +477,7 @@ func (c *converter) ASFollowToFollow(ctx context.Context, followable ap.Followab
|
|||
if err != nil {
|
||||
return nil, errors.New("error extracting object property from follow")
|
||||
}
|
||||
targetAccount, err := c.db.GetAccountByURI(ctx, target.String())
|
||||
targetAccount, err := c.state.DB.GetAccountByURI(ctx, target.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with uri %s from the database: %s", origin.String(), err)
|
||||
}
|
||||
|
|
@ -485,7 +491,8 @@ func (c *converter) ASFollowToFollow(ctx context.Context, followable ap.Followab
|
|||
return follow, nil
|
||||
}
|
||||
|
||||
func (c *converter) ASLikeToFave(ctx context.Context, likeable ap.Likeable) (*gtsmodel.StatusFave, error) {
|
||||
// ASLikeToFave converts a remote activitystreams 'like' representation into a gts model status fave.
|
||||
func (c *Converter) ASLikeToFave(ctx context.Context, likeable ap.Likeable) (*gtsmodel.StatusFave, error) {
|
||||
idProp := likeable.GetJSONLDId()
|
||||
if idProp == nil || !idProp.IsIRI() {
|
||||
return nil, errors.New("no id property set on like, or was not an iri")
|
||||
|
|
@ -496,7 +503,7 @@ func (c *converter) ASLikeToFave(ctx context.Context, likeable ap.Likeable) (*gt
|
|||
if err != nil {
|
||||
return nil, errors.New("error extracting actor property from like")
|
||||
}
|
||||
originAccount, err := c.db.GetAccountByURI(ctx, origin.String())
|
||||
originAccount, err := c.state.DB.GetAccountByURI(ctx, origin.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with uri %s from the database: %s", origin.String(), err)
|
||||
}
|
||||
|
|
@ -506,7 +513,7 @@ func (c *converter) ASLikeToFave(ctx context.Context, likeable ap.Likeable) (*gt
|
|||
return nil, errors.New("error extracting object property from like")
|
||||
}
|
||||
|
||||
targetStatus, err := c.db.GetStatusByURI(ctx, target.String())
|
||||
targetStatus, err := c.state.DB.GetStatusByURI(ctx, target.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting status with uri %s from the database: %s", target.String(), err)
|
||||
}
|
||||
|
|
@ -515,7 +522,7 @@ func (c *converter) ASLikeToFave(ctx context.Context, likeable ap.Likeable) (*gt
|
|||
if targetStatus.Account != nil {
|
||||
targetAccount = targetStatus.Account
|
||||
} else {
|
||||
a, err := c.db.GetAccountByID(ctx, targetStatus.AccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, targetStatus.AccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with id %s from the database: %s", targetStatus.AccountID, err)
|
||||
}
|
||||
|
|
@ -533,7 +540,8 @@ func (c *converter) ASLikeToFave(ctx context.Context, likeable ap.Likeable) (*gt
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) ASBlockToBlock(ctx context.Context, blockable ap.Blockable) (*gtsmodel.Block, error) {
|
||||
// ASBlockToBlock converts a remote activity streams 'block' representation into a gts model block.
|
||||
func (c *Converter) ASBlockToBlock(ctx context.Context, blockable ap.Blockable) (*gtsmodel.Block, error) {
|
||||
idProp := blockable.GetJSONLDId()
|
||||
if idProp == nil || !idProp.IsIRI() {
|
||||
return nil, errors.New("ASBlockToBlock: no id property set on block, or was not an iri")
|
||||
|
|
@ -544,7 +552,7 @@ func (c *converter) ASBlockToBlock(ctx context.Context, blockable ap.Blockable)
|
|||
if err != nil {
|
||||
return nil, errors.New("ASBlockToBlock: error extracting actor property from block")
|
||||
}
|
||||
originAccount, err := c.db.GetAccountByURI(ctx, origin.String())
|
||||
originAccount, err := c.state.DB.GetAccountByURI(ctx, origin.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with uri %s from the database: %s", origin.String(), err)
|
||||
}
|
||||
|
|
@ -554,7 +562,7 @@ func (c *converter) ASBlockToBlock(ctx context.Context, blockable ap.Blockable)
|
|||
return nil, errors.New("ASBlockToBlock: error extracting object property from block")
|
||||
}
|
||||
|
||||
targetAccount, err := c.db.GetAccountByURI(ctx, target.String())
|
||||
targetAccount, err := c.state.DB.GetAccountByURI(ctx, target.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting account with uri %s from the database: %s", origin.String(), err)
|
||||
}
|
||||
|
|
@ -568,6 +576,19 @@ func (c *converter) ASBlockToBlock(ctx context.Context, blockable ap.Blockable)
|
|||
}, nil
|
||||
}
|
||||
|
||||
// ASAnnounceToStatus converts an activitystreams 'announce' into a status.
|
||||
//
|
||||
// The returned bool indicates whether this status is new (true) or not new (false).
|
||||
//
|
||||
// In other words, if the status is already in the database with the ID set on the announceable, then that will be returned,
|
||||
// the returned bool will be false, and no further processing is necessary. If the returned bool is true, indicating
|
||||
// that this is a new announce, then further processing will be necessary, because the returned status will be bareboned and
|
||||
// require further dereferencing.
|
||||
//
|
||||
// This is useful when multiple users on an instance might receive the same boost, and we only want to process the boost once.
|
||||
//
|
||||
// NOTE -- this is different from one status being boosted multiple times! In this case, new boosts should indeed be created.
|
||||
//
|
||||
// Implementation note: this function creates and returns a boost WRAPPER
|
||||
// status which references the boosted status in its BoostOf field. No
|
||||
// dereferencing is done on the boosted status by this function. Callers
|
||||
|
|
@ -577,7 +598,7 @@ func (c *converter) ASBlockToBlock(ctx context.Context, blockable ap.Blockable)
|
|||
// The returned boolean indicates whether or not the boost has already been
|
||||
// seen before by this instance. If it was, then status.BoostOf should be a
|
||||
// fully filled-out status. If not, then only status.BoostOf.URI will be set.
|
||||
func (c *converter) ASAnnounceToStatus(ctx context.Context, announceable ap.Announceable) (*gtsmodel.Status, bool, error) {
|
||||
func (c *Converter) ASAnnounceToStatus(ctx context.Context, announceable ap.Announceable) (*gtsmodel.Status, bool, error) {
|
||||
// Ensure item has an ID URI set.
|
||||
_, statusURIStr, err := getURI(announceable)
|
||||
if err != nil {
|
||||
|
|
@ -591,7 +612,7 @@ func (c *converter) ASAnnounceToStatus(ctx context.Context, announceable ap.Anno
|
|||
)
|
||||
|
||||
// Check if we already have this boost in the database.
|
||||
status, err = c.db.GetStatusByURI(ctx, statusURIStr)
|
||||
status, err = c.state.DB.GetStatusByURI(ctx, statusURIStr)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
// Real database error.
|
||||
err = gtserror.Newf("db error trying to get status with uri %s: %w", statusURIStr, err)
|
||||
|
|
@ -648,7 +669,7 @@ func (c *converter) ASAnnounceToStatus(ctx context.Context, announceable ap.Anno
|
|||
// This should have been dereferenced already before
|
||||
// we hit this point so we can confidently error out
|
||||
// if we don't have it.
|
||||
account, err := c.db.GetAccountByURI(ctx, accountURIStr)
|
||||
account, err := c.state.DB.GetAccountByURI(ctx, accountURIStr)
|
||||
if err != nil {
|
||||
err = gtserror.Newf("db error trying to get account with uri %s: %w", accountURIStr, err)
|
||||
return nil, isNew, err
|
||||
|
|
@ -678,7 +699,8 @@ func (c *converter) ASAnnounceToStatus(ctx context.Context, announceable ap.Anno
|
|||
return status, isNew, nil
|
||||
}
|
||||
|
||||
func (c *converter) ASFlagToReport(ctx context.Context, flaggable ap.Flaggable) (*gtsmodel.Report, error) {
|
||||
// ASFlagToReport converts a remote activitystreams 'flag' representation into a gts model report.
|
||||
func (c *Converter) ASFlagToReport(ctx context.Context, flaggable ap.Flaggable) (*gtsmodel.Report, error) {
|
||||
// Extract flag uri.
|
||||
idProp := flaggable.GetJSONLDId()
|
||||
if idProp == nil || !idProp.IsIRI() {
|
||||
|
|
@ -692,7 +714,7 @@ func (c *converter) ASFlagToReport(ctx context.Context, flaggable ap.Flaggable)
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("ASFlagToReport: error extracting actor: %w", err)
|
||||
}
|
||||
account, err := c.db.GetAccountByURI(ctx, actor.String())
|
||||
account, err := c.state.DB.GetAccountByURI(ctx, actor.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ASFlagToReport: error in db fetching account with uri %s: %w", actor.String(), err)
|
||||
}
|
||||
|
|
@ -744,7 +766,7 @@ func (c *converter) ASFlagToReport(ctx context.Context, flaggable ap.Flaggable)
|
|||
if targetAccountURI == nil {
|
||||
return nil, errors.New("ASFlagToReport: flaggable objects contained no recognizable target account uri")
|
||||
}
|
||||
targetAccount, err := c.db.GetAccountByURI(ctx, targetAccountURI.String())
|
||||
targetAccount, err := c.state.DB.GetAccountByURI(ctx, targetAccountURI.String())
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("ASFlagToReport: account with uri %s could not be found in the db", targetAccountURI.String())
|
||||
|
|
@ -761,13 +783,13 @@ func (c *converter) ASFlagToReport(ctx context.Context, flaggable ap.Flaggable)
|
|||
statusURIString := statusURI.String()
|
||||
|
||||
// try getting this status by URI first, then URL
|
||||
status, err := c.db.GetStatusByURI(ctx, statusURIString)
|
||||
status, err := c.state.DB.GetStatusByURI(ctx, statusURIString)
|
||||
if err != nil {
|
||||
if !errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("ASFlagToReport: db error getting status with uri %s: %w", statusURIString, err)
|
||||
}
|
||||
|
||||
status, err = c.db.GetStatusByURL(ctx, statusURIString)
|
||||
status, err = c.state.DB.GetStatusByURL(ctx, statusURIString)
|
||||
if err != nil {
|
||||
if !errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("ASFlagToReport: db error getting status with url %s: %w", statusURIString, err)
|
||||
|
|
|
|||
|
|
@ -18,218 +18,20 @@
|
|||
package typeutils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
"sync"
|
||||
|
||||
"github.com/gorilla/feeds"
|
||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/state"
|
||||
)
|
||||
|
||||
// TypeConverter is an interface for the common action of converting between apimodule (frontend, serializable) models,
|
||||
// internal gts models used in the database, and activitypub models used in federation.
|
||||
//
|
||||
// It requires access to the database because many of the conversions require pulling out database entries and counting them etc.
|
||||
// That said, it *absolutely should not* manipulate database entries in any way, only examine them.
|
||||
type TypeConverter interface {
|
||||
/*
|
||||
INTERNAL (gts) MODEL TO FRONTEND (api) MODEL
|
||||
*/
|
||||
|
||||
// AccountToAPIAccountSensitive takes a db model account as a param, and returns a populated apitype account, or an error
|
||||
// if something goes wrong. The returned account should be ready to serialize on an API level, and may have sensitive fields,
|
||||
// so serve it only to an authorized user who should have permission to see it.
|
||||
AccountToAPIAccountSensitive(ctx context.Context, account *gtsmodel.Account) (*apimodel.Account, error)
|
||||
// AccountToAPIAccountPublic takes a db model account as a param, and returns a populated apitype account, or an error
|
||||
// if something goes wrong. The returned account should be ready to serialize on an API level, and may NOT have sensitive fields.
|
||||
// In other words, this is the public record that the server has of an account.
|
||||
AccountToAPIAccountPublic(ctx context.Context, account *gtsmodel.Account) (*apimodel.Account, error)
|
||||
// AccountToAPIAccountBlocked takes a db model account as a param, and returns a apitype account, or an error if
|
||||
// something goes wrong. The returned account will be a bare minimum representation of the account. This function should be used
|
||||
// when someone wants to view an account they've blocked.
|
||||
AccountToAPIAccountBlocked(ctx context.Context, account *gtsmodel.Account) (*apimodel.Account, error)
|
||||
// AppToAPIAppSensitive takes a db model application as a param, and returns a populated apitype application, or an error
|
||||
// if something goes wrong. The returned application should be ready to serialize on an API level, and may have sensitive fields
|
||||
// (such as client id and client secret), so serve it only to an authorized user who should have permission to see it.
|
||||
AppToAPIAppSensitive(ctx context.Context, application *gtsmodel.Application) (*apimodel.Application, error)
|
||||
// AppToAPIAppPublic takes a db model application as a param, and returns a populated apitype application, or an error
|
||||
// if something goes wrong. The returned application should be ready to serialize on an API level, and has sensitive
|
||||
// fields sanitized so that it can be served to non-authorized accounts without revealing any private information.
|
||||
AppToAPIAppPublic(ctx context.Context, application *gtsmodel.Application) (*apimodel.Application, error)
|
||||
// AttachmentToAPIAttachment converts a gts model media attacahment into its api representation for serialization on the API.
|
||||
AttachmentToAPIAttachment(ctx context.Context, attachment *gtsmodel.MediaAttachment) (apimodel.Attachment, error)
|
||||
// MentionToAPIMention converts a gts model mention into its api (frontend) representation for serialization on the API.
|
||||
MentionToAPIMention(ctx context.Context, m *gtsmodel.Mention) (apimodel.Mention, error)
|
||||
// EmojiToAPIEmoji converts a gts model emoji into its api (frontend) representation for serialization on the API.
|
||||
EmojiToAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (apimodel.Emoji, error)
|
||||
// EmojiToAdminAPIEmoji converts a gts model emoji into an API representation with extra admin information.
|
||||
EmojiToAdminAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (*apimodel.AdminEmoji, error)
|
||||
// EmojiCategoryToAPIEmojiCategory converts a gts model emoji category into its api (frontend) representation.
|
||||
EmojiCategoryToAPIEmojiCategory(ctx context.Context, category *gtsmodel.EmojiCategory) (*apimodel.EmojiCategory, error)
|
||||
// TagToAPITag converts a gts model tag into its api (frontend) representation for serialization on the API.
|
||||
// If stubHistory is set to 'true', then the 'history' field of the tag will be populated with a pointer to an empty slice, for API compatibility reasons.
|
||||
TagToAPITag(ctx context.Context, t *gtsmodel.Tag, stubHistory bool) (apimodel.Tag, error)
|
||||
// StatusToAPIStatus converts a gts model status into its api (frontend) representation for serialization on the API.
|
||||
//
|
||||
// Requesting account can be nil.
|
||||
StatusToAPIStatus(ctx context.Context, s *gtsmodel.Status, requestingAccount *gtsmodel.Account) (*apimodel.Status, error)
|
||||
// VisToAPIVis converts a gts visibility into its api equivalent
|
||||
VisToAPIVis(ctx context.Context, m gtsmodel.Visibility) apimodel.Visibility
|
||||
// InstanceToAPIV1Instance converts a gts instance into its api equivalent for serving at /api/v1/instance
|
||||
InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV1, error)
|
||||
// InstanceToAPIV2Instance converts a gts instance into its api equivalent for serving at /api/v2/instance
|
||||
InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV2, error)
|
||||
// InstanceRulesToAPIRules converts all local instance rules into their api equivalent for serving at /api/v1/instance/rules
|
||||
InstanceRulesToAPIRules(r []gtsmodel.Rule) []apimodel.InstanceRule
|
||||
// InstanceRuleToAdminAPIRule converts a local instance rule into its api equivalent for serving at /api/v1/admin/instance/rules/:id
|
||||
InstanceRuleToAdminAPIRule(r *gtsmodel.Rule) *apimodel.AdminInstanceRule
|
||||
// RelationshipToAPIRelationship converts a gts relationship into its api equivalent for serving in various places
|
||||
RelationshipToAPIRelationship(ctx context.Context, r *gtsmodel.Relationship) (*apimodel.Relationship, error)
|
||||
// NotificationToAPINotification converts a gts notification into a api notification
|
||||
NotificationToAPINotification(ctx context.Context, n *gtsmodel.Notification) (*apimodel.Notification, error)
|
||||
// DomainPermToAPIDomainPerm converts a gts model domin block or allow into an api domain permission.
|
||||
DomainPermToAPIDomainPerm(ctx context.Context, d gtsmodel.DomainPermission, export bool) (*apimodel.DomainPermission, error)
|
||||
// ReportToAPIReport converts a gts model report into an api model report, for serving at /api/v1/reports
|
||||
ReportToAPIReport(ctx context.Context, r *gtsmodel.Report) (*apimodel.Report, error)
|
||||
// ReportToAdminAPIReport converts a gts model report into an admin view report, for serving at /api/v1/admin/reports
|
||||
ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Report, requestingAccount *gtsmodel.Account) (*apimodel.AdminReport, error)
|
||||
// ListToAPIList converts one gts model list into an api model list, for serving at /api/v1/lists/{id}
|
||||
ListToAPIList(ctx context.Context, l *gtsmodel.List) (*apimodel.List, error)
|
||||
// MarkersToAPIMarker converts several gts model markers into an api marker, for serving at /api/v1/markers
|
||||
MarkersToAPIMarker(ctx context.Context, markers []*gtsmodel.Marker) (*apimodel.Marker, error)
|
||||
|
||||
/*
|
||||
INTERNAL (gts) MODEL TO FRONTEND (rss) MODEL
|
||||
*/
|
||||
|
||||
StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*feeds.Item, error)
|
||||
|
||||
/*
|
||||
ACTIVITYSTREAMS MODEL TO INTERNAL (gts) MODEL
|
||||
*/
|
||||
|
||||
// ASRepresentationToAccount converts a remote account/person/application representation into a gts model account.
|
||||
//
|
||||
// If accountDomain is provided then this value will be used as the account's Domain, else the AP ID host.
|
||||
ASRepresentationToAccount(ctx context.Context, accountable ap.Accountable, accountDomain string) (*gtsmodel.Account, error)
|
||||
// ASStatus converts a remote activitystreams 'status' representation into a gts model status.
|
||||
ASStatusToStatus(ctx context.Context, statusable ap.Statusable) (*gtsmodel.Status, error)
|
||||
// ASFollowToFollowRequest converts a remote activitystreams `follow` representation into gts model follow request.
|
||||
ASFollowToFollowRequest(ctx context.Context, followable ap.Followable) (*gtsmodel.FollowRequest, error)
|
||||
// ASFollowToFollowRequest converts a remote activitystreams `follow` representation into gts model follow.
|
||||
ASFollowToFollow(ctx context.Context, followable ap.Followable) (*gtsmodel.Follow, error)
|
||||
// ASLikeToFave converts a remote activitystreams 'like' representation into a gts model status fave.
|
||||
ASLikeToFave(ctx context.Context, likeable ap.Likeable) (*gtsmodel.StatusFave, error)
|
||||
// ASBlockToBlock converts a remote activity streams 'block' representation into a gts model block.
|
||||
ASBlockToBlock(ctx context.Context, blockable ap.Blockable) (*gtsmodel.Block, error)
|
||||
// ASAnnounceToStatus converts an activitystreams 'announce' into a status.
|
||||
//
|
||||
// The returned bool indicates whether this status is new (true) or not new (false).
|
||||
//
|
||||
// In other words, if the status is already in the database with the ID set on the announceable, then that will be returned,
|
||||
// the returned bool will be false, and no further processing is necessary. If the returned bool is true, indicating
|
||||
// that this is a new announce, then further processing will be necessary, because the returned status will be bareboned and
|
||||
// require further dereferencing.
|
||||
//
|
||||
// This is useful when multiple users on an instance might receive the same boost, and we only want to process the boost once.
|
||||
//
|
||||
// NOTE -- this is different from one status being boosted multiple times! In this case, new boosts should indeed be created.
|
||||
ASAnnounceToStatus(ctx context.Context, announceable ap.Announceable) (status *gtsmodel.Status, new bool, err error)
|
||||
// ASFlagToReport converts a remote activitystreams 'flag' representation into a gts model report.
|
||||
ASFlagToReport(ctx context.Context, flaggable ap.Flaggable) (report *gtsmodel.Report, err error)
|
||||
|
||||
/*
|
||||
INTERNAL (gts) MODEL TO ACTIVITYSTREAMS MODEL
|
||||
*/
|
||||
|
||||
// AccountToAS converts a gts model account into an activity streams person, suitable for federation
|
||||
AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error)
|
||||
// AccountToASMinimal converts a gts model account into an activity streams person, suitable for federation.
|
||||
//
|
||||
// The returned account will just have the Type, Username, PublicKey, and ID properties set. This is
|
||||
// suitable for serving to requesters to whom we want to give as little information as possible because
|
||||
// we don't trust them (yet).
|
||||
AccountToASMinimal(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error)
|
||||
// StatusToAS converts a gts model status into an activity streams note, suitable for federation
|
||||
StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.ActivityStreamsNote, error)
|
||||
// StatusToASDelete converts a gts model status into a Delete of that status, using just the
|
||||
// URI of the status as object, and addressing the Delete appropriately.
|
||||
StatusToASDelete(ctx context.Context, status *gtsmodel.Status) (vocab.ActivityStreamsDelete, error)
|
||||
// FollowToASFollow converts a gts model Follow into an activity streams Follow, suitable for federation
|
||||
FollowToAS(ctx context.Context, f *gtsmodel.Follow) (vocab.ActivityStreamsFollow, error)
|
||||
// MentionToAS converts a gts model mention into an activity streams Mention, suitable for federation
|
||||
MentionToAS(ctx context.Context, m *gtsmodel.Mention) (vocab.ActivityStreamsMention, error)
|
||||
// EmojiToAS converts a gts emoji into a mastodon ns Emoji, suitable for federation
|
||||
EmojiToAS(ctx context.Context, e *gtsmodel.Emoji) (vocab.TootEmoji, error)
|
||||
// TagToAS converts a gts model tag into a toot Hashtag, suitable for federation.
|
||||
TagToAS(ctx context.Context, t *gtsmodel.Tag) (vocab.TootHashtag, error)
|
||||
// AttachmentToAS converts a gts model media attachment into an activity streams Attachment, suitable for federation
|
||||
AttachmentToAS(ctx context.Context, a *gtsmodel.MediaAttachment) (vocab.ActivityStreamsDocument, error)
|
||||
// FaveToAS converts a gts model status fave into an activityStreams LIKE, suitable for federation.
|
||||
FaveToAS(ctx context.Context, f *gtsmodel.StatusFave) (vocab.ActivityStreamsLike, error)
|
||||
// BoostToAS converts a gts model boost into an activityStreams ANNOUNCE, suitable for federation
|
||||
BoostToAS(ctx context.Context, boostWrapperStatus *gtsmodel.Status, boostingAccount *gtsmodel.Account, boostedAccount *gtsmodel.Account) (vocab.ActivityStreamsAnnounce, error)
|
||||
// BlockToAS converts a gts model block into an activityStreams BLOCK, suitable for federation.
|
||||
BlockToAS(ctx context.Context, block *gtsmodel.Block) (vocab.ActivityStreamsBlock, error)
|
||||
// StatusToASRepliesCollection converts a gts model status into an activityStreams REPLIES collection.
|
||||
StatusToASRepliesCollection(ctx context.Context, status *gtsmodel.Status, onlyOtherAccounts bool) (vocab.ActivityStreamsCollection, error)
|
||||
// StatusURIsToASRepliesPage returns a collection page with appropriate next/part of pagination.
|
||||
StatusURIsToASRepliesPage(ctx context.Context, status *gtsmodel.Status, onlyOtherAccounts bool, minID string, replies map[string]*url.URL) (vocab.ActivityStreamsCollectionPage, error)
|
||||
// OutboxToASCollection returns an ordered collection with appropriate id, next, and last fields.
|
||||
// The returned collection won't have any actual entries; just links to where entries can be obtained.
|
||||
OutboxToASCollection(ctx context.Context, outboxID string) (vocab.ActivityStreamsOrderedCollection, error)
|
||||
// StatusesToASOutboxPage returns an ordered collection page using the given statuses and parameters as contents.
|
||||
//
|
||||
// The maxID and minID should be the parameters that were passed to the database to obtain the given statuses.
|
||||
// These will be used to create the 'id' field of the collection.
|
||||
//
|
||||
// OutboxID is used to create the 'partOf' field in the collection.
|
||||
//
|
||||
// Appropriate 'next' and 'prev' fields will be created based on the highest and lowest IDs present in the statuses slice.
|
||||
StatusesToASOutboxPage(ctx context.Context, outboxID string, maxID string, minID string, statuses []*gtsmodel.Status) (vocab.ActivityStreamsOrderedCollectionPage, error)
|
||||
// StatusesToASFeaturedCollection converts a slice of statuses into an ordered collection
|
||||
// of URIs, suitable for serializing and serving via the activitypub API.
|
||||
StatusesToASFeaturedCollection(ctx context.Context, featuredCollectionID string, statuses []*gtsmodel.Status) (vocab.ActivityStreamsOrderedCollection, error)
|
||||
// ReportToASFlag converts a gts model report into an activitystreams FLAG, suitable for federation.
|
||||
ReportToASFlag(ctx context.Context, r *gtsmodel.Report) (vocab.ActivityStreamsFlag, error)
|
||||
|
||||
/*
|
||||
INTERNAL (gts) MODEL TO INTERNAL MODEL
|
||||
*/
|
||||
|
||||
// FollowRequestToFollow just converts a follow request into a follow, that's it! No bells and whistles.
|
||||
FollowRequestToFollow(ctx context.Context, f *gtsmodel.FollowRequest) *gtsmodel.Follow
|
||||
// StatusToBoost wraps the given status into a boosting status.
|
||||
StatusToBoost(ctx context.Context, s *gtsmodel.Status, boostingAccount *gtsmodel.Account) (*gtsmodel.Status, error)
|
||||
|
||||
/*
|
||||
WRAPPER CONVENIENCE FUNCTIONS
|
||||
*/
|
||||
|
||||
// WrapPersonInUpdate
|
||||
WrapPersonInUpdate(person vocab.ActivityStreamsPerson, originAccount *gtsmodel.Account) (vocab.ActivityStreamsUpdate, error)
|
||||
// WrapNoteInCreate wraps a Note 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.
|
||||
WrapNoteInCreate(note vocab.ActivityStreamsNote, objectIRIOnly bool) (vocab.ActivityStreamsCreate, error)
|
||||
}
|
||||
|
||||
type converter struct {
|
||||
db db.DB
|
||||
type Converter struct {
|
||||
state *state.State
|
||||
defaultAvatars []string
|
||||
randAvatars sync.Map
|
||||
}
|
||||
|
||||
// NewConverter returns a new Converter
|
||||
func NewConverter(db db.DB) TypeConverter {
|
||||
return &converter{
|
||||
db: db,
|
||||
func NewConverter(state *state.State) *Converter {
|
||||
return &Converter{
|
||||
state: state,
|
||||
defaultAvatars: populateDefaultAvatars(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ type TypeUtilsTestSuite struct {
|
|||
testReports map[string]*gtsmodel.Report
|
||||
testMentions map[string]*gtsmodel.Mention
|
||||
|
||||
typeconverter typeutils.TypeConverter
|
||||
typeconverter *typeutils.Converter
|
||||
}
|
||||
|
||||
func (suite *TypeUtilsTestSuite) SetupTest() {
|
||||
|
|
@ -502,7 +502,7 @@ func (suite *TypeUtilsTestSuite) SetupTest() {
|
|||
suite.testEmojis = testrig.NewTestEmojis()
|
||||
suite.testReports = testrig.NewTestReports()
|
||||
suite.testMentions = testrig.NewTestMentions()
|
||||
suite.typeconverter = typeutils.NewConverter(suite.db)
|
||||
suite.typeconverter = typeutils.NewConverter(&suite.state)
|
||||
|
||||
testrig.StandardDBSetup(suite.db, nil)
|
||||
}
|
||||
|
|
@ -519,7 +519,7 @@ func (suite *TypeUtilsTestSuite) GetProcessor() *processing.Processor {
|
|||
testrig.StartTimelines(
|
||||
&suite.state,
|
||||
visibility.NewFilter(&suite.state),
|
||||
testrig.NewTestTypeConverter(suite.db),
|
||||
suite.typeconverter,
|
||||
)
|
||||
|
||||
httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media")
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ func populateDefaultAvatars() (defaultAvatars []string) {
|
|||
//
|
||||
// If there are no default avatars available, this function is a
|
||||
// no-op.
|
||||
func (c *converter) ensureAvatar(account *apimodel.Account) {
|
||||
func (c *Converter) ensureAvatar(account *apimodel.Account) {
|
||||
if (account.Avatar != "" && account.AvatarStatic != "") || len(c.defaultAvatars) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
@ -126,7 +126,7 @@ func (c *converter) ensureAvatar(account *apimodel.Account) {
|
|||
//
|
||||
// If a value for the header URL is already set, this function is
|
||||
// a no-op.
|
||||
func (c *converter) ensureHeader(account *apimodel.Account) {
|
||||
func (c *Converter) ensureHeader(account *apimodel.Account) {
|
||||
if account.Header != "" && account.HeaderStatic != "" {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/uris"
|
||||
)
|
||||
|
||||
func (c *converter) FollowRequestToFollow(ctx context.Context, f *gtsmodel.FollowRequest) *gtsmodel.Follow {
|
||||
// FollowRequestToFollow just converts a follow request into a follow, that's it! No bells and whistles.
|
||||
func (c *Converter) FollowRequestToFollow(ctx context.Context, f *gtsmodel.FollowRequest) *gtsmodel.Follow {
|
||||
showReblogs := *f.ShowReblogs
|
||||
notify := *f.Notify
|
||||
return >smodel.Follow{
|
||||
|
|
@ -41,7 +42,8 @@ func (c *converter) FollowRequestToFollow(ctx context.Context, f *gtsmodel.Follo
|
|||
}
|
||||
}
|
||||
|
||||
func (c *converter) StatusToBoost(ctx context.Context, s *gtsmodel.Status, boostingAccount *gtsmodel.Account) (*gtsmodel.Status, error) {
|
||||
// StatusToBoost wraps the given status into a boosting status.
|
||||
func (c *Converter) StatusToBoost(ctx context.Context, s *gtsmodel.Status, boostingAccount *gtsmodel.Account) (*gtsmodel.Status, error) {
|
||||
// the wrapper won't use the same ID as the boosted status so we generate some new UUIDs
|
||||
accountURIs := uris.GenerateURIsForAccount(boostingAccount.Username)
|
||||
boostWrapperStatusID := id.NewULID()
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/uris"
|
||||
)
|
||||
|
||||
// Converts a gts model account into an Activity Streams person type.
|
||||
func (c *converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) {
|
||||
// AccountToAS converts a gts model account into an activity streams person, suitable for federation
|
||||
func (c *Converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) {
|
||||
person := streams.NewActivityStreamsPerson()
|
||||
|
||||
// id should be the activitypub URI of this user
|
||||
|
|
@ -220,7 +220,7 @@ func (c *converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab
|
|||
if len(a.EmojiIDs) > len(emojis) {
|
||||
emojis = []*gtsmodel.Emoji{}
|
||||
for _, emojiID := range a.EmojiIDs {
|
||||
emoji, err := c.db.GetEmojiByID(ctx, emojiID)
|
||||
emoji, err := c.state.DB.GetEmojiByID(ctx, emojiID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AccountToAS: error getting emoji %s from database: %s", emojiID, err)
|
||||
}
|
||||
|
|
@ -269,7 +269,7 @@ func (c *converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab
|
|||
// Used as profile avatar.
|
||||
if a.AvatarMediaAttachmentID != "" {
|
||||
if a.AvatarMediaAttachment == nil {
|
||||
avatar, err := c.db.GetAttachmentByID(ctx, a.AvatarMediaAttachmentID)
|
||||
avatar, err := c.state.DB.GetAttachmentByID(ctx, a.AvatarMediaAttachmentID)
|
||||
if err == nil {
|
||||
a.AvatarMediaAttachment = avatar
|
||||
} else {
|
||||
|
|
@ -303,7 +303,7 @@ func (c *converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab
|
|||
// Used as profile header.
|
||||
if a.HeaderMediaAttachmentID != "" {
|
||||
if a.HeaderMediaAttachment == nil {
|
||||
header, err := c.db.GetAttachmentByID(ctx, a.HeaderMediaAttachmentID)
|
||||
header, err := c.state.DB.GetAttachmentByID(ctx, a.HeaderMediaAttachmentID)
|
||||
if err == nil {
|
||||
a.HeaderMediaAttachment = header
|
||||
} else {
|
||||
|
|
@ -336,10 +336,12 @@ func (c *converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab
|
|||
return person, nil
|
||||
}
|
||||
|
||||
// Converts a gts model account into a VERY MINIMAL Activity Streams person type.
|
||||
// AccountToASMinimal converts a gts model account into an activity streams person, suitable for federation.
|
||||
//
|
||||
// The returned account will just have the Type, Username, PublicKey, and ID properties set.
|
||||
func (c *converter) AccountToASMinimal(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) {
|
||||
// The returned account will just have the Type, Username, PublicKey, and ID properties set. This is
|
||||
// suitable for serving to requesters to whom we want to give as little information as possible because
|
||||
// we don't trust them (yet).
|
||||
func (c *Converter) AccountToASMinimal(ctx context.Context, a *gtsmodel.Account) (vocab.ActivityStreamsPerson, error) {
|
||||
person := streams.NewActivityStreamsPerson()
|
||||
|
||||
// id should be the activitypub URI of this user
|
||||
|
|
@ -401,13 +403,14 @@ func (c *converter) AccountToASMinimal(ctx context.Context, a *gtsmodel.Account)
|
|||
return person, nil
|
||||
}
|
||||
|
||||
func (c *converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.ActivityStreamsNote, error) {
|
||||
// StatusToAS converts a gts model status into an activity streams note, suitable for federation
|
||||
func (c *Converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.ActivityStreamsNote, error) {
|
||||
// ensure prerequisites here before we get stuck in
|
||||
|
||||
// check if author account is already attached to status and attach it if not
|
||||
// if we can't retrieve this, bail here already because we can't attribute the status to anyone
|
||||
if s.Account == nil {
|
||||
a, err := c.db.GetAccountByID(ctx, s.AccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, s.AccountID)
|
||||
if err != nil {
|
||||
return nil, gtserror.Newf("error retrieving author account from db: %w", err)
|
||||
}
|
||||
|
|
@ -478,7 +481,7 @@ func (c *converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.A
|
|||
// tag -- mentions
|
||||
mentions := s.Mentions
|
||||
if len(s.MentionIDs) > len(mentions) {
|
||||
mentions, err = c.db.GetMentions(ctx, s.MentionIDs)
|
||||
mentions, err = c.state.DB.GetMentions(ctx, s.MentionIDs)
|
||||
if err != nil {
|
||||
return nil, gtserror.Newf("error getting mentions: %w", err)
|
||||
}
|
||||
|
|
@ -496,7 +499,7 @@ func (c *converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.A
|
|||
if len(s.EmojiIDs) > len(emojis) {
|
||||
emojis = []*gtsmodel.Emoji{}
|
||||
for _, emojiID := range s.EmojiIDs {
|
||||
emoji, err := c.db.GetEmojiByID(ctx, emojiID)
|
||||
emoji, err := c.state.DB.GetEmojiByID(ctx, emojiID)
|
||||
if err != nil {
|
||||
return nil, gtserror.Newf("error getting emoji %s from database: %w", emojiID, err)
|
||||
}
|
||||
|
|
@ -514,7 +517,7 @@ func (c *converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.A
|
|||
// tag -- hashtags
|
||||
hashtags := s.Tags
|
||||
if len(s.TagIDs) > len(hashtags) {
|
||||
hashtags, err = c.db.GetTags(ctx, s.TagIDs)
|
||||
hashtags, err = c.state.DB.GetTags(ctx, s.TagIDs)
|
||||
if err != nil {
|
||||
return nil, gtserror.Newf("error getting tags: %w", err)
|
||||
}
|
||||
|
|
@ -605,7 +608,7 @@ func (c *converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.A
|
|||
if len(s.AttachmentIDs) > len(attachments) {
|
||||
attachments = []*gtsmodel.MediaAttachment{}
|
||||
for _, attachmentID := range s.AttachmentIDs {
|
||||
attachment, err := c.db.GetAttachmentByID(ctx, attachmentID)
|
||||
attachment, err := c.state.DB.GetAttachmentByID(ctx, attachmentID)
|
||||
if err != nil {
|
||||
return nil, gtserror.Newf("error getting attachment %s from database: %w", attachmentID, err)
|
||||
}
|
||||
|
|
@ -639,13 +642,15 @@ func (c *converter) StatusToAS(ctx context.Context, s *gtsmodel.Status) (vocab.A
|
|||
return status, nil
|
||||
}
|
||||
|
||||
func (c *converter) StatusToASDelete(ctx context.Context, s *gtsmodel.Status) (vocab.ActivityStreamsDelete, error) {
|
||||
// StatusToASDelete converts a gts model status into a Delete of that status, using just the
|
||||
// URI of the status as object, and addressing the Delete appropriately.
|
||||
func (c *Converter) StatusToASDelete(ctx context.Context, s *gtsmodel.Status) (vocab.ActivityStreamsDelete, error) {
|
||||
// Parse / fetch some information
|
||||
// we need to create the Delete.
|
||||
|
||||
if s.Account == nil {
|
||||
var err error
|
||||
s.Account, err = c.db.GetAccountByID(ctx, s.AccountID)
|
||||
s.Account, err = c.state.DB.GetAccountByID(ctx, s.AccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatusToASDelete: error retrieving author account from db: %w", err)
|
||||
}
|
||||
|
|
@ -717,7 +722,7 @@ func (c *converter) StatusToASDelete(ctx context.Context, s *gtsmodel.Status) (v
|
|||
// Ensure mentions are populated.
|
||||
mentions := s.Mentions
|
||||
if len(s.MentionIDs) > len(mentions) {
|
||||
mentions, err = c.db.GetMentions(ctx, s.MentionIDs)
|
||||
mentions, err = c.state.DB.GetMentions(ctx, s.MentionIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("StatusToASDelete: error getting mentions: %w", err)
|
||||
}
|
||||
|
|
@ -752,7 +757,7 @@ func (c *converter) StatusToASDelete(ctx context.Context, s *gtsmodel.Status) (v
|
|||
// Only address to this account if it
|
||||
// wasn't already included as a mention.
|
||||
if s.InReplyToAccount == nil {
|
||||
s.InReplyToAccount, err = c.db.GetAccountByID(ctx, s.InReplyToAccountID)
|
||||
s.InReplyToAccount, err = c.state.DB.GetAccountByID(ctx, s.InReplyToAccountID)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("StatusToASDelete: db error getting account %s: %w", s.InReplyToAccountID, err)
|
||||
}
|
||||
|
|
@ -774,8 +779,9 @@ func (c *converter) StatusToASDelete(ctx context.Context, s *gtsmodel.Status) (v
|
|||
return delete, nil
|
||||
}
|
||||
|
||||
func (c *converter) FollowToAS(ctx context.Context, f *gtsmodel.Follow) (vocab.ActivityStreamsFollow, error) {
|
||||
if err := c.db.PopulateFollow(ctx, f); err != nil {
|
||||
// FollowToASFollow converts a gts model Follow into an activity streams Follow, suitable for federation
|
||||
func (c *Converter) FollowToAS(ctx context.Context, f *gtsmodel.Follow) (vocab.ActivityStreamsFollow, error) {
|
||||
if err := c.state.DB.PopulateFollow(ctx, f); err != nil {
|
||||
return nil, gtserror.Newf("error populating follow: %w", err)
|
||||
}
|
||||
|
||||
|
|
@ -824,9 +830,10 @@ func (c *converter) FollowToAS(ctx context.Context, f *gtsmodel.Follow) (vocab.A
|
|||
return follow, nil
|
||||
}
|
||||
|
||||
func (c *converter) MentionToAS(ctx context.Context, m *gtsmodel.Mention) (vocab.ActivityStreamsMention, error) {
|
||||
// MentionToAS converts a gts model mention into an activity streams Mention, suitable for federation
|
||||
func (c *Converter) MentionToAS(ctx context.Context, m *gtsmodel.Mention) (vocab.ActivityStreamsMention, error) {
|
||||
if m.TargetAccount == nil {
|
||||
a, err := c.db.GetAccountByID(ctx, m.TargetAccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, m.TargetAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("MentionToAS: error getting target account from db: %s", err)
|
||||
}
|
||||
|
|
@ -865,7 +872,8 @@ func (c *converter) MentionToAS(ctx context.Context, m *gtsmodel.Mention) (vocab
|
|||
return mention, nil
|
||||
}
|
||||
|
||||
func (c *converter) TagToAS(ctx context.Context, t *gtsmodel.Tag) (vocab.TootHashtag, error) {
|
||||
// TagToAS converts a gts model tag into a toot Hashtag, suitable for federation.
|
||||
func (c *Converter) TagToAS(ctx context.Context, t *gtsmodel.Tag) (vocab.TootHashtag, error) {
|
||||
// This is probably already lowercase,
|
||||
// but let's err on the safe side.
|
||||
nameLower := strings.ToLower(t.Name)
|
||||
|
|
@ -891,20 +899,20 @@ func (c *converter) TagToAS(ctx context.Context, t *gtsmodel.Tag) (vocab.TootHas
|
|||
return tag, nil
|
||||
}
|
||||
|
||||
/*
|
||||
we're making something like this:
|
||||
{
|
||||
"id": "https://example.com/emoji/123",
|
||||
"type": "Emoji",
|
||||
"name": ":kappa:",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/png",
|
||||
"url": "https://example.com/files/kappa.png"
|
||||
}
|
||||
}
|
||||
*/
|
||||
func (c *converter) EmojiToAS(ctx context.Context, e *gtsmodel.Emoji) (vocab.TootEmoji, error) {
|
||||
// EmojiToAS converts a gts emoji into a mastodon ns Emoji, suitable for federation.
|
||||
// we're making something like this:
|
||||
//
|
||||
// {
|
||||
// "id": "https://example.com/emoji/123",
|
||||
// "type": "Emoji",
|
||||
// "name": ":kappa:",
|
||||
// "icon": {
|
||||
// "type": "Image",
|
||||
// "mediaType": "image/png",
|
||||
// "url": "https://example.com/files/kappa.png"
|
||||
// }
|
||||
// }
|
||||
func (c *Converter) EmojiToAS(ctx context.Context, e *gtsmodel.Emoji) (vocab.TootEmoji, error) {
|
||||
// create the emoji
|
||||
emoji := streams.NewTootEmoji()
|
||||
|
||||
|
|
@ -947,7 +955,8 @@ func (c *converter) EmojiToAS(ctx context.Context, e *gtsmodel.Emoji) (vocab.Too
|
|||
return emoji, nil
|
||||
}
|
||||
|
||||
func (c *converter) AttachmentToAS(ctx context.Context, a *gtsmodel.MediaAttachment) (vocab.ActivityStreamsDocument, error) {
|
||||
// AttachmentToAS converts a gts model media attachment into an activity streams Attachment, suitable for federation
|
||||
func (c *Converter) AttachmentToAS(ctx context.Context, a *gtsmodel.MediaAttachment) (vocab.ActivityStreamsDocument, error) {
|
||||
// type -- Document
|
||||
doc := streams.NewActivityStreamsDocument()
|
||||
|
||||
|
|
@ -981,21 +990,20 @@ func (c *converter) AttachmentToAS(ctx context.Context, a *gtsmodel.MediaAttachm
|
|||
return doc, nil
|
||||
}
|
||||
|
||||
/*
|
||||
We want to end up with something like this:
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"actor": "https://ondergrond.org/users/dumpsterqueer",
|
||||
"id": "https://ondergrond.org/users/dumpsterqueer#likes/44584",
|
||||
"object": "https://testingtesting123.xyz/users/gotosocial_test_account/statuses/771aea80-a33d-4d6d-8dfd-57d4d2bfcbd4",
|
||||
"type": "Like"
|
||||
}
|
||||
*/
|
||||
func (c *converter) FaveToAS(ctx context.Context, f *gtsmodel.StatusFave) (vocab.ActivityStreamsLike, error) {
|
||||
// FaveToAS converts a gts model status fave into an activityStreams LIKE, suitable for federation.
|
||||
// We want to end up with something like this:
|
||||
//
|
||||
// {
|
||||
// "@context": "https://www.w3.org/ns/activitystreams",
|
||||
// "actor": "https://ondergrond.org/users/dumpsterqueer",
|
||||
// "id": "https://ondergrond.org/users/dumpsterqueer#likes/44584",
|
||||
// "object": "https://testingtesting123.xyz/users/gotosocial_test_account/statuses/771aea80-a33d-4d6d-8dfd-57d4d2bfcbd4",
|
||||
// "type": "Like"
|
||||
// }
|
||||
func (c *Converter) FaveToAS(ctx context.Context, f *gtsmodel.StatusFave) (vocab.ActivityStreamsLike, error) {
|
||||
// check if targetStatus is already pinned to this fave, and fetch it if not
|
||||
if f.Status == nil {
|
||||
s, err := c.db.GetStatusByID(ctx, f.StatusID)
|
||||
s, err := c.state.DB.GetStatusByID(ctx, f.StatusID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("FaveToAS: error fetching target status from database: %s", err)
|
||||
}
|
||||
|
|
@ -1004,7 +1012,7 @@ func (c *converter) FaveToAS(ctx context.Context, f *gtsmodel.StatusFave) (vocab
|
|||
|
||||
// check if the targetAccount is already pinned to this fave, and fetch it if not
|
||||
if f.TargetAccount == nil {
|
||||
a, err := c.db.GetAccountByID(ctx, f.TargetAccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, f.TargetAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("FaveToAS: error fetching target account from database: %s", err)
|
||||
}
|
||||
|
|
@ -1013,7 +1021,7 @@ func (c *converter) FaveToAS(ctx context.Context, f *gtsmodel.StatusFave) (vocab
|
|||
|
||||
// check if the faving account is already pinned to this fave, and fetch it if not
|
||||
if f.Account == nil {
|
||||
a, err := c.db.GetAccountByID(ctx, f.AccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, f.AccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("FaveToAS: error fetching faving account from database: %s", err)
|
||||
}
|
||||
|
|
@ -1062,10 +1070,11 @@ func (c *converter) FaveToAS(ctx context.Context, f *gtsmodel.StatusFave) (vocab
|
|||
return like, nil
|
||||
}
|
||||
|
||||
func (c *converter) BoostToAS(ctx context.Context, boostWrapperStatus *gtsmodel.Status, boostingAccount *gtsmodel.Account, boostedAccount *gtsmodel.Account) (vocab.ActivityStreamsAnnounce, error) {
|
||||
// BoostToAS converts a gts model boost into an activityStreams ANNOUNCE, suitable for federation
|
||||
func (c *Converter) BoostToAS(ctx context.Context, boostWrapperStatus *gtsmodel.Status, boostingAccount *gtsmodel.Account, boostedAccount *gtsmodel.Account) (vocab.ActivityStreamsAnnounce, error) {
|
||||
// the boosted status is probably pinned to the boostWrapperStatus but double check to make sure
|
||||
if boostWrapperStatus.BoostOf == nil {
|
||||
b, err := c.db.GetStatusByID(ctx, boostWrapperStatus.BoostOfID)
|
||||
b, err := c.state.DB.GetStatusByID(ctx, boostWrapperStatus.BoostOfID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("BoostToAS: error getting status with ID %s from the db: %s", boostWrapperStatus.BoostOfID, err)
|
||||
}
|
||||
|
|
@ -1139,20 +1148,19 @@ func (c *converter) BoostToAS(ctx context.Context, boostWrapperStatus *gtsmodel.
|
|||
return announce, nil
|
||||
}
|
||||
|
||||
/*
|
||||
we want to end up with something like this:
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"actor": "https://example.org/users/some_user",
|
||||
"id":"https://example.org/users/some_user/blocks/SOME_ULID_OF_A_BLOCK",
|
||||
"object":"https://some_other.instance/users/some_other_user",
|
||||
"type":"Block"
|
||||
}
|
||||
*/
|
||||
func (c *converter) BlockToAS(ctx context.Context, b *gtsmodel.Block) (vocab.ActivityStreamsBlock, error) {
|
||||
// BlockToAS converts a gts model block into an activityStreams BLOCK, suitable for federation.
|
||||
// we want to end up with something like this:
|
||||
//
|
||||
// {
|
||||
// "@context": "https://www.w3.org/ns/activitystreams",
|
||||
// "actor": "https://example.org/users/some_user",
|
||||
// "id":"https://example.org/users/some_user/blocks/SOME_ULID_OF_A_BLOCK",
|
||||
// "object":"https://some_other.instance/users/some_other_user",
|
||||
// "type":"Block"
|
||||
// }
|
||||
func (c *Converter) BlockToAS(ctx context.Context, b *gtsmodel.Block) (vocab.ActivityStreamsBlock, error) {
|
||||
if b.Account == nil {
|
||||
a, err := c.db.GetAccountByID(ctx, b.AccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, b.AccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("BlockToAS: error getting block owner account from database: %s", err)
|
||||
}
|
||||
|
|
@ -1160,7 +1168,7 @@ func (c *converter) BlockToAS(ctx context.Context, b *gtsmodel.Block) (vocab.Act
|
|||
}
|
||||
|
||||
if b.TargetAccount == nil {
|
||||
a, err := c.db.GetAccountByID(ctx, b.TargetAccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, b.TargetAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("BlockToAS: error getting block target account from database: %s", err)
|
||||
}
|
||||
|
|
@ -1209,23 +1217,22 @@ func (c *converter) BlockToAS(ctx context.Context, b *gtsmodel.Block) (vocab.Act
|
|||
return block, nil
|
||||
}
|
||||
|
||||
/*
|
||||
the goal is to end up with something like this:
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
|
||||
"type": "Collection",
|
||||
"first": {
|
||||
"id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?page=true",
|
||||
"type": "CollectionPage",
|
||||
"next": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?only_other_accounts=true&page=true",
|
||||
"partOf": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
|
||||
"items": []
|
||||
}
|
||||
}
|
||||
*/
|
||||
func (c *converter) StatusToASRepliesCollection(ctx context.Context, status *gtsmodel.Status, onlyOtherAccounts bool) (vocab.ActivityStreamsCollection, error) {
|
||||
// StatusToASRepliesCollection converts a gts model status into an activityStreams REPLIES collection.
|
||||
// the goal is to end up with something like this:
|
||||
//
|
||||
// {
|
||||
// "@context": "https://www.w3.org/ns/activitystreams",
|
||||
// "id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
|
||||
// "type": "Collection",
|
||||
// "first": {
|
||||
// "id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?page=true",
|
||||
// "type": "CollectionPage",
|
||||
// "next": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?only_other_accounts=true&page=true",
|
||||
// "partOf": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
|
||||
// "items": []
|
||||
// }
|
||||
// }
|
||||
func (c *Converter) StatusToASRepliesCollection(ctx context.Context, status *gtsmodel.Status, onlyOtherAccounts bool) (vocab.ActivityStreamsCollection, error) {
|
||||
collectionID := fmt.Sprintf("%s/replies", status.URI)
|
||||
collectionIDURI, err := url.Parse(collectionID)
|
||||
if err != nil {
|
||||
|
|
@ -1274,22 +1281,21 @@ func (c *converter) StatusToASRepliesCollection(ctx context.Context, status *gts
|
|||
return collection, nil
|
||||
}
|
||||
|
||||
/*
|
||||
the goal is to end up with something like this:
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?only_other_accounts=true&page=true",
|
||||
"type": "CollectionPage",
|
||||
"next": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?min_id=106720870266901180&only_other_accounts=true&page=true",
|
||||
"partOf": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
|
||||
"items": [
|
||||
"https://example.com/users/someone/statuses/106720752853216226",
|
||||
"https://somewhere.online/users/eeeeeeeeeep/statuses/106720870163727231"
|
||||
]
|
||||
}
|
||||
*/
|
||||
func (c *converter) StatusURIsToASRepliesPage(ctx context.Context, status *gtsmodel.Status, onlyOtherAccounts bool, minID string, replies map[string]*url.URL) (vocab.ActivityStreamsCollectionPage, error) {
|
||||
// StatusURIsToASRepliesPage returns a collection page with appropriate next/part of pagination.
|
||||
// the goal is to end up with something like this:
|
||||
//
|
||||
// {
|
||||
// "@context": "https://www.w3.org/ns/activitystreams",
|
||||
// "id": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?only_other_accounts=true&page=true",
|
||||
// "type": "CollectionPage",
|
||||
// "next": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies?min_id=106720870266901180&only_other_accounts=true&page=true",
|
||||
// "partOf": "https://example.org/users/whatever/statuses/01FCNEXAGAKPEX1J7VJRPJP490/replies",
|
||||
// "items": [
|
||||
// "https://example.com/users/someone/statuses/106720752853216226",
|
||||
// "https://somewhere.online/users/eeeeeeeeeep/statuses/106720870163727231"
|
||||
// ]
|
||||
// }
|
||||
func (c *Converter) StatusURIsToASRepliesPage(ctx context.Context, status *gtsmodel.Status, onlyOtherAccounts bool, minID string, replies map[string]*url.URL) (vocab.ActivityStreamsCollectionPage, error) {
|
||||
collectionID := fmt.Sprintf("%s/replies", status.URI)
|
||||
|
||||
page := streams.NewActivityStreamsCollectionPage()
|
||||
|
|
@ -1345,31 +1351,37 @@ func (c *converter) StatusURIsToASRepliesPage(ctx context.Context, status *gtsmo
|
|||
return page, nil
|
||||
}
|
||||
|
||||
/*
|
||||
the goal is to end up with something like this:
|
||||
|
||||
{
|
||||
"id": "https://example.org/users/whatever/outbox?page=true",
|
||||
"type": "OrderedCollectionPage",
|
||||
"next": "https://example.org/users/whatever/outbox?max_id=01FJC1Q0E3SSQR59TD2M1KP4V8&page=true",
|
||||
"prev": "https://example.org/users/whatever/outbox?min_id=01FJC1Q0E3SSQR59TD2M1KP4V8&page=true",
|
||||
"partOf": "https://example.org/users/whatever/outbox",
|
||||
"orderedItems": [
|
||||
"id": "https://example.org/users/whatever/statuses/01FJC1MKPVX2VMWP2ST93Q90K7/activity",
|
||||
"type": "Create",
|
||||
"actor": "https://example.org/users/whatever",
|
||||
"published": "2021-10-18T20:06:18Z",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://example.org/users/whatever/followers"
|
||||
],
|
||||
"object": "https://example.org/users/whatever/statuses/01FJC1MKPVX2VMWP2ST93Q90K7"
|
||||
]
|
||||
}
|
||||
*/
|
||||
func (c *converter) StatusesToASOutboxPage(ctx context.Context, outboxID string, maxID string, minID string, statuses []*gtsmodel.Status) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
||||
// StatusesToASOutboxPage returns an ordered collection page using the given statuses and parameters as contents.
|
||||
//
|
||||
// The maxID and minID should be the parameters that were passed to the database to obtain the given statuses.
|
||||
// These will be used to create the 'id' field of the collection.
|
||||
//
|
||||
// OutboxID is used to create the 'partOf' field in the collection.
|
||||
//
|
||||
// Appropriate 'next' and 'prev' fields will be created based on the highest and lowest IDs present in the statuses slice.
|
||||
// the goal is to end up with something like this:
|
||||
//
|
||||
// {
|
||||
// "id": "https://example.org/users/whatever/outbox?page=true",
|
||||
// "type": "OrderedCollectionPage",
|
||||
// "next": "https://example.org/users/whatever/outbox?max_id=01FJC1Q0E3SSQR59TD2M1KP4V8&page=true",
|
||||
// "prev": "https://example.org/users/whatever/outbox?min_id=01FJC1Q0E3SSQR59TD2M1KP4V8&page=true",
|
||||
// "partOf": "https://example.org/users/whatever/outbox",
|
||||
// "orderedItems": [
|
||||
// "id": "https://example.org/users/whatever/statuses/01FJC1MKPVX2VMWP2ST93Q90K7/activity",
|
||||
// "type": "Create",
|
||||
// "actor": "https://example.org/users/whatever",
|
||||
// "published": "2021-10-18T20:06:18Z",
|
||||
// "to": [
|
||||
// "https://www.w3.org/ns/activitystreams#Public"
|
||||
// ],
|
||||
// "cc": [
|
||||
// "https://example.org/users/whatever/followers"
|
||||
// ],
|
||||
// "object": "https://example.org/users/whatever/statuses/01FJC1MKPVX2VMWP2ST93Q90K7"
|
||||
// ]
|
||||
// }
|
||||
func (c *Converter) StatusesToASOutboxPage(ctx context.Context, outboxID string, maxID string, minID string, statuses []*gtsmodel.Status) (vocab.ActivityStreamsOrderedCollectionPage, error) {
|
||||
page := streams.NewActivityStreamsOrderedCollectionPage()
|
||||
|
||||
// .id
|
||||
|
|
@ -1450,17 +1462,17 @@ func (c *converter) StatusesToASOutboxPage(ctx context.Context, outboxID string,
|
|||
return page, nil
|
||||
}
|
||||
|
||||
/*
|
||||
we want something that looks like this:
|
||||
|
||||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": "https://example.org/users/whatever/outbox",
|
||||
"type": "OrderedCollection",
|
||||
"first": "https://example.org/users/whatever/outbox?page=true"
|
||||
}
|
||||
*/
|
||||
func (c *converter) OutboxToASCollection(ctx context.Context, outboxID string) (vocab.ActivityStreamsOrderedCollection, error) {
|
||||
// OutboxToASCollection returns an ordered collection with appropriate id, next, and last fields.
|
||||
// The returned collection won't have any actual entries; just links to where entries can be obtained.
|
||||
// we want something that looks like this:
|
||||
//
|
||||
// {
|
||||
// "@context": "https://www.w3.org/ns/activitystreams",
|
||||
// "id": "https://example.org/users/whatever/outbox",
|
||||
// "type": "OrderedCollection",
|
||||
// "first": "https://example.org/users/whatever/outbox?page=true"
|
||||
// }
|
||||
func (c *Converter) OutboxToASCollection(ctx context.Context, outboxID string) (vocab.ActivityStreamsOrderedCollection, error) {
|
||||
collection := streams.NewActivityStreamsOrderedCollection()
|
||||
|
||||
collectionIDProp := streams.NewJSONLDIdProperty()
|
||||
|
|
@ -1483,7 +1495,9 @@ func (c *converter) OutboxToASCollection(ctx context.Context, outboxID string) (
|
|||
return collection, nil
|
||||
}
|
||||
|
||||
func (c *converter) StatusesToASFeaturedCollection(ctx context.Context, featuredCollectionID string, statuses []*gtsmodel.Status) (vocab.ActivityStreamsOrderedCollection, error) {
|
||||
// StatusesToASFeaturedCollection converts a slice of statuses into an ordered collection
|
||||
// of URIs, suitable for serializing and serving via the activitypub API.
|
||||
func (c *Converter) StatusesToASFeaturedCollection(ctx context.Context, featuredCollectionID string, statuses []*gtsmodel.Status) (vocab.ActivityStreamsOrderedCollection, error) {
|
||||
collection := streams.NewActivityStreamsOrderedCollection()
|
||||
|
||||
collectionIDProp := streams.NewJSONLDIdProperty()
|
||||
|
|
@ -1511,7 +1525,8 @@ func (c *converter) StatusesToASFeaturedCollection(ctx context.Context, featured
|
|||
return collection, nil
|
||||
}
|
||||
|
||||
func (c *converter) ReportToASFlag(ctx context.Context, r *gtsmodel.Report) (vocab.ActivityStreamsFlag, error) {
|
||||
// ReportToASFlag converts a gts model report into an activitystreams FLAG, suitable for federation.
|
||||
func (c *Converter) ReportToASFlag(ctx context.Context, r *gtsmodel.Report) (vocab.ActivityStreamsFlag, error) {
|
||||
flag := streams.NewActivityStreamsFlag()
|
||||
|
||||
flagIDProp := streams.NewJSONLDIdProperty()
|
||||
|
|
@ -1524,7 +1539,7 @@ func (c *converter) ReportToASFlag(ctx context.Context, r *gtsmodel.Report) (voc
|
|||
|
||||
// for privacy, set the actor as the INSTANCE ACTOR,
|
||||
// not as the actor who created the report
|
||||
instanceAccount, err := c.db.GetInstanceAccount(ctx, "")
|
||||
instanceAccount, err := c.state.DB.GetInstanceAccount(ctx, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting instance account: %w", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,10 @@ func toMastodonVersion(in string) string {
|
|||
return instanceMastodonVersion + "+" + strings.ReplaceAll(in, " ", "-")
|
||||
}
|
||||
|
||||
func (c *converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
// AppToAPIAppSensitive takes a db model application as a param, and returns a populated apitype application, or an error
|
||||
// if something goes wrong. The returned application should be ready to serialize on an API level, and may have sensitive fields
|
||||
// (such as client id and client secret), so serve it only to an authorized user who should have permission to see it.
|
||||
func (c *Converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
// we can build this sensitive account easily by first getting the public account....
|
||||
apiAccount, err := c.AccountToAPIAccountPublic(ctx, a)
|
||||
if err != nil {
|
||||
|
|
@ -68,7 +71,7 @@ func (c *converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmode
|
|||
// then adding the Source object to it...
|
||||
|
||||
// check pending follow requests aimed at this account
|
||||
frc, err := c.db.CountAccountFollowRequests(ctx, a.ID)
|
||||
frc, err := c.state.DB.CountAccountFollowRequests(ctx, a.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error counting follow requests: %s", err)
|
||||
}
|
||||
|
|
@ -91,8 +94,11 @@ func (c *converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmode
|
|||
return apiAccount, nil
|
||||
}
|
||||
|
||||
func (c *converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
if err := c.db.PopulateAccount(ctx, a); err != nil {
|
||||
// AccountToAPIAccountPublic takes a db model account as a param, and returns a populated apitype account, or an error
|
||||
// if something goes wrong. The returned account should be ready to serialize on an API level, and may NOT have sensitive fields.
|
||||
// In other words, this is the public record that the server has of an account.
|
||||
func (c *Converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
if err := c.state.DB.PopulateAccount(ctx, a); err != nil {
|
||||
log.Errorf(ctx, "error(s) populating account, will continue: %s", err)
|
||||
}
|
||||
|
||||
|
|
@ -102,23 +108,23 @@ func (c *converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
|||
// - Statuses count
|
||||
// - Last status time
|
||||
|
||||
followersCount, err := c.db.CountAccountFollowers(ctx, a.ID)
|
||||
followersCount, err := c.state.DB.CountAccountFollowers(ctx, a.ID)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("AccountToAPIAccountPublic: error counting followers: %w", err)
|
||||
}
|
||||
|
||||
followingCount, err := c.db.CountAccountFollows(ctx, a.ID)
|
||||
followingCount, err := c.state.DB.CountAccountFollows(ctx, a.ID)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("AccountToAPIAccountPublic: error counting following: %w", err)
|
||||
}
|
||||
|
||||
statusesCount, err := c.db.CountAccountStatuses(ctx, a.ID)
|
||||
statusesCount, err := c.state.DB.CountAccountStatuses(ctx, a.ID)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("AccountToAPIAccountPublic: error counting statuses: %w", err)
|
||||
}
|
||||
|
||||
var lastStatusAt *string
|
||||
lastPosted, err := c.db.GetAccountLastPosted(ctx, a.ID, false)
|
||||
lastPosted, err := c.state.DB.GetAccountLastPosted(ctx, a.ID, false)
|
||||
if err != nil && !errors.Is(err, db.ErrNoEntries) {
|
||||
return nil, fmt.Errorf("AccountToAPIAccountPublic: error counting statuses: %w", err)
|
||||
}
|
||||
|
|
@ -182,7 +188,7 @@ func (c *converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
|||
// fetch more info. Skip for instance
|
||||
// accounts since they have no user.
|
||||
if !a.IsInstance() {
|
||||
user, err := c.db.GetUserByAccountID(ctx, a.ID)
|
||||
user, err := c.state.DB.GetUserByAccountID(ctx, a.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AccountToAPIAccountPublic: error getting user from database for account id %s: %w", a.ID, err)
|
||||
}
|
||||
|
|
@ -238,7 +244,7 @@ func (c *converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
|
|||
return accountFrontend, nil
|
||||
}
|
||||
|
||||
func (c *converter) fieldsToAPIFields(f []*gtsmodel.Field) []apimodel.Field {
|
||||
func (c *Converter) fieldsToAPIFields(f []*gtsmodel.Field) []apimodel.Field {
|
||||
fields := make([]apimodel.Field, len(f))
|
||||
|
||||
for i, field := range f {
|
||||
|
|
@ -257,7 +263,10 @@ func (c *converter) fieldsToAPIFields(f []*gtsmodel.Field) []apimodel.Field {
|
|||
return fields
|
||||
}
|
||||
|
||||
func (c *converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
// AccountToAPIAccountBlocked takes a db model account as a param, and returns a apitype account, or an error if
|
||||
// something goes wrong. The returned account will be a bare minimum representation of the account. This function should be used
|
||||
// when someone wants to view an account they've blocked.
|
||||
func (c *Converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) {
|
||||
var (
|
||||
acct string
|
||||
role *apimodel.AccountRole
|
||||
|
|
@ -277,7 +286,7 @@ func (c *converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.
|
|||
// fetch more info. Skip for instance
|
||||
// accounts since they have no user.
|
||||
if !a.IsInstance() {
|
||||
user, err := c.db.GetUserByAccountID(ctx, a.ID)
|
||||
user, err := c.state.DB.GetUserByAccountID(ctx, a.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AccountToAPIAccountPublic: error getting user from database for account id %s: %w", a.ID, err)
|
||||
}
|
||||
|
|
@ -308,7 +317,7 @@ func (c *converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Account) (*apimodel.AdminAccountInfo, error) {
|
||||
func (c *Converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Account) (*apimodel.AdminAccountInfo, error) {
|
||||
var (
|
||||
email string
|
||||
ip *string
|
||||
|
|
@ -334,7 +343,7 @@ func (c *converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac
|
|||
} else if !a.IsInstance() {
|
||||
// This is a local, non-instance
|
||||
// acct; we can fetch more info.
|
||||
user, err := c.db.GetUserByAccountID(ctx, a.ID)
|
||||
user, err := c.state.DB.GetUserByAccountID(ctx, a.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("AccountToAdminAPIAccount: error getting user from database for account id %s: %w", a.ID, err)
|
||||
}
|
||||
|
|
@ -393,7 +402,7 @@ func (c *converter) AccountToAdminAPIAccount(ctx context.Context, a *gtsmodel.Ac
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) AppToAPIAppSensitive(ctx context.Context, a *gtsmodel.Application) (*apimodel.Application, error) {
|
||||
func (c *Converter) AppToAPIAppSensitive(ctx context.Context, a *gtsmodel.Application) (*apimodel.Application, error) {
|
||||
return &apimodel.Application{
|
||||
ID: a.ID,
|
||||
Name: a.Name,
|
||||
|
|
@ -404,14 +413,18 @@ func (c *converter) AppToAPIAppSensitive(ctx context.Context, a *gtsmodel.Applic
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) AppToAPIAppPublic(ctx context.Context, a *gtsmodel.Application) (*apimodel.Application, error) {
|
||||
// AppToAPIAppPublic takes a db model application as a param, and returns a populated apitype application, or an error
|
||||
// if something goes wrong. The returned application should be ready to serialize on an API level, and has sensitive
|
||||
// fields sanitized so that it can be served to non-authorized accounts without revealing any private information.
|
||||
func (c *Converter) AppToAPIAppPublic(ctx context.Context, a *gtsmodel.Application) (*apimodel.Application, error) {
|
||||
return &apimodel.Application{
|
||||
Name: a.Name,
|
||||
Website: a.Website,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) AttachmentToAPIAttachment(ctx context.Context, a *gtsmodel.MediaAttachment) (apimodel.Attachment, error) {
|
||||
// AttachmentToAPIAttachment converts a gts model media attacahment into its api representation for serialization on the API.
|
||||
func (c *Converter) AttachmentToAPIAttachment(ctx context.Context, a *gtsmodel.MediaAttachment) (apimodel.Attachment, error) {
|
||||
apiAttachment := apimodel.Attachment{
|
||||
ID: a.ID,
|
||||
Type: strings.ToLower(string(a.Type)),
|
||||
|
|
@ -479,9 +492,10 @@ func (c *converter) AttachmentToAPIAttachment(ctx context.Context, a *gtsmodel.M
|
|||
return apiAttachment, nil
|
||||
}
|
||||
|
||||
func (c *converter) MentionToAPIMention(ctx context.Context, m *gtsmodel.Mention) (apimodel.Mention, error) {
|
||||
// MentionToAPIMention converts a gts model mention into its api (frontend) representation for serialization on the API.
|
||||
func (c *Converter) MentionToAPIMention(ctx context.Context, m *gtsmodel.Mention) (apimodel.Mention, error) {
|
||||
if m.TargetAccount == nil {
|
||||
targetAccount, err := c.db.GetAccountByID(ctx, m.TargetAccountID)
|
||||
targetAccount, err := c.state.DB.GetAccountByID(ctx, m.TargetAccountID)
|
||||
if err != nil {
|
||||
return apimodel.Mention{}, err
|
||||
}
|
||||
|
|
@ -511,12 +525,13 @@ func (c *converter) MentionToAPIMention(ctx context.Context, m *gtsmodel.Mention
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) EmojiToAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (apimodel.Emoji, error) {
|
||||
// EmojiToAPIEmoji converts a gts model emoji into its api (frontend) representation for serialization on the API.
|
||||
func (c *Converter) EmojiToAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (apimodel.Emoji, error) {
|
||||
var category string
|
||||
if e.CategoryID != "" {
|
||||
if e.Category == nil {
|
||||
var err error
|
||||
e.Category, err = c.db.GetEmojiCategory(ctx, e.CategoryID)
|
||||
e.Category, err = c.state.DB.GetEmojiCategory(ctx, e.CategoryID)
|
||||
if err != nil {
|
||||
return apimodel.Emoji{}, err
|
||||
}
|
||||
|
|
@ -533,7 +548,8 @@ func (c *converter) EmojiToAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (api
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) EmojiToAdminAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (*apimodel.AdminEmoji, error) {
|
||||
// EmojiToAdminAPIEmoji converts a gts model emoji into an API representation with extra admin information.
|
||||
func (c *Converter) EmojiToAdminAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (*apimodel.AdminEmoji, error) {
|
||||
emoji, err := c.EmojiToAPIEmoji(ctx, e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -562,14 +578,17 @@ func (c *converter) EmojiToAdminAPIEmoji(ctx context.Context, e *gtsmodel.Emoji)
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) EmojiCategoryToAPIEmojiCategory(ctx context.Context, category *gtsmodel.EmojiCategory) (*apimodel.EmojiCategory, error) {
|
||||
// EmojiCategoryToAPIEmojiCategory converts a gts model emoji category into its api (frontend) representation.
|
||||
func (c *Converter) EmojiCategoryToAPIEmojiCategory(ctx context.Context, category *gtsmodel.EmojiCategory) (*apimodel.EmojiCategory, error) {
|
||||
return &apimodel.EmojiCategory{
|
||||
ID: category.ID,
|
||||
Name: category.Name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) TagToAPITag(ctx context.Context, t *gtsmodel.Tag, stubHistory bool) (apimodel.Tag, error) {
|
||||
// TagToAPITag converts a gts model tag into its api (frontend) representation for serialization on the API.
|
||||
// If stubHistory is set to 'true', then the 'history' field of the tag will be populated with a pointer to an empty slice, for API compatibility reasons.
|
||||
func (c *Converter) TagToAPITag(ctx context.Context, t *gtsmodel.Tag, stubHistory bool) (apimodel.Tag, error) {
|
||||
return apimodel.Tag{
|
||||
Name: strings.ToLower(t.Name),
|
||||
URL: uris.GenerateURIForTag(t.Name),
|
||||
|
|
@ -584,8 +603,11 @@ func (c *converter) TagToAPITag(ctx context.Context, t *gtsmodel.Tag, stubHistor
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) StatusToAPIStatus(ctx context.Context, s *gtsmodel.Status, requestingAccount *gtsmodel.Account) (*apimodel.Status, error) {
|
||||
if err := c.db.PopulateStatus(ctx, s); err != nil {
|
||||
// StatusToAPIStatus converts a gts model status into its api (frontend) representation for serialization on the API.
|
||||
//
|
||||
// Requesting account can be nil.
|
||||
func (c *Converter) StatusToAPIStatus(ctx context.Context, s *gtsmodel.Status, requestingAccount *gtsmodel.Account) (*apimodel.Status, error) {
|
||||
if err := c.state.DB.PopulateStatus(ctx, s); err != nil {
|
||||
// Ensure author account present + correct;
|
||||
// can't really go further without this!
|
||||
if s.Account == nil {
|
||||
|
|
@ -600,17 +622,17 @@ func (c *converter) StatusToAPIStatus(ctx context.Context, s *gtsmodel.Status, r
|
|||
return nil, fmt.Errorf("error converting status author: %w", err)
|
||||
}
|
||||
|
||||
repliesCount, err := c.db.CountStatusReplies(ctx, s.ID)
|
||||
repliesCount, err := c.state.DB.CountStatusReplies(ctx, s.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error counting replies: %w", err)
|
||||
}
|
||||
|
||||
reblogsCount, err := c.db.CountStatusBoosts(ctx, s.ID)
|
||||
reblogsCount, err := c.state.DB.CountStatusBoosts(ctx, s.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error counting reblogs: %w", err)
|
||||
}
|
||||
|
||||
favesCount, err := c.db.CountStatusFaves(ctx, s.ID)
|
||||
favesCount, err := c.state.DB.CountStatusFaves(ctx, s.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error counting faves: %w", err)
|
||||
}
|
||||
|
|
@ -699,7 +721,7 @@ func (c *converter) StatusToAPIStatus(ctx context.Context, s *gtsmodel.Status, r
|
|||
}
|
||||
|
||||
if appID := s.CreatedWithApplicationID; appID != "" {
|
||||
app, err := c.db.GetApplicationByID(ctx, appID)
|
||||
app, err := c.state.DB.GetApplicationByID(ctx, appID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting application %s: %w", appID, err)
|
||||
}
|
||||
|
|
@ -723,8 +745,8 @@ func (c *converter) StatusToAPIStatus(ctx context.Context, s *gtsmodel.Status, r
|
|||
return apiStatus, nil
|
||||
}
|
||||
|
||||
// VisToapi converts a gts visibility into its api equivalent
|
||||
func (c *converter) VisToAPIVis(ctx context.Context, m gtsmodel.Visibility) apimodel.Visibility {
|
||||
// VisToAPIVis converts a gts visibility into its api equivalent
|
||||
func (c *Converter) VisToAPIVis(ctx context.Context, m gtsmodel.Visibility) apimodel.Visibility {
|
||||
switch m {
|
||||
case gtsmodel.VisibilityPublic:
|
||||
return apimodel.VisibilityPublic
|
||||
|
|
@ -738,14 +760,16 @@ func (c *converter) VisToAPIVis(ctx context.Context, m gtsmodel.Visibility) apim
|
|||
return ""
|
||||
}
|
||||
|
||||
func (c *converter) InstanceRuleToAPIRule(r gtsmodel.Rule) apimodel.InstanceRule {
|
||||
// InstanceRuleToAdminAPIRule converts a local instance rule into its api equivalent for serving at /api/v1/admin/instance/rules/:id
|
||||
func (c *Converter) InstanceRuleToAPIRule(r gtsmodel.Rule) apimodel.InstanceRule {
|
||||
return apimodel.InstanceRule{
|
||||
ID: r.ID,
|
||||
Text: r.Text,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *converter) InstanceRulesToAPIRules(r []gtsmodel.Rule) []apimodel.InstanceRule {
|
||||
// InstanceRulesToAPIRules converts all local instance rules into their api equivalent for serving at /api/v1/instance/rules
|
||||
func (c *Converter) InstanceRulesToAPIRules(r []gtsmodel.Rule) []apimodel.InstanceRule {
|
||||
rules := make([]apimodel.InstanceRule, len(r))
|
||||
|
||||
for i, v := range r {
|
||||
|
|
@ -755,7 +779,8 @@ func (c *converter) InstanceRulesToAPIRules(r []gtsmodel.Rule) []apimodel.Instan
|
|||
return rules
|
||||
}
|
||||
|
||||
func (c *converter) InstanceRuleToAdminAPIRule(r *gtsmodel.Rule) *apimodel.AdminInstanceRule {
|
||||
// InstanceRuleToAdminAPIRule converts a local instance rule into its api equivalent for serving at /api/v1/admin/instance/rules/:id
|
||||
func (c *Converter) InstanceRuleToAdminAPIRule(r *gtsmodel.Rule) *apimodel.AdminInstanceRule {
|
||||
return &apimodel.AdminInstanceRule{
|
||||
ID: r.ID,
|
||||
CreatedAt: util.FormatISO8601(r.CreatedAt),
|
||||
|
|
@ -764,7 +789,8 @@ func (c *converter) InstanceRuleToAdminAPIRule(r *gtsmodel.Rule) *apimodel.Admin
|
|||
}
|
||||
}
|
||||
|
||||
func (c *converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV1, error) {
|
||||
// InstanceToAPIV1Instance converts a gts instance into its api equivalent for serving at /api/v1/instance
|
||||
func (c *Converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV1, error) {
|
||||
instance := &apimodel.InstanceV1{
|
||||
URI: i.URI,
|
||||
AccountDomain: config.GetAccountDomain(),
|
||||
|
|
@ -810,19 +836,19 @@ func (c *converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
|
||||
// statistics
|
||||
stats := make(map[string]int, 3)
|
||||
userCount, err := c.db.CountInstanceUsers(ctx, i.Domain)
|
||||
userCount, err := c.state.DB.CountInstanceUsers(ctx, i.Domain)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV1Instance: db error getting counting instance users: %w", err)
|
||||
}
|
||||
stats["user_count"] = userCount
|
||||
|
||||
statusCount, err := c.db.CountInstanceStatuses(ctx, i.Domain)
|
||||
statusCount, err := c.state.DB.CountInstanceStatuses(ctx, i.Domain)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV1Instance: db error getting counting instance statuses: %w", err)
|
||||
}
|
||||
stats["status_count"] = statusCount
|
||||
|
||||
domainCount, err := c.db.CountInstanceDomains(ctx, i.Domain)
|
||||
domainCount, err := c.state.DB.CountInstanceDomains(ctx, i.Domain)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV1Instance: db error getting counting instance domains: %w", err)
|
||||
}
|
||||
|
|
@ -830,14 +856,14 @@ func (c *converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
instance.Stats = stats
|
||||
|
||||
// thumbnail
|
||||
iAccount, err := c.db.GetInstanceAccount(ctx, "")
|
||||
iAccount, err := c.state.DB.GetInstanceAccount(ctx, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV1Instance: db error getting instance account: %w", err)
|
||||
}
|
||||
|
||||
if iAccount.AvatarMediaAttachmentID != "" {
|
||||
if iAccount.AvatarMediaAttachment == nil {
|
||||
avi, err := c.db.GetAttachmentByID(ctx, iAccount.AvatarMediaAttachmentID)
|
||||
avi, err := c.state.DB.GetAttachmentByID(ctx, iAccount.AvatarMediaAttachmentID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIInstance: error getting instance avatar attachment with id %s: %w", iAccount.AvatarMediaAttachmentID, err)
|
||||
}
|
||||
|
|
@ -854,7 +880,7 @@ func (c *converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
// contact account
|
||||
if i.ContactAccountID != "" {
|
||||
if i.ContactAccount == nil {
|
||||
contactAccount, err := c.db.GetAccountByID(ctx, i.ContactAccountID)
|
||||
contactAccount, err := c.state.DB.GetAccountByID(ctx, i.ContactAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV1Instance: db error getting instance contact account %s: %w", i.ContactAccountID, err)
|
||||
}
|
||||
|
|
@ -871,7 +897,8 @@ func (c *converter) InstanceToAPIV1Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
return instance, nil
|
||||
}
|
||||
|
||||
func (c *converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV2, error) {
|
||||
// InstanceToAPIV2Instance converts a gts instance into its api equivalent for serving at /api/v2/instance
|
||||
func (c *Converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Instance) (*apimodel.InstanceV2, error) {
|
||||
instance := &apimodel.InstanceV2{
|
||||
Domain: i.Domain,
|
||||
AccountDomain: config.GetAccountDomain(),
|
||||
|
|
@ -891,14 +918,14 @@ func (c *converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
// thumbnail
|
||||
thumbnail := apimodel.InstanceV2Thumbnail{}
|
||||
|
||||
iAccount, err := c.db.GetInstanceAccount(ctx, "")
|
||||
iAccount, err := c.state.DB.GetInstanceAccount(ctx, "")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV2Instance: db error getting instance account: %w", err)
|
||||
}
|
||||
|
||||
if iAccount.AvatarMediaAttachmentID != "" {
|
||||
if iAccount.AvatarMediaAttachment == nil {
|
||||
avi, err := c.db.GetAttachmentByID(ctx, iAccount.AvatarMediaAttachmentID)
|
||||
avi, err := c.state.DB.GetAttachmentByID(ctx, iAccount.AvatarMediaAttachmentID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV2Instance: error getting instance avatar attachment with id %s: %w", iAccount.AvatarMediaAttachmentID, err)
|
||||
}
|
||||
|
|
@ -945,7 +972,7 @@ func (c *converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
instance.Contact.Email = i.ContactEmail
|
||||
if i.ContactAccountID != "" {
|
||||
if i.ContactAccount == nil {
|
||||
contactAccount, err := c.db.GetAccountByID(ctx, i.ContactAccountID)
|
||||
contactAccount, err := c.state.DB.GetAccountByID(ctx, i.ContactAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("InstanceToAPIV2Instance: db error getting instance contact account %s: %w", i.ContactAccountID, err)
|
||||
}
|
||||
|
|
@ -962,7 +989,8 @@ func (c *converter) InstanceToAPIV2Instance(ctx context.Context, i *gtsmodel.Ins
|
|||
return instance, nil
|
||||
}
|
||||
|
||||
func (c *converter) RelationshipToAPIRelationship(ctx context.Context, r *gtsmodel.Relationship) (*apimodel.Relationship, error) {
|
||||
// RelationshipToAPIRelationship converts a gts relationship into its api equivalent for serving in various places
|
||||
func (c *Converter) RelationshipToAPIRelationship(ctx context.Context, r *gtsmodel.Relationship) (*apimodel.Relationship, error) {
|
||||
return &apimodel.Relationship{
|
||||
ID: r.ID,
|
||||
Following: r.Following,
|
||||
|
|
@ -980,9 +1008,10 @@ func (c *converter) RelationshipToAPIRelationship(ctx context.Context, r *gtsmod
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) NotificationToAPINotification(ctx context.Context, n *gtsmodel.Notification) (*apimodel.Notification, error) {
|
||||
// NotificationToAPINotification converts a gts notification into a api notification
|
||||
func (c *Converter) NotificationToAPINotification(ctx context.Context, n *gtsmodel.Notification) (*apimodel.Notification, error) {
|
||||
if n.TargetAccount == nil {
|
||||
tAccount, err := c.db.GetAccountByID(ctx, n.TargetAccountID)
|
||||
tAccount, err := c.state.DB.GetAccountByID(ctx, n.TargetAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NotificationToapi: error getting target account with id %s from the db: %s", n.TargetAccountID, err)
|
||||
}
|
||||
|
|
@ -990,7 +1019,7 @@ func (c *converter) NotificationToAPINotification(ctx context.Context, n *gtsmod
|
|||
}
|
||||
|
||||
if n.OriginAccount == nil {
|
||||
ogAccount, err := c.db.GetAccountByID(ctx, n.OriginAccountID)
|
||||
ogAccount, err := c.state.DB.GetAccountByID(ctx, n.OriginAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NotificationToapi: error getting origin account with id %s from the db: %s", n.OriginAccountID, err)
|
||||
}
|
||||
|
|
@ -1005,7 +1034,7 @@ func (c *converter) NotificationToAPINotification(ctx context.Context, n *gtsmod
|
|||
var apiStatus *apimodel.Status
|
||||
if n.StatusID != "" {
|
||||
if n.Status == nil {
|
||||
status, err := c.db.GetStatusByID(ctx, n.StatusID)
|
||||
status, err := c.state.DB.GetStatusByID(ctx, n.StatusID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("NotificationToapi: error getting status with id %s from the db: %s", n.StatusID, err)
|
||||
}
|
||||
|
|
@ -1041,7 +1070,8 @@ func (c *converter) NotificationToAPINotification(ctx context.Context, n *gtsmod
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) DomainPermToAPIDomainPerm(
|
||||
// DomainPermToAPIDomainPerm converts a gts model domin block or allow into an api domain permission.
|
||||
func (c *Converter) DomainPermToAPIDomainPerm(
|
||||
ctx context.Context,
|
||||
d gtsmodel.DomainPermission,
|
||||
export bool,
|
||||
|
|
@ -1076,7 +1106,8 @@ func (c *converter) DomainPermToAPIDomainPerm(
|
|||
return domainPerm, nil
|
||||
}
|
||||
|
||||
func (c *converter) ReportToAPIReport(ctx context.Context, r *gtsmodel.Report) (*apimodel.Report, error) {
|
||||
// ReportToAPIReport converts a gts model report into an api model report, for serving at /api/v1/reports
|
||||
func (c *Converter) ReportToAPIReport(ctx context.Context, r *gtsmodel.Report) (*apimodel.Report, error) {
|
||||
report := &apimodel.Report{
|
||||
ID: r.ID,
|
||||
CreatedAt: util.FormatISO8601(r.CreatedAt),
|
||||
|
|
@ -1098,7 +1129,7 @@ func (c *converter) ReportToAPIReport(ctx context.Context, r *gtsmodel.Report) (
|
|||
}
|
||||
|
||||
if r.TargetAccount == nil {
|
||||
tAccount, err := c.db.GetAccountByID(ctx, r.TargetAccountID)
|
||||
tAccount, err := c.state.DB.GetAccountByID(ctx, r.TargetAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReportToAPIReport: error getting target account with id %s from the db: %s", r.TargetAccountID, err)
|
||||
}
|
||||
|
|
@ -1114,7 +1145,8 @@ func (c *converter) ReportToAPIReport(ctx context.Context, r *gtsmodel.Report) (
|
|||
return report, nil
|
||||
}
|
||||
|
||||
func (c *converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Report, requestingAccount *gtsmodel.Account) (*apimodel.AdminReport, error) {
|
||||
// ReportToAdminAPIReport converts a gts model report into an admin view report, for serving at /api/v1/admin/reports
|
||||
func (c *Converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Report, requestingAccount *gtsmodel.Account) (*apimodel.AdminReport, error) {
|
||||
var (
|
||||
err error
|
||||
actionTakenAt *string
|
||||
|
|
@ -1128,7 +1160,7 @@ func (c *converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Repo
|
|||
}
|
||||
|
||||
if r.Account == nil {
|
||||
r.Account, err = c.db.GetAccountByID(ctx, r.AccountID)
|
||||
r.Account, err = c.state.DB.GetAccountByID(ctx, r.AccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReportToAdminAPIReport: error getting account with id %s from the db: %w", r.AccountID, err)
|
||||
}
|
||||
|
|
@ -1139,7 +1171,7 @@ func (c *converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Repo
|
|||
}
|
||||
|
||||
if r.TargetAccount == nil {
|
||||
r.TargetAccount, err = c.db.GetAccountByID(ctx, r.TargetAccountID)
|
||||
r.TargetAccount, err = c.state.DB.GetAccountByID(ctx, r.TargetAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReportToAdminAPIReport: error getting target account with id %s from the db: %w", r.TargetAccountID, err)
|
||||
}
|
||||
|
|
@ -1151,7 +1183,7 @@ func (c *converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Repo
|
|||
|
||||
if r.ActionTakenByAccountID != "" {
|
||||
if r.ActionTakenByAccount == nil {
|
||||
r.ActionTakenByAccount, err = c.db.GetAccountByID(ctx, r.ActionTakenByAccountID)
|
||||
r.ActionTakenByAccount, err = c.state.DB.GetAccountByID(ctx, r.ActionTakenByAccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReportToAdminAPIReport: error getting action taken by account with id %s from the db: %w", r.ActionTakenByAccountID, err)
|
||||
}
|
||||
|
|
@ -1165,7 +1197,7 @@ func (c *converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Repo
|
|||
|
||||
statuses := make([]*apimodel.Status, 0, len(r.StatusIDs))
|
||||
if len(r.StatusIDs) != 0 && len(r.Statuses) == 0 {
|
||||
r.Statuses, err = c.db.GetStatusesByIDs(ctx, r.StatusIDs)
|
||||
r.Statuses, err = c.state.DB.GetStatusesByIDs(ctx, r.StatusIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReportToAdminAPIReport: error getting statuses from the db: %w", err)
|
||||
}
|
||||
|
|
@ -1180,7 +1212,7 @@ func (c *converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Repo
|
|||
|
||||
rules := make([]*apimodel.InstanceRule, 0, len(r.RuleIDs))
|
||||
if len(r.RuleIDs) != 0 && len(r.Rules) == 0 {
|
||||
r.Rules, err = c.db.GetRulesByIDs(ctx, r.RuleIDs)
|
||||
r.Rules, err = c.state.DB.GetRulesByIDs(ctx, r.RuleIDs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ReportToAdminAPIReport: error getting rules from the db: %w", err)
|
||||
}
|
||||
|
|
@ -1215,7 +1247,8 @@ func (c *converter) ReportToAdminAPIReport(ctx context.Context, r *gtsmodel.Repo
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) ListToAPIList(ctx context.Context, l *gtsmodel.List) (*apimodel.List, error) {
|
||||
// ListToAPIList converts one gts model list into an api model list, for serving at /api/v1/lists/{id}
|
||||
func (c *Converter) ListToAPIList(ctx context.Context, l *gtsmodel.List) (*apimodel.List, error) {
|
||||
return &apimodel.List{
|
||||
ID: l.ID,
|
||||
Title: l.Title,
|
||||
|
|
@ -1223,7 +1256,8 @@ func (c *converter) ListToAPIList(ctx context.Context, l *gtsmodel.List) (*apimo
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (c *converter) MarkersToAPIMarker(ctx context.Context, markers []*gtsmodel.Marker) (*apimodel.Marker, error) {
|
||||
// MarkersToAPIMarker converts several gts model markers into an api marker, for serving at /api/v1/markers
|
||||
func (c *Converter) MarkersToAPIMarker(ctx context.Context, markers []*gtsmodel.Marker) (*apimodel.Marker, error) {
|
||||
apiMarker := &apimodel.Marker{}
|
||||
for _, marker := range markers {
|
||||
apiTimelineMarker := &apimodel.TimelineMarker{
|
||||
|
|
@ -1244,7 +1278,7 @@ func (c *converter) MarkersToAPIMarker(ctx context.Context, markers []*gtsmodel.
|
|||
}
|
||||
|
||||
// convertAttachmentsToAPIAttachments will convert a slice of GTS model attachments to frontend API model attachments, falling back to IDs if no GTS models supplied.
|
||||
func (c *converter) convertAttachmentsToAPIAttachments(ctx context.Context, attachments []*gtsmodel.MediaAttachment, attachmentIDs []string) ([]apimodel.Attachment, error) {
|
||||
func (c *Converter) convertAttachmentsToAPIAttachments(ctx context.Context, attachments []*gtsmodel.MediaAttachment, attachmentIDs []string) ([]apimodel.Attachment, error) {
|
||||
var errs gtserror.MultiError
|
||||
|
||||
if len(attachments) == 0 {
|
||||
|
|
@ -1255,7 +1289,7 @@ func (c *converter) convertAttachmentsToAPIAttachments(ctx context.Context, atta
|
|||
|
||||
// Fetch GTS models for attachment IDs
|
||||
for _, id := range attachmentIDs {
|
||||
attachment, err := c.db.GetAttachmentByID(ctx, id)
|
||||
attachment, err := c.state.DB.GetAttachmentByID(ctx, id)
|
||||
if err != nil {
|
||||
errs.Appendf("error fetching attachment %s from database: %v", id, err)
|
||||
continue
|
||||
|
|
@ -1281,7 +1315,7 @@ func (c *converter) convertAttachmentsToAPIAttachments(ctx context.Context, atta
|
|||
}
|
||||
|
||||
// convertEmojisToAPIEmojis will convert a slice of GTS model emojis to frontend API model emojis, falling back to IDs if no GTS models supplied.
|
||||
func (c *converter) convertEmojisToAPIEmojis(ctx context.Context, emojis []*gtsmodel.Emoji, emojiIDs []string) ([]apimodel.Emoji, error) {
|
||||
func (c *Converter) convertEmojisToAPIEmojis(ctx context.Context, emojis []*gtsmodel.Emoji, emojiIDs []string) ([]apimodel.Emoji, error) {
|
||||
var errs gtserror.MultiError
|
||||
|
||||
if len(emojis) == 0 {
|
||||
|
|
@ -1292,7 +1326,7 @@ func (c *converter) convertEmojisToAPIEmojis(ctx context.Context, emojis []*gtsm
|
|||
|
||||
// Fetch GTS models for emoji IDs
|
||||
for _, id := range emojiIDs {
|
||||
emoji, err := c.db.GetEmojiByID(ctx, id)
|
||||
emoji, err := c.state.DB.GetEmojiByID(ctx, id)
|
||||
if err != nil {
|
||||
errs.Appendf("error fetching emoji %s from database: %v", id, err)
|
||||
continue
|
||||
|
|
@ -1318,7 +1352,7 @@ func (c *converter) convertEmojisToAPIEmojis(ctx context.Context, emojis []*gtsm
|
|||
}
|
||||
|
||||
// convertMentionsToAPIMentions will convert a slice of GTS model mentions to frontend API model mentions, falling back to IDs if no GTS models supplied.
|
||||
func (c *converter) convertMentionsToAPIMentions(ctx context.Context, mentions []*gtsmodel.Mention, mentionIDs []string) ([]apimodel.Mention, error) {
|
||||
func (c *Converter) convertMentionsToAPIMentions(ctx context.Context, mentions []*gtsmodel.Mention, mentionIDs []string) ([]apimodel.Mention, error) {
|
||||
var errs gtserror.MultiError
|
||||
|
||||
if len(mentions) == 0 {
|
||||
|
|
@ -1327,7 +1361,7 @@ func (c *converter) convertMentionsToAPIMentions(ctx context.Context, mentions [
|
|||
// GTS model mentions were not populated
|
||||
//
|
||||
// Fetch GTS models for mention IDs
|
||||
mentions, err = c.db.GetMentions(ctx, mentionIDs)
|
||||
mentions, err = c.state.DB.GetMentions(ctx, mentionIDs)
|
||||
if err != nil {
|
||||
errs.Appendf("error fetching mentions from database: %v", err)
|
||||
}
|
||||
|
|
@ -1350,13 +1384,13 @@ func (c *converter) convertMentionsToAPIMentions(ctx context.Context, mentions [
|
|||
}
|
||||
|
||||
// convertTagsToAPITags will convert a slice of GTS model tags to frontend API model tags, falling back to IDs if no GTS models supplied.
|
||||
func (c *converter) convertTagsToAPITags(ctx context.Context, tags []*gtsmodel.Tag, tagIDs []string) ([]apimodel.Tag, error) {
|
||||
func (c *Converter) convertTagsToAPITags(ctx context.Context, tags []*gtsmodel.Tag, tagIDs []string) ([]apimodel.Tag, error) {
|
||||
var errs gtserror.MultiError
|
||||
|
||||
if len(tags) == 0 {
|
||||
var err error
|
||||
|
||||
tags, err = c.db.GetTags(ctx, tagIDs)
|
||||
tags, err = c.state.DB.GetTags(ctx, tagIDs)
|
||||
if err != nil {
|
||||
errs.Appendf("error fetching tags from database: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ const (
|
|||
rssDescriptionMaxRunes = 256
|
||||
)
|
||||
|
||||
func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*feeds.Item, error) {
|
||||
func (c *Converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*feeds.Item, error) {
|
||||
// see https://cyber.harvard.edu/rss/rss.html
|
||||
|
||||
// Title -- The title of the item.
|
||||
|
|
@ -57,7 +57,7 @@ func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*f
|
|||
// Author -- Email address of the author of the item.
|
||||
// example: oprah\@oxygen.net
|
||||
if s.Account == nil {
|
||||
a, err := c.db.GetAccountByID(ctx, s.AccountID)
|
||||
a, err := c.state.DB.GetAccountByID(ctx, s.AccountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting status author: %s", err)
|
||||
}
|
||||
|
|
@ -110,7 +110,7 @@ func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*f
|
|||
if len(s.Attachments) > 0 {
|
||||
attachment = s.Attachments[0]
|
||||
} else if len(s.AttachmentIDs) > 0 {
|
||||
a, err := c.db.GetAttachmentByID(ctx, s.AttachmentIDs[0])
|
||||
a, err := c.state.DB.GetAttachmentByID(ctx, s.AttachmentIDs[0])
|
||||
if err == nil {
|
||||
attachment = a
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ func (c *converter) StatusToRSSItem(ctx context.Context, s *gtsmodel.Status) (*f
|
|||
} else {
|
||||
for _, e := range s.EmojiIDs {
|
||||
gtsEmoji := >smodel.Emoji{}
|
||||
if err := c.db.GetByID(ctx, e, gtsEmoji); err != nil {
|
||||
if err := c.state.DB.GetByID(ctx, e, gtsEmoji); err != nil {
|
||||
log.Errorf(ctx, "error getting emoji with id %s: %s", e, err)
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,29 +36,29 @@ type statusInteractions struct {
|
|||
Pinned bool
|
||||
}
|
||||
|
||||
func (c *converter) interactionsWithStatusForAccount(ctx context.Context, s *gtsmodel.Status, requestingAccount *gtsmodel.Account) (*statusInteractions, error) {
|
||||
func (c *Converter) interactionsWithStatusForAccount(ctx context.Context, s *gtsmodel.Status, requestingAccount *gtsmodel.Account) (*statusInteractions, error) {
|
||||
si := &statusInteractions{}
|
||||
|
||||
if requestingAccount != nil {
|
||||
faved, err := c.db.IsStatusFavedBy(ctx, s.ID, requestingAccount.ID)
|
||||
faved, err := c.state.DB.IsStatusFavedBy(ctx, s.ID, requestingAccount.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error checking if requesting account has faved status: %s", err)
|
||||
}
|
||||
si.Faved = faved
|
||||
|
||||
reblogged, err := c.db.IsStatusBoostedBy(ctx, s.ID, requestingAccount.ID)
|
||||
reblogged, err := c.state.DB.IsStatusBoostedBy(ctx, s.ID, requestingAccount.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error checking if requesting account has reblogged status: %s", err)
|
||||
}
|
||||
si.Reblogged = reblogged
|
||||
|
||||
muted, err := c.db.IsStatusMutedBy(ctx, s, requestingAccount.ID)
|
||||
muted, err := c.state.DB.IsStatusMutedBy(ctx, s, requestingAccount.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error checking if requesting account has muted status: %s", err)
|
||||
}
|
||||
si.Muted = muted
|
||||
|
||||
bookmarked, err := c.db.IsStatusBookmarkedBy(ctx, s, requestingAccount.ID)
|
||||
bookmarked, err := c.state.DB.IsStatusBookmarkedBy(ctx, s, requestingAccount.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error checking if requesting account has bookmarked status: %s", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/uris"
|
||||
)
|
||||
|
||||
func (c *converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, originAccount *gtsmodel.Account) (vocab.ActivityStreamsUpdate, error) {
|
||||
// WrapPersonInUpdate ...
|
||||
func (c *Converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, originAccount *gtsmodel.Account) (vocab.ActivityStreamsUpdate, error) {
|
||||
update := streams.NewActivityStreamsUpdate()
|
||||
|
||||
// set the actor
|
||||
|
|
@ -84,7 +85,12 @@ func (c *converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, origi
|
|||
return update, nil
|
||||
}
|
||||
|
||||
func (c *converter) WrapNoteInCreate(note vocab.ActivityStreamsNote, objectIRIOnly bool) (vocab.ActivityStreamsCreate, error) {
|
||||
// WrapNoteInCreate wraps a Note 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) WrapNoteInCreate(note vocab.ActivityStreamsNote, objectIRIOnly bool) (vocab.ActivityStreamsCreate, error) {
|
||||
create := streams.NewActivityStreamsCreate()
|
||||
|
||||
// Object property
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue