commit f90d4b2
default
·
2023-06-07 09:15:58 +0000 UTC
parent 125317a
New function timeline_request_replies(). This function downloads and stores all replies to a message, recursively. Increases traffic. Mastodon instances request the user actor again and again without caching (when the 'replies' Collection is downloaded). Maybe I'm not doing something correctly?
1 files changed,
+67,
-7
+67,
-7
1@@ -143,16 +143,18 @@ int actor_request(snac *snac, const char *actor, xs_dict **data)
2 }
3
4
5-int timeline_request(snac *snac, char **id, d_char **wrk)
6+void timeline_request_replies(snac *user, const xs_dict *msg);
7+
8+int timeline_request(snac *snac, char **id, xs_str **wrk)
9 /* ensures that an entry and its ancestors are in the timeline */
10 {
11 int status = 0;
12
13 if (!xs_is_null(*id)) {
14- /* is the admired object already there? */
15- if (!object_here(*id)) {
16- xs *object = NULL;
17+ xs *object = NULL;
18
19+ /* is the object already there? */
20+ if (!valid_status(object_get(*id, &object))) {
21 /* no; download it */
22 status = activitypub_request(snac, *id, &object);
23
24@@ -180,20 +182,78 @@ int timeline_request(snac *snac, char **id, d_char **wrk)
25 /* does it have an ancestor? */
26 char *in_reply_to = xs_dict_get(object, "inReplyTo");
27
28+ /* store */
29+ timeline_add(snac, *id, object);
30+
31 /* recurse! */
32 timeline_request(snac, &in_reply_to, NULL);
33-
34- /* finally store */
35- timeline_add(snac, *id, object);
36 }
37 }
38 }
39+
40+ if (object)
41+ timeline_request_replies(snac, object);
42 }
43
44 return status;
45 }
46
47
48+void timeline_request_replies(snac *user, const xs_dict *msg)
49+/* requests all replies of a message */
50+/* FIXME: experimental -- needs more testing */
51+{
52+ /* does it have a replies collection? */
53+ const xs_dict *replies = xs_dict_get(msg, "replies");
54+
55+ if (!xs_is_null(replies)) {
56+ const char *type = xs_dict_get(replies, "type");
57+ const char *first = xs_dict_get(replies, "first");
58+
59+ if (!xs_is_null(type) && !xs_is_null(first) && strcmp(type, "Collection") == 0) {
60+ const char *next = xs_dict_get(first, "next");
61+
62+ if (!xs_is_null(next)) {
63+ xs *rpls = NULL;
64+ int status = activitypub_request(user, next, &rpls);
65+
66+ /* request the Collection of replies */
67+ if (valid_status(status)) {
68+ xs_list *items = xs_dict_get(rpls, "items");
69+
70+ if (xs_type(items) == XSTYPE_LIST) {
71+ xs_val *v;
72+
73+ /* request them all */
74+ while (xs_list_iter(&items, &v)) {
75+ if (xs_type(v) == XSTYPE_DICT) {
76+ /* not an id, but the object itself (!) */
77+ const char *id = xs_dict_get(v, "id");
78+
79+ if (!xs_is_null(id)) {
80+ snac_debug(user, 0, xs_fmt("embedded reply %s", id));
81+
82+ object_add(id, v);
83+
84+ /* get its own children */
85+ timeline_request_replies(user, v);
86+ }
87+ }
88+ else {
89+ snac_debug(user, 0, xs_fmt("request reply %s", v));
90+ timeline_request(user, &v, NULL);
91+ }
92+ }
93+ }
94+ }
95+ else
96+ snac_debug(user, 0, xs_fmt("reply collection get %s %d", next, status));
97+ }
98+ }
99+ }
100+}
101+
102+
103 int send_to_inbox_raw(const char *keyid, const char *seckey,
104 const xs_str *inbox, const xs_dict *msg,
105 xs_val **payload, int *p_size, int timeout)