commit b2316c0
Merge pull request 'Implement mastoapi markers' (#247) from nowster/snac2:markers into master Reviewed-on: https://codeberg.org/grunfink/snac2/pulls/247
3 files changed,
+120,
-7
M
data.c
+66,
-0
1@@ -2840,6 +2840,72 @@ xs_str *notify_check_time(snac *snac, int reset)
2 return t;
3 }
4
5+xs_dict *markers_get(snac *snac, const xs_list *markers)
6+{
7+ xs_dict *data = NULL;
8+ xs_dict *returns = xs_dict_new();
9+ xs *fn = xs_fmt("%s/markers.json", snac->basedir);
10+ const xs_str *v = NULL;
11+ FILE *f;
12+
13+ if ((f = fopen(fn, "r")) != NULL) {
14+ data = xs_json_load(f);
15+ fclose(f);
16+ }
17+
18+ if (xs_is_null(data))
19+ data = xs_dict_new();
20+
21+ xs_list_foreach(markers, v) {
22+ const xs_dict *mark = xs_dict_get(data, v);
23+ if (!xs_is_null(mark)) {
24+ returns = xs_dict_append(returns, v, mark);
25+ }
26+ }
27+ return returns;
28+}
29+
30+xs_dict *markers_set(snac *snac, const char *home_marker, const char *notify_marker)
31+/* gets or sets notification marker */
32+{
33+ xs_dict *data = NULL;
34+ xs_dict *written = xs_dict_new();
35+ xs *fn = xs_fmt("%s/markers.json", snac->basedir);
36+ FILE *f;
37+
38+ if ((f = fopen(fn, "r")) != NULL) {
39+ data = xs_json_load(f);
40+ fclose(f);
41+ }
42+
43+ if (xs_is_null(data))
44+ data = xs_dict_new();
45+
46+ if (!xs_is_null(home_marker)) {
47+ xs_dict *home = xs_dict_new();
48+ home = xs_dict_append(home, "last_read_id", home_marker);
49+ home = xs_dict_append(home, "version", xs_stock(0));
50+ home = xs_dict_append(home, "updated_at", tid(0));
51+ data = xs_dict_set(data, "home", home);
52+ written = xs_dict_append(written, "home", home);
53+ }
54+
55+ if (!xs_is_null(notify_marker)) {
56+ xs_dict *notify = xs_dict_new();
57+ notify = xs_dict_append(notify, "last_read_id", notify_marker);
58+ notify = xs_dict_append(notify, "version", xs_stock(0));
59+ notify = xs_dict_append(notify, "updated_at", tid(0));
60+ data = xs_dict_set(data, "notifications", notify);
61+ written = xs_dict_append(written, "notifications", notify);
62+ }
63+
64+ if ((f = fopen(fn, "w")) != NULL) {
65+ xs_json_dump(data, 4, f);
66+ fclose(f);
67+ }
68+
69+ return written;
70+}
71
72 void notify_add(snac *snac, const char *type, const char *utype,
73 const char *actor, const char *objid, const xs_dict *msg)
+51,
-7
1@@ -1788,6 +1788,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
2 xs *out = xs_list_new();
3 const xs_dict *v;
4 const xs_list *excl = xs_dict_get(args, "exclude_types[]");
5+ const char *min_id = xs_dict_get(args, "min_id");
6 const char *max_id = xs_dict_get(args, "max_id");
7
8 xs_list_foreach(l, v) {
9@@ -1814,10 +1815,14 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
10 continue;
11
12 if (max_id) {
13- if (strcmp(fid, max_id) == 0)
14- max_id = NULL;
15+ if (strcmp(fid, max_id) > 0)
16+ continue;
17+ }
18
19- continue;
20+ if (min_id) {
21+ if (strcmp(fid, min_id) <= 0) {
22+ continue;
23+ }
24 }
25
26 /* convert the type */
27@@ -2298,9 +2303,22 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
28 }
29 else
30 if (strcmp(cmd, "/v1/markers") == 0) { /** **/
31- *body = xs_dup("{}");
32- *ctype = "application/json";
33- status = HTTP_STATUS_OK;
34+ if (logged_in) {
35+ const xs_list *timeline = xs_dict_get(args, "timeline[]");
36+ xs_str *json = NULL;
37+ if (!xs_is_null(timeline))
38+ json = xs_json_dumps(markers_get(&snac1, timeline), 4);
39+
40+ if (!xs_is_null(json))
41+ *body = json;
42+ else
43+ *body = xs_dup("{}");
44+
45+ *ctype = "application/json";
46+ status = HTTP_STATUS_OK;
47+ }
48+ else
49+ status = HTTP_STATUS_UNAUTHORIZED;
50 }
51 else
52 if (strcmp(cmd, "/v1/followed_tags") == 0) { /** **/
53@@ -2997,9 +3015,35 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
54 }
55 }
56 }
57+ }
58+ else if (strcmp(cmd, "/v1/markers") == 0) { /** **/
59+ xs_str *json = NULL;
60+ if (logged_in) {
61+ const xs_str *home_marker = xs_dict_get(args, "home[last_read_id]");
62+ if (xs_is_null(home_marker)) {
63+ const xs_dict *home = xs_dict_get(args, "home");
64+ if (!xs_is_null(home))
65+ home_marker = xs_dict_get(home, "last_read_id");
66+ }
67+
68+ const xs_str *notify_marker = xs_dict_get(args, "notifications[last_read_id]");
69+ if (xs_is_null(notify_marker)) {
70+ const xs_dict *notify = xs_dict_get(args, "notifications");
71+ if (!xs_is_null(notify))
72+ notify_marker = xs_dict_get(notify, "last_read_id");
73+ }
74+ json = xs_json_dumps(markers_set(&snac, home_marker, notify_marker), 4);
75+ }
76+ if (!xs_is_null(json))
77+ *body = json;
78 else
79- status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
80+ *body = xs_dup("{}");
81+
82+ *ctype = "application/json";
83+ status = HTTP_STATUS_OK;
84 }
85+ else
86+ status = HTTP_STATUS_UNPROCESSABLE_CONTENT;
87
88 /* user cleanup */
89 if (logged_in)
M
snac.h
+3,
-0
1@@ -236,6 +236,9 @@ int notify_new_num(snac *snac);
2 xs_list *notify_list(snac *snac, int skip, int show);
3 void notify_clear(snac *snac);
4
5+xs_dict *markers_get(snac *snac, const xs_list *markers);
6+xs_dict *markers_set(snac *snac, const char *home_marker, const char *notify_marker);
7+
8 void inbox_add(const char *inbox);
9 void inbox_add_by_actor(const xs_dict *actor);
10 xs_list *inbox_list(void);