55 lines
2.1 KiB
C#
55 lines
2.1 KiB
C#
using PrivaPub.Api.Mastodon.Entities;
|
|||
|
|
using PrivaPub.Federation.Actors;
|
||
|
|
using PrivaPub.StaticServices;
|
||
|
|
|
||
|
|
namespace PrivaPub.Api.Mastodon.Mappers
|
||
|
|
{
|
||
|
|
public class AccountSearch
|
||
|
|
{
|
||
|
|
readonly MastodonMapper _mapper;
|
||
|
|
readonly DbEntities _dbEntities;
|
||
|
|
readonly ILocalActorService _localActors;
|
||
|
|
readonly IRemoteActorService _remoteActors;
|
||
|
|
|
||
|
|
public AccountSearch(MastodonMapper mapper, DbEntities dbEntities, ILocalActorService localActors, IRemoteActorService remoteActors)
|
||
|
|
{
|
||
|
|
_mapper = mapper;
|
||
|
|
_dbEntities = dbEntities;
|
||
|
|
_localActors = localActors;
|
||
|
|
_remoteActors = remoteActors;
|
||
|
|
}
|
||
|
|
|
||
|
|
public async Task<List<Account>> Find(string q, bool resolve, int limit, CancellationToken token)
|
||
|
|
{
|
||
|
|
q = q?.Trim().TrimStart('@');
|
||
|
|
if (string.IsNullOrEmpty(q))
|
||
|
|
return new List<Account>();
|
||
|
|
var results = new List<Account>();
|
||
|
|
var parts = q.Split('@');
|
||
|
|
var localDomain = new Uri(_localActors.BaseAddress).Authority;
|
||
|
|
if (parts.Length == 2 && !parts[1].Equals(localDomain, StringComparison.OrdinalIgnoreCase) && !string.IsNullOrEmpty(parts[0]))
|
||
|
|
{
|
||
|
|
var userName = parts[0];
|
||
|
|
var domain = parts[1].ToLowerInvariant();
|
||
|
|
var known = await _dbEntities.ForeignAvatars.Match(f => f.UserName == userName && f.Domain == domain).ExecuteFirstAsync(token);
|
||
|
|
if (known == default && resolve)
|
||
|
|
{
|
||
|
|
var actorUri = await _remoteActors.ResolveHandle(q, token);
|
||
|
|
known = actorUri == default ? default : await _remoteActors.GetActor(actorUri, refresh: false, token);
|
||
|
|
}
|
||
|
|
if (known != default)
|
||
|
|
results.Add(_mapper.Foreign(known));
|
||
|
|
return results;
|
||
|
|
}
|
||
|
|
|
||
|
|
var prefix = parts[0].ToLowerInvariant();
|
||
|
|
foreach (var avatar in await _dbEntities.Avatars.Match(a => a.UserName.StartsWith(prefix) && !a.DeletionAt.HasValue && a.Settings.IsDiscoverable != false)
|
||
|
|
.Limit(limit).ExecuteAsync(token))
|
||
|
|
results.Add(await _mapper.Local(_localActors.FromAvatar(avatar), false, token));
|
||
|
|
foreach (var foreign in await _dbEntities.ForeignAvatars.Match(f => f.UserName.StartsWith(parts[0]) && f.IsDiscoverable)
|
||
|
|
.Limit(Math.Max(0, limit - results.Count)).ExecuteAsync(token))
|
||
|
|
results.Add(_mapper.Foreign(foreign));
|
||
|
|
return results;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|