mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 00:22:26 -05:00 
			
		
		
		
	some updates to statuses and accounts
This commit is contained in:
		
					parent
					
						
							
								30718d7d10
							
						
					
				
			
			
				commit
				
					
						0b8b0948f6
					
				
			
		
					 11 changed files with 251 additions and 132 deletions
				
			
		|  | @ -32,6 +32,8 @@ import ( | |||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	// LimitKey is for setting the return amount limit for eg., requesting an account's statuses | ||||
| 	LimitKey = "limit" | ||||
| 	// IDKey is the key to use for retrieving account ID in requests | ||||
| 	IDKey = "id" | ||||
| 	// BasePath is the base API path for this module | ||||
|  | @ -42,6 +44,8 @@ const ( | |||
| 	VerifyPath = BasePath + "/verify_credentials" | ||||
| 	// UpdateCredentialsPath is for updating account credentials | ||||
| 	UpdateCredentialsPath = BasePath + "/update_credentials" | ||||
| 	// GetStatusesPath is for showing an account's statuses | ||||
| 	GetStatusesPath = BasePathWithID + "/statuses" | ||||
| ) | ||||
| 
 | ||||
| // Module implements the ClientAPIModule interface for account-related actions | ||||
|  | @ -65,6 +69,7 @@ func (m *Module) Route(r router.Router) error { | |||
| 	r.AttachHandler(http.MethodPost, BasePath, m.AccountCreatePOSTHandler) | ||||
| 	r.AttachHandler(http.MethodGet, BasePathWithID, m.muxHandler) | ||||
| 	r.AttachHandler(http.MethodPatch, BasePathWithID, m.muxHandler) | ||||
| 	r.AttachHandler(http.MethodGet, GetStatusesPath, m.AccountStatusesGETHandler) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										61
									
								
								internal/api/client/account/statuses.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								internal/api/client/account/statuses.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,61 @@ | |||
| /* | ||||
|    GoToSocial | ||||
|    Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org | ||||
| 
 | ||||
|    This program is free software: you can redistribute it and/or modify | ||||
|    it under the terms of the GNU Affero General Public License as published by | ||||
|    the Free Software Foundation, either version 3 of the License, or | ||||
|    (at your option) any later version. | ||||
| 
 | ||||
|    This program is distributed in the hope that it will be useful, | ||||
|    but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|    GNU Affero General Public License for more details. | ||||
| 
 | ||||
|    You should have received a copy of the GNU Affero General Public License | ||||
|    along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
| */ | ||||
| 
 | ||||
| package account | ||||
| 
 | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"github.com/gin-gonic/gin" | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/oauth" | ||||
| ) | ||||
| 
 | ||||
| // AccountStatusesGETHandler serves the statuses of the requested account, if they're visible to the requester. | ||||
| func (m *Module) AccountStatusesGETHandler(c *gin.Context) { | ||||
| 	authed, err := oauth.Authed(c, false, false, false, false) | ||||
| 	if err != nil { | ||||
| 		c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"}) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	targetAcctID := c.Param(IDKey) | ||||
| 	if targetAcctID == "" { | ||||
| 		c.JSON(http.StatusBadRequest, gin.H{"error": "no account id specified"}) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	limit := 30 | ||||
| 	limitString := c.Query(LimitKey) | ||||
| 	if limitString != "" { | ||||
| 		l, err := strconv.ParseInt(limitString, 10, 64) | ||||
| 		if err != nil { | ||||
| 			c.JSON(http.StatusBadRequest, gin.H{"error": "couldn't parse limit query param"}) | ||||
| 			return | ||||
| 		} | ||||
| 		limit = int(l) | ||||
| 	} | ||||
| 
 | ||||
| 	statuses, errWithCode := m.processor.AccountStatusesGet(authed, targetAcctID, limit) | ||||
| 	if errWithCode != nil { | ||||
| 		c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()}) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	c.JSON(http.StatusOK, statuses) | ||||
| } | ||||
|  | @ -86,23 +86,23 @@ type Status struct { | |||
| // It should be used at the path https://mastodon.example/api/v1/statuses | ||||
| type StatusCreateRequest struct { | ||||
| 	// Text content of the status. If media_ids is provided, this becomes optional. Attaching a poll is optional while status is provided. | ||||
| 	Status string `form:"status"` | ||||
| 	Status string `form:"status" json:"status" xml:"status"` | ||||
| 	// Array of Attachment ids to be attached as media. If provided, status becomes optional, and poll cannot be used. | ||||
| 	MediaIDs []string `form:"media_ids" json:"media_ids" xml:"media_ids"` | ||||
| 	// Poll to include with this status. | ||||
| 	Poll *PollRequest `form:"poll"` | ||||
| 	Poll *PollRequest `form:"poll" json:"poll" xml:"poll"` | ||||
| 	// ID of the status being replied to, if status is a reply | ||||
| 	InReplyToID string `form:"in_reply_to_id"` | ||||
| 	InReplyToID string `form:"in_reply_to_id" json:"in_reply_to_id" xml:"in_reply_to_id"` | ||||
| 	// Mark status and attached media as sensitive? | ||||
| 	Sensitive bool `form:"sensitive"` | ||||
| 	Sensitive bool `form:"sensitive" json:"sensitive" xml:"sensitive"` | ||||
| 	// Text to be shown as a warning or subject before the actual content. Statuses are generally collapsed behind this field. | ||||
| 	SpoilerText string `form:"spoiler_text"` | ||||
| 	SpoilerText string `form:"spoiler_text" json:"spoiler_text" xml:"spoiler_text"` | ||||
| 	// Visibility of the posted status. Enumerable oneOf public, unlisted, private, direct. | ||||
| 	Visibility Visibility `form:"visibility"` | ||||
| 	Visibility Visibility `form:"visibility" json:"visibility" xml:"visibility"` | ||||
| 	// ISO 8601 Datetime at which to schedule a status. Providing this paramter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future. | ||||
| 	ScheduledAt string `form:"scheduled_at"` | ||||
| 	ScheduledAt string `form:"scheduled_at" json:"scheduled_at" xml:"scheduled_at"` | ||||
| 	// ISO 639 language code for this status. | ||||
| 	Language string `form:"language"` | ||||
| 	Language string `form:"language" json:"language" xml:"language"` | ||||
| } | ||||
| 
 | ||||
| // Visibility denotes the visibility of this status to other users | ||||
|  | @ -130,13 +130,13 @@ type AdvancedStatusCreateForm struct { | |||
| // to the standard mastodon-compatible ones. | ||||
| type AdvancedVisibilityFlagsForm struct { | ||||
| 	// The gotosocial visibility model | ||||
| 	VisibilityAdvanced *string `form:"visibility_advanced"` | ||||
| 	VisibilityAdvanced *string `form:"visibility_advanced" json:"visibility_advanced" xml:"visibility_advanced"` | ||||
| 	// This status will be federated beyond the local timeline(s) | ||||
| 	Federated *bool `form:"federated"` | ||||
| 	Federated *bool `form:"federated" json:"federated" xml:"federated"` | ||||
| 	// This status can be boosted/reblogged | ||||
| 	Boostable *bool `form:"boostable"` | ||||
| 	Boostable *bool `form:"boostable" json:"boostable" xml:"boostable"` | ||||
| 	// This status can be replied to | ||||
| 	Replyable *bool `form:"replyable"` | ||||
| 	Replyable *bool `form:"replyable" json:"replyable" xml:"replyable"` | ||||
| 	// This status can be liked/faved | ||||
| 	Likeable *bool `form:"likeable"` | ||||
| 	Likeable *bool `form:"likeable" json:"likeable" xml:"likeable"` | ||||
| } | ||||
|  |  | |||
|  | @ -364,7 +364,7 @@ func (f *federatingDB) Get(c context.Context, id *url.URL) (value vocab.Type, er | |||
| // | ||||
| // Under certain conditions and network activities, Create may be called | ||||
| // multiple times for the same ActivityStreams object. | ||||
| func (f *federatingDB) Create(c context.Context, asType vocab.Type) error { | ||||
| func (f *federatingDB) Create(ctx context.Context, asType vocab.Type) error { | ||||
| 	l := f.log.WithFields( | ||||
| 		logrus.Fields{ | ||||
| 			"func":   "Create", | ||||
|  | @ -373,6 +373,24 @@ func (f *federatingDB) Create(c context.Context, asType vocab.Type) error { | |||
| 	) | ||||
| 	l.Debugf("received CREATE asType %+v", asType) | ||||
| 
 | ||||
| 	targetAcctI := ctx.Value(util.APAccount) | ||||
| 	if targetAcctI == nil { | ||||
| 		l.Error("target account wasn't set on context") | ||||
| 	} | ||||
| 	targetAcct, ok := targetAcctI.(*gtsmodel.Account) | ||||
| 	if !ok { | ||||
| 		l.Error("target account was set on context but couldn't be parsed") | ||||
| 	} | ||||
| 
 | ||||
| 	fromFederatorChanI := ctx.Value(util.APFromFederatorChanKey) | ||||
| 	if fromFederatorChanI == nil { | ||||
| 		l.Error("from federator channel wasn't set on context") | ||||
| 	} | ||||
| 	fromFederatorChan, ok := fromFederatorChanI.(chan gtsmodel.FromFederator) | ||||
| 	if !ok { | ||||
| 		l.Error("from federator channel was set on context but couldn't be parsed") | ||||
| 	} | ||||
| 
 | ||||
| 	switch gtsmodel.ActivityStreamsActivity(asType.GetTypeName()) { | ||||
| 	case gtsmodel.ActivityStreamsCreate: | ||||
| 		create, ok := asType.(vocab.ActivityStreamsCreate) | ||||
|  | @ -391,6 +409,12 @@ func (f *federatingDB) Create(c context.Context, asType vocab.Type) error { | |||
| 				if err := f.db.Put(status); err != nil { | ||||
| 					return fmt.Errorf("database error inserting status: %s", err) | ||||
| 				} | ||||
| 
 | ||||
| 				fromFederatorChan <- gtsmodel.FromFederator{ | ||||
| 					APObjectType: gtsmodel.ActivityStreamsNote, | ||||
| 					APActivityType: gtsmodel.ActivityStreamsCreate, | ||||
| 					Activity: status, | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	case gtsmodel.ActivityStreamsFollow: | ||||
|  | @ -407,6 +431,12 @@ func (f *federatingDB) Create(c context.Context, asType vocab.Type) error { | |||
| 		if err := f.db.Put(followRequest); err != nil { | ||||
| 			return fmt.Errorf("database error inserting follow request: %s", err) | ||||
| 		} | ||||
| 
 | ||||
| 		if !targetAcct.Locked { | ||||
| 			if err := f.db.AcceptFollowRequest(followRequest.AccountID, followRequest.TargetAccountID); err != nil { | ||||
| 				return fmt.Errorf("database error accepting follow request: %s", err) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  |  | |||
|  | @ -71,49 +71,7 @@ func (f *federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Reques | |||
| 		l.Debug(err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// derefence the actor of the activity already | ||||
| 	// var requestingActorIRI *url.URL | ||||
| 	// actorProp := activity.GetActivityStreamsActor() | ||||
| 	// if actorProp != nil { | ||||
| 	// 	for i := actorProp.Begin(); i != actorProp.End(); i = i.Next() { | ||||
| 	// 		if i.IsIRI() { | ||||
| 	// 			requestingActorIRI = i.GetIRI() | ||||
| 	// 			break | ||||
| 	// 		} | ||||
| 	// 	} | ||||
| 	// } | ||||
| 	// if requestingActorIRI != nil { | ||||
| 
 | ||||
| 	// 	requestedAccountI := ctx.Value(util.APAccount) | ||||
| 	// 	requestedAccount, ok := requestedAccountI.(*gtsmodel.Account) | ||||
| 	// 	if !ok { | ||||
| 	// 		return nil, errors.New("requested account was not set on request context") | ||||
| 	// 	} | ||||
| 
 | ||||
| 	// 	requestingActor := >smodel.Account{} | ||||
| 	// 	if err := f.db.GetWhere("uri", requestingActorIRI.String(), requestingActor); err != nil { | ||||
| 	// 		// there's been a proper error so return it | ||||
| 	// 		if _, ok := err.(db.ErrNoEntries); !ok { | ||||
| 	// 			return nil, fmt.Errorf("error getting requesting actor with id %s: %s", requestingActorIRI.String(), err) | ||||
| 	// 		} | ||||
| 
 | ||||
| 	// 		// we don't know this account (yet) so let's dereference it right now | ||||
| 	// 		person, err := f.DereferenceRemoteAccount(requestedAccount.Username, publicKeyOwnerURI) | ||||
| 	// 		if err != nil { | ||||
| 	// 			return ctx, false, fmt.Errorf("error dereferencing account with public key id %s: %s", publicKeyOwnerURI.String(), err) | ||||
| 	// 		} | ||||
| 
 | ||||
| 	// 		a, err := f.typeConverter.ASRepresentationToAccount(person) | ||||
| 	// 		if err != nil { | ||||
| 	// 			return ctx, false, fmt.Errorf("error converting person with public key id %s to account: %s", publicKeyOwnerURI.String(), err) | ||||
| 	// 		} | ||||
| 	// 		requestingAccount = a | ||||
| 	// 	} | ||||
| 	// } | ||||
| 
 | ||||
| 	// set the activity on the context for use later on | ||||
| 
 | ||||
| 	return context.WithValue(ctx, util.APActivity, activity), nil | ||||
| } | ||||
| 
 | ||||
|  | @ -285,14 +243,6 @@ func (f *federator) FederatingCallbacks(ctx context.Context) (wrapped pub.Federa | |||
| 	} | ||||
| 
 | ||||
| 	wrapped = pub.FederatingWrappedCallbacks{ | ||||
| 		// Follow handles additional side effects for the Follow ActivityStreams | ||||
| 		// type, specific to the application using go-fed. | ||||
| 		// | ||||
| 		// The wrapping function can have one of several default behaviors, | ||||
| 		// depending on the value of the OnFollow setting. | ||||
| 		Follow: func(context.Context, vocab.ActivityStreamsFollow) error { | ||||
| 			return nil | ||||
| 		}, | ||||
| 		// OnFollow determines what action to take for this particular callback | ||||
| 		// if a Follow Activity is handled. | ||||
| 		OnFollow: onFollow, | ||||
|  |  | |||
							
								
								
									
										29
									
								
								internal/gtsmodel/messages.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								internal/gtsmodel/messages.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| package gtsmodel | ||||
| 
 | ||||
| // ToClientAPI wraps a message that travels from the processor into the client API | ||||
| type ToClientAPI struct { | ||||
| 	APObjectType   ActivityStreamsObject | ||||
| 	APActivityType ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| } | ||||
| 
 | ||||
| // FromClientAPI wraps a message that travels from client API into the processor | ||||
| type FromClientAPI struct { | ||||
| 	APObjectType   ActivityStreamsObject | ||||
| 	APActivityType ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| } | ||||
| 
 | ||||
| // ToFederator wraps a message that travels from the processor into the federator | ||||
| type ToFederator struct { | ||||
| 	APObjectType   ActivityStreamsObject | ||||
| 	APActivityType ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| } | ||||
| 
 | ||||
| // FromFederator wraps a message that travels from the federator into the processor | ||||
| type FromFederator struct { | ||||
| 	APObjectType   ActivityStreamsObject | ||||
| 	APActivityType ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| } | ||||
|  | @ -166,3 +166,67 @@ func (p *processor) AccountUpdate(authed *oauth.Auth, form *apimodel.UpdateCrede | |||
| 	} | ||||
| 	return acctSensitive, nil | ||||
| } | ||||
| 
 | ||||
| func (p *processor) AccountStatusesGet(authed *oauth.Auth, targetAccountID string, limit int) ([]apimodel.Status, ErrorWithCode) { | ||||
| 	targetAccount := >smodel.Account{} | ||||
| 	if err := p.db.GetByID(targetAccountID, targetAccount); err != nil { | ||||
| 		if _, ok := err.(db.ErrNoEntries); ok { | ||||
| 			return nil, NewErrorNotFound(fmt.Errorf("no entry found for account id %s", targetAccountID)) | ||||
| 		} | ||||
| 		return nil, NewErrorInternalError(err) | ||||
| 	} | ||||
| 
 | ||||
| 	statuses := []gtsmodel.Status{} | ||||
| 	apiStatuses := []apimodel.Status{} | ||||
| 	if err := p.db.GetStatusesByTimeDescending(targetAccountID, &statuses, limit); err != nil { | ||||
| 		if _, ok := err.(db.ErrNoEntries); ok { | ||||
| 			return apiStatuses, nil | ||||
| 		} | ||||
| 		return nil, NewErrorInternalError(err) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, s := range statuses { | ||||
| 		relevantAccounts, err := p.db.PullRelevantAccountsFromStatus(&s) | ||||
| 		if err != nil { | ||||
| 			return nil, NewErrorInternalError(err) | ||||
| 		} | ||||
| 
 | ||||
| 		visible, err := p.db.StatusVisible(&s, targetAccount, authed.Account, relevantAccounts) | ||||
| 		if err != nil { | ||||
| 			return nil, NewErrorInternalError(err) | ||||
| 		} | ||||
| 		if !visible { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		var boostedStatus *gtsmodel.Status | ||||
| 		if s.BoostOfID != "" { | ||||
| 			bs := >smodel.Status{} | ||||
| 			if err := p.db.GetByID(s.BoostOfID, bs); err != nil { | ||||
| 				return nil, NewErrorInternalError(err) | ||||
| 			} | ||||
| 			boostedRelevantAccounts, err := p.db.PullRelevantAccountsFromStatus(bs) | ||||
| 			if err != nil { | ||||
| 				return nil, NewErrorInternalError(err) | ||||
| 			} | ||||
| 
 | ||||
| 			boostedVisible, err := p.db.StatusVisible(bs, relevantAccounts.BoostedAccount, authed.Account, boostedRelevantAccounts) | ||||
| 			if err != nil { | ||||
| 				return nil, NewErrorInternalError(err) | ||||
| 			} | ||||
| 
 | ||||
| 			if boostedVisible { | ||||
| 				boostedStatus = bs | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		apiStatus, err := p.tc.StatusToMasto(&s, targetAccount, authed.Account, relevantAccounts.BoostedAccount, relevantAccounts.ReplyToAccount, boostedStatus) | ||||
| 		if err != nil { | ||||
| 			return nil, NewErrorInternalError(err) | ||||
| 		} | ||||
| 
 | ||||
| 		apiStatuses = append(apiStatuses, *apiStatus) | ||||
| 	} | ||||
| 
 | ||||
| 	return apiStatuses, nil | ||||
| } | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ func (p *processor) authenticateAndDereferenceFediRequest(username string, r *ht | |||
| 	} | ||||
| 
 | ||||
| 	// put it in our channel to queue it for async processing | ||||
| 	p.FromFederator() <- FromFederator{ | ||||
| 	p.FromFederator() <- gtsmodel.FromFederator{ | ||||
| 		APObjectType:   gtsmodel.ActivityStreamsProfile, | ||||
| 		APActivityType: gtsmodel.ActivityStreamsCreate, | ||||
| 		Activity:       requestingAccount, | ||||
|  |  | |||
|  | @ -23,7 +23,6 @@ import ( | |||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| 
 | ||||
| 	"github.com/sirupsen/logrus" | ||||
| 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" | ||||
|  | @ -45,13 +44,13 @@ import ( | |||
| // for clean distribution of messages without slowing down the client API and harming the user experience. | ||||
| type Processor interface { | ||||
| 	// ToClientAPI returns a channel for putting in messages that need to go to the gts client API. | ||||
| 	ToClientAPI() chan ToClientAPI | ||||
| 	ToClientAPI() chan gtsmodel.ToClientAPI | ||||
| 	// FromClientAPI returns a channel for putting messages in that come from the client api going to the processor | ||||
| 	FromClientAPI() chan FromClientAPI | ||||
| 	FromClientAPI() chan gtsmodel.FromClientAPI | ||||
| 	// ToFederator returns a channel for putting in messages that need to go to the federator (activitypub). | ||||
| 	ToFederator() chan ToFederator | ||||
| 	ToFederator() chan gtsmodel.ToFederator | ||||
| 	// FromFederator returns a channel for putting messages in that come from the federator (activitypub) going into the processor | ||||
| 	FromFederator() chan FromFederator | ||||
| 	FromFederator() chan gtsmodel.FromFederator | ||||
| 	// Start starts the Processor, reading from its channels and passing messages back and forth. | ||||
| 	Start() error | ||||
| 	// Stop stops the processor cleanly, finishing handling any remaining messages before closing down. | ||||
|  | @ -71,6 +70,7 @@ type Processor interface { | |||
| 	AccountGet(authed *oauth.Auth, targetAccountID string) (*apimodel.Account, error) | ||||
| 	// AccountUpdate processes the update of an account with the given form | ||||
| 	AccountUpdate(authed *oauth.Auth, form *apimodel.UpdateCredentialsRequest) (*apimodel.Account, error) | ||||
| 	AccountStatusesGet(authed *oauth.Auth, targetAccountID string, limit int) ([]apimodel.Status, ErrorWithCode) | ||||
| 
 | ||||
| 	// AdminEmojiCreate handles the creation of a new instance emoji by an admin, using the given form. | ||||
| 	AdminEmojiCreate(authed *oauth.Auth, form *apimodel.EmojiCreateRequest) (*apimodel.Emoji, error) | ||||
|  | @ -142,10 +142,10 @@ type Processor interface { | |||
| // processor just implements the Processor interface | ||||
| type processor struct { | ||||
| 	// federator     pub.FederatingActor | ||||
| 	toClientAPI   chan ToClientAPI | ||||
| 	fromClientAPI chan FromClientAPI | ||||
| 	toFederator   chan ToFederator | ||||
| 	fromFederator chan FromFederator | ||||
| 	toClientAPI   chan gtsmodel.ToClientAPI | ||||
| 	fromClientAPI chan gtsmodel.FromClientAPI | ||||
| 	toFederator   chan gtsmodel.ToFederator | ||||
| 	fromFederator chan gtsmodel.FromFederator | ||||
| 	federator     federation.Federator | ||||
| 	stop          chan interface{} | ||||
| 	log           *logrus.Logger | ||||
|  | @ -160,10 +160,10 @@ type processor struct { | |||
| // NewProcessor returns a new Processor that uses the given federator and logger | ||||
| func NewProcessor(config *config.Config, tc typeutils.TypeConverter, federator federation.Federator, oauthServer oauth.Server, mediaHandler media.Handler, storage storage.Storage, db db.DB, log *logrus.Logger) Processor { | ||||
| 	return &processor{ | ||||
| 		toClientAPI:   make(chan ToClientAPI, 100), | ||||
| 		fromClientAPI: make(chan FromClientAPI, 100), | ||||
| 		toFederator:   make(chan ToFederator, 100), | ||||
| 		fromFederator: make(chan FromFederator, 100), | ||||
| 		toClientAPI:   make(chan gtsmodel.ToClientAPI, 100), | ||||
| 		fromClientAPI: make(chan gtsmodel.FromClientAPI, 100), | ||||
| 		toFederator:   make(chan gtsmodel.ToFederator, 100), | ||||
| 		fromFederator: make(chan gtsmodel.FromFederator, 100), | ||||
| 		federator:     federator, | ||||
| 		stop:          make(chan interface{}), | ||||
| 		log:           log, | ||||
|  | @ -176,19 +176,19 @@ func NewProcessor(config *config.Config, tc typeutils.TypeConverter, federator f | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (p *processor) ToClientAPI() chan ToClientAPI { | ||||
| func (p *processor) ToClientAPI() chan gtsmodel.ToClientAPI { | ||||
| 	return p.toClientAPI | ||||
| } | ||||
| 
 | ||||
| func (p *processor) FromClientAPI() chan FromClientAPI { | ||||
| func (p *processor) FromClientAPI() chan gtsmodel.FromClientAPI { | ||||
| 	return p.fromClientAPI | ||||
| } | ||||
| 
 | ||||
| func (p *processor) ToFederator() chan ToFederator { | ||||
| func (p *processor) ToFederator() chan gtsmodel.ToFederator { | ||||
| 	return p.toFederator | ||||
| } | ||||
| 
 | ||||
| func (p *processor) FromFederator() chan FromFederator { | ||||
| func (p *processor) FromFederator() chan gtsmodel.FromFederator { | ||||
| 	return p.fromFederator | ||||
| } | ||||
| 
 | ||||
|  | @ -209,6 +209,9 @@ func (p *processor) Start() error { | |||
| 				p.log.Infof("received message TO federator: %+v", federatorMsg) | ||||
| 			case federatorMsg := <-p.fromFederator: | ||||
| 				p.log.Infof("received message FROM federator: %+v", federatorMsg) | ||||
| 				if err := p.processFromFederator(federatorMsg); err != nil { | ||||
| 					p.log.Error(err) | ||||
| 				} | ||||
| 			case <-p.stop: | ||||
| 				break DistLoop | ||||
| 			} | ||||
|  | @ -224,35 +227,11 @@ func (p *processor) Stop() error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // ToClientAPI wraps a message that travels from the processor into the client API | ||||
| type ToClientAPI struct { | ||||
| 	APObjectType   gtsmodel.ActivityStreamsObject | ||||
| 	APActivityType gtsmodel.ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| func (p *processor) processFromFederator(federatorMsg gtsmodel.FromFederator) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // FromClientAPI wraps a message that travels from client API into the processor | ||||
| type FromClientAPI struct { | ||||
| 	APObjectType   gtsmodel.ActivityStreamsObject | ||||
| 	APActivityType gtsmodel.ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| } | ||||
| 
 | ||||
| // ToFederator wraps a message that travels from the processor into the federator | ||||
| type ToFederator struct { | ||||
| 	APObjectType   gtsmodel.ActivityStreamsObject | ||||
| 	APActivityType gtsmodel.ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| } | ||||
| 
 | ||||
| // FromFederator wraps a message that travels from the federator into the processor | ||||
| type FromFederator struct { | ||||
| 	APObjectType   gtsmodel.ActivityStreamsObject | ||||
| 	APActivityType gtsmodel.ActivityStreamsActivity | ||||
| 	Activity       interface{} | ||||
| } | ||||
| 
 | ||||
| func (p *processor) processFromClientAPI(clientMsg FromClientAPI) error { | ||||
| func (p *processor) processFromClientAPI(clientMsg gtsmodel.FromClientAPI) error { | ||||
| 	switch clientMsg.APObjectType { | ||||
| 	case gtsmodel.ActivityStreamsNote: | ||||
| 		status, ok := clientMsg.Activity.(*gtsmodel.Status) | ||||
|  | @ -273,30 +252,30 @@ func (p *processor) processFromClientAPI(clientMsg FromClientAPI) error { | |||
| } | ||||
| 
 | ||||
| func (p *processor) federateStatus(status *gtsmodel.Status) error { | ||||
| 	// derive the sending account -- it might be attached to the status already | ||||
| 	sendingAcct := >smodel.Account{} | ||||
| 	if status.GTSAccount != nil { | ||||
| 		sendingAcct = status.GTSAccount | ||||
| 	} else { | ||||
| 		// it wasn't attached so get it from the db instead | ||||
| 		if err := p.db.GetByID(status.AccountID, sendingAcct); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	// // derive the sending account -- it might be attached to the status already | ||||
| 	// sendingAcct := >smodel.Account{} | ||||
| 	// if status.GTSAccount != nil { | ||||
| 	// 	sendingAcct = status.GTSAccount | ||||
| 	// } else { | ||||
| 	// 	// it wasn't attached so get it from the db instead | ||||
| 	// 	if err := p.db.GetByID(status.AccountID, sendingAcct); err != nil { | ||||
| 	// 		return err | ||||
| 	// 	} | ||||
| 	// } | ||||
| 
 | ||||
| 	outboxURI, err := url.Parse(sendingAcct.OutboxURI) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	// outboxURI, err := url.Parse(sendingAcct.OutboxURI) | ||||
| 	// if err != nil { | ||||
| 	// 	return err | ||||
| 	// } | ||||
| 
 | ||||
| 	// convert the status to AS format Note | ||||
| 	note, err := p.tc.StatusToAS(status) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	// // convert the status to AS format Note | ||||
| 	// note, err := p.tc.StatusToAS(status) | ||||
| 	// if err != nil { | ||||
| 	// 	return err | ||||
| 	// } | ||||
| 
 | ||||
| 	_, err = p.federator.FederatingActor().Send(context.Background(), outboxURI, note) | ||||
| 	return err | ||||
| 	// _, err = p.federator.FederatingActor().Send(context.Background(), outboxURI, note) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *processor) notifyStatus(status *gtsmodel.Status) error { | ||||
|  |  | |||
|  | @ -82,7 +82,7 @@ func (p *processor) StatusCreate(auth *oauth.Auth, form *apimodel.AdvancedStatus | |||
| 	} | ||||
| 
 | ||||
| 	// put the new status in the appropriate channel for async processing | ||||
| 	p.fromClientAPI <- FromClientAPI{ | ||||
| 	p.fromClientAPI <- gtsmodel.FromClientAPI{ | ||||
| 		APObjectType:   newStatus.ActivityStreamsType, | ||||
| 		APActivityType: gtsmodel.ActivityStreamsCreate, | ||||
| 		Activity:       newStatus, | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ package typeutils | |||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/superseriousbusiness/gotosocial/internal/api/model" | ||||
|  | @ -195,7 +196,7 @@ func (c *converter) AppToMastoPublic(a *gtsmodel.Application) (*model.Applicatio | |||
| func (c *converter) AttachmentToMasto(a *gtsmodel.MediaAttachment) (model.Attachment, error) { | ||||
| 	return model.Attachment{ | ||||
| 		ID:               a.ID, | ||||
| 		Type:             string(a.Type), | ||||
| 		Type:             strings.ToLower(string(a.Type)), | ||||
| 		URL:              a.URL, | ||||
| 		PreviewURL:       a.Thumbnail.URL, | ||||
| 		RemoteURL:        a.RemoteURL, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue