diff options
Diffstat (limited to 'neighborhood.c')
| -rw-r--r-- | neighborhood.c | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/neighborhood.c b/neighborhood.c new file mode 100644 index 0000000..964a633 --- /dev/null +++ b/neighborhood.c @@ -0,0 +1,90 @@ +/* snac - A simple, minimalistic ActivityPub instance */ +/* copyright (c) 2022 - 2026 grunfink et al. / MIT license */ + +/* BEGIN neighborhood */ +/* neighborhood feed: feed of public posts from servers listed in server.json + under the "neighborhood" key. */ + +#include "xs.h" +#include "xs_set.h" + +#include "snac.h" + +xs_str *neighborhood_index_fn(void) +/* returns the filename of the neighborhood index */ +{ + return xs_fmt("%s/neighborhood.idx", srv_basedir); +} + + +int neighborhood_contains_actor(const char *actor) +/* 1 if the actor's host is in srv_config["neighborhood"], 0 otherwise */ +{ + if (!xs_is_string(actor) || *actor == '\0') + return 0; + + const xs_list *neighborhoods = xs_dict_get(srv_config, "neighborhood"); + if (xs_type(neighborhoods) != XSTYPE_LIST) + return 0; + + /* extract host: third segment of "https://host/..." */ + xs *parts = xs_split(actor, "/"); + const char *raw_host = xs_list_get(parts, 2); + if (!xs_is_string(raw_host) || *raw_host == '\0') + return 0; + + xs *host = xs_tolower_i(xs_dup(raw_host)); + + const xs_str *v; + int c = 0; + while (xs_list_next(neighborhoods, &v, &c)) { + if (!xs_is_string(v)) + continue; + xs *candidate = xs_tolower_i(xs_dup(v)); + if (strcmp(host, candidate) == 0) + return 1; + } + + return 0; +} + + +void neighborhood_update_indexes(const char *id, const xs_dict *msg) +/* adds id to neighborhood.idx when the author's host is allowlisted and the post is public */ +{ + if (!xs_is_string(id) || msg == NULL) + return; + + if (xs_type(xs_dict_get(srv_config, "neighborhood")) != XSTYPE_LIST) + return; + + if (get_msg_visibility(msg) != SCOPE_PUBLIC) + return; + + const char *atto = get_atto(msg); + if (!neighborhood_contains_actor(atto)) + return; + + xs *fn = neighborhood_index_fn(); + if (!index_in(fn, id)) + index_add(fn, id); +} + + +xs_list *timeline_neighborhood_list(int skip, int show) +/* returns the timeline for the neighborhood */ +{ + xs *idx = neighborhood_index_fn(); + xs *lst = index_list_desc(idx, skip, show); + + /* make the list unique */ + xs_set rep; + xs_set_init(&rep); + const char *md5; + + xs_list_foreach(lst, md5) + xs_set_add(&rep, md5); + + return xs_set_result(&rep); +} +/* END neighborhood */ |