diff options
Diffstat (limited to 'mastoapi.c')
| -rw-r--r-- | mastoapi.c | 177 |
1 files changed, 102 insertions, 75 deletions
| @@ -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); |