summaryrefslogtreecommitdiff
path: root/data.c
diff options
context:
space:
mode:
authorGravatar poesty2023-05-07 07:27:24 +0000
committerGravatar poesty2023-05-07 07:27:24 +0000
commite65760a349112abce39404ca50f6bc2f1301bed9 (patch)
treec2484af8006961d95dcf39cf16c3749100a713c9 /data.c
parentFixed webfinger and curl issues (diff)
parentVersion 2.30 RELEASED. (diff)
downloadsnac2-e65760a349112abce39404ca50f6bc2f1301bed9.tar.gz
snac2-e65760a349112abce39404ca50f6bc2f1301bed9.tar.xz
snac2-e65760a349112abce39404ca50f6bc2f1301bed9.zip
Merge pull request 'master' (#1) from grunfink/snac2:master into master
Reviewed-on: https://codeberg.org/poesty/snac2/pulls/1
Diffstat (limited to 'data.c')
-rw-r--r--data.c121
1 files changed, 110 insertions, 11 deletions
diff --git a/data.c b/data.c
index c2d29c1..72b63f8 100644
--- a/data.c
+++ b/data.c
@@ -328,6 +328,51 @@ int index_add(const char *fn, const char *id)
328} 328}
329 329
330 330
331int index_del_md5(const char *fn, const char *md5)
332/* deletes an md5 from an index */
333{
334 int status = 404;
335 FILE *f;
336
337 pthread_mutex_lock(&data_mutex);
338
339 if ((f = fopen(fn, "r+")) != NULL) {
340 char line[256];
341
342 while (fgets(line, sizeof(line), f) != NULL) {
343 line[32] = '\0';
344
345 if (strcmp(line, md5) == 0) {
346 /* found! just rewind, overwrite it with garbage
347 and an eventual call to index_gc() will clean it
348 [yes: this breaks index_len()] */
349 fseek(f, -33, SEEK_CUR);
350 fwrite("-", 1, 1, f);
351 status = 200;
352
353 break;
354 }
355 }
356
357 fclose(f);
358 }
359 else
360 status = 500;
361
362 pthread_mutex_unlock(&data_mutex);
363
364 return status;
365}
366
367
368int index_del(const char *fn, const char *id)
369/* deletes an id from an index */
370{
371 xs *md5 = xs_md5_hex(id, strlen(id));
372 return index_del_md5(fn, md5);
373}
374
375
331int index_gc(const char *fn) 376int index_gc(const char *fn)
332/* garbage-collects an index, deleting objects that are not here */ 377/* garbage-collects an index, deleting objects that are not here */
333{ 378{
@@ -772,6 +817,23 @@ int object_admire(const char *id, const char *actor, int like)
772} 817}
773 818
774 819
820int object_unadmire(const char *id, const char *actor, int like)
821/* actor no longer likes or announces this object */
822{
823 int status;
824 xs *fn = _object_fn(id);
825
826 fn = xs_replace_i(fn, ".json", like ? "_l.idx" : "_a.idx");
827
828 status = index_del(fn, actor);
829
830 srv_debug(0,
831 xs_fmt("object_unadmire (%s) %s %s %d", like ? "Like" : "Announce", actor, fn, status));
832
833 return status;
834}
835
836
775int _object_user_cache(snac *snac, const char *id, const char *cachedir, int del) 837int _object_user_cache(snac *snac, const char *id, const char *cachedir, int del)
776/* adds or deletes from a user cache */ 838/* adds or deletes from a user cache */
777{ 839{
@@ -969,8 +1031,13 @@ void timeline_update_indexes(snac *snac, const char *id)
969 1031
970 if (valid_status(object_get(id, &msg))) { 1032 if (valid_status(object_get(id, &msg))) {
971 /* if its ours and is public, also store in public */ 1033 /* if its ours and is public, also store in public */
972 if (is_msg_public(snac, msg)) 1034 if (is_msg_public(snac, msg)) {
973 object_user_cache_add(snac, id, "public"); 1035 object_user_cache_add(snac, id, "public");
1036
1037 /* also add it to the instance public timeline */
1038 xs *ipt = xs_fmt("%s/public.idx", srv_basedir);
1039 index_add(ipt, id);
1040 }
974 } 1041 }
975 } 1042 }
976} 1043}
@@ -1041,7 +1108,7 @@ xs_list *timeline_top_level(snac *snac, xs_list *list)
1041} 1108}
1042 1109
1043 1110
1044d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show) 1111xs_list *timeline_simple_list(snac *snac, const char *idx_name, int skip, int show)
1045/* returns a timeline (with all entries) */ 1112/* returns a timeline (with all entries) */
1046{ 1113{
1047 int c_max; 1114 int c_max;
@@ -1059,7 +1126,7 @@ d_char *timeline_simple_list(snac *snac, const char *idx_name, int skip, int sho
1059} 1126}
1060 1127
1061 1128
1062d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show) 1129xs_list *timeline_list(snac *snac, const char *idx_name, int skip, int show)
1063/* returns a timeline (only top level entries) */ 1130/* returns a timeline (only top level entries) */
1064{ 1131{
1065 xs *list = timeline_simple_list(snac, idx_name, skip, show); 1132 xs *list = timeline_simple_list(snac, idx_name, skip, show);
@@ -1068,6 +1135,15 @@ d_char *timeline_list(snac *snac, const char *idx_name, int skip, int show)
1068} 1135}
1069 1136
1070 1137
1138xs_list *timeline_instance_list(int skip, int show)
1139/* returns the timeline for the full instance */
1140{
1141 xs *idx = xs_fmt("%s/public.idx", srv_basedir);
1142
1143 return index_list_desc(idx, skip, show);
1144}
1145
1146
1071/** following **/ 1147/** following **/
1072 1148
1073/* this needs special treatment and cannot use the object db as is, 1149/* this needs special treatment and cannot use the object db as is,
@@ -1273,30 +1349,49 @@ int is_hidden(snac *snac, const char *id)
1273} 1349}
1274 1350
1275 1351
1276int actor_add(snac *snac, const char *actor, d_char *msg) 1352int actor_add(const char *actor, xs_dict *msg)
1277/* adds an actor */ 1353/* adds an actor */
1278{ 1354{
1279 return object_add_ow(actor, msg); 1355 return object_add_ow(actor, msg);
1280} 1356}
1281 1357
1282 1358
1283int actor_get(snac *snac, const char *actor, d_char **data) 1359int actor_get(snac *snac1, const char *actor, xs_dict **data)
1284/* returns an already downloaded actor */ 1360/* returns an already downloaded actor */
1285{ 1361{
1286 int status = 200; 1362 int status = 200;
1287 d_char *d; 1363 xs_dict *d = NULL;
1288 1364
1289 if (strcmp(actor, snac->actor) == 0) { 1365 if (strcmp(actor, snac1->actor) == 0) {
1290 /* this actor */ 1366 /* this actor */
1291 if (data) 1367 if (data)
1292 *data = msg_actor(snac); 1368 *data = msg_actor(snac1);
1293 1369
1294 return status; 1370 return status;
1295 } 1371 }
1296 1372
1373 if (xs_startswith(actor, srv_baseurl)) {
1374 /* it's a (possible) local user */
1375 xs *l = xs_split(actor, "/");
1376 const char *uid = xs_list_get(l, -1);
1377 snac user;
1378
1379 if (!xs_is_null(uid) && user_open(&user, uid)) {
1380 if (data)
1381 *data = msg_actor(&user);
1382
1383 user_free(&user);
1384 return 200;
1385 }
1386 else
1387 return 404;
1388 }
1389
1297 /* read the object */ 1390 /* read the object */
1298 if (!valid_status(status = object_get(actor, &d))) 1391 if (!valid_status(status = object_get(actor, &d))) {
1392 d = xs_free(d);
1299 return status; 1393 return status;
1394 }
1300 1395
1301 if (data) 1396 if (data)
1302 *data = d; 1397 *data = d;
@@ -1719,7 +1814,7 @@ static xs_dict *_new_qmsg(const char *type, const xs_val *msg, int retries)
1719} 1814}
1720 1815
1721 1816
1722void enqueue_input(snac *snac, xs_dict *msg, xs_dict *req, int retries) 1817void enqueue_input(snac *snac, const xs_dict *msg, const xs_dict *req, int retries)
1723/* enqueues an input message */ 1818/* enqueues an input message */
1724{ 1819{
1725 xs *qmsg = _new_qmsg("input", msg, retries); 1820 xs *qmsg = _new_qmsg("input", msg, retries);
@@ -2020,7 +2115,11 @@ void purge_server(void)
2020 xs *ib_dir = xs_fmt("%s/inbox", srv_basedir); 2115 xs *ib_dir = xs_fmt("%s/inbox", srv_basedir);
2021 _purge_dir(ib_dir, 7); 2116 _purge_dir(ib_dir, 7);
2022 2117
2023 srv_debug(1, xs_fmt("purge: global (obj: %d, idx: %d)", cnt, icnt)); 2118 /* purge the instance timeline */
2119 xs *itl_fn = xs_fmt("%s/public.idx", srv_basedir);
2120 int itl_gc = index_gc(itl_fn);
2121
2122 srv_debug(1, xs_fmt("purge: global (obj: %d, idx: %d, itl: %d)", cnt, icnt, itl_gc));
2024} 2123}
2025 2124
2026 2125