summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--activitypub.c110
-rw-r--r--data.c19
-rw-r--r--main.c11
-rw-r--r--mastoapi.c8
-rw-r--r--snac.h4
-rw-r--r--utils.c12
6 files changed, 150 insertions, 14 deletions
diff --git a/activitypub.c b/activitypub.c
index 09da229..2c0aa98 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -1021,6 +1021,107 @@ void collect_replies(snac *user, const char *id)
1021} 1021}
1022 1022
1023 1023
1024void collect_outbox(snac *user, const char *actor_id)
1025/* gets an actor's outbox and inserts a bunch of posts in a user's timeline */
1026{
1027 int status;
1028 xs *actor = NULL;
1029
1030 if (!valid_status(status = actor_request(user, actor_id, &actor))) {
1031 snac_debug(user, 1, xs_fmt("collect_outbox: cannot get actor object '%s' %d", actor_id, status));
1032 return;
1033 }
1034
1035 xs *outbox = NULL;
1036 const char *outbox_url = xs_dict_get(actor, "outbox");
1037
1038 if (!xs_is_string(outbox_url))
1039 return;
1040
1041 if (!valid_status(status = activitypub_request(user, outbox_url, &outbox))) {
1042 snac_debug(user, 1, xs_fmt("collect_outbox: cannot get actor outbox '%s' %d", outbox_url, status));
1043 return;
1044 }
1045
1046 const xs_list *ordered_items = xs_dict_get(outbox, "orderedItems");
1047
1048 if (!xs_is_list(ordered_items)) {
1049 /* the list is not here; does it have a 'first'? */
1050 const char *first = xs_dict_get(outbox, "first");
1051
1052 if (xs_is_string(first)) {
1053 /* download this instead */
1054 xs *first2 = xs_dup(first);
1055 xs_free(outbox);
1056
1057 if (!valid_status(status = activitypub_request(user, first2, &outbox))) {
1058 snac_debug(user, 1, xs_fmt("collect_outbox: cannot get first page of outbox '%s' %d", first2, status));
1059 return;
1060 }
1061
1062 /* last chance */
1063 ordered_items = xs_dict_get(outbox, "orderedItems");
1064 }
1065 }
1066
1067 if (!xs_is_list(ordered_items)) {
1068 snac_debug(user, 1, xs_fmt("collect_outbox: cannot get list of posts for actor '%s' outbox", actor_id));
1069 return;
1070 }
1071
1072 /* well, ok, then */
1073 int max = 4;
1074 const xs_val *v;
1075
1076 xs_list_foreach(ordered_items, v) {
1077 if (max == 0)
1078 break;
1079
1080 xs *post = NULL;
1081
1082 if (xs_is_string(v)) {
1083 /* it's probably the post url */
1084 if (!valid_status(activitypub_request(user, v, &post)))
1085 continue;
1086 }
1087 else
1088 if (xs_is_dict(v))
1089 post = xs_dup(v);
1090
1091 if (post == NULL)
1092 continue;
1093
1094 const char *type = xs_dict_get(post, "type");
1095
1096 if (!xs_is_string(type) || strcmp(type, "Create")) {
1097 /* not a post */
1098 continue;
1099 }
1100
1101 const xs_dict *object = xs_dict_get(post, "object");
1102
1103 if (!xs_is_dict(object))
1104 continue;
1105
1106 type = xs_dict_get(object, "type");
1107 const char *id = xs_dict_get(object, "id");
1108 const char *attr_to = get_atto(object);
1109
1110 if (!xs_is_string(type) || !xs_is_string(id) || !xs_is_string(attr_to))
1111 continue;
1112
1113 if (!timeline_here(user, id)) {
1114 timeline_add(user, id, object);
1115 snac_log(user, xs_fmt("new '%s' (collect_outbox) %s %s", type, attr_to, id));
1116 }
1117 else
1118 snac_debug(user, 1, xs_fmt("collect_outbox: post '%s' already here", id));
1119
1120 max--;
1121 }
1122}
1123
1124
1024void notify(snac *snac, const char *type, const char *utype, const char *actor, const xs_dict *msg) 1125void notify(snac *snac, const char *type, const char *utype, const char *actor, const xs_dict *msg)
1025/* notifies the user of relevant events */ 1126/* notifies the user of relevant events */
1026{ 1127{
@@ -2487,6 +2588,9 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
2487 if (following_check(snac, actor)) { 2588 if (following_check(snac, actor)) {
2488 following_add(snac, actor, msg); 2589 following_add(snac, actor, msg);
2489 snac_log(snac, xs_fmt("confirmed follow from %s", actor)); 2590 snac_log(snac, xs_fmt("confirmed follow from %s", actor));
2591
2592 /* request a bit of this fellow's outbox */
2593 enqueue_collect_outbox(snac, actor);
2490 } 2594 }
2491 else 2595 else
2492 snac_log(snac, xs_fmt("spurious follow accept from %s", actor)); 2596 snac_log(snac, xs_fmt("spurious follow accept from %s", actor));
@@ -2979,6 +3083,12 @@ void process_user_queue_item(snac *user, xs_dict *q_item)
2979 collect_replies(user, post); 3083 collect_replies(user, post);
2980 } 3084 }
2981 else 3085 else
3086 if (strcmp(type, "collect_outbox") == 0) {
3087 const char *actor_id = xs_dict_get(q_item, "message");
3088
3089 collect_outbox(user, actor_id);
3090 }
3091 else
2982 snac_log(user, xs_fmt("unexpected user q_item type '%s'", type)); 3092 snac_log(user, xs_fmt("unexpected user q_item type '%s'", type));
2983} 3093}
2984 3094
diff --git a/data.c b/data.c
index ca5e3ed..7e90a06 100644
--- a/data.c
+++ b/data.c
@@ -2429,8 +2429,8 @@ xs_list *list_timeline(snac *user, const char *list, int skip, int show)
2429} 2429}
2430 2430
2431 2431
2432xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op) 2432xs_val *list_members(snac *user, const char *list, const char *actor_md5, int op)
2433/* list content management */ 2433/* list member management */
2434{ 2434{
2435 xs_val *l = NULL; 2435 xs_val *l = NULL;
2436 2436
@@ -2443,7 +2443,7 @@ xs_val *list_content(snac *user, const char *list, const char *actor_md5, int op
2443 xs *fn = xs_fmt("%s/list/%s.lst", user->basedir, list); 2443 xs *fn = xs_fmt("%s/list/%s.lst", user->basedir, list);
2444 2444
2445 switch (op) { 2445 switch (op) {
2446 case 0: /** list content **/ 2446 case 0: /** list members **/
2447 l = index_list(fn, XS_ALL); 2447 l = index_list(fn, XS_ALL);
2448 2448
2449 break; 2449 break;
@@ -3589,6 +3589,19 @@ void enqueue_collect_replies(snac *user, const char *post)
3589} 3589}
3590 3590
3591 3591
3592void enqueue_collect_outbox(snac *user, const char *actor_id)
3593/* enqueues a collect outbox request */
3594{
3595 xs *qmsg = _new_qmsg("collect_outbox", actor_id, 0);
3596 const char *ntid = xs_dict_get(qmsg, "ntid");
3597 xs *fn = xs_fmt("%s/queue/%s.json", user->basedir, ntid);
3598
3599 qmsg = _enqueue_put(fn, qmsg);
3600
3601 snac_debug(user, 1, xs_fmt("enqueue_collect_outbox %s", actor_id));
3602}
3603
3604
3592int was_question_voted(snac *user, const char *id) 3605int was_question_voted(snac *user, const char *id)
3593/* returns true if the user voted in this poll */ 3606/* returns true if the user voted in this poll */
3594{ 3607{
diff --git a/main.c b/main.c
index b855e06..f767355 100644
--- a/main.c
+++ b/main.c
@@ -355,7 +355,7 @@ int main(int argc, char *argv[])
355 xs *lid = list_maint(&snac, url, 4); 355 xs *lid = list_maint(&snac, url, 4);
356 356
357 if (lid != NULL) { 357 if (lid != NULL) {
358 xs *lcont = list_content(&snac, lid, NULL, 0); 358 xs *lcont = list_members(&snac, lid, NULL, 0);
359 const char *md5; 359 const char *md5;
360 360
361 xs_list_foreach(lcont, md5) { 361 xs_list_foreach(lcont, md5) {
@@ -411,7 +411,7 @@ int main(int argc, char *argv[])
411 if (valid_status(webfinger_request(account, &actor, &uid))) { 411 if (valid_status(webfinger_request(account, &actor, &uid))) {
412 xs *md5 = xs_md5_hex(actor, strlen(actor)); 412 xs *md5 = xs_md5_hex(actor, strlen(actor));
413 413
414 list_content(&snac, lid, md5, 1); 414 list_members(&snac, lid, md5, 1);
415 printf("Actor %s (%s) added to list '%s' (%s)\n", actor, uid, url, lid); 415 printf("Actor %s (%s) added to list '%s' (%s)\n", actor, uid, url, lid);
416 } 416 }
417 else 417 else
@@ -434,7 +434,7 @@ int main(int argc, char *argv[])
434 if (lid != NULL) { 434 if (lid != NULL) {
435 xs *md5 = xs_md5_hex(account, strlen(account)); 435 xs *md5 = xs_md5_hex(account, strlen(account));
436 436
437 list_content(&snac, lid, md5, 2); 437 list_members(&snac, lid, md5, 2);
438 printf("Actor %s deleted from list '%s' (%s)\n", account, url, lid); 438 printf("Actor %s deleted from list '%s' (%s)\n", account, url, lid);
439 } 439 }
440 else 440 else
@@ -739,6 +739,11 @@ int main(int argc, char *argv[])
739 return 0; 739 return 0;
740 } 740 }
741 741
742 if (strcmp(cmd, "collect_outbox") == 0) { /** **/
743 enqueue_collect_outbox(&snac, url);
744 return 0;
745 }
746
742 if (strcmp(cmd, "insert") == 0) { /** **/ 747 if (strcmp(cmd, "insert") == 0) { /** **/
743 int status; 748 int status;
744 xs *data = NULL; 749 xs *data = NULL;
diff --git a/mastoapi.c b/mastoapi.c
index 42f3a47..568426b 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -1560,7 +1560,7 @@ xs_list *mastoapi_account_lists(snac *user, const char *uid)
1560 const char *list_id = xs_list_get(li, 0); 1560 const char *list_id = xs_list_get(li, 0);
1561 const char *list_title = xs_list_get(li, 1); 1561 const char *list_title = xs_list_get(li, 1);
1562 if (uid) { 1562 if (uid) {
1563 xs *users = list_content(user, list_id, NULL, 0); 1563 xs *users = list_members(user, list_id, NULL, 0);
1564 if (xs_list_in(users, actor_md5) == -1) 1564 if (xs_list_in(users, actor_md5) == -1)
1565 continue; 1565 continue;
1566 } 1566 }
@@ -2087,7 +2087,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
2087 p = xs_list_get(l, -2); 2087 p = xs_list_get(l, -2);
2088 2088
2089 if (p && xs_is_hex(p)) { 2089 if (p && xs_is_hex(p)) {
2090 xs *actors = list_content(&snac1, p, NULL, 0); 2090 xs *actors = list_members(&snac1, p, NULL, 0);
2091 xs *out = xs_list_new(); 2091 xs *out = xs_list_new();
2092 int c = 0; 2092 int c = 0;
2093 const char *v; 2093 const char *v;
@@ -3297,7 +3297,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
3297 const char *v; 3297 const char *v;
3298 3298
3299 while (xs_list_next(accts, &v, &c)) { 3299 while (xs_list_next(accts, &v, &c)) {
3300 list_content(&snac, id, v, 1); 3300 list_members(&snac, id, v, 1);
3301 } 3301 }
3302 3302
3303 xs *out = xs_dict_new(); 3303 xs *out = xs_dict_new();
@@ -3507,7 +3507,7 @@ int mastoapi_delete_handler(const xs_dict *req, const char *q_path,
3507 const char *v; 3507 const char *v;
3508 3508
3509 while (xs_list_next(accts, &v, &c)) { 3509 while (xs_list_next(accts, &v, &c)) {
3510 list_content(&snac, p, v, 2); 3510 list_members(&snac, p, v, 2);
3511 } 3511 }
3512 } 3512 }
3513 else { 3513 else {
diff --git a/snac.h b/snac.h
index 403bba0..a871576 100644
--- a/snac.h
+++ b/snac.h
@@ -233,7 +233,7 @@ xs_list *tag_search(const char *tag, int skip, int show);
233xs_val *list_maint(snac *user, const char *list, int op); 233xs_val *list_maint(snac *user, const char *list, int op);
234xs_str *list_timeline_fn(snac *user, const char *list); 234xs_str *list_timeline_fn(snac *user, const char *list);
235xs_list *list_timeline(snac *user, const char *list, int skip, int show); 235xs_list *list_timeline(snac *user, const char *list, int skip, int show);
236xs_val *list_content(snac *user, const char *list_id, const char *actor_md5, int op); 236xs_val *list_members(snac *user, const char *list_id, const char *actor_md5, int op);
237void list_distribute(snac *user, const char *who, const xs_dict *post); 237void list_distribute(snac *user, const char *who, const xs_dict *post);
238 238
239int actor_add(const char *actor, const xs_dict *msg); 239int actor_add(const char *actor, const xs_dict *msg);
@@ -298,6 +298,7 @@ void enqueue_actor_refresh(snac *user, const char *actor, int forward_secs);
298void enqueue_webmention(const xs_dict *msg); 298void enqueue_webmention(const xs_dict *msg);
299void enqueue_notify_webhook(snac *user, const xs_dict *noti, int retries); 299void enqueue_notify_webhook(snac *user, const xs_dict *noti, int retries);
300void enqueue_collect_replies(snac *user, const char *post); 300void enqueue_collect_replies(snac *user, const char *post);
301void enqueue_collect_outbox(snac *user, const char *actor_id);
301 302
302int was_question_voted(snac *user, const char *id); 303int was_question_voted(snac *user, const char *id);
303 304
@@ -336,6 +337,7 @@ const char *default_avatar_base64(void);
336xs_str *process_tags(snac *snac, const char *content, xs_list **tag); 337xs_str *process_tags(snac *snac, const char *content, xs_list **tag);
337 338
338void collect_replies(snac *user, const char *id); 339void collect_replies(snac *user, const char *id);
340void collect_outbox(snac *user, const char *actor_id);
339 341
340const char *get_atto(const xs_dict *msg); 342const char *get_atto(const xs_dict *msg);
341const char *get_in_reply_to(const xs_dict *msg); 343const char *get_in_reply_to(const xs_dict *msg);
diff --git a/utils.c b/utils.c
index 8db20bd..bdee09d 100644
--- a/utils.c
+++ b/utils.c
@@ -229,6 +229,9 @@ int snac_init(const char *basedir)
229 xs *ibdir = xs_fmt("%s/inbox", srv_basedir); 229 xs *ibdir = xs_fmt("%s/inbox", srv_basedir);
230 mkdirx(ibdir); 230 mkdirx(ibdir);
231 231
232 xs *langdir = xs_fmt("%s/lang", srv_basedir);
233 mkdirx(langdir);
234
232 xs *gfn = xs_fmt("%s/greeting.html", srv_basedir); 235 xs *gfn = xs_fmt("%s/greeting.html", srv_basedir);
233 if ((f = fopen(gfn, "w")) == NULL) { 236 if ((f = fopen(gfn, "w")) == NULL) {
234 printf("ERROR: cannot create '%s'\n", gfn); 237 printf("ERROR: cannot create '%s'\n", gfn);
@@ -253,7 +256,10 @@ int snac_init(const char *basedir)
253 xs_json_dump(srv_config, 4, f); 256 xs_json_dump(srv_config, 4, f);
254 fclose(f); 257 fclose(f);
255 258
256 printf("Done.\n"); 259 printf("Done.\n\n");
260
261 printf("Wanted web UI language files (.po) must be copied manually to %s\n", langdir);
262
257 return 0; 263 return 0;
258} 264}
259 265
@@ -681,7 +687,7 @@ void export_csv(snac *user)
681 const char *lid = xs_list_get(li, 0); 687 const char *lid = xs_list_get(li, 0);
682 const char *ltitle = xs_list_get(li, 1); 688 const char *ltitle = xs_list_get(li, 1);
683 689
684 xs *actors = list_content(user, lid, NULL, 0); 690 xs *actors = list_members(user, lid, NULL, 0);
685 const char *md5; 691 const char *md5;
686 692
687 xs_list_foreach(actors, md5) { 693 xs_list_foreach(actors, md5) {
@@ -907,7 +913,7 @@ void import_list_csv(snac *user, const char *ifn)
907 if (valid_status(webfinger_request(acct, &url, &uid))) { 913 if (valid_status(webfinger_request(acct, &url, &uid))) {
908 xs *actor_md5 = xs_md5_hex(url, strlen(url)); 914 xs *actor_md5 = xs_md5_hex(url, strlen(url));
909 915
910 list_content(user, list_id, actor_md5, 1); 916 list_members(user, list_id, actor_md5, 1);
911 snac_log(user, xs_fmt("Added %s to list %s", url, lname)); 917 snac_log(user, xs_fmt("Added %s to list %s", url, lname));
912 918
913 if (!following_check(user, url)) { 919 if (!following_check(user, url)) {