commit b2316c0aa9820283978cb43ec8b870db8bbe2f9e
parent 29ac9156e2301eccee492a3ec27ab8fb9168f192
Author: grunfink <grunfink@noreply.codeberg.org>
Date: Fri, 20 Dec 2024 07:31:07 +0000
Merge pull request 'Implement mastoapi markers' (#247) from nowster/snac2:markers into master
Reviewed-on: https://codeberg.org/grunfink/snac2/pulls/247
Diffstat:
M | data.c | | | 66 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | mastoapi.c | | | 58 | +++++++++++++++++++++++++++++++++++++++++++++++++++------- |
M | snac.h | | | 3 | +++ |
3 files changed, 120 insertions(+), 7 deletions(-)
diff --git a/data.c b/data.c
@@ -2840,6 +2840,72 @@ xs_str *notify_check_time(snac *snac, int reset)
return t;
}
+xs_dict *markers_get(snac *snac, const xs_list *markers)
+{
+ xs_dict *data = NULL;
+ xs_dict *returns = xs_dict_new();
+ xs *fn = xs_fmt("%s/markers.json", snac->basedir);
+ const xs_str *v = NULL;
+ FILE *f;
+
+ if ((f = fopen(fn, "r")) != NULL) {
+ data = xs_json_load(f);
+ fclose(f);
+ }
+
+ if (xs_is_null(data))
+ data = xs_dict_new();
+
+ xs_list_foreach(markers, v) {
+ const xs_dict *mark = xs_dict_get(data, v);
+ if (!xs_is_null(mark)) {
+ returns = xs_dict_append(returns, v, mark);
+ }
+ }
+ return returns;
+}
+
+xs_dict *markers_set(snac *snac, const char *home_marker, const char *notify_marker)
+/* gets or sets notification marker */
+{
+ xs_dict *data = NULL;
+ xs_dict *written = xs_dict_new();
+ xs *fn = xs_fmt("%s/markers.json", snac->basedir);
+ FILE *f;
+
+ if ((f = fopen(fn, "r")) != NULL) {
+ data = xs_json_load(f);
+ fclose(f);
+ }
+
+ if (xs_is_null(data))
+ data = xs_dict_new();
+
+ if (!xs_is_null(home_marker)) {
+ xs_dict *home = xs_dict_new();
+ home = xs_dict_append(home, "last_read_id", home_marker);
+ home = xs_dict_append(home, "version", xs_stock(0));
+ home = xs_dict_append(home, "updated_at", tid(0));
+ data = xs_dict_set(data, "home", home);
+ written = xs_dict_append(written, "home", home);
+ }
+
+ if (!xs_is_null(notify_marker)) {
+ xs_dict *notify = xs_dict_new();
+ notify = xs_dict_append(notify, "last_read_id", notify_marker);
+ notify = xs_dict_append(notify, "version", xs_stock(0));
+ notify = xs_dict_append(notify, "updated_at", tid(0));
+ data = xs_dict_set(data, "notifications", notify);
+ written = xs_dict_append(written, "notifications", notify);
+ }
+
+ if ((f = fopen(fn, "w")) != NULL) {
+ xs_json_dump(data, 4, f);
+ fclose(f);
+ }
+
+ return written;
+}
void notify_add(snac *snac, const char *type, const char *utype,
const char *actor, const char *objid, const xs_dict *msg)
diff --git a/mastoapi.c b/mastoapi.c
@@ -1788,6 +1788,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
xs *out = xs_list_new();
const xs_dict *v;
const xs_list *excl = xs_dict_get(args, "exclude_types[]");
+ const char *min_id = xs_dict_get(args, "min_id");
const char *max_id = xs_dict_get(args, "max_id");
xs_list_foreach(l, v) {
@@ -1814,10 +1815,14 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
continue;
if (max_id) {
- if (strcmp(fid, max_id) == 0)
- max_id = NULL;
+ if (strcmp(fid, max_id) > 0)
+ continue;
+ }
- continue;
+ if (min_id) {
+ if (strcmp(fid, min_id) <= 0) {
+ continue;
+ }
}
/* convert the type */
@@ -2298,9 +2303,22 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
}
else
if (strcmp(cmd, "/v1/markers") == 0) { /** **/
- *body = xs_dup("{}");
- *ctype = "application/json";
- status = HTTP_STATUS_OK;
+ if (logged_in) {
+ const xs_list *timeline = xs_dict_get(args, "timeline[]");
+ xs_str *json = NULL;
+ if (!xs_is_null(timeline))
+ json = xs_json_dumps(markers_get(&snac1, timeline), 4);
+
+ if (!xs_is_null(json))
+ *body = json;
+ else
+ *body = xs_dup("{}");
+
+ *ctype = "application/json";
+ status = HTTP_STATUS_OK;
+ }
+ else
+ status = HTTP_STATUS_UNAUTHORIZED;
}
else
if (strcmp(cmd, "/v1/followed_tags") == 0) { /** **/
@@ -2997,9 +3015,35 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
}
}
}
+ }
+ else if (strcmp(cmd, "/v1/markers") == 0) { /** **/
+ xs_str *json = NULL;
+ if (logged_in) {
+ const xs_str *home_marker = xs_dict_get(args, "home[last_read_id]");
+ if (xs_is_null(home_marker)) {
+ const xs_dict *home = xs_dict_get(args, "home");
+ 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");
+ if (!xs_is_null(notify))
+ notify_marker = xs_dict_get(notify, "last_read_id");
+ }
+ json = xs_json_dumps(markers_set(&snac, home_marker, notify_marker), 4);
+ }
+ if (!xs_is_null(json))
+ *body = json;
else
- status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
+ *body = xs_dup("{}");
+
+ *ctype = "application/json";
+ status = HTTP_STATUS_OK;
}
+ else
+ status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
/* user cleanup */
if (logged_in)
diff --git a/snac.h b/snac.h
@@ -236,6 +236,9 @@ int notify_new_num(snac *snac);
xs_list *notify_list(snac *snac, int skip, int show);
void notify_clear(snac *snac);
+xs_dict *markers_get(snac *snac, const xs_list *markers);
+xs_dict *markers_set(snac *snac, const char *home_marker, const char *notify_marker);
+
void inbox_add(const char *inbox);
void inbox_add_by_actor(const xs_dict *actor);
xs_list *inbox_list(void);