Browse Source

Merge pull request 'Implement mastoapi markers' (#247) from nowster/snac2:markers into master

Reviewed-on: https://codeberg.org/grunfink/snac2/pulls/247
grunfink 3 months ago
parent
commit
b2316c0aa9
3 changed files with 120 additions and 7 deletions
  1. 66 0
      data.c
  2. 51 7
      mastoapi.c
  3. 3 0
      snac.h

+ 66 - 0
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)

+ 51 - 7
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)

+ 3 - 0
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);