From ec37139f5aac4f54d09f768c54195fb528fd3088 Mon Sep 17 00:00:00 2001 From: postscriptum Date: Thu, 22 May 2025 04:35:52 +0300 Subject: cleanup ending spaces --- mastoapi.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 7fa0078..dee73e8 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -381,7 +381,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path, } } - /* no code? + /* no code? I'm not sure of the impacts of this right now, but Subway Tooter does not provide a code so one must be generated */ if (xs_is_null(code)){ @@ -1780,7 +1780,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, } else if (strcmp(opt, "statuses") == 0) { - /* we don't serve statuses of others; return the empty list */ + /* we don't serve statuses of others; return the empty list */ out = xs_list_new(); } else @@ -1999,7 +1999,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, } else if (strcmp(cmd, "/v2/filters") == 0) { /** **/ - /* snac will never have filters + /* snac will never have filters * but still, without a v2 endpoint a short delay is introduced * in some apps */ *body = xs_dup("[]"); @@ -2459,7 +2459,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (logged_in) { const xs_list *timeline = xs_dict_get(args, "timeline[]"); xs_str *json = NULL; - if (!xs_is_null(timeline)) + if (!xs_is_null(timeline)) json = xs_json_dumps(markers_get(&snac1, timeline), 4); if (!xs_is_null(json)) @@ -3227,7 +3227,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, if (!xs_is_null(home)) home_marker = xs_dict_get(home, "last_read_id"); } - + const xs_str *notify_marker = xs_dict_get(args, "notifications[last_read_id]"); if (xs_is_null(notify_marker)) { const xs_dict *notify = xs_dict_get(args, "notifications"); -- cgit v1.2.3 From 450e679f5197cfe3101d2b3f032f3fabeadfc848 Mon Sep 17 00:00:00 2001 From: postscriptum Date: Thu, 22 May 2025 04:37:13 +0300 Subject: add missed replacement to the `mastoapi_get_handler` function (`search` case) --- mastoapi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index dee73e8..0348ec6 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -15,6 +15,7 @@ #include "xs_url.h" #include "xs_mime.h" #include "xs_match.h" +#include "xs_unicode.h" #include "snac.h" @@ -1637,7 +1638,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, const char *aq = xs_dict_get(args, "q"); if (!xs_is_null(aq)) { - xs *q = xs_tolower_i(xs_dup(aq)); + xs *q = xs_utf8_to_lower(xs_dup(aq)); out = xs_list_new(); xs *wing = following_list(&snac1); xs *wers = follower_list(&snac1); -- cgit v1.2.3 From 56816b305155fee2154c7991ba9be8c0e7671307 Mon Sep 17 00:00:00 2001 From: grunfink Date: Thu, 22 May 2025 11:18:48 +0200 Subject: Minor memory leak fixes. --- mastoapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index c46a971..9875b12 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1638,7 +1638,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, const char *aq = xs_dict_get(args, "q"); if (!xs_is_null(aq)) { - xs *q = xs_utf8_to_lower(xs_dup(aq)); + xs *q = xs_utf8_to_lower(aq); out = xs_list_new(); xs *wing = following_list(&snac1); xs *wers = follower_list(&snac1); -- cgit v1.2.3 From 631e44a64a20741b5e4716bf75caf7fa743fef82 Mon Sep 17 00:00:00 2001 From: grunfink Date: Tue, 27 May 2025 21:08:57 +0200 Subject: Renamed timeline_here() to timeline_here_by_md5(), as it always should have been. --- mastoapi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 9875b12..c88fd1b 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -2510,7 +2510,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (xs_startswith(q, "https://")) { xs *md5 = xs_md5_hex(q, strlen(q)); - if (!timeline_here(&snac1, md5)) { + if (!timeline_here_by_md5(&snac1, md5)) { xs *object = NULL; int status; -- cgit v1.2.3 From 5bc451159420d5d51a507fda82a623069cfae92b Mon Sep 17 00:00:00 2001 From: grunfink Date: Tue, 27 May 2025 21:14:23 +0200 Subject: New function timeline_here(). --- mastoapi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index c88fd1b..df713a8 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -2508,9 +2508,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, /* reply something only for offset 0; otherwise, apps like Tusky keep asking again and again */ if (xs_startswith(q, "https://")) { - xs *md5 = xs_md5_hex(q, strlen(q)); - - if (!timeline_here_by_md5(&snac1, md5)) { + if (!timeline_here(&snac1, q)) { xs *object = NULL; int status; -- cgit v1.2.3 From 34d85b3e1bbda2e89191026b3815dd9b6f23afcb Mon Sep 17 00:00:00 2001 From: grunfink Date: Thu, 29 May 2025 13:12:43 +0200 Subject: mastoapi: fixed uploaded images name collision. --- mastoapi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index df713a8..27c476e 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -2978,8 +2978,10 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, if (*fn != '\0') { char *ext = strrchr(fn, '.'); - xs *hash = xs_md5_hex(fn, strlen(fn)); - xs *id = xs_fmt("%s%s", hash, ext); + char rnd[32]; + xs_rnd_buf(rnd, sizeof(rnd)); + xs *hash = xs_md5_hex(rnd, sizeof(rnd)); + xs *id = xs_fmt("post-%s%s", hash, ext ? ext : ""); xs *url = xs_fmt("%s/s/%s", snac.actor, id); int fo = xs_number_get(xs_list_get(file, 1)); int fs = xs_number_get(xs_list_get(file, 2)); -- cgit v1.2.3 From cc0e90fbf7c22991bf72af38c5d47d8b3a5ab552 Mon Sep 17 00:00:00 2001 From: grunfink Date: Wed, 11 Jun 2025 04:40:47 +0200 Subject: mastoapi: fixed reblog identifiers. This fixes weird behaviour in apps like Tusky, where boosts' content disappear after clicking on them. --- mastoapi.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 27c476e..2c86ff9 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1134,9 +1134,15 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg) bst = xs_dict_set(bst, "content", ""); bst = xs_dict_set(bst, "reblog", st); + /* reblogs must have their own id */ + xs *b_id = xs_fmt("%s%s", xs_dict_get(st, "id"), boosted_by_md5); + bst = xs_dict_set(bst, "id", b_id); + xs_free(st); st = bst; } + else + xs_free(bst); } return st; -- cgit v1.2.3 From 699d22a86438a93a12e802e4c39c44416b4ab4a0 Mon Sep 17 00:00:00 2001 From: grunfink Date: Wed, 11 Jun 2025 19:54:07 +0200 Subject: mastoapi: reverted reblog id, as it was breaking things. --- mastoapi.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 2c86ff9..19aa610 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1134,10 +1134,6 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg) bst = xs_dict_set(bst, "content", ""); bst = xs_dict_set(bst, "reblog", st); - /* reblogs must have their own id */ - xs *b_id = xs_fmt("%s%s", xs_dict_get(st, "id"), boosted_by_md5); - bst = xs_dict_set(bst, "id", b_id); - xs_free(st); st = bst; } -- cgit v1.2.3 From 55213f660d0c2a14ee5b556c4422b3b9199c9355 Mon Sep 17 00:00:00 2001 From: grunfink Date: Thu, 12 Jun 2025 10:59:26 +0200 Subject: mastoapi: another try to fix collapsing boosted posts in some apps. --- mastoapi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 19aa610..ca44751 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1134,6 +1134,9 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg) bst = xs_dict_set(bst, "content", ""); bst = xs_dict_set(bst, "reblog", st); + xs *b_id = xs_toupper_i(xs_dup(xs_dict_get(st, "id"))); + bst = xs_dict_set(bst, "id", b_id); + xs_free(st); st = bst; } @@ -2338,15 +2341,17 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, /* information about a status */ if (logged_in) { xs *l = xs_split(cmd, "/"); - const char *id = xs_list_get(l, 3); + const char *oid = xs_list_get(l, 3); const char *op = xs_list_get(l, 4); - if (!xs_is_null(id)) { + if (!xs_is_null(oid)) { xs *msg = NULL; xs *out = NULL; /* skip the 'fake' part of the id */ - id = MID_TO_MD5(id); + oid = MID_TO_MD5(oid); + + xs *id = xs_tolower_i(xs_dup(oid)); if (valid_status(object_get_by_md5(id, &msg))) { if (op == NULL) { -- cgit v1.2.3 From f8055ccfb52c5fdf9c08b608060409625982cd05 Mon Sep 17 00:00:00 2001 From: grunfink Date: Mon, 16 Jun 2025 05:11:33 +0200 Subject: mastoapi: added entrypoint /v1/followed_tags. --- mastoapi.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index ca44751..9437f27 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -2483,6 +2483,40 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, } else if (strcmp(cmd, "/v1/followed_tags") == 0) { /** **/ + if (logged_in) { + xs *r = xs_list_new(); + const xs_list *followed_hashtags = xs_dict_get_def(snac1.config, + "followed_hashtags", xs_stock(XSTYPE_LIST)); + const char *hashtag; + + xs_list_foreach(followed_hashtags, hashtag) { + if (*hashtag == '#') { + xs *d = xs_dict_new(); + xs *s = xs_fmt("%s?t=%s", srv_baseurl, hashtag + 1); + + d = xs_dict_set(d, "name", hashtag + 1); + d = xs_dict_set(d, "url", s); + d = xs_dict_set(d, "history", xs_stock(XSTYPE_LIST)); + + r = xs_list_append(r, d); + } + } + + *body = xs_json_dumps(r, 4); + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } + else + status = HTTP_STATUS_UNAUTHORIZED; + } + else + if (strcmp(cmd, "/v1/blocks") == 0) { /** **/ + *body = xs_dup("[]"); + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } + else + if (strcmp(cmd, "/v1/mutes") == 0) { /** **/ *body = xs_dup("[]"); *ctype = "application/json"; status = HTTP_STATUS_OK; -- cgit v1.2.3 From 5a0f23c76a989a389fa3cc1573bc73ef3031964f Mon Sep 17 00:00:00 2001 From: grunfink Date: Mon, 16 Jun 2025 05:44:23 +0200 Subject: mastoapi: Added followed hashtag maintenance. --- mastoapi.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 9437f27..2e8063b 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -3337,6 +3337,54 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, } } } + else + if (xs_startswith(cmd, "/v1/tags/")) { /** **/ + if (logged_in) { + xs *l = xs_split(cmd, "/"); + const char *i_tag = xs_list_get(l, 3); + const char *cmd = xs_list_get(l, 4); + + status = HTTP_STATUS_UNPROCESSABLE_CONTENT; + + if (xs_is_string(i_tag) && xs_is_string(cmd)) { + int ok = 0; + + xs *tag = xs_fmt("#%s", i_tag); + xs *followed_hashtags = xs_dup(xs_dict_get_def(snac.config, + "followed_hashtags", xs_stock(XSTYPE_LIST))); + + if (strcmp(cmd, "follow") == 0) { + followed_hashtags = xs_list_append(followed_hashtags, tag); + ok = 1; + } + else + if (strcmp(cmd, "unfollow") == 0) { + int off = xs_list_in(followed_hashtags, tag); + + if (off != -1) + followed_hashtags = xs_list_del(followed_hashtags, off); + + ok = 1; + } + + if (ok) { + /* update */ + xs_dict_set(snac.config, "followed_hashtags", followed_hashtags); + user_persist(&snac, 0); + + xs *d = xs_dict_new(); + xs *s = xs_fmt("%s?t=%s", srv_baseurl, i_tag); + d = xs_dict_set(d, "name", i_tag); + d = xs_dict_set(d, "url", s); + d = xs_dict_set(d, "history", xs_stock(XSTYPE_LIST)); + + *body = xs_json_dumps(d, 4); + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } + } + } + } else status = HTTP_STATUS_UNPROCESSABLE_CONTENT; -- cgit v1.2.3 From fa986ad91e15bdea6a9764d04fdb90e404d39e55 Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 21 Jun 2025 19:08:38 +0200 Subject: Added support for /api/v1/instance/extended_description (with a hardcoded text). --- mastoapi.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 2e8063b..0829a84 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -2337,6 +2337,21 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, status = HTTP_STATUS_OK; } else + if (strcmp(cmd, "/v1/instance/extended_description") == 0) { /** **/ + xs *d = xs_dict_new(); + xs *greeting = xs_fmt("%s/greeting.html", srv_basedir); + time_t t = mtime(greeting); + xs *updated_at = xs_str_iso_date(t); + xs *content = xs_replace(snac_blurb, "%host%", xs_dict_get(srv_config, "host")); + + d = xs_dict_set(d, "updated_at", updated_at); + d = xs_dict_set(d, "content", content); + + *body = xs_json_dumps(d, 4); + *ctype = "application/json"; + status = HTTP_STATUS_OK; + } + else if (xs_startswith(cmd, "/v1/statuses/")) { /** **/ /* information about a status */ if (logged_in) { -- cgit v1.2.3 From 42895f7be2c77b4dd391beecae0652de719d090c Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 5 Jul 2025 19:11:05 +0200 Subject: mastoapi: fixed a bug in mastoapi_timeline(). --- mastoapi.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index 0829a84..d4e4e08 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1344,9 +1344,9 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn if ((f = fopen(index_fn, "r")) == NULL) return out; - const char *max_id = xs_dict_get(args, "max_id"); - const char *since_id = xs_dict_get(args, "since_id"); - const char *min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */ + const char *o_max_id = xs_dict_get(args, "max_id"); + const char *o_since_id = xs_dict_get(args, "since_id"); + const char *o_min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */ const char *limit_s = xs_dict_get(args, "limit"); int (*iterator)(FILE *, char *); int initial_status = 0; @@ -1354,6 +1354,10 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn int limit = 0; int cnt = 0; + xs *max_id = o_max_id ? xs_tolower_i(xs_dup(o_max_id)) : NULL; + xs *since_id = o_since_id ? xs_tolower_i(xs_dup(o_since_id)) : NULL; + xs *min_id = o_min_id ? xs_tolower_i(xs_dup(o_min_id)) : NULL; + if (!xs_is_null(limit_s)) limit = atoi(limit_s); -- cgit v1.2.3 From daeb5a1cc576d35ea54aaeaec0e65d11d278acef Mon Sep 17 00:00:00 2001 From: grunfink Date: Sat, 5 Jul 2025 19:21:31 +0200 Subject: mastoapi: fixed the fix. --- mastoapi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'mastoapi.c') diff --git a/mastoapi.c b/mastoapi.c index d4e4e08..7fb995a 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1381,7 +1381,7 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn /* only return entries older that max_id */ if (max_id) { if (strcmp(md5, MID_TO_MD5(max_id)) == 0) { - max_id = NULL; + max_id = xs_free(max_id); if (ascending) break; } @@ -1394,7 +1394,7 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn if (strcmp(md5, MID_TO_MD5(since_id)) == 0) { if (!ascending) break; - since_id = NULL; + since_id = xs_free(since_id); } if (ascending) continue; -- cgit v1.2.3