gtsocial-umbx

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

accounts.go (3572B)


      1 // GoToSocial
      2 // Copyright (C) GoToSocial Authors admin@gotosocial.org
      3 // SPDX-License-Identifier: AGPL-3.0-or-later
      4 //
      5 // This program is free software: you can redistribute it and/or modify
      6 // it under the terms of the GNU Affero General Public License as published by
      7 // the Free Software Foundation, either version 3 of the License, or
      8 // (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU Affero General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU Affero General Public License
     16 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 package search
     19 
     20 import (
     21 	"context"
     22 	"errors"
     23 	"strings"
     24 
     25 	"codeberg.org/gruf/go-kv"
     26 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     27 	"github.com/superseriousbusiness/gotosocial/internal/db"
     28 	"github.com/superseriousbusiness/gotosocial/internal/gtserror"
     29 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
     30 	"github.com/superseriousbusiness/gotosocial/internal/id"
     31 	"github.com/superseriousbusiness/gotosocial/internal/log"
     32 )
     33 
     34 // Accounts does a partial search for accounts that
     35 // match the given query. It expects input that looks
     36 // like a namestring, and will normalize plaintext to look
     37 // more like a namestring. For queries that include domain,
     38 // it will only return one match at most. For namestrings
     39 // that exclude domain, multiple matches may be returned.
     40 //
     41 // This behavior aligns more or less with Mastodon's API.
     42 // See https://docs.joinmastodon.org/methods/accounts/#search.
     43 func (p *Processor) Accounts(
     44 	ctx context.Context,
     45 	requestingAccount *gtsmodel.Account,
     46 	query string,
     47 	limit int,
     48 	offset int,
     49 	resolve bool,
     50 	following bool,
     51 ) ([]*apimodel.Account, gtserror.WithCode) {
     52 	var (
     53 		foundAccounts = make([]*gtsmodel.Account, 0, limit)
     54 		appendAccount = func(foundAccount *gtsmodel.Account) { foundAccounts = append(foundAccounts, foundAccount) }
     55 	)
     56 
     57 	// Validate query.
     58 	query = strings.TrimSpace(query)
     59 	if query == "" {
     60 		err := gtserror.New("search query was empty string after trimming space")
     61 		return nil, gtserror.NewErrorBadRequest(err, err.Error())
     62 	}
     63 
     64 	// Be nice and normalize query by prepending '@'.
     65 	// This will make it easier for accountsByNamestring
     66 	// to pick this up as a valid namestring.
     67 	if query[0] != '@' {
     68 		query = "@" + query
     69 	}
     70 
     71 	log.
     72 		WithContext(ctx).
     73 		WithFields(kv.Fields{
     74 			{"limit", limit},
     75 			{"offset", offset},
     76 			{"query", query},
     77 			{"resolve", resolve},
     78 			{"following", following},
     79 		}...).
     80 		Debugf("beginning search")
     81 
     82 	// todo: Currently we don't support offset for paging;
     83 	// if caller supplied an offset greater than 0, return
     84 	// nothing as though there were no additional results.
     85 	if offset > 0 {
     86 		return p.packageAccounts(ctx, requestingAccount, foundAccounts)
     87 	}
     88 
     89 	// Return all accounts we can find that match the
     90 	// provided query. If it's not a namestring, this
     91 	// won't return an error, it'll just return 0 results.
     92 	if _, err := p.accountsByNamestring(
     93 		ctx,
     94 		requestingAccount,
     95 		id.Highest,
     96 		id.Lowest,
     97 		limit,
     98 		offset,
     99 		query,
    100 		resolve,
    101 		following,
    102 		appendAccount,
    103 	); err != nil && !errors.Is(err, db.ErrNoEntries) {
    104 		err = gtserror.Newf("error searching by namestring: %w", err)
    105 		return nil, gtserror.NewErrorInternalError(err)
    106 	}
    107 
    108 	// Return whatever we got (if anything).
    109 	return p.packageAccounts(ctx, requestingAccount, foundAccounts)
    110 }