diff options
| -rw-r--r-- | RELEASE_NOTES.md | 2 | ||||
| -rw-r--r-- | activitypub.c | 6 | ||||
| -rw-r--r-- | data.c | 17 | ||||
| -rw-r--r-- | html.c | 43 | ||||
| -rw-r--r-- | mastoapi.c | 16 | ||||
| -rw-r--r-- | snac.h | 2 |
6 files changed, 50 insertions, 36 deletions
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 21c2153..484e425 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | 4 | ||
| 5 | The number of pending follow confirmations is shown next to the "people" link. | 5 | The number of pending follow confirmations is shown next to the "people" link. |
| 6 | 6 | ||
| 7 | Faster performance metrics (contributed by dandelions). | ||
| 8 | |||
| 7 | Mastodon API: added follow confirmation endpoints. | 9 | Mastodon API: added follow confirmation endpoints. |
| 8 | 10 | ||
| 9 | ## 2.77 "Ugly Links Everywhere" | 11 | ## 2.77 "Ugly Links Everywhere" |
diff --git a/activitypub.c b/activitypub.c index a7e133a..120b4a1 100644 --- a/activitypub.c +++ b/activitypub.c | |||
| @@ -3204,8 +3204,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 3204 | int total = 0; | 3204 | int total = 0; |
| 3205 | 3205 | ||
| 3206 | if (show_contact_metrics) { | 3206 | if (show_contact_metrics) { |
| 3207 | xs *l = follower_list(&snac); | 3207 | total = follower_list_len(&snac); |
| 3208 | total = xs_list_len(l); | ||
| 3209 | } | 3208 | } |
| 3210 | 3209 | ||
| 3211 | xs *id = xs_fmt("%s/%s", snac.actor, p_path); | 3210 | xs *id = xs_fmt("%s/%s", snac.actor, p_path); |
| @@ -3216,8 +3215,7 @@ int activitypub_get_handler(const xs_dict *req, const char *q_path, | |||
| 3216 | int total = 0; | 3215 | int total = 0; |
| 3217 | 3216 | ||
| 3218 | if (show_contact_metrics) { | 3217 | if (show_contact_metrics) { |
| 3219 | xs *l = following_list(&snac); | 3218 | total = following_list_len(&snac); |
| 3220 | total = xs_list_len(l); | ||
| 3221 | } | 3219 | } |
| 3222 | 3220 | ||
| 3223 | xs *id = xs_fmt("%s/%s", snac.actor, p_path); | 3221 | xs *id = xs_fmt("%s/%s", snac.actor, p_path); |
| @@ -1215,6 +1215,14 @@ int follower_check(snac *snac, const char *actor) | |||
| 1215 | } | 1215 | } |
| 1216 | 1216 | ||
| 1217 | 1217 | ||
| 1218 | int follower_list_len(snac *snac) | ||
| 1219 | /* returns the number of followers */ | ||
| 1220 | { | ||
| 1221 | xs *list = object_user_cache_list(snac, "followers", XS_ALL, 0); | ||
| 1222 | return xs_list_len(list); | ||
| 1223 | } | ||
| 1224 | |||
| 1225 | |||
| 1218 | xs_list *follower_list(snac *snac) | 1226 | xs_list *follower_list(snac *snac) |
| 1219 | /* returns the list of followers */ | 1227 | /* returns the list of followers */ |
| 1220 | { | 1228 | { |
| @@ -1709,6 +1717,15 @@ int following_get(snac *snac, const char *actor, xs_dict **data) | |||
| 1709 | } | 1717 | } |
| 1710 | 1718 | ||
| 1711 | 1719 | ||
| 1720 | int following_list_len(snac *snac) | ||
| 1721 | /* returns number of people being followed */ | ||
| 1722 | { | ||
| 1723 | xs *spec = xs_fmt("%s/following/" "*_a.json", snac->basedir); | ||
| 1724 | xs *glist = xs_glob(spec, 0, 0); | ||
| 1725 | return xs_list_len(glist); | ||
| 1726 | } | ||
| 1727 | |||
| 1728 | |||
| 1712 | xs_list *following_list(snac *snac) | 1729 | xs_list *following_list(snac *snac) |
| 1713 | /* returns the list of people being followed */ | 1730 | /* returns the list of people being followed */ |
| 1714 | { | 1731 | { |
| @@ -332,7 +332,8 @@ xs_html *html_actor_icon(snac *user, xs_dict *actor, const char *date, | |||
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | 334 | ||
| 335 | xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, const char *proxy, const char *md5) | 335 | xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, |
| 336 | const char *proxy, const char *md5, const char *lang) | ||
| 336 | { | 337 | { |
| 337 | xs *actor = NULL; | 338 | xs *actor = NULL; |
| 338 | xs_html *actor_icon = NULL; | 339 | xs_html *actor_icon = NULL; |
| @@ -341,7 +342,6 @@ xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, con | |||
| 341 | const char *date = NULL; | 342 | const char *date = NULL; |
| 342 | const char *udate = NULL; | 343 | const char *udate = NULL; |
| 343 | const char *url = NULL; | 344 | const char *url = NULL; |
| 344 | const char *lang = NULL; | ||
| 345 | int priv = 0; | 345 | int priv = 0; |
| 346 | const char *type = xs_dict_get(msg, "type"); | 346 | const char *type = xs_dict_get(msg, "type"); |
| 347 | 347 | ||
| @@ -353,16 +353,6 @@ xs_html *html_msg_icon(snac *user, const char *actor_id, const xs_dict *msg, con | |||
| 353 | date = xs_dict_get(msg, "published"); | 353 | date = xs_dict_get(msg, "published"); |
| 354 | udate = xs_dict_get(msg, "updated"); | 354 | udate = xs_dict_get(msg, "updated"); |
| 355 | 355 | ||
| 356 | lang = xs_dict_get(msg, "contentMap"); | ||
| 357 | if (xs_is_dict(lang)) { | ||
| 358 | const char *v; | ||
| 359 | int c = 0; | ||
| 360 | |||
| 361 | xs_dict_next(lang, &lang, &v, &c); | ||
| 362 | } | ||
| 363 | else | ||
| 364 | lang = NULL; | ||
| 365 | |||
| 366 | actor_icon = html_actor_icon(user, actor, date, udate, url, priv, 0, proxy, lang, md5); | 356 | actor_icon = html_actor_icon(user, actor, date, udate, url, priv, 0, proxy, lang, md5); |
| 367 | } | 357 | } |
| 368 | 358 | ||
| @@ -821,11 +811,7 @@ xs_html *html_user_head(snac *user, const char *desc, const char *url) | |||
| 821 | 811 | ||
| 822 | /* show metrics in og:description? */ | 812 | /* show metrics in og:description? */ |
| 823 | if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { | 813 | if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { |
| 824 | xs *fwers = follower_list(user); | 814 | xs *s1 = xs_fmt(L("%d following, %d followers"), following_list_len(user), follower_list_len(user)); |
| 825 | xs *fwing = following_list(user); | ||
| 826 | |||
| 827 | xs *s1 = xs_fmt(L("%d following, %d followers"), | ||
| 828 | xs_list_len(fwing), xs_list_len(fwers)); | ||
| 829 | 815 | ||
| 830 | s1 = xs_str_cat(s1, " · "); | 816 | s1 = xs_str_cat(s1, " · "); |
| 831 | 817 | ||
| @@ -1166,11 +1152,7 @@ static xs_html *html_user_body(snac *user, int read_only) | |||
| 1166 | } | 1152 | } |
| 1167 | 1153 | ||
| 1168 | if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { | 1154 | if (xs_is_true(xs_dict_get(user->config, "show_contact_metrics"))) { |
| 1169 | xs *fwers = follower_list(user); | 1155 | xs *s1 = xs_fmt(L("%d following, %d followers"), following_list_len(user), follower_list_len(user)); |
| 1170 | xs *fwing = following_list(user); | ||
| 1171 | |||
| 1172 | xs *s1 = xs_fmt(L("%d following, %d followers"), | ||
| 1173 | xs_list_len(fwing), xs_list_len(fwers)); | ||
| 1174 | 1156 | ||
| 1175 | xs_html_add(top_user, | 1157 | xs_html_add(top_user, |
| 1176 | xs_html_tag("p", | 1158 | xs_html_tag("p", |
| @@ -1951,6 +1933,15 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, | |||
| 1951 | return xs_html_tag("mark", | 1933 | return xs_html_tag("mark", |
| 1952 | xs_html_text(L("Truncated (too deep)"))); | 1934 | xs_html_text(L("Truncated (too deep)"))); |
| 1953 | 1935 | ||
| 1936 | const char *lang = NULL; | ||
| 1937 | const xs_dict *cmap = xs_dict_get(msg, "contentMap"); | ||
| 1938 | if (xs_is_dict(cmap)) { | ||
| 1939 | const char *dummy; | ||
| 1940 | int c = 0; | ||
| 1941 | |||
| 1942 | xs_dict_next(cmap, &lang, &dummy, &c); | ||
| 1943 | } | ||
| 1944 | |||
| 1954 | if (strcmp(type, "Follow") == 0) { | 1945 | if (strcmp(type, "Follow") == 0) { |
| 1955 | return xs_html_tag("div", | 1946 | return xs_html_tag("div", |
| 1956 | xs_html_attr("class", "snac-post"), | 1947 | xs_html_attr("class", "snac-post"), |
| @@ -1959,7 +1950,7 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, | |||
| 1959 | xs_html_tag("div", | 1950 | xs_html_tag("div", |
| 1960 | xs_html_attr("class", "snac-origin"), | 1951 | xs_html_attr("class", "snac-origin"), |
| 1961 | xs_html_text(L("follows you"))), | 1952 | xs_html_text(L("follows you"))), |
| 1962 | html_msg_icon(read_only ? NULL : user, xs_dict_get(msg, "actor"), msg, proxy, NULL))); | 1953 | html_msg_icon(read_only ? NULL : user, xs_dict_get(msg, "actor"), msg, proxy, NULL, lang))); |
| 1963 | } | 1954 | } |
| 1964 | else | 1955 | else |
| 1965 | if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) { | 1956 | if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) { |
| @@ -2140,13 +2131,17 @@ xs_html *html_entry(snac *user, xs_dict *msg, int read_only, | |||
| 2140 | } | 2131 | } |
| 2141 | 2132 | ||
| 2142 | xs_html_add(post_header, | 2133 | xs_html_add(post_header, |
| 2143 | html_msg_icon(read_only ? NULL : user, actor, msg, proxy, md5)); | 2134 | html_msg_icon(read_only ? NULL : user, actor, msg, proxy, md5, lang)); |
| 2144 | 2135 | ||
| 2145 | /** post content **/ | 2136 | /** post content **/ |
| 2146 | 2137 | ||
| 2147 | xs_html *snac_content_wrap = xs_html_tag("div", | 2138 | xs_html *snac_content_wrap = xs_html_tag("div", |
| 2148 | xs_html_attr("class", "e-content snac-content")); | 2139 | xs_html_attr("class", "e-content snac-content")); |
| 2149 | 2140 | ||
| 2141 | if (xs_is_string(lang)) | ||
| 2142 | xs_html_add(snac_content_wrap, | ||
| 2143 | xs_html_attr("lang", lang)); | ||
| 2144 | |||
| 2150 | xs_html_add(entry, | 2145 | xs_html_add(entry, |
| 2151 | snac_content_wrap); | 2146 | snac_content_wrap); |
| 2152 | 2147 | ||
| @@ -680,10 +680,10 @@ xs_dict *mastoapi_account(snac *logged, const xs_dict *actor) | |||
| 680 | 680 | ||
| 681 | /* does this user want to publish their contact metrics? */ | 681 | /* does this user want to publish their contact metrics? */ |
| 682 | if (xs_is_true(xs_dict_get(user.config, "show_contact_metrics"))) { | 682 | if (xs_is_true(xs_dict_get(user.config, "show_contact_metrics"))) { |
| 683 | xs *fwing = following_list(&user); | 683 | int fwing = following_list_len(&user); |
| 684 | xs *fwers = follower_list(&user); | 684 | int fwers = follower_list_len(&user); |
| 685 | xs *ni = xs_number_new(xs_list_len(fwing)); | 685 | xs *ni = xs_number_new(fwing); |
| 686 | xs *ne = xs_number_new(xs_list_len(fwers)); | 686 | xs *ne = xs_number_new(fwers); |
| 687 | 687 | ||
| 688 | acct = xs_dict_append(acct, "followers_count", ne); | 688 | acct = xs_dict_append(acct, "followers_count", ne); |
| 689 | acct = xs_dict_append(acct, "following_count", ni); | 689 | acct = xs_dict_append(acct, "following_count", ni); |
| @@ -1309,10 +1309,10 @@ void credentials_get(char **body, char **ctype, int *status, snac snac) | |||
| 1309 | 1309 | ||
| 1310 | /* does this user want to publish their contact metrics? */ | 1310 | /* does this user want to publish their contact metrics? */ |
| 1311 | if (xs_is_true(xs_dict_get(snac.config, "show_contact_metrics"))) { | 1311 | if (xs_is_true(xs_dict_get(snac.config, "show_contact_metrics"))) { |
| 1312 | xs *fwing = following_list(&snac); | 1312 | int fwing = following_list_len(&snac); |
| 1313 | xs *fwers = follower_list(&snac); | 1313 | int fwers = follower_list_len(&snac); |
| 1314 | xs *ni = xs_number_new(xs_list_len(fwing)); | 1314 | xs *ni = xs_number_new(fwing); |
| 1315 | xs *ne = xs_number_new(xs_list_len(fwers)); | 1315 | xs *ne = xs_number_new(fwers); |
| 1316 | 1316 | ||
| 1317 | acct = xs_dict_append(acct, "followers_count", ne); | 1317 | acct = xs_dict_append(acct, "followers_count", ne); |
| 1318 | acct = xs_dict_append(acct, "following_count", ni); | 1318 | acct = xs_dict_append(acct, "following_count", ni); |
| @@ -153,6 +153,7 @@ int follower_add(snac *snac, const char *actor); | |||
| 153 | int follower_del(snac *snac, const char *actor); | 153 | int follower_del(snac *snac, const char *actor); |
| 154 | int follower_check(snac *snac, const char *actor); | 154 | int follower_check(snac *snac, const char *actor); |
| 155 | xs_list *follower_list(snac *snac); | 155 | xs_list *follower_list(snac *snac); |
| 156 | int follower_list_len(snac *snac); | ||
| 156 | 157 | ||
| 157 | int pending_add(snac *user, const char *actor, const xs_dict *msg); | 158 | int pending_add(snac *user, const char *actor, const xs_dict *msg); |
| 158 | int pending_check(snac *user, const char *actor); | 159 | int pending_check(snac *user, const char *actor); |
| @@ -184,6 +185,7 @@ int following_del(snac *snac, const char *actor); | |||
| 184 | int following_check(snac *snac, const char *actor); | 185 | int following_check(snac *snac, const char *actor); |
| 185 | int following_get(snac *snac, const char *actor, xs_dict **data); | 186 | int following_get(snac *snac, const char *actor, xs_dict **data); |
| 186 | xs_list *following_list(snac *snac); | 187 | xs_list *following_list(snac *snac); |
| 188 | int following_list_len(snac *snac); | ||
| 187 | 189 | ||
| 188 | void mute(snac *snac, const char *actor); | 190 | void mute(snac *snac, const char *actor); |
| 189 | void unmute(snac *snac, const char *actor); | 191 | void unmute(snac *snac, const char *actor); |