summaryrefslogtreecommitdiff
path: root/mastoapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'mastoapi.c')
-rw-r--r--mastoapi.c177
1 files changed, 102 insertions, 75 deletions
diff --git a/mastoapi.c b/mastoapi.c
index d702c47..78fd802 100644
--- a/mastoapi.c
+++ b/mastoapi.c
@@ -289,7 +289,11 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
289 *body = xs_dup(code); 289 *body = xs_dup(code);
290 } 290 }
291 else { 291 else {
292 *body = xs_fmt("%s?code=%s", redir, code); 292 if (xs_str_in(redir, "?"))
293 *body = xs_fmt("%s&code=%s", redir, code);
294 else
295 *body = xs_fmt("%s?code=%s", redir, code);
296
293 status = 303; 297 status = 303;
294 } 298 }
295 299
@@ -335,8 +339,8 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
335 /* FIXME: this 'scope' parameter is mandatory for the official Mastodon API, 339 /* FIXME: this 'scope' parameter is mandatory for the official Mastodon API,
336 but if it's enabled, it makes it crash after some more steps, which 340 but if it's enabled, it makes it crash after some more steps, which
337 is FAR WORSE */ 341 is FAR WORSE */
338// const char *scope = xs_dict_get(args, "scope");
339 const char *scope = NULL; 342 const char *scope = NULL;
343// scope = xs_dict_get(args, "scope");
340 344
341 /* no client_secret? check if it's inside an authorization header 345 /* no client_secret? check if it's inside an authorization header
342 (AndStatus does it this way) */ 346 (AndStatus does it this way) */
@@ -359,9 +363,9 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
359 } 363 }
360 } 364 }
361 365
362 /* no code? 366 /* no code?
363 I'm not sure of the impacts of this right now, but Subway Tooter does not 367 I'm not sure of the impacts of this right now, but Subway Tooter does not
364 provide a code so one must be generated */ 368 provide a code so one must be generated */
365 if (xs_is_null(code)){ 369 if (xs_is_null(code)){
366 code = random_str(); 370 code = random_str();
367 } 371 }
@@ -522,6 +526,12 @@ xs_dict *mastoapi_account(const xs_dict *actor)
522 acct = xs_dict_append(acct, "id", acct_md5); 526 acct = xs_dict_append(acct, "id", acct_md5);
523 acct = xs_dict_append(acct, "username", prefu); 527 acct = xs_dict_append(acct, "username", prefu);
524 acct = xs_dict_append(acct, "display_name", display_name); 528 acct = xs_dict_append(acct, "display_name", display_name);
529 acct = xs_dict_append(acct, "discoverable", xs_stock(XSTYPE_TRUE));
530 acct = xs_dict_append(acct, "group", xs_stock(XSTYPE_FALSE));
531 acct = xs_dict_append(acct, "hide_collections", xs_stock(XSTYPE_FALSE));
532 acct = xs_dict_append(acct, "indexable", xs_stock(XSTYPE_TRUE));
533 acct = xs_dict_append(acct, "noindex", xs_stock(XSTYPE_FALSE));
534 acct = xs_dict_append(acct, "roles", xs_stock(XSTYPE_LIST));
525 535
526 { 536 {
527 /* create the acct field as user@host */ 537 /* create the acct field as user@host */
@@ -543,13 +553,14 @@ xs_dict *mastoapi_account(const xs_dict *actor)
543 note = ""; 553 note = "";
544 554
545 if (strcmp(xs_dict_get(actor, "type"), "Service") == 0) 555 if (strcmp(xs_dict_get(actor, "type"), "Service") == 0)
546 acct = xs_dict_append(acct, "bot", xs_stock_true); 556 acct = xs_dict_append(acct, "bot", xs_stock(XSTYPE_TRUE));
547 else 557 else
548 acct = xs_dict_append(acct, "bot", xs_stock_false); 558 acct = xs_dict_append(acct, "bot", xs_stock(XSTYPE_FALSE));
549 559
550 acct = xs_dict_append(acct, "note", note); 560 acct = xs_dict_append(acct, "note", note);
551 561
552 acct = xs_dict_append(acct, "url", id); 562 acct = xs_dict_append(acct, "url", id);
563 acct = xs_dict_append(acct, "uri", id);
553 564
554 xs *avatar = NULL; 565 xs *avatar = NULL;
555 xs_dict *av = xs_dict_get(actor, "icon"); 566 xs_dict *av = xs_dict_get(actor, "icon");
@@ -574,7 +585,7 @@ xs_dict *mastoapi_account(const xs_dict *actor)
574 header = xs_dup(xs_dict_get(hd, "url")); 585 header = xs_dup(xs_dict_get(hd, "url"));
575 586
576 if (xs_is_null(header)) 587 if (xs_is_null(header))
577 header = xs_dup(""); 588 header = xs_fmt("%s/header.png", srv_baseurl);
578 589
579 acct = xs_dict_append(acct, "header", header); 590 acct = xs_dict_append(acct, "header", header);
580 acct = xs_dict_append(acct, "header_static", header); 591 acct = xs_dict_append(acct, "header_static", header);
@@ -602,7 +613,7 @@ xs_dict *mastoapi_account(const xs_dict *actor)
602 d1 = xs_dict_append(d1, "shortcode", nm); 613 d1 = xs_dict_append(d1, "shortcode", nm);
603 d1 = xs_dict_append(d1, "url", url); 614 d1 = xs_dict_append(d1, "url", url);
604 d1 = xs_dict_append(d1, "static_url", url); 615 d1 = xs_dict_append(d1, "static_url", url);
605 d1 = xs_dict_append(d1, "visible_in_picker", xs_stock_true); 616 d1 = xs_dict_append(d1, "visible_in_picker", xs_stock(XSTYPE_TRUE));
606 617
607 eml = xs_list_append(eml, d1); 618 eml = xs_list_append(eml, d1);
608 } 619 }
@@ -613,10 +624,10 @@ xs_dict *mastoapi_account(const xs_dict *actor)
613 acct = xs_dict_append(acct, "emojis", eml); 624 acct = xs_dict_append(acct, "emojis", eml);
614 } 625 }
615 626
616 acct = xs_dict_append(acct, "locked", xs_stock_false); 627 acct = xs_dict_append(acct, "locked", xs_stock(XSTYPE_FALSE));
617 acct = xs_dict_append(acct, "followers_count", xs_stock_0); 628 acct = xs_dict_append(acct, "followers_count", xs_stock(0));
618 acct = xs_dict_append(acct, "following_count", xs_stock_0); 629 acct = xs_dict_append(acct, "following_count", xs_stock(0));
619 acct = xs_dict_append(acct, "statuses_count", xs_stock_0); 630 acct = xs_dict_append(acct, "statuses_count", xs_stock(0));
620 631
621 xs *fields = xs_list_new(); 632 xs *fields = xs_list_new();
622 p = xs_dict_get(actor, "attachment"); 633 p = xs_dict_get(actor, "attachment");
@@ -624,19 +635,19 @@ xs_dict *mastoapi_account(const xs_dict *actor)
624 635
625 /* dict of validated links */ 636 /* dict of validated links */
626 xs_dict *val_links = NULL; 637 xs_dict *val_links = NULL;
627 xs_dict *metadata = xs_stock_dict; 638 xs_dict *metadata = xs_stock(XSTYPE_DICT);
628 snac user = {0}; 639 snac user = {0};
629 640
630 if (xs_startswith(id, srv_baseurl)) { 641 if (xs_startswith(id, srv_baseurl)) {
631 /* if it's a local user, open it and pick its validated links */ 642 /* if it's a local user, open it and pick its validated links */
632 if (user_open(&user, prefu)) { 643 if (user_open(&user, prefu)) {
633 val_links = user.links; 644 val_links = user.links;
634 metadata = xs_dict_get_def(user.config, "metadata", xs_stock_dict); 645 metadata = xs_dict_get_def(user.config, "metadata", xs_stock(XSTYPE_DICT));
635 } 646 }
636 } 647 }
637 648
638 if (xs_is_null(val_links)) 649 if (xs_is_null(val_links))
639 val_links = xs_stock_dict; 650 val_links = xs_stock(XSTYPE_DICT);
640 651
641 while (xs_list_iter(&p, &v)) { 652 while (xs_list_iter(&p, &v)) {
642 char *type = xs_dict_get(v, "type"); 653 char *type = xs_dict_get(v, "type");
@@ -665,7 +676,7 @@ xs_dict *mastoapi_account(const xs_dict *actor)
665 d = xs_dict_append(d, "value", value); 676 d = xs_dict_append(d, "value", value);
666 d = xs_dict_append(d, "verified_at", 677 d = xs_dict_append(d, "verified_at",
667 xs_type(val_date) == XSTYPE_STRING && *val_date ? 678 xs_type(val_date) == XSTYPE_STRING && *val_date ?
668 val_date : xs_stock_null); 679 val_date : xs_stock(XSTYPE_NULL));
669 680
670 fields = xs_list_append(fields, d); 681 fields = xs_list_append(fields, d);
671 } 682 }
@@ -703,13 +714,13 @@ xs_dict *mastoapi_poll(snac *snac, const xs_dict *msg)
703 xs *fd = mastoapi_date(xs_dict_get(msg, "endTime")); 714 xs *fd = mastoapi_date(xs_dict_get(msg, "endTime"));
704 poll = xs_dict_append(poll, "expires_at", fd); 715 poll = xs_dict_append(poll, "expires_at", fd);
705 poll = xs_dict_append(poll, "expired", 716 poll = xs_dict_append(poll, "expired",
706 xs_dict_get(msg, "closed") != NULL ? xs_stock_true : xs_stock_false); 717 xs_dict_get(msg, "closed") != NULL ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
707 718
708 if ((opts = xs_dict_get(msg, "oneOf")) != NULL) 719 if ((opts = xs_dict_get(msg, "oneOf")) != NULL)
709 poll = xs_dict_append(poll, "multiple", xs_stock_false); 720 poll = xs_dict_append(poll, "multiple", xs_stock(XSTYPE_FALSE));
710 else { 721 else {
711 opts = xs_dict_get(msg, "anyOf"); 722 opts = xs_dict_get(msg, "anyOf");
712 poll = xs_dict_append(poll, "multiple", xs_stock_true); 723 poll = xs_dict_append(poll, "multiple", xs_stock(XSTYPE_TRUE));
713 } 724 }
714 725
715 while (xs_list_iter(&opts, &v)) { 726 while (xs_list_iter(&opts, &v)) {
@@ -736,7 +747,7 @@ xs_dict *mastoapi_poll(snac *snac, const xs_dict *msg)
736 747
737 poll = xs_dict_append(poll, "voted", 748 poll = xs_dict_append(poll, "voted",
738 (snac && was_question_voted(snac, xs_dict_get(msg, "id"))) ? 749 (snac && was_question_voted(snac, xs_dict_get(msg, "id"))) ?
739 xs_stock_true : xs_stock_false); 750 xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
740 751
741 return poll; 752 return poll;
742} 753}
@@ -746,7 +757,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
746/* converts an ActivityPub note to a Mastodon status */ 757/* converts an ActivityPub note to a Mastodon status */
747{ 758{
748 xs *actor = NULL; 759 xs *actor = NULL;
749 actor_get(get_atto(msg), &actor); 760 actor_get_refresh(snac, get_atto(msg), &actor);
750 761
751 /* if the author is not here, discard */ 762 /* if the author is not here, discard */
752 if (actor == NULL) 763 if (actor == NULL)
@@ -802,7 +813,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
802 813
803 tmp = xs_dict_get(msg, "sensitive"); 814 tmp = xs_dict_get(msg, "sensitive");
804 if (xs_is_null(tmp)) 815 if (xs_is_null(tmp))
805 tmp = xs_stock_false; 816 tmp = xs_stock(XSTYPE_FALSE);
806 817
807 st = xs_dict_append(st, "sensitive", tmp); 818 st = xs_dict_append(st, "sensitive", tmp);
808 819
@@ -921,7 +932,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
921 d1 = xs_dict_append(d1, "shortcode", nm); 932 d1 = xs_dict_append(d1, "shortcode", nm);
922 d1 = xs_dict_append(d1, "url", url); 933 d1 = xs_dict_append(d1, "url", url);
923 d1 = xs_dict_append(d1, "static_url", url); 934 d1 = xs_dict_append(d1, "static_url", url);
924 d1 = xs_dict_append(d1, "visible_in_picker", xs_stock_true); 935 d1 = xs_dict_append(d1, "visible_in_picker", xs_stock(XSTYPE_TRUE));
925 d1 = xs_dict_append(d1, "category", "Emojis"); 936 d1 = xs_dict_append(d1, "category", "Emojis");
926 937
927 eml = xs_list_append(eml, d1); 938 eml = xs_list_append(eml, d1);
@@ -942,7 +953,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
942 953
943 st = xs_dict_append(st, "favourites_count", ixc); 954 st = xs_dict_append(st, "favourites_count", ixc);
944 st = xs_dict_append(st, "favourited", 955 st = xs_dict_append(st, "favourited",
945 (snac && xs_list_in(idx, snac->md5) != -1) ? xs_stock_true : xs_stock_false); 956 (snac && xs_list_in(idx, snac->md5) != -1) ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
946 957
947 xs_free(idx); 958 xs_free(idx);
948 xs_free(ixc); 959 xs_free(ixc);
@@ -951,7 +962,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
951 962
952 st = xs_dict_append(st, "reblogs_count", ixc); 963 st = xs_dict_append(st, "reblogs_count", ixc);
953 st = xs_dict_append(st, "reblogged", 964 st = xs_dict_append(st, "reblogged",
954 (snac && xs_list_in(idx, snac->md5) != -1) ? xs_stock_true : xs_stock_false); 965 (snac && xs_list_in(idx, snac->md5) != -1) ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
955 966
956 /* get the last person who boosted this */ 967 /* get the last person who boosted this */
957 xs *boosted_by_md5 = NULL; 968 xs *boosted_by_md5 = NULL;
@@ -966,8 +977,8 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
966 st = xs_dict_append(st, "replies_count", ixc); 977 st = xs_dict_append(st, "replies_count", ixc);
967 978
968 /* default in_reply_to values */ 979 /* default in_reply_to values */
969 st = xs_dict_append(st, "in_reply_to_id", xs_stock_null); 980 st = xs_dict_append(st, "in_reply_to_id", xs_stock(XSTYPE_NULL));
970 st = xs_dict_append(st, "in_reply_to_account_id", xs_stock_null); 981 st = xs_dict_append(st, "in_reply_to_account_id", xs_stock(XSTYPE_NULL));
971 982
972 tmp = xs_dict_get(msg, "inReplyTo"); 983 tmp = xs_dict_get(msg, "inReplyTo");
973 if (!xs_is_null(tmp)) { 984 if (!xs_is_null(tmp)) {
@@ -985,9 +996,9 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
985 } 996 }
986 } 997 }
987 998
988 st = xs_dict_append(st, "reblog", xs_stock_null); 999 st = xs_dict_append(st, "reblog", xs_stock(XSTYPE_NULL));
989 st = xs_dict_append(st, "card", xs_stock_null); 1000 st = xs_dict_append(st, "card", xs_stock(XSTYPE_NULL));
990 st = xs_dict_append(st, "language", xs_stock_null); 1001 st = xs_dict_append(st, "language", xs_stock(XSTYPE_NULL));
991 1002
992 tmp = xs_dict_get(msg, "sourceContent"); 1003 tmp = xs_dict_get(msg, "sourceContent");
993 if (xs_is_null(tmp)) 1004 if (xs_is_null(tmp))
@@ -998,7 +1009,7 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
998 tmp = xs_dict_get(msg, "updated"); 1009 tmp = xs_dict_get(msg, "updated");
999 xs *fd2 = NULL; 1010 xs *fd2 = NULL;
1000 if (xs_is_null(tmp)) 1011 if (xs_is_null(tmp))
1001 tmp = xs_stock_null; 1012 tmp = xs_stock(XSTYPE_NULL);
1002 else { 1013 else {
1003 fd2 = mastoapi_date(tmp); 1014 fd2 = mastoapi_date(tmp);
1004 tmp = fd2; 1015 tmp = fd2;
@@ -1011,12 +1022,12 @@ xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
1011 st = xs_dict_append(st, "poll", poll); 1022 st = xs_dict_append(st, "poll", poll);
1012 } 1023 }
1013 else 1024 else
1014 st = xs_dict_append(st, "poll", xs_stock_null); 1025 st = xs_dict_append(st, "poll", xs_stock(XSTYPE_NULL));
1015 1026
1016 st = xs_dict_append(st, "bookmarked", xs_stock_false); 1027 st = xs_dict_append(st, "bookmarked", xs_stock(XSTYPE_FALSE));
1017 1028
1018 st = xs_dict_append(st, "pinned", 1029 st = xs_dict_append(st, "pinned",
1019 (snac && is_pinned(snac, id)) ? xs_stock_true : xs_stock_false); 1030 (snac && is_pinned(snac, id)) ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
1020 1031
1021 /* is it a boost? */ 1032 /* is it a boost? */
1022 if (!xs_is_null(boosted_by_md5)) { 1033 if (!xs_is_null(boosted_by_md5)) {
@@ -1060,21 +1071,21 @@ xs_dict *mastoapi_relationship(snac *snac, const char *md5)
1060 1071
1061 rel = xs_dict_append(rel, "id", md5); 1072 rel = xs_dict_append(rel, "id", md5);
1062 rel = xs_dict_append(rel, "following", 1073 rel = xs_dict_append(rel, "following",
1063 following_check(snac, actor) ? xs_stock_true : xs_stock_false); 1074 following_check(snac, actor) ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
1064 1075
1065 rel = xs_dict_append(rel, "showing_reblogs", xs_stock_true); 1076 rel = xs_dict_append(rel, "showing_reblogs", xs_stock(XSTYPE_TRUE));
1066 rel = xs_dict_append(rel, "notifying", xs_stock_false); 1077 rel = xs_dict_append(rel, "notifying", xs_stock(XSTYPE_FALSE));
1067 rel = xs_dict_append(rel, "followed_by", 1078 rel = xs_dict_append(rel, "followed_by",
1068 follower_check(snac, actor) ? xs_stock_true : xs_stock_false); 1079 follower_check(snac, actor) ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
1069 1080
1070 rel = xs_dict_append(rel, "blocking", 1081 rel = xs_dict_append(rel, "blocking",
1071 is_muted(snac, actor) ? xs_stock_true : xs_stock_false); 1082 is_muted(snac, actor) ? xs_stock(XSTYPE_TRUE) : xs_stock(XSTYPE_FALSE));
1072 1083
1073 rel = xs_dict_append(rel, "muting", xs_stock_false); 1084 rel = xs_dict_append(rel, "muting", xs_stock(XSTYPE_FALSE));
1074 rel = xs_dict_append(rel, "muting_notifications", xs_stock_false); 1085 rel = xs_dict_append(rel, "muting_notifications", xs_stock(XSTYPE_FALSE));
1075 rel = xs_dict_append(rel, "requested", xs_stock_false); 1086 rel = xs_dict_append(rel, "requested", xs_stock(XSTYPE_FALSE));
1076 rel = xs_dict_append(rel, "domain_blocking", xs_stock_false); 1087 rel = xs_dict_append(rel, "domain_blocking", xs_stock(XSTYPE_FALSE));
1077 rel = xs_dict_append(rel, "endorsed", xs_stock_false); 1088 rel = xs_dict_append(rel, "endorsed", xs_stock(XSTYPE_FALSE));
1078 rel = xs_dict_append(rel, "note", ""); 1089 rel = xs_dict_append(rel, "note", "");
1079 } 1090 }
1080 1091
@@ -1142,9 +1153,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1142 acct = xs_dict_append(acct, "last_status_at", xs_dict_get(snac1.config, "published")); 1153 acct = xs_dict_append(acct, "last_status_at", xs_dict_get(snac1.config, "published"));
1143 acct = xs_dict_append(acct, "note", xs_dict_get(snac1.config, "bio")); 1154 acct = xs_dict_append(acct, "note", xs_dict_get(snac1.config, "bio"));
1144 acct = xs_dict_append(acct, "url", snac1.actor); 1155 acct = xs_dict_append(acct, "url", snac1.actor);
1145 acct = xs_dict_append(acct, "header", ""); 1156 acct = xs_dict_append(acct, "locked", xs_stock(XSTYPE_FALSE));
1146 acct = xs_dict_append(acct, "header_static", "");
1147 acct = xs_dict_append(acct, "locked", xs_stock_false);
1148 acct = xs_dict_append(acct, "bot", xs_dict_get(snac1.config, "bot")); 1157 acct = xs_dict_append(acct, "bot", xs_dict_get(snac1.config, "bot"));
1149 1158
1150 xs *src = xs_json_loads("{\"privacy\":\"public\"," 1159 xs *src = xs_json_loads("{\"privacy\":\"public\","
@@ -1162,6 +1171,17 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1162 acct = xs_dict_append(acct, "avatar", avatar); 1171 acct = xs_dict_append(acct, "avatar", avatar);
1163 acct = xs_dict_append(acct, "avatar_static", avatar); 1172 acct = xs_dict_append(acct, "avatar_static", avatar);
1164 1173
1174 xs *header = NULL;
1175 char *hd = xs_dict_get(snac1.config, "header");
1176
1177 if (!xs_is_null(hd))
1178 header = xs_dup(hd);
1179 else
1180 header = xs_fmt("%s/header.png", srv_baseurl);
1181
1182 acct = xs_dict_append(acct, "header", header);
1183 acct = xs_dict_append(acct, "header_static", header);
1184
1165 xs_dict *metadata = xs_dict_get(snac1.config, "metadata"); 1185 xs_dict *metadata = xs_dict_get(snac1.config, "metadata");
1166 if (xs_type(metadata) == XSTYPE_DICT) { 1186 if (xs_type(metadata) == XSTYPE_DICT) {
1167 xs *fields = xs_list_new(); 1187 xs *fields = xs_list_new();
@@ -1170,7 +1190,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1170 1190
1171 xs_dict *val_links = snac1.links; 1191 xs_dict *val_links = snac1.links;
1172 if (xs_is_null(val_links)) 1192 if (xs_is_null(val_links))
1173 val_links = xs_stock_dict; 1193 val_links = xs_stock(XSTYPE_DICT);
1174 1194
1175 int c = 0; 1195 int c = 0;
1176 while (xs_dict_next(metadata, &k, &v, &c)) { 1196 while (xs_dict_next(metadata, &k, &v, &c)) {
@@ -1190,7 +1210,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1190 d = xs_dict_append(d, "value", v); 1210 d = xs_dict_append(d, "value", v);
1191 d = xs_dict_append(d, "verified_at", 1211 d = xs_dict_append(d, "verified_at",
1192 xs_type(val_date) == XSTYPE_STRING && *val_date ? 1212 xs_type(val_date) == XSTYPE_STRING && *val_date ?
1193 val_date : xs_stock_null); 1213 val_date : xs_stock(XSTYPE_NULL));
1194 1214
1195 fields = xs_list_append(fields, d); 1215 fields = xs_list_append(fields, d);
1196 } 1216 }
@@ -1198,9 +1218,9 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1198 acct = xs_dict_set(acct, "fields", fields); 1218 acct = xs_dict_set(acct, "fields", fields);
1199 } 1219 }
1200 1220
1201 acct = xs_dict_append(acct, "followers_count", xs_stock_0); 1221 acct = xs_dict_append(acct, "followers_count", xs_stock(0));
1202 acct = xs_dict_append(acct, "following_count", xs_stock_0); 1222 acct = xs_dict_append(acct, "following_count", xs_stock(0));
1203 acct = xs_dict_append(acct, "statuses_count", xs_stock_0); 1223 acct = xs_dict_append(acct, "statuses_count", xs_stock(0));
1204 1224
1205 *body = xs_json_dumps(acct, 4); 1225 *body = xs_json_dumps(acct, 4);
1206 *ctype = "application/json"; 1226 *ctype = "application/json";
@@ -1716,8 +1736,8 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1716 else 1736 else
1717 if (strcmp(cmd, "/v2/filters") == 0) { /** **/ 1737 if (strcmp(cmd, "/v2/filters") == 0) { /** **/
1718 /* snac will never have filters 1738 /* snac will never have filters
1719 * but still, without a v2 endpoint a short delay is introduced 1739 * but still, without a v2 endpoint a short delay is introduced
1720 * in some apps */ 1740 * in some apps */
1721 *body = xs_dup("[]"); 1741 *body = xs_dup("[]");
1722 *ctype = "application/json"; 1742 *ctype = "application/json";
1723 status = 200; 1743 status = 200;
@@ -1797,7 +1817,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1797 1817
1798 ins = xs_dict_append(ins, "email", v); 1818 ins = xs_dict_append(ins, "email", v);
1799 1819
1800 ins = xs_dict_append(ins, "rules", xs_stock_list); 1820 ins = xs_dict_append(ins, "rules", xs_stock(XSTYPE_LIST));
1801 1821
1802 xs *l1 = xs_list_append(xs_list_new(), "en"); 1822 xs *l1 = xs_list_append(xs_list_new(), "en");
1803 ins = xs_dict_append(ins, "languages", l1); 1823 ins = xs_dict_append(ins, "languages", l1);
@@ -1808,14 +1828,14 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
1808 1828
1809 ins = xs_dict_append(ins, "urls", urls); 1829 ins = xs_dict_append(ins, "urls", urls);
1810 1830
1811 xs *d2 = xs_dict_append(xs_dict_new(), "user_count", xs_stock_0); 1831 xs *d2 = xs_dict_append(xs_dict_new(), "user_count", xs_stock(0));
1812 d2 = xs_dict_append(d2, "status_count", xs_stock_0); 1832 d2 = xs_dict_append(d2, "status_count", xs_stock(0));
1813 d2 = xs_dict_append(d2, "domain_count", xs_stock_0); 1833 d2 = xs_dict_append(d2, "domain_count", xs_stock(0));
1814 ins = xs_dict_append(ins, "stats", d2); 1834 ins = xs_dict_append(ins, "stats", d2);
1815 1835
1816 ins = xs_dict_append(ins, "registrations", xs_stock_false); 1836 ins = xs_dict_append(ins, "registrations", xs_stock(XSTYPE_FALSE));
1817 ins = xs_dict_append(ins, "approval_required", xs_stock_false); 1837 ins = xs_dict_append(ins, "approval_required", xs_stock(XSTYPE_FALSE));
1818 ins = xs_dict_append(ins, "invites_enabled", xs_stock_false); 1838 ins = xs_dict_append(ins, "invites_enabled", xs_stock(XSTYPE_FALSE));
1819 1839
1820 xs *cfg = xs_dict_new(); 1840 xs *cfg = xs_dict_new();
1821 1841
@@ -2063,7 +2083,7 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
2063 d = xs_dict_append(d, "name", q); 2083 d = xs_dict_append(d, "name", q);
2064 xs *url = xs_fmt("%s?t=%s", srv_baseurl, q); 2084 xs *url = xs_fmt("%s?t=%s", srv_baseurl, q);
2065 d = xs_dict_append(d, "url", url); 2085 d = xs_dict_append(d, "url", url);
2066 d = xs_dict_append(d, "history", xs_stock_list); 2086 d = xs_dict_append(d, "history", xs_stock(XSTYPE_LIST));
2067 2087
2068 htl = xs_list_append(htl, d); 2088 htl = xs_list_append(htl, d);
2069 } 2089 }
@@ -2103,8 +2123,6 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2103 if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/")) 2123 if (!xs_startswith(q_path, "/api/v1/") && !xs_startswith(q_path, "/api/v2/"))
2104 return 0; 2124 return 0;
2105 2125
2106 srv_debug(1, xs_fmt("mastoapi_post_handler %s", q_path));
2107
2108 int status = 404; 2126 int status = 404;
2109 xs *args = NULL; 2127 xs *args = NULL;
2110 char *i_ctype = xs_dict_get(req, "content-type"); 2128 char *i_ctype = xs_dict_get(req, "content-type");
@@ -2115,7 +2133,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2115 } 2133 }
2116 else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded")) 2134 else if (i_ctype && xs_startswith(i_ctype, "application/x-www-form-urlencoded"))
2117 { 2135 {
2118 // Some apps send form data instead of json so we should cater for those 2136 // Some apps send form data instead of json so we should cater for those
2119 if (!xs_is_null(payload)) { 2137 if (!xs_is_null(payload)) {
2120 xs *upl = xs_url_dec(payload); 2138 xs *upl = xs_url_dec(payload);
2121 args = xs_url_vars(upl); 2139 args = xs_url_vars(upl);
@@ -2241,7 +2259,7 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2241 strcmp(visibility, "public") == 0 ? 0 : 1); 2259 strcmp(visibility, "public") == 0 ? 0 : 1);
2242 2260
2243 if (!xs_is_null(summary) && *summary) { 2261 if (!xs_is_null(summary) && *summary) {
2244 msg = xs_dict_set(msg, "sensitive", xs_stock_true); 2262 msg = xs_dict_set(msg, "sensitive", xs_stock(XSTYPE_TRUE));
2245 msg = xs_dict_set(msg, "summary", summary); 2263 msg = xs_dict_set(msg, "summary", summary);
2246 } 2264 }
2247 2265
@@ -2298,11 +2316,13 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2298 } 2316 }
2299 else 2317 else
2300 if (strcmp(op, "unfavourite") == 0) { /** **/ 2318 if (strcmp(op, "unfavourite") == 0) { /** **/
2301 /* partial support: as the original Like message 2319 xs *n_msg = msg_repulsion(&snac, id, "Like");
2302 is not stored anywhere here, it's not possible 2320
2303 to send an Undo + Like; the only thing done here 2321 if (n_msg != NULL) {
2304 is to delete the actor from the list of likes */ 2322 enqueue_message(&snac, n_msg);
2305 object_unadmire(id, snac.actor, 1); 2323
2324 out = mastoapi_status(&snac, msg);
2325 }
2306 } 2326 }
2307 else 2327 else
2308 if (strcmp(op, "reblog") == 0) { /** **/ 2328 if (strcmp(op, "reblog") == 0) { /** **/
@@ -2317,8 +2337,13 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2317 } 2337 }
2318 else 2338 else
2319 if (strcmp(op, "unreblog") == 0) { /** **/ 2339 if (strcmp(op, "unreblog") == 0) { /** **/
2320 /* partial support: see comment in 'unfavourite' */ 2340 xs *n_msg = msg_repulsion(&snac, id, "Announce");
2321 object_unadmire(id, snac.actor, 0); 2341
2342 if (n_msg != NULL) {
2343 enqueue_message(&snac, n_msg);
2344
2345 out = mastoapi_status(&snac, msg);
2346 }
2322 } 2347 }
2323 else 2348 else
2324 if (strcmp(op, "bookmark") == 0) { /** **/ 2349 if (strcmp(op, "bookmark") == 0) { /** **/
@@ -2603,6 +2628,8 @@ int mastoapi_post_handler(const xs_dict *req, const char *q_path,
2603 if (logged_in) 2628 if (logged_in)
2604 user_free(&snac); 2629 user_free(&snac);
2605 2630
2631 srv_debug(1, xs_fmt("mastoapi_post_handler %s %d", q_path, status));
2632
2606 return status; 2633 return status;
2607} 2634}
2608 2635
@@ -2701,7 +2728,7 @@ int mastoapi_put_handler(const xs_dict *req, const char *q_path,
2701 if (valid_status(timeline_get_by_md5(&snac, md5, &msg))) { 2728 if (valid_status(timeline_get_by_md5(&snac, md5, &msg))) {
2702 const char *content = xs_dict_get(args, "status"); 2729 const char *content = xs_dict_get(args, "status");
2703 xs *atls = xs_list_new(); 2730 xs *atls = xs_list_new();
2704 xs *f_content = not_really_markdown(content, &atls); 2731 xs *f_content = not_really_markdown(content, &atls, NULL);
2705 2732
2706 /* replace fields with new content */ 2733 /* replace fields with new content */
2707 msg = xs_dict_set(msg, "sourceContent", content); 2734 msg = xs_dict_set(msg, "sourceContent", content);