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
+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;
M
httpd.c
+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);