From 339dc1a3255f39087476fa511e94d98016b76338 Mon Sep 17 00:00:00 2001 From: default Date: Fri, 9 Aug 2024 16:57:14 +0200 Subject: [PATCH] Use index_desc_first() / index_desc_next() in mastoapi_timeline(). --- mastoapi.c | 157 +++++++++++++++++++++++++++++------------------------ 1 file changed, 85 insertions(+), 72 deletions(-) diff --git a/mastoapi.c b/mastoapi.c index 7f9ec6c..4d920de 100644 --- a/mastoapi.c +++ b/mastoapi.c @@ -1261,9 +1261,20 @@ void credentials_get(char **body, char **ctype, int *status, snac snac) } -xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index) +xs_list *mastoapi_timeline(snac *user, const xs_dict *args, int skip, const char *index_fn) { - xs_list *out = xs_list_new(); + xs_list *out = xs_list_new(); + FILE *f; + char md5[MD5_HEX_SIZE]; + + if (dbglevel) { + xs *js = xs_json_dumps(args, 0); + srv_log(xs_fmt("mastoapi_timeline args: %s", js)); + } + + 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"); @@ -1277,86 +1288,87 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index) if (limit == 0) limit = 20; - xs *timeline = timeline_simple_list(user, index, 0, 2048); + if (index_desc_first(f, md5, skip)) { + do { + xs *msg = NULL; - xs_list *p = timeline; - const xs_str *v; + /* only return entries older that max_id */ + if (max_id) { + if (strcmp(md5, MID_TO_MD5(max_id)) == 0) + max_id = NULL; - while (xs_list_iter(&p, &v) && cnt < limit) { - xs *msg = NULL; - - /* only return entries older that max_id */ - if (max_id) { - if (strcmp(v, MID_TO_MD5(max_id)) == 0) - max_id = NULL; - - continue; - } - - /* only returns entries newer than since_id */ - if (since_id) { - if (strcmp(v, MID_TO_MD5(since_id)) == 0) - break; - } - - /* only returns entries newer than min_id */ - /* what does really "Return results immediately newer than ID" mean? */ - if (min_id) { - if (strcmp(v, MID_TO_MD5(min_id)) == 0) - break; - } - - /* get the entry */ - if (!valid_status(timeline_get_by_md5(user, v, &msg))) - continue; - - /* discard non-Notes */ - const char *id = xs_dict_get(msg, "id"); - const char *type = xs_dict_get(msg, "type"); - if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) - continue; - - const char *from = NULL; - if (strcmp(type, "Page") == 0) - from = xs_dict_get(msg, "audience"); - - if (from == NULL) - from = get_atto(msg); - - if (from == NULL) - continue; - - /* is this message from a person we don't follow? */ - if (strcmp(from, user->actor) && !following_check(user, from)) { - /* discard if it was not boosted */ - xs *idx = object_announces(id); - - if (xs_list_len(idx) == 0) continue; - } + } - /* discard notes from muted morons */ - if (is_muted(user, from)) - continue; + /* only returns entries newer than since_id */ + if (since_id) { + if (strcmp(md5, MID_TO_MD5(since_id)) == 0) + break; + } - /* discard hidden notes */ - if (is_hidden(user, id)) - continue; + /* only returns entries newer than min_id */ + /* what does really "Return results immediately newer than ID" mean? */ + if (min_id) { + if (strcmp(md5, MID_TO_MD5(min_id)) == 0) + break; + } - /* if it has a name and it's not a Page or a Video, - it's a poll vote, so discard it */ - if (!xs_is_null(xs_dict_get(msg, "name")) && !xs_match(type, "Page|Video")) - continue; + /* get the entry */ + if (!valid_status(timeline_get_by_md5(user, md5, &msg))) + continue; - /* convert the Note into a Mastodon status */ - xs *st = mastoapi_status(user, msg); + /* discard non-Notes */ + const char *id = xs_dict_get(msg, "id"); + const char *type = xs_dict_get(msg, "type"); + if (!xs_match(type, POSTLIKE_OBJECT_TYPE)) + continue; - if (st != NULL) - out = xs_list_append(out, st); + const char *from = NULL; + if (strcmp(type, "Page") == 0) + from = xs_dict_get(msg, "audience"); - cnt++; + if (from == NULL) + from = get_atto(msg); + + if (from == NULL) + continue; + + /* is this message from a person we don't follow? */ + if (strcmp(from, user->actor) && !following_check(user, from)) { + /* discard if it was not boosted */ + xs *idx = object_announces(id); + + if (xs_list_len(idx) == 0) + continue; + } + + /* discard notes from muted morons */ + if (is_muted(user, from)) + continue; + + /* discard hidden notes */ + if (is_hidden(user, id)) + continue; + + /* if it has a name and it's not a Page or a Video, + it's a poll vote, so discard it */ + if (!xs_is_null(xs_dict_get(msg, "name")) && !xs_match(type, "Page|Video")) + continue; + + /* convert the Note into a Mastodon status */ + xs *st = mastoapi_status(user, msg); + + if (st != NULL) + out = xs_list_append(out, st); + + cnt++; + } while (cnt < limit && index_desc_next(f, md5)); } + fclose(f); + + srv_debug(1, xs_fmt("mastoapi_timeline: %d %d", cnt, xs_list_len(out))); + return out; } @@ -1619,7 +1631,8 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, if (strcmp(cmd, "/v1/timelines/home") == 0) { /** **/ /* the private timeline */ if (logged_in) { - xs *out = mastoapi_timeline(&snac1, args, "private"); + xs *ifn = user_index_fn(&snac1, "private"); + xs *out = mastoapi_timeline(&snac1, args, 0, ifn); *body = xs_json_dumps(out, 4); *ctype = "application/json";