A handle finds its account, not posts and a made-up hashtag
Since status search by words, searching "@name@host" also answered posts sharing the handle's words and a hashtag "#@name@host" made of the query, so a client that opens the profile when the account is the only result (decePub's search) stayed on the list. A handle now searches accounts only, and a hashtag result is offered only when the query is one (letters, marks, digits and underscores, with a letter). Found by decePub's end-to-end tests: every profile follow test failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
17922f4dfd
commit
4a9a3d3235
3 files changed
+31
-3
No files matched your search
@@ -73,10 +73,11 @@ namespace PrivaPub.Api.Mastodon.Controllers
|
||||
{
|
||||
results.Accounts = await _search.Find(q, resolve, Limit(), Math.Max(0, offset), token);
|
||||
}
|
||||
if (type is null or "statuses" && MyId != default && !q.StartsWith('#'))
|
||||
// an account's handle asks for the account, never for posts that happen to share its words
|
||||
if (type is null or "statuses" && MyId != default && !q.StartsWith('#') && !Handle().IsMatch(q))
|
||||
results.Statuses = await Words(q, Math.Max(0, offset), Limit(), token);
|
||||
if (type is null or "hashtags" && q.TrimStart('#') is { Length: > 0 } tag)
|
||||
results.Hashtags.Add(new { name = tag.ToLowerInvariant(), url = $"{_localActors.BaseAddress}/tags/{Uri.EscapeDataString(tag.ToLowerInvariant())}", history = Array.Empty<object>() });
|
||||
if (type is null or "hashtags" && TagsController.Normalise(q) is var tag && TagsController.IsHashtag(tag))
|
||||
results.Hashtags.Add(new { name = tag, url = $"{_localActors.BaseAddress}/tags/{Uri.EscapeDataString(tag)}", history = Array.Empty<object>() });
|
||||
return Json(results);
|
||||
}
|
||||
}
|
||||
@@ -85,6 +86,9 @@ namespace PrivaPub.Api.Mastodon.Controllers
|
||||
{
|
||||
const int WordCandidates = 400;
|
||||
|
||||
[System.Text.RegularExpressions.GeneratedRegex(@"^@?[^\s@]+@[^\s@]+$|^@[^\s@]+$")]
|
||||
private static partial System.Text.RegularExpressions.Regex Handle();
|
||||
|
||||
// Posts by their words, as Mastodon searches them: those the persona wrote, boosted, favourited, bookmarked or was
|
||||
// named in, and public posts of authors who let themselves be indexed; newest first, what the persona may see only
|
||||
async Task<List<Status>> Words(string q, int offset, int limit, CancellationToken token)
|
||||
|
||||
@@ -31,6 +31,12 @@ namespace PrivaPub.Api.Mastodon.Controllers
|
||||
|
||||
public static string Normalise(string name) => name?.Trim().TrimStart('#').Normalize(NormalizationForm.FormKC).ToLowerInvariant() ?? string.Empty;
|
||||
|
||||
// what a hashtag can be, as Mastodon has it: letters, marks, digits and underscores, with a letter or underscore
|
||||
public static bool IsHashtag(string normal) =>
|
||||
normal.Length is > 0 and <= 100 && normal.All(c => char.IsLetterOrDigit(c) || c == '_' || char.GetUnicodeCategory(c) is
|
||||
System.Globalization.UnicodeCategory.NonSpacingMark or System.Globalization.UnicodeCategory.SpacingCombiningMark)
|
||||
&& normal.Any(c => char.IsLetter(c) || c == '_');
|
||||
|
||||
// a day's uses and authors, newest first, for the last week, as Mastodon gives them (strings, days as unix time)
|
||||
public static async Task<List<object>> History(DbEntities dbEntities, string tag, CancellationToken token)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user