commit 29fb430

default  ·  2024-04-29 07:26:37 +0000 UTC
parent 9a13e33
More work in lists.
4 files changed,  +141, -15
M data.c
M snac.h
M data.c
+36, -2
 1@@ -1732,6 +1732,7 @@ xs_list *tag_search(char *tag, int skip, int show)
 2 /** lists **/
 3 
 4 xs_val *list_maint(snac *user, const char *list, int op)
 5+/* list maintenance */
 6 {
 7     xs_val *l = NULL;
 8 
 9@@ -1810,15 +1811,48 @@ xs_val *list_maint(snac *user, const char *list, int op)
10                 fn = xs_replace_i(fn, ".id", ".lst");
11                 unlink(fn);
12 
13-                fn = xs_replace_i(fn, ".list", ".idx");
14+                fn = xs_replace_i(fn, ".lst", ".idx");
15                 unlink(fn);
16             }
17         }
18 
19         break;
20+    }
21+
22+    return l;
23+}
24+
25+
26+xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op)
27+/* list content management */
28+{
29+    xs_val *l = NULL;
30+
31+    if (!xs_is_hex(list))
32+        return NULL;
33+
34+    if (actor_md5 != NULL && !xs_is_hex(actor_md5))
35+        return NULL;
36+
37+    xs *fn = xs_fmt("%s/list/%s.lst", user->basedir, list);
38+
39+    switch (op) {
40+    case 0: /** list content **/
41+        l = index_list(fn, XS_ALL);
42 
43-    case 3: /** list content (list is the id) **/
44         break;
45+
46+    case 1: /** append actor to list **/
47+        if (actor_md5 != NULL) {
48+            if (!index_in(fn, actor_md5))
49+                index_add_md5(fn, actor_md5);
50+        }
51+
52+        break;
53+
54+    case 2: /** delete actor from list **/
55+        if (actor_md5 != NULL)
56+            index_del_md5(fn, actor_md5);
57     }
58 
59     return l;
+1, -1
1@@ -360,7 +360,7 @@ void httpd_connection(FILE *f)
2 #ifndef NO_MASTODON_API
3         if (status == 0)
4             status = mastoapi_delete_handler(req, q_path,
5-                    &body, &b_size, &ctype);
6+                    payload, p_size, &body, &b_size, &ctype);
7 #endif
8     }
9 
+100, -10
  1@@ -1765,7 +1765,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
  2         status = 200;
  3     }
  4     else
  5-    if (strcmp(cmd, "/v1/lists") == 0) { /** **/
  6+    if (strcmp(cmd, "/v1/lists") == 0) { /** list of lists **/
  7         if (logged_in) {
  8             xs *lol = list_maint(&snac1, NULL, 0);
  9             xs *l   = xs_list_new();
 10@@ -1789,6 +1789,36 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 11         }
 12     }
 13     else
 14+    if (xs_startswith(cmd, "/v1/lists/")) { /** list information **/
 15+        if (logged_in) {
 16+            xs *l = xs_split(cmd, "/");
 17+            char *op = xs_list_get(l, -1);
 18+            char *id = xs_list_get(l, -2);
 19+
 20+            if (op && id && xs_is_hex(id)) {
 21+                if (strcmp(op, "accounts") == 0) {
 22+                    xs *actors = list_content(&snac1, id, NULL, 0);
 23+                    xs *out = xs_list_new();
 24+                    int c = 0;
 25+                    char *v;
 26+
 27+                    while (xs_list_next(actors, &v, &c)) {
 28+                        xs *actor = NULL;
 29+
 30+                        if (valid_status(object_get_by_md5(v, &actor))) {
 31+                            xs *acct = mastoapi_account(actor);
 32+                            out = xs_list_append(out, acct);
 33+                        }
 34+                    }
 35+
 36+                    *body  = xs_json_dumps(out, 4);
 37+                    *ctype = "application/json";
 38+                    status = 200;
 39+                }
 40+            }
 41+        }
 42+    }
 43+    else
 44     if (strcmp(cmd, "/v1/scheduled_statuses") == 0) { /** **/
 45         /* snac does not schedule notes */
 46         *body  = xs_dup("[]");
 47@@ -2676,6 +2706,29 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
 48                 status = 422;
 49         }
 50     }
 51+    if (xs_startswith(cmd, "/v1/lists/")) { /** list maintenance **/
 52+        if (logged_in) {
 53+            xs *l = xs_split(cmd, "/");
 54+            char *op = xs_list_get(l, -1);
 55+            char *id = xs_list_get(l, -2);
 56+
 57+            if (op && id && xs_is_hex(id)) {
 58+                if (strcmp(op, "accounts") == 0) {
 59+                    xs_list *accts = xs_dict_get(args, "account_ids[]");
 60+                    int c = 0;
 61+                    char *v;
 62+
 63+                    while (xs_list_next(accts, &v, &c)) {
 64+                        list_content(&snac, id, v, 1);
 65+                    }
 66+
 67+                    status = 200;
 68+                }
 69+            }
 70+        }
 71+        else
 72+            status = 422;
 73+    }
 74 
 75     /* user cleanup */
 76     if (logged_in)
 77@@ -2688,18 +2741,39 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
 78 
 79 
 80 int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
 81-                             char **body, int *b_size, char **ctype) {
 82-
 83-    (void)req;
 84+                          const char *payload, int p_size,
 85+                          char **body, int *b_size, char **ctype)
 86+{
 87+    (void)p_size;
 88     (void)body;
 89     (void)b_size;
 90     (void)ctype;
 91 
 92-    int status = 404;
 93-
 94     if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
 95         return 0;
 96 
 97+    int status    = 404;
 98+    xs *args      = NULL;
 99+    char *i_ctype = xs_dict_get(req, "content-type");
100+
101+    if (i_ctype && xs_startswith(i_ctype, "application/json")) {
102+        if (!xs_is_null(payload))
103+            args = xs_json_loads(payload);
104+    }
105+    else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded"))
106+    {
107+        // Some apps send form data instead of json so we should cater for those
108+        if (!xs_is_null(payload)) {
109+            xs *upl = xs_url_dec(payload);
110+            args    = xs_url_vars(upl);
111+        }
112+    }
113+    else
114+        args = xs_dup(xs_dict_get(req, "p_vars"));
115+
116+    if (args == NULL)
117+        return 400;
118+
119     snac snac = {0};
120     int logged_in = process_auth_token(&snac, req);
121 
122@@ -2713,10 +2787,26 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
123     if (xs_startswith(cmd, "/v1/lists/")) {
124         if (logged_in) {
125             xs *l = xs_split(cmd, "/");
126-            char *id = xs_list_get(l, -1);
127-
128-            if (xs_is_hex(id)) {
129-                list_maint(&snac, id, 2);
130+            char *p = xs_list_get(l, -1);
131+
132+            if (p) {
133+                if (strcmp(p, "accounts") == 0) {
134+                    /* delete account from list */
135+                    p = xs_list_get(l, -2);
136+                    xs_list *accts = xs_dict_get(args, "account_ids[]");
137+                    int c = 0;
138+                    char *v;
139+
140+                    while (xs_list_next(accts, &v, &c)) {
141+                        list_content(&snac, p, v, 2);
142+                    }
143+                }
144+                else {
145+                    /* delete list */
146+                    if (xs_is_hex(p)) {
147+                        list_maint(&snac, p, 2);
148+                    }
149+                }
150             }
151 
152             status = 200;
M snac.h
+4, -2
 1@@ -175,6 +175,7 @@ void tag_index(const char *id, const xs_dict *obj);
 2 xs_list *tag_search(char *tag, int skip, int show);
 3 
 4 xs_val *list_maint(snac *user, const char *list, int op);
 5+xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op);
 6 
 7 int actor_add(const char *actor, xs_dict *msg);
 8 int actor_get(const char *actor, xs_dict **data);
 9@@ -339,11 +340,12 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
10                        char **body, int *b_size, char **ctype);
11 int mastoapi_get_handler(const xs_dict *req, const char *q_path,
12                          char **body, int *b_size, char **ctype);
13-int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
14-                         char **body, int *b_size, char **ctype);
15 int mastoapi_post_handler(const xs_dict *req, const char *q_path,
16                           const char *payload, int p_size,
17                           char **body, int *b_size, char **ctype);
18+int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
19+                          const char *payload, int p_size,
20+                          char **body, int *b_size, char **ctype);
21 int mastoapi_put_handler(const xs_dict *req, const char *q_path,
22                           const char *payload, int p_size,
23                           char **body, int *b_size, char **ctype);