commit 02a5006

default  ·  2023-04-09 22:08:51 +0000 UTC
parent ca89f8b
More mastoapi work.
1 files changed,  +137, -8
+137, -8
  1@@ -3,6 +3,7 @@
  2 
  3 #include "xs.h"
  4 #include "xs_encdec.h"
  5+#include "xs_openssl.h"
  6 #include "xs_json.h"
  7 #include "xs_io.h"
  8 #include "xs_time.h"
  9@@ -347,9 +348,9 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 10         printf("mastoapi get:\n%s\n", j);
 11     }
 12 
 13-    int status   = 404;
 14-    xs_dict *msg = xs_dict_get(req, "q_vars");
 15-    xs *cmd      = xs_replace(q_path, "/api/v1", "");
 16+    int status    = 404;
 17+    xs_dict *args = xs_dict_get(req, "q_vars");
 18+    xs *cmd       = xs_replace(q_path, "/api/v1", "");
 19     char *v;
 20 
 21     snac snac = {0};
 22@@ -376,7 +377,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 23 
 24     if (strcmp(cmd, "/accounts/verify_credentials") == 0) {
 25         if (logged_in) {
 26-            xs_dict *acct = xs_dict_new();
 27+            xs *acct = xs_dict_new();
 28 
 29             acct = xs_dict_append(acct, "id",           xs_dict_get(snac.config, "uid"));
 30             acct = xs_dict_append(acct, "username",     xs_dict_get(snac.config, "uid"));
 31@@ -386,12 +387,13 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 32             acct = xs_dict_append(acct, "note",         xs_dict_get(snac.config, "bio"));
 33             acct = xs_dict_append(acct, "url",          snac.actor);
 34 
 35-            xs *avatar = xs_dup(xs_dict_get(snac.config, "avatar"));
 36+            xs *avatar = NULL;
 37+            char *av   = xs_dict_get(snac.config, "avatar");
 38 
 39-            if (xs_is_null(avatar) || *avatar == '\0') {
 40-                xs_free(avatar);
 41+            if (xs_is_null(av) || *av == '\0')
 42                 avatar = xs_fmt("%s/susie.png", srv_baseurl);
 43-            }
 44+            else
 45+                avatar = xs_dup(av);
 46 
 47             acct = xs_dict_append(acct, "avatar", avatar);
 48 
 49@@ -403,6 +405,133 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
 50             status = 422;   // "Unprocessable entity" (no login)
 51         }
 52     }
 53+    else
 54+    if (strcmp(cmd, "/timelines/home") == 0) {
 55+        /* the private timeline */
 56+        if (logged_in) {
 57+            const char *max_id   = xs_dict_get(args, "max_id");
 58+            const char *since_id = xs_dict_get(args, "since_id");
 59+            const char *min_id   = xs_dict_get(args, "min_id");
 60+            const char *limit_s  = xs_dict_get(args, "limit");
 61+            int limit = 20;
 62+            int cnt = 0;
 63+
 64+            if (!xs_is_null(limit_s))
 65+                limit = atoi(limit_s);
 66+
 67+            xs *out      = xs_list_new();
 68+            xs *timeline = timeline_list(&snac, "private", 0, limit);
 69+            xs_list *p = timeline;
 70+            xs_str *v;
 71+
 72+            while (xs_list_iter(&p, &v) && cnt < limit) {
 73+                xs *msg = NULL;
 74+
 75+                if (max_id)
 76+                    break;
 77+
 78+                /* get the entry */
 79+                if (!valid_status(timeline_get_by_md5(&snac, v, &msg)))
 80+                    continue;
 81+
 82+                /* discard not-Notes */
 83+                if (strcmp(xs_dict_get(msg, "type"), "Note") != 0)
 84+                    continue;
 85+
 86+                xs *actor = NULL;
 87+                actor_get(&snac, xs_dict_get(msg, "attributedTo"), &actor);
 88+
 89+                /* if the author is not here, discard */
 90+                if (actor == NULL)
 91+                    continue;
 92+
 93+                xs *acct = xs_dict_new();
 94+
 95+                const char *display_name = xs_dict_get(actor, "name");
 96+                if (xs_is_null(display_name) || *display_name == '\0')
 97+                    display_name = xs_dict_get(actor, "preferredUsername");
 98+
 99+                const char *id = xs_dict_get(actor, "id");
100+                xs *acct_md5 = xs_md5_hex(id, strlen(id));
101+                acct = xs_dict_append(acct, "id",           acct_md5);
102+                acct = xs_dict_append(acct, "username",     xs_dict_get(actor, "preferredUsername"));
103+                acct = xs_dict_append(acct, "acct",         xs_dict_get(actor, "preferredUsername"));
104+                acct = xs_dict_append(acct, "display_name", display_name);
105+                acct = xs_dict_append(acct, "created_at",   xs_dict_get(actor, "published"));
106+                acct = xs_dict_append(acct, "note",         xs_dict_get(actor, "summary"));
107+                acct = xs_dict_append(acct, "url",          id);
108+
109+                xs *avatar  = NULL;
110+                xs_dict *av = xs_dict_get(actor, "icon");
111+
112+                if (xs_type(av) == XSTYPE_DICT)
113+                    avatar = xs_dup(xs_dict_get(av, "url"));
114+                else
115+                    avatar = xs_fmt("%s/susie.png", srv_baseurl);
116+
117+                acct = xs_dict_append(acct, "avatar", avatar);
118+
119+                xs *f  = xs_val_new(XSTYPE_FALSE);
120+                xs *t  = xs_val_new(XSTYPE_TRUE);
121+                xs *n  = xs_val_new(XSTYPE_NULL);
122+                xs *el = xs_list_new();
123+                xs *ed = xs_dict_new();
124+                char *tmp;
125+
126+                xs *st = xs_dict_new();
127+
128+                st = xs_dict_append(st, "id",           v);
129+                st = xs_dict_append(st, "uri",          xs_dict_get(msg, "id"));
130+                st = xs_dict_append(st, "created_at",   xs_dict_get(msg, "published"));
131+                st = xs_dict_append(st, "account",      acct);
132+                st = xs_dict_append(st, "content",      xs_dict_get(msg, "content"));
133+                st = xs_dict_append(st, "visibility",   "public");
134+
135+                tmp = xs_dict_get(msg, "sensitive");
136+                if (xs_is_null(tmp))
137+                    tmp = f;
138+
139+                st = xs_dict_append(st, "sensitive",    tmp);
140+                st = xs_dict_append(st, "spoiler_text", "");
141+
142+                st = xs_dict_append(st, "media_attachments", el);
143+                st = xs_dict_append(st, "mentions",          el);
144+                st = xs_dict_append(st, "tags",              el);
145+                st = xs_dict_append(st, "emojis",            el);
146+
147+                st = xs_dict_append(st, "reblogs_count", xs_number_new(0));
148+                st = xs_dict_append(st, "favourites_count", xs_number_new(0));
149+                st = xs_dict_append(st, "replies_count", xs_number_new(0));
150+
151+                st = xs_dict_append(st, "url",          xs_dict_get(msg, "id"));
152+
153+                st = xs_dict_append(st, "in_reply_to_id",         n);
154+                st = xs_dict_append(st, "in_reply_to_account_id", n);
155+                st = xs_dict_append(st, "reblog",                 n);
156+                st = xs_dict_append(st, "poll",                   n);
157+                st = xs_dict_append(st, "card",                   ed);
158+
159+                st = xs_dict_append(st, "language",  "en");
160+                st = xs_dict_append(st, "text",      "");
161+                st = xs_dict_append(st, "edited_at", n);
162+
163+                out = xs_list_append(out, st);
164+
165+                cnt++;
166+            }
167+
168+            *body  = xs_json_dumps_pp(out, 4);
169+            *ctype = "application/json";
170+            status = 200;
171+        }
172+        else {
173+            status = 401; // unauthorized
174+        }
175+    }
176+    else
177+    if (strcmp(cmd, "/timelines/public") == 0) {
178+        /* the public timeline */
179+    }
180 
181     /* user cleanup */
182     if (logged_in)