summaryrefslogtreecommitdiff
path: root/activitypub.c
diff options
context:
space:
mode:
authorGravatar grunfink2025-08-16 16:42:50 +0200
committerGravatar grunfink2025-08-16 16:42:50 +0200
commit86de22fe92560db8d0661a6f4ee9be07a84043a3 (patch)
tree4a4c5d5aedde7faae4909990911a8b681589d363 /activitypub.c
parentUpdated RELEASE_NOTES. (diff)
downloadpenes-snac2-86de22fe92560db8d0661a6f4ee9be07a84043a3.tar.gz
penes-snac2-86de22fe92560db8d0661a6f4ee9be07a84043a3.tar.xz
penes-snac2-86de22fe92560db8d0661a6f4ee9be07a84043a3.zip
New function collect_replies().
Diffstat (limited to 'activitypub.c')
-rw-r--r--activitypub.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/activitypub.c b/activitypub.c
index 634e243..a375584 100644
--- a/activitypub.c
+++ b/activitypub.c
@@ -936,6 +936,94 @@ xs_str *process_tags(snac *snac, const char *content, xs_list **tag)
936} 936}
937 937
938 938
939void collect_replies(snac *user, const char *id)
940/* collects all replies for a post */
941{
942 xs *obj = NULL;
943
944 if (!valid_status(object_get(id, &obj))) {
945 snac_debug(user, 1, xs_fmt("collect_replies: object '%s' is not here", id));
946 return;
947 }
948
949 const char *next = xs_dict_get_path(obj, "replies.first.next");
950 if (!xs_is_string(next)) {
951 snac_debug(user, 1, xs_fmt("collect_replies: object '%s' does not have a replies.first.next URL", id));
952 return;
953 }
954
955 /* pick the first level replies (may be empty) */
956 const xs_list *level0_replies = xs_dict_get_path(obj, "replies.first.items");
957
958 xs *reply_obj = NULL;
959
960 if (!valid_status(object_get(next, &reply_obj))) {
961 if (!valid_status(activitypub_request(user, next, &reply_obj))) {
962 snac_debug(user, 1, xs_fmt("collect_replies: cannot get replies object '%s'", next));
963 return;
964 }
965 }
966
967 const xs_list *level1_replies = xs_dict_get(reply_obj, "items");
968 if (!xs_is_list(level1_replies)) {
969 snac_debug(user, 1, xs_fmt("collect_replies: cannot get reply items from object '%s'", next));
970 return;
971 }
972
973 xs *items = NULL;
974
975 if (xs_is_list(level0_replies))
976 items = xs_list_cat(xs_dup(level0_replies), level1_replies);
977 else
978 items = xs_dup(level1_replies);
979
980 const xs_val *v;
981
982 xs_list_foreach(items, v) {
983 xs *reply = NULL;
984
985 if (xs_is_string(v)) {
986 /* request the object */
987 if (!valid_status(object_get(v, &reply))) {
988 if (!valid_status(activitypub_request(user, v, &reply))) {
989 snac_debug(user, 1, xs_fmt("collect_replies: error requesting object '%s'", v));
990 continue;
991 }
992 }
993 }
994 else
995 if (xs_is_dict(v)) {
996 /* actually the post object */
997 reply = xs_dup(v);
998 }
999
1000 if (!xs_is_dict(reply))
1001 continue;
1002
1003 const char *id = xs_dict_get(reply, "id");
1004 const char *type = xs_dict_get(reply, "type");
1005 const char *attr_to = get_atto(reply);
1006
1007 if (!xs_is_string(id) || !xs_is_string(type) || !xs_is_string(attr_to))
1008 continue;
1009
1010 if (!xs_match(type, POSTLIKE_OBJECT_TYPE))
1011 continue;
1012
1013 if (timeline_here(user, id)) {
1014 snac_debug(user, 1, xs_fmt("collect_replies: item already in timeline %s", id));
1015 continue;
1016 }
1017
1018 enqueue_actor_refresh(user, attr_to, 0);
1019
1020 timeline_add(user, id, reply);
1021
1022 snac_log(user, xs_fmt("new '%s' (collect_replies) %s %s", type, attr_to, id));
1023 }
1024}
1025
1026
939void notify(snac *snac, const char *type, const char *utype, const char *actor, const xs_dict *msg) 1027void notify(snac *snac, const char *type, const char *utype, const char *actor, const xs_dict *msg)
940/* notifies the user of relevant events */ 1028/* notifies the user of relevant events */
941{ 1029{