commit 79224ca
default
·
2023-04-11 07:50:12 +0000 UTC
parent 7c9846e
New function mastodon_status().
3 files changed,
+182,
-171
+3,
-3
1@@ -242,7 +242,7 @@ int send_to_actor(snac *snac, char *actor, char *msg, d_char **payload, int *p_s
2 }
3
4
5-d_char *recipient_list(snac *snac, char *msg, int expand_public)
6+xs_list *recipient_list(snac *snac, const xs_dict *msg, int expand_public)
7 /* returns the list of recipients for a message */
8 {
9 char *to = xs_dict_get(msg, "to");
10@@ -285,7 +285,7 @@ d_char *recipient_list(snac *snac, char *msg, int expand_public)
11 }
12
13
14-int is_msg_public(snac *snac, xs_dict *msg)
15+int is_msg_public(snac *snac, const xs_dict *msg)
16 /* checks if a message is public */
17 {
18 xs *rcpts = recipient_list(snac, msg, 0);
19@@ -294,7 +294,7 @@ int is_msg_public(snac *snac, xs_dict *msg)
20 }
21
22
23-int is_msg_for_me(snac *snac, xs_dict *c_msg)
24+int is_msg_for_me(snac *snac, const xs_dict *c_msg)
25 /* checks if this message is for me */
26 {
27 const char *type = xs_dict_get(c_msg, "type");
+177,
-166
1@@ -403,7 +403,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
2 xs_str *mastoapi_id(const xs_dict *msg)
3 /* returns a somewhat Mastodon-compatible status id */
4 {
5- char tmp[256] = "";
6+ char tmp[15] = "";
7 int n = 0;
8 const char *id = xs_dict_get(msg, "id");
9 const char *published = xs_dict_get(msg, "published");
10@@ -424,6 +424,178 @@ xs_str *mastoapi_id(const xs_dict *msg)
11 }
12
13
14+xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
15+/* converts an ActivityPub note to a Mastodon status */
16+{
17+ xs *actor = NULL;
18+ actor_get(snac, xs_dict_get(msg, "attributedTo"), &actor);
19+
20+ /* if the author is not here, discard */
21+ if (actor == NULL)
22+ return NULL;
23+
24+ /** shave the yak converting an ActivityPub Note to a Mastodon status **/
25+
26+ xs *acct = xs_dict_new();
27+
28+ const char *display_name = xs_dict_get(actor, "name");
29+ if (xs_is_null(display_name) || *display_name == '\0')
30+ display_name = xs_dict_get(actor, "preferredUsername");
31+
32+ const char *id = xs_dict_get(actor, "id");
33+ const char *pub = xs_dict_get(actor, "published");
34+ xs *acct_md5 = xs_md5_hex(id, strlen(id));
35+ acct = xs_dict_append(acct, "id", acct_md5);
36+ acct = xs_dict_append(acct, "username", xs_dict_get(actor, "preferredUsername"));
37+ acct = xs_dict_append(acct, "acct", xs_dict_get(actor, "preferredUsername"));
38+ acct = xs_dict_append(acct, "display_name", display_name);
39+
40+ if (pub)
41+ acct = xs_dict_append(acct, "created_at", pub);
42+
43+ acct = xs_dict_append(acct, "note", xs_dict_get(actor, "summary"));
44+ acct = xs_dict_append(acct, "url", id);
45+
46+ xs *avatar = NULL;
47+ xs_dict *av = xs_dict_get(actor, "icon");
48+
49+ if (xs_type(av) == XSTYPE_DICT)
50+ avatar = xs_dup(xs_dict_get(av, "url"));
51+ else
52+ avatar = xs_fmt("%s/susie.png", srv_baseurl);
53+
54+ acct = xs_dict_append(acct, "avatar", avatar);
55+
56+ xs *f = xs_val_new(XSTYPE_FALSE);
57+ xs *t = xs_val_new(XSTYPE_TRUE);
58+ xs *n = xs_val_new(XSTYPE_NULL);
59+ xs *el = xs_list_new();
60+ xs *idx = NULL;
61+ xs *ixc = NULL;
62+
63+ char *tmp;
64+ id = xs_dict_get(msg, "id");
65+ xs *mid = mastoapi_id(msg);
66+
67+ xs_dict *st = xs_dict_new();
68+
69+ st = xs_dict_append(st, "id", mid);
70+ st = xs_dict_append(st, "uri", id);
71+ st = xs_dict_append(st, "url", id);
72+ st = xs_dict_append(st, "created_at", xs_dict_get(msg, "published"));
73+ st = xs_dict_append(st, "account", acct);
74+ st = xs_dict_append(st, "content", xs_dict_get(msg, "content"));
75+
76+ st = xs_dict_append(st, "visibility",
77+ is_msg_public(snac, msg) ? "public" : "private");
78+
79+ tmp = xs_dict_get(msg, "sensitive");
80+ if (xs_is_null(tmp))
81+ tmp = f;
82+
83+ st = xs_dict_append(st, "sensitive", tmp);
84+
85+ tmp = xs_dict_get(msg, "summary");
86+ if (xs_is_null(tmp))
87+ tmp = "";
88+
89+ st = xs_dict_append(st, "spoiler_text", tmp);
90+
91+ /* create the list of attachments */
92+ xs *matt = xs_list_new();
93+ xs_list *att = xs_dict_get(msg, "attachment");
94+ xs_str *aobj;
95+
96+ while (xs_list_iter(&att, &aobj)) {
97+ const char *mtype = xs_dict_get(aobj, "mediaType");
98+
99+ if (!xs_is_null(mtype) && xs_startswith(mtype, "image/")) {
100+ xs *matteid = xs_fmt("%s_%d", id, xs_list_len(matt));
101+ xs *matte = xs_dict_new();
102+
103+ matte = xs_dict_append(matte, "id", matteid);
104+ matte = xs_dict_append(matte, "type", "image");
105+ matte = xs_dict_append(matte, "url", xs_dict_get(aobj, "url"));
106+ matte = xs_dict_append(matte, "preview_url", xs_dict_get(aobj, "url"));
107+ matte = xs_dict_append(matte, "remote_url", xs_dict_get(aobj, "url"));
108+ matte = xs_dict_append(matte, "description", xs_dict_get(aobj, "name"));
109+
110+ matt = xs_list_append(matt, matte);
111+ }
112+ }
113+
114+ st = xs_dict_append(st, "media_attachments", matt);
115+
116+ st = xs_dict_append(st, "mentions", el);
117+ st = xs_dict_append(st, "tags", el);
118+ st = xs_dict_append(st, "emojis", el);
119+
120+ xs_free(idx);
121+ xs_free(ixc);
122+ idx = object_likes(id);
123+ ixc = xs_number_new(xs_list_len(idx));
124+
125+ st = xs_dict_append(st, "favourites_count", ixc);
126+ st = xs_dict_append(st, "favourited",
127+ xs_list_in(idx, snac->md5) != -1 ? t : f);
128+
129+ xs_free(idx);
130+ xs_free(ixc);
131+ idx = object_announces(id);
132+ ixc = xs_number_new(xs_list_len(idx));
133+
134+ st = xs_dict_append(st, "reblogs_count", ixc);
135+ st = xs_dict_append(st, "reblogged",
136+ xs_list_in(idx, snac->md5) != -1 ? t : f);
137+
138+ xs_free(idx);
139+ xs_free(ixc);
140+ idx = object_children(id);
141+ ixc = xs_number_new(xs_list_len(idx));
142+
143+ st = xs_dict_append(st, "replies_count", ixc);
144+
145+ /* default in_reply_to values */
146+ st = xs_dict_append(st, "in_reply_to_id", n);
147+ st = xs_dict_append(st, "in_reply_to_account_id", n);
148+
149+ tmp = xs_dict_get(msg, "inReplyTo");
150+ if (!xs_is_null(tmp)) {
151+ xs *irto = NULL;
152+
153+ if (valid_status(object_get(tmp, &irto))) {
154+ xs *irt_mid = mastoapi_id(irto);
155+ st = xs_dict_set(st, "in_reply_to_id", irt_mid);
156+
157+ char *at = NULL;
158+ if (!xs_is_null(at = xs_dict_get(irto, "attributedTo"))) {
159+ xs *at_md5 = xs_md5_hex(at, strlen(at));
160+ st = xs_dict_set(st, "in_reply_to_account_id", at_md5);
161+ }
162+ }
163+ }
164+
165+ st = xs_dict_append(st, "reblog", n);
166+ st = xs_dict_append(st, "poll", n);
167+ st = xs_dict_append(st, "card", n);
168+ st = xs_dict_append(st, "language", n);
169+
170+ tmp = xs_dict_get(msg, "sourceContent");
171+ if (xs_is_null(tmp))
172+ tmp = "";
173+
174+ st = xs_dict_append(st, "text", tmp);
175+
176+ tmp = xs_dict_get(msg, "updated");
177+ if (xs_is_null(tmp))
178+ tmp = n;
179+
180+ st = xs_dict_append(st, "edited_at", tmp);
181+
182+ return st;
183+}
184+
185+
186 int mastoapi_get_handler(const xs_dict *req, const char *q_path,
187 char **body, int *b_size, char **ctype)
188 {
189@@ -548,172 +720,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
190 if (strcmp(xs_dict_get(msg, "type"), "Note") != 0)
191 continue;
192
193- xs *actor = NULL;
194- actor_get(&snac, xs_dict_get(msg, "attributedTo"), &actor);
195-
196- /* if the author is not here, discard */
197- if (actor == NULL)
198- continue;
199-
200- /** shave the yak converting an ActivityPub Note to a Mastodon status **/
201-
202- xs *acct = xs_dict_new();
203-
204- const char *display_name = xs_dict_get(actor, "name");
205- if (xs_is_null(display_name) || *display_name == '\0')
206- display_name = xs_dict_get(actor, "preferredUsername");
207-
208- const char *id = xs_dict_get(actor, "id");
209- const char *pub = xs_dict_get(actor, "published");
210- xs *acct_md5 = xs_md5_hex(id, strlen(id));
211- acct = xs_dict_append(acct, "id", acct_md5);
212- acct = xs_dict_append(acct, "username", xs_dict_get(actor, "preferredUsername"));
213- acct = xs_dict_append(acct, "acct", xs_dict_get(actor, "preferredUsername"));
214- acct = xs_dict_append(acct, "display_name", display_name);
215-
216- if (pub)
217- acct = xs_dict_append(acct, "created_at", pub);
218-
219- acct = xs_dict_append(acct, "note", xs_dict_get(actor, "summary"));
220- acct = xs_dict_append(acct, "url", id);
221-
222- xs *avatar = NULL;
223- xs_dict *av = xs_dict_get(actor, "icon");
224-
225- if (xs_type(av) == XSTYPE_DICT)
226- avatar = xs_dup(xs_dict_get(av, "url"));
227- else
228- avatar = xs_fmt("%s/susie.png", srv_baseurl);
229-
230- acct = xs_dict_append(acct, "avatar", avatar);
231-
232- xs *f = xs_val_new(XSTYPE_FALSE);
233- xs *t = xs_val_new(XSTYPE_TRUE);
234- xs *n = xs_val_new(XSTYPE_NULL);
235- xs *el = xs_list_new();
236- xs *idx = NULL;
237- xs *ixc = NULL;
238-
239- char *tmp;
240- id = xs_dict_get(msg, "id");
241- xs *mid = mastoapi_id(msg);
242-
243- xs *st = xs_dict_new();
244-
245- st = xs_dict_append(st, "id", mid);
246- st = xs_dict_append(st, "uri", id);
247- st = xs_dict_append(st, "url", id);
248- st = xs_dict_append(st, "created_at", xs_dict_get(msg, "published"));
249- st = xs_dict_append(st, "account", acct);
250- st = xs_dict_append(st, "content", xs_dict_get(msg, "content"));
251-
252- st = xs_dict_append(st, "visibility",
253- is_msg_public(&snac, msg) ? "public" : "private");
254-
255- tmp = xs_dict_get(msg, "sensitive");
256- if (xs_is_null(tmp))
257- tmp = f;
258-
259- st = xs_dict_append(st, "sensitive", tmp);
260-
261- tmp = xs_dict_get(msg, "summary");
262- if (xs_is_null(tmp))
263- tmp = "";
264-
265- st = xs_dict_append(st, "spoiler_text", tmp);
266-
267- /* create the list of attachments */
268- xs *matt = xs_list_new();
269- xs_list *att = xs_dict_get(msg, "attachment");
270- xs_str *aobj;
271-
272- while (xs_list_iter(&att, &aobj)) {
273- const char *mtype = xs_dict_get(aobj, "mediaType");
274-
275- if (!xs_is_null(mtype) && xs_startswith(mtype, "image/")) {
276- xs *matteid = xs_fmt("%s_%d", id, xs_list_len(matt));
277- xs *matte = xs_dict_new();
278-
279- matte = xs_dict_append(matte, "id", matteid);
280- matte = xs_dict_append(matte, "type", "image");
281- matte = xs_dict_append(matte, "url", xs_dict_get(aobj, "url"));
282- matte = xs_dict_append(matte, "preview_url", xs_dict_get(aobj, "url"));
283- matte = xs_dict_append(matte, "remote_url", xs_dict_get(aobj, "url"));
284- matte = xs_dict_append(matte, "description", xs_dict_get(aobj, "name"));
285-
286- matt = xs_list_append(matt, matte);
287- }
288- }
289-
290- st = xs_dict_append(st, "media_attachments", matt);
291-
292- st = xs_dict_append(st, "mentions", el);
293- st = xs_dict_append(st, "tags", el);
294- st = xs_dict_append(st, "emojis", el);
295-
296- xs_free(idx);
297- xs_free(ixc);
298- idx = object_likes(id);
299- ixc = xs_number_new(xs_list_len(idx));
300-
301- st = xs_dict_append(st, "favourites_count", ixc);
302- st = xs_dict_append(st, "favourited",
303- xs_list_in(idx, snac.md5) != -1 ? t : f);
304-
305- xs_free(idx);
306- xs_free(ixc);
307- idx = object_announces(id);
308- ixc = xs_number_new(xs_list_len(idx));
309-
310- st = xs_dict_append(st, "reblogs_count", ixc);
311- st = xs_dict_append(st, "reblogged",
312- xs_list_in(idx, snac.md5) != -1 ? t : f);
313-
314- xs_free(idx);
315- xs_free(ixc);
316- idx = object_children(id);
317- ixc = xs_number_new(xs_list_len(idx));
318-
319- st = xs_dict_append(st, "replies_count", ixc);
320-
321- /* default in_reply_to values */
322- st = xs_dict_append(st, "in_reply_to_id", n);
323- st = xs_dict_append(st, "in_reply_to_account_id", n);
324-
325- tmp = xs_dict_get(msg, "inReplyTo");
326- if (!xs_is_null(tmp)) {
327- xs *irto = NULL;
328-
329- if (valid_status(object_get(tmp, &irto))) {
330- xs *irt_mid = mastoapi_id(irto);
331- st = xs_dict_set(st, "in_reply_to_id", irt_mid);
332-
333- char *at = NULL;
334- if (!xs_is_null(at = xs_dict_get(irto, "attributedTo"))) {
335- xs *at_md5 = xs_md5_hex(at, strlen(at));
336- st = xs_dict_set(st, "in_reply_to_account_id", at_md5);
337- }
338- }
339- }
340-
341- st = xs_dict_append(st, "reblog", n);
342- st = xs_dict_append(st, "poll", n);
343- st = xs_dict_append(st, "card", n);
344- st = xs_dict_append(st, "language", n);
345-
346- tmp = xs_dict_get(msg, "sourceContent");
347- if (xs_is_null(tmp))
348- tmp = "";
349-
350- st = xs_dict_append(st, "text", tmp);
351-
352- tmp = xs_dict_get(msg, "updated");
353- if (xs_is_null(tmp))
354- tmp = n;
355-
356- st = xs_dict_append(st, "edited_at", tmp);
357+ /* convert the Note into a Mastodon status */
358+ xs *st = mastoapi_status(&snac, msg);
359
360- out = xs_list_append(out, st);
361+ if (st != NULL)
362+ out = xs_list_append(out, st);
363
364 cnt++;
365 }
M
snac.h
+2,
-2
1@@ -196,8 +196,8 @@ int send_to_inbox(snac *snac, const xs_str *inbox, const xs_dict *msg,
2 xs_val **payload, int *p_size, int timeout);
3 d_char *get_actor_inbox(snac *snac, char *actor);
4 int send_to_actor(snac *snac, char *actor, char *msg, d_char **payload, int *p_size, int timeout);
5-int is_msg_public(snac *snac, xs_dict *msg);
6-int is_msg_for_me(snac *snac, xs_dict *msg);
7+int is_msg_public(snac *snac, const xs_dict *msg);
8+int is_msg_for_me(snac *snac, const xs_dict *msg);
9
10 int process_user_queue(snac *snac);
11 void process_queue_item(xs_dict *q_item);