summaryrefslogtreecommitdiff
path: root/activitypub.c
diff options
context:
space:
mode:
Diffstat (limited to 'activitypub.c')
-rw-r--r--activitypub.c74
1 files changed, 67 insertions, 7 deletions
diff --git a/activitypub.c b/activitypub.c
index f5898b4..06d4117 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -143,16 +143,18 @@ int actor_request(snac *snac, const char *actor, xs_dict **data)
143} 143}
144 144
145 145
146int timeline_request(snac *snac, char **id, d_char **wrk) 146void timeline_request_replies(snac *user, const xs_dict *msg);
147
148int timeline_request(snac *snac, char **id, xs_str **wrk)
147/* ensures that an entry and its ancestors are in the timeline */ 149/* ensures that an entry and its ancestors are in the timeline */
148{ 150{
149 int status = 0; 151 int status = 0;
150 152
151 if (!xs_is_null(*id)) { 153 if (!xs_is_null(*id)) {
152 /* is the admired object already there? */ 154 xs *object = NULL;
153 if (!object_here(*id)) {
154 xs *object = NULL;
155 155
156 /* is the object already there? */
157 if (!valid_status(object_get(*id, &object))) {
156 /* no; download it */ 158 /* no; download it */
157 status = activitypub_request(snac, *id, &object); 159 status = activitypub_request(snac, *id, &object);
158 160
@@ -180,20 +182,78 @@ int timeline_request(snac *snac, char **id, d_char **wrk)
180 /* does it have an ancestor? */ 182 /* does it have an ancestor? */
181 char *in_reply_to = xs_dict_get(object, "inReplyTo"); 183 char *in_reply_to = xs_dict_get(object, "inReplyTo");
182 184
185 /* store */
186 timeline_add(snac, *id, object);
187
183 /* recurse! */ 188 /* recurse! */
184 timeline_request(snac, &in_reply_to, NULL); 189 timeline_request(snac, &in_reply_to, NULL);
185
186 /* finally store */
187 timeline_add(snac, *id, object);
188 } 190 }
189 } 191 }
190 } 192 }
193
194 if (object)
195 timeline_request_replies(snac, object);
191 } 196 }
192 197
193 return status; 198 return status;
194} 199}
195 200
196 201
202void timeline_request_replies(snac *user, const xs_dict *msg)
203/* requests all replies of a message */
204/* FIXME: experimental -- needs more testing */
205{
206 /* does it have a replies collection? */
207 const xs_dict *replies = xs_dict_get(msg, "replies");
208
209 if (!xs_is_null(replies)) {
210 const char *type = xs_dict_get(replies, "type");
211 const char *first = xs_dict_get(replies, "first");
212
213 if (!xs_is_null(type) && !xs_is_null(first) && strcmp(type, "Collection") == 0) {
214 const char *next = xs_dict_get(first, "next");
215
216 if (!xs_is_null(next)) {
217 xs *rpls = NULL;
218 int status = activitypub_request(user, next, &rpls);
219
220 /* request the Collection of replies */
221 if (valid_status(status)) {
222 xs_list *items = xs_dict_get(rpls, "items");
223
224 if (xs_type(items) == XSTYPE_LIST) {
225 xs_val *v;
226
227 /* request them all */
228 while (xs_list_iter(&items, &v)) {
229 if (xs_type(v) == XSTYPE_DICT) {
230 /* not an id, but the object itself (!) */
231 const char *id = xs_dict_get(v, "id");
232
233 if (!xs_is_null(id)) {
234 snac_debug(user, 0, xs_fmt("embedded reply %s", id));
235
236 object_add(id, v);
237
238 /* get its own children */
239 timeline_request_replies(user, v);
240 }
241 }
242 else {
243 snac_debug(user, 0, xs_fmt("request reply %s", v));
244 timeline_request(user, &v, NULL);
245 }
246 }
247 }
248 }
249 else
250 snac_debug(user, 0, xs_fmt("reply collection get %s %d", next, status));
251 }
252 }
253 }
254}
255
256
197int send_to_inbox_raw(const char *keyid, const char *seckey, 257int send_to_inbox_raw(const char *keyid, const char *seckey,
198 const xs_str *inbox, const xs_dict *msg, 258 const xs_str *inbox, const xs_dict *msg,
199 xs_val **payload, int *p_size, int timeout) 259 xs_val **payload, int *p_size, int timeout)