Browse Source

More work in lists.

default 11 months ago
parent
commit
29fb430797
4 changed files with 141 additions and 15 deletions
  1. 36 2
      data.c
  2. 1 1
      httpd.c
  3. 100 10
      mastoapi.c
  4. 4 2
      snac.h

+ 36 - 2
data.c

@@ -1732,6 +1732,7 @@ xs_list *tag_search(char *tag, int skip, int show)
 /** lists **/
 
 xs_val *list_maint(snac *user, const char *list, int op)
+/* list maintenance */
 {
     xs_val *l = NULL;
 
@@ -1810,15 +1811,48 @@ xs_val *list_maint(snac *user, const char *list, int op)
                 fn = xs_replace_i(fn, ".id", ".lst");
                 unlink(fn);
 
-                fn = xs_replace_i(fn, ".list", ".idx");
+                fn = xs_replace_i(fn, ".lst", ".idx");
                 unlink(fn);
             }
         }
 
         break;
+    }
+
+    return l;
+}
+
+
+xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op)
+/* list content management */
+{
+    xs_val *l = NULL;
+
+    if (!xs_is_hex(list))
+        return NULL;
+
+    if (actor_md5 != NULL && !xs_is_hex(actor_md5))
+        return NULL;
+
+    xs *fn = xs_fmt("%s/list/%s.lst", user->basedir, list);
+
+    switch (op) {
+    case 0: /** list content **/
+        l = index_list(fn, XS_ALL);
 
-    case 3: /** list content (list is the id) **/
         break;
+
+    case 1: /** append actor to list **/
+        if (actor_md5 != NULL) {
+            if (!index_in(fn, actor_md5))
+                index_add_md5(fn, actor_md5);
+        }
+
+        break;
+
+    case 2: /** delete actor from list **/
+        if (actor_md5 != NULL)
+            index_del_md5(fn, actor_md5);
     }
 
     return l;

+ 1 - 1
httpd.c

@@ -360,7 +360,7 @@ void httpd_connection(FILE *f)
 #ifndef NO_MASTODON_API
         if (status == 0)
             status = mastoapi_delete_handler(req, q_path,
-                    &body, &b_size, &ctype);
+                    payload, p_size, &body, &b_size, &ctype);
 #endif
     }
 

+ 100 - 10
mastoapi.c

@@ -1765,7 +1765,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
         status = 200;
     }
     else
-    if (strcmp(cmd, "/v1/lists") == 0) { /** **/
+    if (strcmp(cmd, "/v1/lists") == 0) { /** list of lists **/
         if (logged_in) {
             xs *lol = list_maint(&snac1, NULL, 0);
             xs *l   = xs_list_new();
@@ -1789,6 +1789,36 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
         }
     }
     else
+    if (xs_startswith(cmd, "/v1/lists/")) { /** list information **/
+        if (logged_in) {
+            xs *l = xs_split(cmd, "/");
+            char *op = xs_list_get(l, -1);
+            char *id = xs_list_get(l, -2);
+
+            if (op && id && xs_is_hex(id)) {
+                if (strcmp(op, "accounts") == 0) {
+                    xs *actors = list_content(&snac1, id, NULL, 0);
+                    xs *out = xs_list_new();
+                    int c = 0;
+                    char *v;
+
+                    while (xs_list_next(actors, &v, &c)) {
+                        xs *actor = NULL;
+
+                        if (valid_status(object_get_by_md5(v, &actor))) {
+                            xs *acct = mastoapi_account(actor);
+                            out = xs_list_append(out, acct);
+                        }
+                    }
+
+                    *body  = xs_json_dumps(out, 4);
+                    *ctype = "application/json";
+                    status = 200;
+                }
+            }
+        }
+    }
+    else
     if (strcmp(cmd, "/v1/scheduled_statuses") == 0) { /** **/
         /* snac does not schedule notes */
         *body  = xs_dup("[]");
@@ -2676,6 +2706,29 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
                 status = 422;
         }
     }
+    if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/
+        if (logged_in) {
+            xs *l = xs_split(cmd, "/");
+            char *op = xs_list_get(l, -1);
+            char *id = xs_list_get(l, -2);
+
+            if (op && id && xs_is_hex(id)) {
+                if (strcmp(op, "accounts") == 0) {
+                    xs_list *accts = xs_dict_get(args, "account_ids[]");
+                    int c = 0;
+                    char *v;
+
+                    while (xs_list_next(accts, &v, &c)) {
+                        list_content(&snac, id, v, 1);
+                    }
+
+                    status = 200;
+                }
+            }
+        }
+        else
+            status = 422;
+    }
 
     /* user cleanup */
     if (logged_in)
@@ -2688,18 +2741,39 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
 
 
 int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
-                             char **body, int *b_size, char **ctype) {
-
-    (void)req;
+                          const char *payload, int p_size,
+                          char **body, int *b_size, char **ctype)
+{
+    (void)p_size;
     (void)body;
     (void)b_size;
     (void)ctype;
 
-    int status = 404;
-
     if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
         return 0;
 
+    int status    = 404;
+    xs *args      = NULL;
+    char *i_ctype = xs_dict_get(req, "content-type");
+
+    if (i_ctype && xs_startswith(i_ctype, "application/json")) {
+        if (!xs_is_null(payload))
+            args = xs_json_loads(payload);
+    }
+    else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded"))
+    {
+        // Some apps send form data instead of json so we should cater for those
+        if (!xs_is_null(payload)) {
+            xs *upl = xs_url_dec(payload);
+            args    = xs_url_vars(upl);
+        }
+    }
+    else
+        args = xs_dup(xs_dict_get(req, "p_vars"));
+
+    if (args == NULL)
+        return 400;
+
     snac snac = {0};
     int logged_in = process_auth_token(&snac, req);
 
@@ -2713,10 +2787,26 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
     if (xs_startswith(cmd, "/v1/lists/")) {
         if (logged_in) {
             xs *l = xs_split(cmd, "/");
-            char *id = xs_list_get(l, -1);
-
-            if (xs_is_hex(id)) {
-                list_maint(&snac, id, 2);
+            char *p = xs_list_get(l, -1);
+
+            if (p) {
+                if (strcmp(p, "accounts") == 0) {
+                    /* delete account from list */
+                    p = xs_list_get(l, -2);
+                    xs_list *accts = xs_dict_get(args, "account_ids[]");
+                    int c = 0;
+                    char *v;
+
+                    while (xs_list_next(accts, &v, &c)) {
+                        list_content(&snac, p, v, 2);
+                    }
+                }
+                else {
+                    /* delete list */
+                    if (xs_is_hex(p)) {
+                        list_maint(&snac, p, 2);
+                    }
+                }
             }
 
             status = 200;

+ 4 - 2
snac.h

@@ -175,6 +175,7 @@ void tag_index(const char *id, const xs_dict *obj);
 xs_list *tag_search(char *tag, int skip, int show);
 
 xs_val *list_maint(snac *user, const char *list, int op);
+xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
 
 int actor_add(const char *actor, xs_dict *msg);
 int actor_get(const char *actor, xs_dict **data);
@@ -339,11 +340,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
                        char **body, int *b_size, char **ctype);
 int mastoapi_get_handler(const xs_dict *req, const char *q_path,
                          char **body, int *b_size, char **ctype);
-int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
-                         char **body, int *b_size, char **ctype);
 int mastoapi_post_handler(const xs_dict *req, const char *q_path,
                           const char *payload, int p_size,
                           char **body, int *b_size, char **ctype);
+int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
+                          const char *payload, int p_size,
+                          char **body, int *b_size, char **ctype);
 int mastoapi_put_handler(const xs_dict *req, const char *q_path,
                           const char *payload, int p_size,
                           char **body, int *b_size, char **ctype);