2021-08-10 14:32:39 +03:00
/ *
GoToSocial
2023-01-05 14:43:00 +03:00
Copyright ( C ) 2021 - 2023 GoToSocial Authors admin @ gotosocial . org
2021-08-10 14:32:39 +03:00
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 dereferencing
import (
2021-08-25 16:34:33 +03:00
"context"
2021-08-10 14:32:39 +03:00
"net/url"
"sync"
2023-02-10 23:15:23 +03:00
"codeberg.org/gruf/go-mutexes"
2021-08-10 14:32:39 +03:00
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/media"
"github.com/superseriousbusiness/gotosocial/internal/transport"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
)
// Dereferencer wraps logic and functionality for doing dereferencing of remote accounts, statuses, etc, from federated instances.
type Dereferencer interface {
2023-02-03 23:03:05 +03:00
// GetAccountByURI will attempt to fetch an account by its URI, first checking the database and in the case of a remote account will either check the
// last_fetched (and updating if beyond fetch interval) or dereferencing for the first-time if this remote account has never been encountered before.
GetAccountByURI ( ctx context . Context , requestUser string , uri * url . URL , block bool ) ( * gtsmodel . Account , error )
// GetAccountByUsernameDomain will attempt to fetch an account by username@domain, first checking the database and in the case of a remote account will either
// check the last_fetched (and updating if beyond fetch interval) or dereferencing for the first-time if this remote account has never been encountered before.
GetAccountByUsernameDomain ( ctx context . Context , requestUser string , username string , domain string , block bool ) ( * gtsmodel . Account , error )
// UpdateAccount updates the given account if last_fetched is beyond fetch interval (or if force is set). An updated account model is returned, any media fetching is done async.
UpdateAccount ( ctx context . Context , requestUser string , account * gtsmodel . Account , force bool ) ( * gtsmodel . Account , error )
2022-11-29 12:24:55 +03:00
GetStatus ( ctx context . Context , username string , remoteStatusID * url . URL , refetch , includeParent bool ) ( * gtsmodel . Status , ap . Statusable , error )
2021-08-10 14:32:39 +03:00
2021-09-14 13:23:56 +03:00
EnrichRemoteStatus ( ctx context . Context , username string , status * gtsmodel . Status , includeParent bool ) ( * gtsmodel . Status , error )
2021-08-25 16:34:33 +03:00
GetRemoteInstance ( ctx context . Context , username string , remoteInstanceURI * url . URL ) ( * gtsmodel . Instance , error )
2022-11-29 12:24:55 +03:00
DereferenceAnnounce ( ctx context . Context , announce * gtsmodel . Status , requestingUsername string ) error
DereferenceThread ( ctx context . Context , username string , statusIRI * url . URL , status * gtsmodel . Status , statusable ap . Statusable )
2021-08-10 14:32:39 +03:00
2022-01-11 19:49:14 +03:00
GetRemoteMedia ( ctx context . Context , requestingUsername string , accountID string , remoteURL string , ai * media . AdditionalMediaInfo ) ( * media . ProcessingMedia , error )
2022-11-11 22:27:37 +03:00
GetRemoteEmoji ( ctx context . Context , requestingUsername string , remoteURL string , shortcode string , domain string , id string , emojiURI string , ai * media . AdditionalEmojiInfo , refresh bool ) ( * media . ProcessingEmoji , error )
2021-08-29 13:03:08 +03:00
2023-02-03 23:03:05 +03:00
Handshaking ( username string , remoteAccountID * url . URL ) bool
2021-08-10 14:32:39 +03:00
}
type deref struct {
2023-02-10 23:15:23 +03:00
db db . DB
typeConverter typeutils . TypeConverter
transportController transport . Controller
mediaManager media . Manager
derefAvatars map [ string ] * media . ProcessingMedia
derefAvatarsMu mutexes . Mutex
derefHeaders map [ string ] * media . ProcessingMedia
derefHeadersMu mutexes . Mutex
derefEmojis map [ string ] * media . ProcessingEmoji
derefEmojisMu mutexes . Mutex
handshakes map [ string ] [ ] * url . URL
handshakeSync sync . Mutex // mutex to lock/unlock when checking or updating the handshakes map
2021-08-10 14:32:39 +03:00
}
// NewDereferencer returns a Dereferencer initialized with the given parameters.
2021-12-28 18:36:00 +03:00
func NewDereferencer ( db db . DB , typeConverter typeutils . TypeConverter , transportController transport . Controller , mediaManager media . Manager ) Dereferencer {
2021-08-10 14:32:39 +03:00
return & deref {
2023-02-10 23:15:23 +03:00
db : db ,
typeConverter : typeConverter ,
transportController : transportController ,
mediaManager : mediaManager ,
derefAvatars : make ( map [ string ] * media . ProcessingMedia ) ,
derefHeaders : make ( map [ string ] * media . ProcessingMedia ) ,
derefEmojis : make ( map [ string ] * media . ProcessingEmoji ) ,
handshakes : make ( map [ string ] [ ] * url . URL ) ,
// use wrapped mutexes to allow safely deferring unlock
// even when more granular locks are required (only unlocks once).
derefAvatarsMu : mutexes . WithSafety ( mutexes . New ( ) ) ,
derefHeadersMu : mutexes . WithSafety ( mutexes . New ( ) ) ,
derefEmojisMu : mutexes . WithSafety ( mutexes . New ( ) ) ,
2021-08-10 14:32:39 +03:00
}
}