mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-07 13:58:06 -06:00
[feature] Dereference remote mentions when the account is not already known (#442)
* remove mention util function from db * add ParseMentionFunc to gtsmodel * add parseMentionFunc to processor * refactor search to simplify it a bit * add parseMentionFunc to account * add parseMentionFunc to status * some renaming for clarity * test dereference of unknown mentioned account
This commit is contained in:
parent
983e696bd6
commit
37d310f981
16 changed files with 420 additions and 183 deletions
|
|
@ -382,86 +382,6 @@ func tweakConnectionValues(sqldb *sql.DB) {
|
|||
CONVERSION FUNCTIONS
|
||||
*/
|
||||
|
||||
// TODO: move these to the type converter, it's bananas that they're here and not there
|
||||
|
||||
func (ps *bunDBService) MentionStringsToMentions(ctx context.Context, targetAccounts []string, originAccountID string, statusID string) ([]*gtsmodel.Mention, error) {
|
||||
ogAccount := >smodel.Account{}
|
||||
if err := ps.conn.NewSelect().Model(ogAccount).Where("id = ?", originAccountID).Scan(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
menchies := []*gtsmodel.Mention{}
|
||||
for _, a := range targetAccounts {
|
||||
// A mentioned account looks like "@test@example.org" or just "@test" for a local account
|
||||
// -- we can guarantee this from the regex that targetAccounts should have been derived from.
|
||||
// But we still need to do a bit of fiddling to get what we need here -- the username and domain (if given).
|
||||
|
||||
// 1. trim off the first @
|
||||
t := strings.TrimPrefix(a, "@")
|
||||
|
||||
// 2. split the username and domain
|
||||
s := strings.Split(t, "@")
|
||||
|
||||
// 3. if it's length 1 it's a local account, length 2 means remote, anything else means something is wrong
|
||||
var local bool
|
||||
switch len(s) {
|
||||
case 1:
|
||||
local = true
|
||||
case 2:
|
||||
local = false
|
||||
default:
|
||||
return nil, fmt.Errorf("mentioned account format '%s' was not valid", a)
|
||||
}
|
||||
|
||||
var username, domain string
|
||||
username = s[0]
|
||||
if !local {
|
||||
domain = s[1]
|
||||
}
|
||||
|
||||
// 4. check we now have a proper username and domain
|
||||
if username == "" || (!local && domain == "") {
|
||||
return nil, fmt.Errorf("username or domain for '%s' was nil", a)
|
||||
}
|
||||
|
||||
// okay we're good now, we can start pulling accounts out of the database
|
||||
mentionedAccount := >smodel.Account{}
|
||||
var err error
|
||||
|
||||
// match username + account, case insensitive
|
||||
if local {
|
||||
// local user -- should have a null domain
|
||||
err = ps.conn.NewSelect().Model(mentionedAccount).Where("LOWER(?) = LOWER(?)", bun.Ident("username"), username).Where("? IS NULL", bun.Ident("domain")).Scan(ctx)
|
||||
} else {
|
||||
// remote user -- should have domain defined
|
||||
err = ps.conn.NewSelect().Model(mentionedAccount).Where("LOWER(?) = LOWER(?)", bun.Ident("username"), username).Where("LOWER(?) = LOWER(?)", bun.Ident("domain"), domain).Scan(ctx)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
// no result found for this username/domain so just don't include it as a mencho and carry on about our business
|
||||
logrus.Debugf("no account found with username '%s' and domain '%s', skipping it", username, domain)
|
||||
continue
|
||||
}
|
||||
// a serious error has happened so bail
|
||||
return nil, fmt.Errorf("error getting account with username '%s' and domain '%s': %s", username, domain, err)
|
||||
}
|
||||
|
||||
// id, createdAt and updatedAt will be populated by the db, so we have everything we need!
|
||||
menchies = append(menchies, >smodel.Mention{
|
||||
StatusID: statusID,
|
||||
OriginAccountID: ogAccount.ID,
|
||||
OriginAccountURI: ogAccount.URI,
|
||||
TargetAccountID: mentionedAccount.ID,
|
||||
NameString: a,
|
||||
TargetAccountURI: mentionedAccount.URI,
|
||||
TargetAccountURL: mentionedAccount.URL,
|
||||
OriginAccount: mentionedAccount,
|
||||
})
|
||||
}
|
||||
return menchies, nil
|
||||
}
|
||||
|
||||
func (ps *bunDBService) TagStringsToTags(ctx context.Context, tags []string, originAccountID string) ([]*gtsmodel.Tag, error) {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
|
|
|
|||
|
|
@ -48,15 +48,6 @@ type DB interface {
|
|||
USEFUL CONVERSION FUNCTIONS
|
||||
*/
|
||||
|
||||
// MentionStringsToMentions takes a slice of deduplicated, lowercase account names in the form "@test@whatever.example.org" for a remote account,
|
||||
// or @test for a local account, which have been mentioned in a status.
|
||||
// It takes the id of the account that wrote the status, and the id of the status itself, and then
|
||||
// checks in the database for the mentioned accounts, and returns a slice of mentions generated based on the given parameters.
|
||||
//
|
||||
// Note: this func doesn't/shouldn't do any manipulation of the accounts in the DB, it's just for checking
|
||||
// if they exist in the db and conveniently returning them if they do.
|
||||
MentionStringsToMentions(ctx context.Context, targetAccounts []string, originAccountID string, statusID string) ([]*gtsmodel.Mention, error)
|
||||
|
||||
// TagStringsToTags takes a slice of deduplicated, lowercase tags in the form "somehashtag", which have been
|
||||
// used in a status. It takes the id of the account that wrote the status, and the id of the status itself, and then
|
||||
// returns a slice of *model.Tag corresponding to the given tags. If the tag already exists in database, that tag
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue