summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar default2023-05-12 11:56:17 +0200
committerGravatar default2023-05-12 11:56:17 +0200
commitd35c949a134524395b20617855570e8d5f0867af (patch)
tree0bf32f8426e0b758073f2866d322954288319525
parentMinor refactor to msg_note(): the tag list is created here, not in process_ta... (diff)
downloadpenes-snac2-d35c949a134524395b20617855570e8d5f0867af.tar.gz
penes-snac2-d35c949a134524395b20617855570e8d5f0867af.tar.xz
penes-snac2-d35c949a134524395b20617855570e8d5f0867af.zip
Resolve (partially) the issue with mentions without server.
Mastodon (mainly from the API) usually include mentions without server, which is just stupid. This patch tries to resolve these broken mentions in process_tags() by looking for a user name starting with it in the already pre-populated tag list. As of now, this only works if the message is an inReplyTo and the broken mention is the one of the original (attributedTo) poster.
-rw-r--r--activitypub.c69
1 files changed, 51 insertions, 18 deletions
diff --git a/activitypub.c b/activitypub.c
index b322a40..51a2cfa 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -368,36 +368,69 @@ void process_tags(snac *snac, const char *content, xs_str **n_content, xs_list *
368 xs_val *v; 368 xs_val *v;
369 int n = 0; 369 int n = 0;
370 370
371 split = xs_regex_split(content, "(@[A-Za-z0-9_]+@[A-Za-z0-9\\.-]+|&#[0-9]+;|#[^ ,\\.:;<]+)"); 371 split = xs_regex_split(content, "(@[A-Za-z0-9_]+(@[A-Za-z0-9\\.-]+)?|&#[0-9]+;|#[^ ,\\.:;<]+)");
372 372
373 p = split; 373 p = split;
374 while (xs_list_iter(&p, &v)) { 374 while (xs_list_iter(&p, &v)) {
375 if ((n & 0x1)) { 375 if ((n & 0x1)) {
376 if (*v == '@') { 376 if (*v == '@') {
377 /* query the webfinger about this fellow */ 377 xs *link = NULL;
378 xs *v2 = xs_strip_chars_i(xs_dup(v), "@."); 378
379 xs *actor = NULL; 379 if (strchr(v + 1, '@') == NULL) {
380 xs *uid = NULL; 380 /* only one @? it's a dumb Mastodon-like mention
381 int status; 381 without server; check if there is anybody
382 whose name starts with this in the tag list */
383 xs_list *p2 = tl;
384 xs_dict *v2;
385 xs *pname = xs_fmt("%s@", v);
386
387 while (xs_list_iter(&p2, &v2)) {
388 const char *type = xs_dict_get(v2, "type");
389
390 if (type && strcmp(type, "Mention") == 0) {
391 const char *name = xs_dict_get(v2, "name");
392 const char *href = xs_dict_get(v2, "href");
393
394 if (name && href && (xs_startswith(name, pname) ||
395 xs_startswith(name, pname + 1))) {
396 /* good enough :shrug2: */
397 link = xs_fmt(
398 "<a href=\"%s\" class=\"u-url mention\">%s</a>", href, name);
399
400 break;
401 }
402 }
403 }
404
405 snac_debug(snac, 2, xs_fmt(
406 "mention without server '%s' (%s)", v, link ? link : "none"));
407 }
408 else {
409 /* query the webfinger about this fellow */
410 xs *v2 = xs_strip_chars_i(xs_dup(v), "@.");
411 xs *actor = NULL;
412 xs *uid = NULL;
413 int status;
382 414
383 status = webfinger_request(v2, &actor, &uid); 415 status = webfinger_request(v2, &actor, &uid);
384 416
385 if (valid_status(status)) { 417 if (valid_status(status)) {
386 xs *d = xs_dict_new(); 418 xs *d = xs_dict_new();
387 xs *n = xs_fmt("@%s", uid); 419 xs *n = xs_fmt("@%s", uid);
388 xs *l = xs_fmt("<a href=\"%s\" class=\"u-url mention\">%s</a>", actor, n);
389 420
390 d = xs_dict_append(d, "type", "Mention"); 421 d = xs_dict_append(d, "type", "Mention");
391 d = xs_dict_append(d, "href", actor); 422 d = xs_dict_append(d, "href", actor);
392 d = xs_dict_append(d, "name", n); 423 d = xs_dict_append(d, "name", n);
393 424
394 tl = xs_list_append(tl, d); 425 tl = xs_list_append(tl, d);
395 426
396 /* add the code */ 427 link = xs_fmt("<a href=\"%s\" class=\"u-url mention\">%s</a>", actor, n);
397 nc = xs_str_cat(nc, l); 428 }
398 } 429 }
430
431 if (!xs_is_null(link))
432 nc = xs_str_cat(nc, link);
399 else 433 else
400 /* store as is */
401 nc = xs_str_cat(nc, v); 434 nc = xs_str_cat(nc, v);
402 } 435 }
403 else 436 else