commit d35c949

default  ·  2023-05-12 09:56:17 +0000 UTC
parent 2e27a80
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.
1 files changed,  +51, -18
+51, -18
 1@@ -368,36 +368,69 @@ void process_tags(snac *snac, const char *content, xs_str **n_content, xs_list *
 2     xs_val *v;
 3     int n = 0;
 4 
 5-    split = xs_regex_split(content, "(@[A-Za-z0-9_]+@[A-Za-z0-9\\.-]+|&#[0-9]+;|#[^ ,\\.:;<]+)");
 6+    split = xs_regex_split(content, "(@[A-Za-z0-9_]+(@[A-Za-z0-9\\.-]+)?|&#[0-9]+;|#[^ ,\\.:;<]+)");
 7 
 8     p = split;
 9     while (xs_list_iter(&p, &v)) {
10         if ((n & 0x1)) {
11             if (*v == '@') {
12-                /* query the webfinger about this fellow */
13-                xs *v2    = xs_strip_chars_i(xs_dup(v), "@.");
14-                xs *actor = NULL;
15-                xs *uid   = NULL;
16-                int status;
17+                xs *link = NULL;
18+
19+                if (strchr(v + 1, '@') == NULL) {
20+                    /* only one @? it's a dumb Mastodon-like mention
21+                       without server; check if there is anybody
22+                       whose name starts with this in the tag list */
23+                    xs_list *p2 = tl;
24+                    xs_dict *v2;
25+                    xs *pname = xs_fmt("%s@", v);
26+
27+                    while (xs_list_iter(&p2, &v2)) {
28+                        const char *type = xs_dict_get(v2, "type");
29+
30+                        if (type && strcmp(type, "Mention") == 0) {
31+                            const char *name = xs_dict_get(v2, "name");
32+                            const char *href = xs_dict_get(v2, "href");
33+
34+                            if (name && href && (xs_startswith(name, pname) ||
35+                                                 xs_startswith(name, pname + 1))) {
36+                                /* good enough :shrug2: */
37+                                link = xs_fmt(
38+                                    "<a href=\"%s\" class=\"u-url mention\">%s</a>", href, name);
39+
40+                                break;
41+                            }
42+                        }
43+                    }
44+
45+                    snac_debug(snac, 2, xs_fmt(
46+                        "mention without server '%s' (%s)", v, link ? link : "none"));
47+                }
48+                else {
49+                    /* query the webfinger about this fellow */
50+                    xs *v2    = xs_strip_chars_i(xs_dup(v), "@.");
51+                    xs *actor = NULL;
52+                    xs *uid   = NULL;
53+                    int status;
54 
55-                status = webfinger_request(v2, &actor, &uid);
56+                    status = webfinger_request(v2, &actor, &uid);
57 
58-                if (valid_status(status)) {
59-                    xs *d = xs_dict_new();
60-                    xs *n = xs_fmt("@%s", uid);
61-                    xs *l = xs_fmt("<a href=\"%s\" class=\"u-url mention\">%s</a>", actor, n);
62+                    if (valid_status(status)) {
63+                        xs *d = xs_dict_new();
64+                        xs *n = xs_fmt("@%s", uid);
65 
66-                    d = xs_dict_append(d, "type",   "Mention");
67-                    d = xs_dict_append(d, "href",   actor);
68-                    d = xs_dict_append(d, "name",   n);
69+                        d = xs_dict_append(d, "type",   "Mention");
70+                        d = xs_dict_append(d, "href",   actor);
71+                        d = xs_dict_append(d, "name",   n);
72 
73-                    tl = xs_list_append(tl, d);
74+                        tl = xs_list_append(tl, d);
75 
76-                    /* add the code */
77-                    nc = xs_str_cat(nc, l);
78+                        link = xs_fmt("<a href=\"%s\" class=\"u-url mention\">%s</a>", actor, n);
79+                    }
80                 }
81+
82+                if (!xs_is_null(link))
83+                    nc = xs_str_cat(nc, link);
84                 else
85-                    /* store as is */
86                     nc = xs_str_cat(nc, v);
87             }
88             else