diff options
Diffstat (limited to 'mastoapi.c')
| -rw-r--r-- | mastoapi.c | 76 |
1 files changed, 52 insertions, 24 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* snac - A simple, minimalistic ActivityPub instance */ | 1 | /* snac - A simple, minimalistic ActivityPub instance */ |
| 2 | /* copyright (c) 2022 - 2024 grunfink et al. / MIT license */ | 2 | /* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ |
| 3 | 3 | ||
| 4 | #ifndef NO_MASTODON_API | 4 | #ifndef NO_MASTODON_API |
| 5 | 5 | ||
| @@ -1339,6 +1339,9 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn | |||
| 1339 | const char *since_id = xs_dict_get(args, "since_id"); | 1339 | const char *since_id = xs_dict_get(args, "since_id"); |
| 1340 | const char *min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */ | 1340 | const char *min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */ |
| 1341 | const char *limit_s = xs_dict_get(args, "limit"); | 1341 | const char *limit_s = xs_dict_get(args, "limit"); |
| 1342 | int (*iterator)(FILE *, char *); | ||
| 1343 | int initial_status = 0; | ||
| 1344 | int ascending = 0; | ||
| 1342 | int limit = 0; | 1345 | int limit = 0; |
| 1343 | int cnt = 0; | 1346 | int cnt = 0; |
| 1344 | 1347 | ||
| @@ -1348,27 +1351,40 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn | |||
| 1348 | if (limit == 0) | 1351 | if (limit == 0) |
| 1349 | limit = 20; | 1352 | limit = 20; |
| 1350 | 1353 | ||
| 1351 | if (index_desc_first(f, md5, 0)) { | 1354 | if (min_id) { |
| 1355 | iterator = &index_asc_next; | ||
| 1356 | initial_status = index_asc_first(f, md5, MID_TO_MD5(min_id)); | ||
| 1357 | ascending = 1; | ||
| 1358 | } | ||
| 1359 | else { | ||
| 1360 | iterator = &index_desc_next; | ||
| 1361 | initial_status = index_desc_first(f, md5, 0); | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | if (initial_status) { | ||
| 1352 | do { | 1365 | do { |
| 1353 | xs *msg = NULL; | 1366 | xs *msg = NULL; |
| 1354 | 1367 | ||
| 1355 | /* only return entries older that max_id */ | 1368 | /* only return entries older that max_id */ |
| 1356 | if (max_id) { | 1369 | if (max_id) { |
| 1357 | if (strcmp(md5, MID_TO_MD5(max_id)) == 0) | 1370 | if (strcmp(md5, MID_TO_MD5(max_id)) == 0) { |
| 1358 | max_id = NULL; | 1371 | max_id = NULL; |
| 1359 | 1372 | if (ascending) | |
| 1360 | continue; | 1373 | break; |
| 1374 | } | ||
| 1375 | if (!ascending) | ||
| 1376 | continue; | ||
| 1361 | } | 1377 | } |
| 1362 | 1378 | ||
| 1363 | /* only returns entries newer than since_id */ | 1379 | /* only returns entries newer than since_id */ |
| 1364 | if (since_id) { | 1380 | if (since_id) { |
| 1365 | if (strcmp(md5, MID_TO_MD5(since_id)) == 0) | 1381 | if (strcmp(md5, MID_TO_MD5(since_id)) == 0) { |
| 1366 | break; | 1382 | if (!ascending) |
| 1367 | } | 1383 | break; |
| 1368 | 1384 | since_id = NULL; | |
| 1369 | if (min_id) { | 1385 | } |
| 1370 | if (strcmp(md5, MID_TO_MD5(min_id)) == 0) | 1386 | if (ascending) |
| 1371 | break; | 1387 | continue; |
| 1372 | } | 1388 | } |
| 1373 | 1389 | ||
| 1374 | /* get the entry */ | 1390 | /* get the entry */ |
| @@ -1428,26 +1444,23 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn | |||
| 1428 | continue; | 1444 | continue; |
| 1429 | } | 1445 | } |
| 1430 | 1446 | ||
| 1431 | /* if it has a name and it's not a Page or a Video, | 1447 | /* if it has a name and it's not an object that may have one, |
| 1432 | it's a poll vote, so discard it */ | 1448 | it's a poll vote, so discard it */ |
| 1433 | if (!xs_is_null(xs_dict_get(msg, "name")) && !xs_match(type, "Page|Video")) | 1449 | if (!xs_is_null(xs_dict_get(msg, "name")) && !xs_match(type, "Page|Video|Audio|Event")) |
| 1434 | continue; | 1450 | continue; |
| 1435 | 1451 | ||
| 1436 | /* convert the Note into a Mastodon status */ | 1452 | /* convert the Note into a Mastodon status */ |
| 1437 | xs *st = mastoapi_status(user, msg); | 1453 | xs *st = mastoapi_status(user, msg); |
| 1438 | 1454 | ||
| 1439 | if (st != NULL) { | 1455 | if (st != NULL) { |
| 1440 | out = xs_list_append(out, st); | 1456 | if (ascending) |
| 1457 | out = xs_list_insert(out, 0, st); | ||
| 1458 | else | ||
| 1459 | out = xs_list_append(out, st); | ||
| 1441 | cnt++; | 1460 | cnt++; |
| 1442 | } | 1461 | } |
| 1443 | if (min_id) { | ||
| 1444 | while (cnt > limit) { | ||
| 1445 | out = xs_list_del(out, 0); | ||
| 1446 | cnt--; | ||
| 1447 | } | ||
| 1448 | } | ||
| 1449 | 1462 | ||
| 1450 | } while ((min_id || (cnt < limit)) && index_desc_next(f, md5)); | 1463 | } while ((cnt < limit) && (*iterator)(f, md5)); |
| 1451 | } | 1464 | } |
| 1452 | 1465 | ||
| 1453 | int more = index_desc_next(f, md5); | 1466 | int more = index_desc_next(f, md5); |
| @@ -1816,6 +1829,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 1816 | const xs_list *excl = xs_dict_get(args, "exclude_types[]"); | 1829 | const xs_list *excl = xs_dict_get(args, "exclude_types[]"); |
| 1817 | const char *min_id = xs_dict_get(args, "min_id"); | 1830 | const char *min_id = xs_dict_get(args, "min_id"); |
| 1818 | const char *max_id = xs_dict_get(args, "max_id"); | 1831 | const char *max_id = xs_dict_get(args, "max_id"); |
| 1832 | const char *limit = xs_dict_get(args, "limit"); | ||
| 1833 | int limit_count = 0; | ||
| 1834 | if (!xs_is_null(limit)) { | ||
| 1835 | limit_count = atoi(limit); | ||
| 1836 | } | ||
| 1819 | 1837 | ||
| 1820 | if (dbglevel) { | 1838 | if (dbglevel) { |
| 1821 | xs *js = xs_json_dumps(args, 0); | 1839 | xs *js = xs_json_dumps(args, 0); |
| @@ -1903,6 +1921,10 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path, | |||
| 1903 | } | 1921 | } |
| 1904 | 1922 | ||
| 1905 | out = xs_list_append(out, mn); | 1923 | out = xs_list_append(out, mn); |
| 1924 | if (!xs_is_null(limit)) { | ||
| 1925 | if (--limit_count <= 0) | ||
| 1926 | break; | ||
| 1927 | } | ||
| 1906 | } | 1928 | } |
| 1907 | 1929 | ||
| 1908 | srv_debug(1, xs_fmt("mastoapi_notifications count %d", xs_list_len(out))); | 1930 | srv_debug(1, xs_fmt("mastoapi_notifications count %d", xs_list_len(out))); |
| @@ -2650,8 +2672,14 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path, | |||
| 2650 | } | 2672 | } |
| 2651 | 2673 | ||
| 2652 | /* prepare the message */ | 2674 | /* prepare the message */ |
| 2653 | xs *msg = msg_note(&snac, content, NULL, irt, attach_list, | 2675 | int scope = 1; |
| 2654 | strcmp(visibility, "public") == 0 ? 0 : 1, language); | 2676 | if (strcmp(visibility, "unlisted") == 0) |
| 2677 | scope = 2; | ||
| 2678 | else | ||
| 2679 | if (strcmp(visibility, "public") == 0) | ||
| 2680 | scope = 0; | ||
| 2681 | |||
| 2682 | xs *msg = msg_note(&snac, content, NULL, irt, attach_list, scope, language); | ||
| 2655 | 2683 | ||
| 2656 | if (!xs_is_null(summary) && *summary) { | 2684 | if (!xs_is_null(summary) && *summary) { |
| 2657 | msg = xs_dict_set(msg, "sensitive", xs_stock(XSTYPE_TRUE)); | 2685 | msg = xs_dict_set(msg, "sensitive", xs_stock(XSTYPE_TRUE)); |