diff options
| author | Giacomo Tesio <giacomo@tesio.it> | 2024-12-05 22:53:40 +0100 |
|---|---|---|
| committer | Giacomo Tesio <giacomo@tesio.it> | 2024-12-05 22:53:40 +0100 |
| commit | bd74ffda5b25cc07e8d559815e027c8dab3b9d73 (patch) | |
| tree | 00725a5d5f53ed421b923de6fc1892c58815cc16 /data.c | |
| parent | b6107c8777a6f98dd89218ede1020a27ee83be70 (diff) | |
| parent | 221eeabf0c00f076ee8ae670811aabbc5b11a826 (diff) | |
Merge branch 'master' into build-with-musl
Diffstat (limited to 'data.c')
| -rw-r--r-- | data.c | 121 |
1 files changed, 120 insertions, 1 deletions
@@ -336,6 +336,35 @@ int user_persist(snac *snac, int publish) xs *bfn = xs_fmt("%s.bak", fn); FILE *f; + if (publish) { + /* check if any of the relevant fields have really changed */ + if ((f = fopen(fn, "r")) != NULL) { + xs *old = xs_json_load(f); + fclose(f); + + if (old != NULL) { + int nw = 0; + const char *fields[] = { "header", "avatar", "name", "bio", "metadata", NULL }; + + for (int n = 0; fields[n]; n++) { + const char *of = xs_dict_get(old, fields[n]); + const char *nf = xs_dict_get(snac->config, fields[n]); + + if (of == NULL && nf == NULL) + continue; + + if (xs_type(of) != XSTYPE_STRING || xs_type(nf) != XSTYPE_STRING || strcmp(of, nf)) { + nw = 1; + break; + } + } + + if (!nw) + publish = 0; + } + } + } + rename(fn, bfn); if ((f = fopen(fn, "w")) != NULL) { @@ -799,7 +828,7 @@ int _object_add(const char *id, const xs_dict *obj, int ow) fclose(f); /* does this object has a parent? */ - const char *in_reply_to = xs_dict_get(obj, "inReplyTo"); + const char *in_reply_to = get_in_reply_to(obj); if (!xs_is_null(in_reply_to) && *in_reply_to) { /* update the children index of the parent */ @@ -1176,6 +1205,96 @@ xs_list *follower_list(snac *snac) } +/** pending followers **/ + +int pending_add(snac *user, const char *actor, const xs_dict *msg) +/* stores the follow message for later confirmation */ +{ + xs *dir = xs_fmt("%s/pending", user->basedir); + xs *md5 = xs_md5_hex(actor, strlen(actor)); + xs *fn = xs_fmt("%s/%s.json", dir, md5); + FILE *f; + + mkdirx(dir); + + if ((f = fopen(fn, "w")) == NULL) + return -1; + + xs_json_dump(msg, 4, f); + fclose(f); + + return 0; +} + + +int pending_check(snac *user, const char *actor) +/* checks if there is a pending follow confirmation for the actor */ +{ + xs *md5 = xs_md5_hex(actor, strlen(actor)); + xs *fn = xs_fmt("%s/pending/%s.json", user->basedir, md5); + + return mtime(fn) != 0; +} + + +xs_dict *pending_get(snac *user, const char *actor) +/* returns the pending follow confirmation for the actor */ +{ + xs *md5 = xs_md5_hex(actor, strlen(actor)); + xs *fn = xs_fmt("%s/pending/%s.json", user->basedir, md5); + xs_dict *msg = NULL; + FILE *f; + + if ((f = fopen(fn, "r")) != NULL) { + msg = xs_json_load(f); + fclose(f); + } + + return msg; +} + + +void pending_del(snac *user, const char *actor) +/* deletes a pending follow confirmation for the actor */ +{ + xs *md5 = xs_md5_hex(actor, strlen(actor)); + xs *fn = xs_fmt("%s/pending/%s.json", user->basedir, md5); + + unlink(fn); +} + + +xs_list *pending_list(snac *user) +/* returns a list of pending follow confirmations */ +{ + xs *spec = xs_fmt("%s/pending/""*.json", user->basedir); + xs *l = xs_glob(spec, 0, 0); + xs_list *r = xs_list_new(); + const char *v; + + xs_list_foreach(l, v) { + FILE *f; + xs *msg = NULL; + + if ((f = fopen(v, "r")) == NULL) + continue; + + msg = xs_json_load(f); + fclose(f); + + if (msg == NULL) + continue; + + const char *actor = xs_dict_get(msg, "actor"); + + if (xs_type(actor) == XSTYPE_STRING) + r = xs_list_append(r, actor); + } + + return r; +} + + /** timeline **/ double timeline_mtime(snac *snac) |