mirror of
https://codeberg.org/grunfink/snac2.git
synced 2024-11-14 17:45:04 +00:00
New function mastodon_status().
This commit is contained in:
parent
7c9846ef3e
commit
79224ca2b5
3 changed files with 182 additions and 171 deletions
|
@ -242,7 +242,7 @@ int send_to_actor(snac *snac, char *actor, char *msg, d_char **payload, int *p_s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
d_char *recipient_list(snac *snac, char *msg, int expand_public)
|
xs_list *recipient_list(snac *snac, const xs_dict *msg, int expand_public)
|
||||||
/* returns the list of recipients for a message */
|
/* returns the list of recipients for a message */
|
||||||
{
|
{
|
||||||
char *to = xs_dict_get(msg, "to");
|
char *to = xs_dict_get(msg, "to");
|
||||||
|
@ -285,7 +285,7 @@ d_char *recipient_list(snac *snac, char *msg, int expand_public)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int is_msg_public(snac *snac, xs_dict *msg)
|
int is_msg_public(snac *snac, const xs_dict *msg)
|
||||||
/* checks if a message is public */
|
/* checks if a message is public */
|
||||||
{
|
{
|
||||||
xs *rcpts = recipient_list(snac, msg, 0);
|
xs *rcpts = recipient_list(snac, msg, 0);
|
||||||
|
@ -294,7 +294,7 @@ int is_msg_public(snac *snac, xs_dict *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int is_msg_for_me(snac *snac, xs_dict *c_msg)
|
int is_msg_for_me(snac *snac, const xs_dict *c_msg)
|
||||||
/* checks if this message is for me */
|
/* checks if this message is for me */
|
||||||
{
|
{
|
||||||
const char *type = xs_dict_get(c_msg, "type");
|
const char *type = xs_dict_get(c_msg, "type");
|
||||||
|
|
343
mastoapi.c
343
mastoapi.c
|
@ -403,7 +403,7 @@ int oauth_post_handler(const xs_dict *req, const char *q_path,
|
||||||
xs_str *mastoapi_id(const xs_dict *msg)
|
xs_str *mastoapi_id(const xs_dict *msg)
|
||||||
/* returns a somewhat Mastodon-compatible status id */
|
/* returns a somewhat Mastodon-compatible status id */
|
||||||
{
|
{
|
||||||
char tmp[256] = "";
|
char tmp[15] = "";
|
||||||
int n = 0;
|
int n = 0;
|
||||||
const char *id = xs_dict_get(msg, "id");
|
const char *id = xs_dict_get(msg, "id");
|
||||||
const char *published = xs_dict_get(msg, "published");
|
const char *published = xs_dict_get(msg, "published");
|
||||||
|
@ -424,6 +424,178 @@ xs_str *mastoapi_id(const xs_dict *msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
xs_dict *mastoapi_status(snac *snac, const xs_dict *msg)
|
||||||
|
/* converts an ActivityPub note to a Mastodon status */
|
||||||
|
{
|
||||||
|
xs *actor = NULL;
|
||||||
|
actor_get(snac, xs_dict_get(msg, "attributedTo"), &actor);
|
||||||
|
|
||||||
|
/* if the author is not here, discard */
|
||||||
|
if (actor == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/** shave the yak converting an ActivityPub Note to a Mastodon status **/
|
||||||
|
|
||||||
|
xs *acct = xs_dict_new();
|
||||||
|
|
||||||
|
const char *display_name = xs_dict_get(actor, "name");
|
||||||
|
if (xs_is_null(display_name) || *display_name == '\0')
|
||||||
|
display_name = xs_dict_get(actor, "preferredUsername");
|
||||||
|
|
||||||
|
const char *id = xs_dict_get(actor, "id");
|
||||||
|
const char *pub = xs_dict_get(actor, "published");
|
||||||
|
xs *acct_md5 = xs_md5_hex(id, strlen(id));
|
||||||
|
acct = xs_dict_append(acct, "id", acct_md5);
|
||||||
|
acct = xs_dict_append(acct, "username", xs_dict_get(actor, "preferredUsername"));
|
||||||
|
acct = xs_dict_append(acct, "acct", xs_dict_get(actor, "preferredUsername"));
|
||||||
|
acct = xs_dict_append(acct, "display_name", display_name);
|
||||||
|
|
||||||
|
if (pub)
|
||||||
|
acct = xs_dict_append(acct, "created_at", pub);
|
||||||
|
|
||||||
|
acct = xs_dict_append(acct, "note", xs_dict_get(actor, "summary"));
|
||||||
|
acct = xs_dict_append(acct, "url", id);
|
||||||
|
|
||||||
|
xs *avatar = NULL;
|
||||||
|
xs_dict *av = xs_dict_get(actor, "icon");
|
||||||
|
|
||||||
|
if (xs_type(av) == XSTYPE_DICT)
|
||||||
|
avatar = xs_dup(xs_dict_get(av, "url"));
|
||||||
|
else
|
||||||
|
avatar = xs_fmt("%s/susie.png", srv_baseurl);
|
||||||
|
|
||||||
|
acct = xs_dict_append(acct, "avatar", avatar);
|
||||||
|
|
||||||
|
xs *f = xs_val_new(XSTYPE_FALSE);
|
||||||
|
xs *t = xs_val_new(XSTYPE_TRUE);
|
||||||
|
xs *n = xs_val_new(XSTYPE_NULL);
|
||||||
|
xs *el = xs_list_new();
|
||||||
|
xs *idx = NULL;
|
||||||
|
xs *ixc = NULL;
|
||||||
|
|
||||||
|
char *tmp;
|
||||||
|
id = xs_dict_get(msg, "id");
|
||||||
|
xs *mid = mastoapi_id(msg);
|
||||||
|
|
||||||
|
xs_dict *st = xs_dict_new();
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "id", mid);
|
||||||
|
st = xs_dict_append(st, "uri", id);
|
||||||
|
st = xs_dict_append(st, "url", id);
|
||||||
|
st = xs_dict_append(st, "created_at", xs_dict_get(msg, "published"));
|
||||||
|
st = xs_dict_append(st, "account", acct);
|
||||||
|
st = xs_dict_append(st, "content", xs_dict_get(msg, "content"));
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "visibility",
|
||||||
|
is_msg_public(snac, msg) ? "public" : "private");
|
||||||
|
|
||||||
|
tmp = xs_dict_get(msg, "sensitive");
|
||||||
|
if (xs_is_null(tmp))
|
||||||
|
tmp = f;
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "sensitive", tmp);
|
||||||
|
|
||||||
|
tmp = xs_dict_get(msg, "summary");
|
||||||
|
if (xs_is_null(tmp))
|
||||||
|
tmp = "";
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "spoiler_text", tmp);
|
||||||
|
|
||||||
|
/* create the list of attachments */
|
||||||
|
xs *matt = xs_list_new();
|
||||||
|
xs_list *att = xs_dict_get(msg, "attachment");
|
||||||
|
xs_str *aobj;
|
||||||
|
|
||||||
|
while (xs_list_iter(&att, &aobj)) {
|
||||||
|
const char *mtype = xs_dict_get(aobj, "mediaType");
|
||||||
|
|
||||||
|
if (!xs_is_null(mtype) && xs_startswith(mtype, "image/")) {
|
||||||
|
xs *matteid = xs_fmt("%s_%d", id, xs_list_len(matt));
|
||||||
|
xs *matte = xs_dict_new();
|
||||||
|
|
||||||
|
matte = xs_dict_append(matte, "id", matteid);
|
||||||
|
matte = xs_dict_append(matte, "type", "image");
|
||||||
|
matte = xs_dict_append(matte, "url", xs_dict_get(aobj, "url"));
|
||||||
|
matte = xs_dict_append(matte, "preview_url", xs_dict_get(aobj, "url"));
|
||||||
|
matte = xs_dict_append(matte, "remote_url", xs_dict_get(aobj, "url"));
|
||||||
|
matte = xs_dict_append(matte, "description", xs_dict_get(aobj, "name"));
|
||||||
|
|
||||||
|
matt = xs_list_append(matt, matte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "media_attachments", matt);
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "mentions", el);
|
||||||
|
st = xs_dict_append(st, "tags", el);
|
||||||
|
st = xs_dict_append(st, "emojis", el);
|
||||||
|
|
||||||
|
xs_free(idx);
|
||||||
|
xs_free(ixc);
|
||||||
|
idx = object_likes(id);
|
||||||
|
ixc = xs_number_new(xs_list_len(idx));
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "favourites_count", ixc);
|
||||||
|
st = xs_dict_append(st, "favourited",
|
||||||
|
xs_list_in(idx, snac->md5) != -1 ? t : f);
|
||||||
|
|
||||||
|
xs_free(idx);
|
||||||
|
xs_free(ixc);
|
||||||
|
idx = object_announces(id);
|
||||||
|
ixc = xs_number_new(xs_list_len(idx));
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "reblogs_count", ixc);
|
||||||
|
st = xs_dict_append(st, "reblogged",
|
||||||
|
xs_list_in(idx, snac->md5) != -1 ? t : f);
|
||||||
|
|
||||||
|
xs_free(idx);
|
||||||
|
xs_free(ixc);
|
||||||
|
idx = object_children(id);
|
||||||
|
ixc = xs_number_new(xs_list_len(idx));
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "replies_count", ixc);
|
||||||
|
|
||||||
|
/* default in_reply_to values */
|
||||||
|
st = xs_dict_append(st, "in_reply_to_id", n);
|
||||||
|
st = xs_dict_append(st, "in_reply_to_account_id", n);
|
||||||
|
|
||||||
|
tmp = xs_dict_get(msg, "inReplyTo");
|
||||||
|
if (!xs_is_null(tmp)) {
|
||||||
|
xs *irto = NULL;
|
||||||
|
|
||||||
|
if (valid_status(object_get(tmp, &irto))) {
|
||||||
|
xs *irt_mid = mastoapi_id(irto);
|
||||||
|
st = xs_dict_set(st, "in_reply_to_id", irt_mid);
|
||||||
|
|
||||||
|
char *at = NULL;
|
||||||
|
if (!xs_is_null(at = xs_dict_get(irto, "attributedTo"))) {
|
||||||
|
xs *at_md5 = xs_md5_hex(at, strlen(at));
|
||||||
|
st = xs_dict_set(st, "in_reply_to_account_id", at_md5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "reblog", n);
|
||||||
|
st = xs_dict_append(st, "poll", n);
|
||||||
|
st = xs_dict_append(st, "card", n);
|
||||||
|
st = xs_dict_append(st, "language", n);
|
||||||
|
|
||||||
|
tmp = xs_dict_get(msg, "sourceContent");
|
||||||
|
if (xs_is_null(tmp))
|
||||||
|
tmp = "";
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "text", tmp);
|
||||||
|
|
||||||
|
tmp = xs_dict_get(msg, "updated");
|
||||||
|
if (xs_is_null(tmp))
|
||||||
|
tmp = n;
|
||||||
|
|
||||||
|
st = xs_dict_append(st, "edited_at", tmp);
|
||||||
|
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int mastoapi_get_handler(const xs_dict *req, const char *q_path,
|
int mastoapi_get_handler(const xs_dict *req, const char *q_path,
|
||||||
char **body, int *b_size, char **ctype)
|
char **body, int *b_size, char **ctype)
|
||||||
{
|
{
|
||||||
|
@ -548,172 +720,11 @@ int mastoapi_get_handler(const xs_dict *req, const char *q_path,
|
||||||
if (strcmp(xs_dict_get(msg, "type"), "Note") != 0)
|
if (strcmp(xs_dict_get(msg, "type"), "Note") != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xs *actor = NULL;
|
/* convert the Note into a Mastodon status */
|
||||||
actor_get(&snac, xs_dict_get(msg, "attributedTo"), &actor);
|
xs *st = mastoapi_status(&snac, msg);
|
||||||
|
|
||||||
/* if the author is not here, discard */
|
if (st != NULL)
|
||||||
if (actor == NULL)
|
out = xs_list_append(out, st);
|
||||||
continue;
|
|
||||||
|
|
||||||
/** shave the yak converting an ActivityPub Note to a Mastodon status **/
|
|
||||||
|
|
||||||
xs *acct = xs_dict_new();
|
|
||||||
|
|
||||||
const char *display_name = xs_dict_get(actor, "name");
|
|
||||||
if (xs_is_null(display_name) || *display_name == '\0')
|
|
||||||
display_name = xs_dict_get(actor, "preferredUsername");
|
|
||||||
|
|
||||||
const char *id = xs_dict_get(actor, "id");
|
|
||||||
const char *pub = xs_dict_get(actor, "published");
|
|
||||||
xs *acct_md5 = xs_md5_hex(id, strlen(id));
|
|
||||||
acct = xs_dict_append(acct, "id", acct_md5);
|
|
||||||
acct = xs_dict_append(acct, "username", xs_dict_get(actor, "preferredUsername"));
|
|
||||||
acct = xs_dict_append(acct, "acct", xs_dict_get(actor, "preferredUsername"));
|
|
||||||
acct = xs_dict_append(acct, "display_name", display_name);
|
|
||||||
|
|
||||||
if (pub)
|
|
||||||
acct = xs_dict_append(acct, "created_at", pub);
|
|
||||||
|
|
||||||
acct = xs_dict_append(acct, "note", xs_dict_get(actor, "summary"));
|
|
||||||
acct = xs_dict_append(acct, "url", id);
|
|
||||||
|
|
||||||
xs *avatar = NULL;
|
|
||||||
xs_dict *av = xs_dict_get(actor, "icon");
|
|
||||||
|
|
||||||
if (xs_type(av) == XSTYPE_DICT)
|
|
||||||
avatar = xs_dup(xs_dict_get(av, "url"));
|
|
||||||
else
|
|
||||||
avatar = xs_fmt("%s/susie.png", srv_baseurl);
|
|
||||||
|
|
||||||
acct = xs_dict_append(acct, "avatar", avatar);
|
|
||||||
|
|
||||||
xs *f = xs_val_new(XSTYPE_FALSE);
|
|
||||||
xs *t = xs_val_new(XSTYPE_TRUE);
|
|
||||||
xs *n = xs_val_new(XSTYPE_NULL);
|
|
||||||
xs *el = xs_list_new();
|
|
||||||
xs *idx = NULL;
|
|
||||||
xs *ixc = NULL;
|
|
||||||
|
|
||||||
char *tmp;
|
|
||||||
id = xs_dict_get(msg, "id");
|
|
||||||
xs *mid = mastoapi_id(msg);
|
|
||||||
|
|
||||||
xs *st = xs_dict_new();
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "id", mid);
|
|
||||||
st = xs_dict_append(st, "uri", id);
|
|
||||||
st = xs_dict_append(st, "url", id);
|
|
||||||
st = xs_dict_append(st, "created_at", xs_dict_get(msg, "published"));
|
|
||||||
st = xs_dict_append(st, "account", acct);
|
|
||||||
st = xs_dict_append(st, "content", xs_dict_get(msg, "content"));
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "visibility",
|
|
||||||
is_msg_public(&snac, msg) ? "public" : "private");
|
|
||||||
|
|
||||||
tmp = xs_dict_get(msg, "sensitive");
|
|
||||||
if (xs_is_null(tmp))
|
|
||||||
tmp = f;
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "sensitive", tmp);
|
|
||||||
|
|
||||||
tmp = xs_dict_get(msg, "summary");
|
|
||||||
if (xs_is_null(tmp))
|
|
||||||
tmp = "";
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "spoiler_text", tmp);
|
|
||||||
|
|
||||||
/* create the list of attachments */
|
|
||||||
xs *matt = xs_list_new();
|
|
||||||
xs_list *att = xs_dict_get(msg, "attachment");
|
|
||||||
xs_str *aobj;
|
|
||||||
|
|
||||||
while (xs_list_iter(&att, &aobj)) {
|
|
||||||
const char *mtype = xs_dict_get(aobj, "mediaType");
|
|
||||||
|
|
||||||
if (!xs_is_null(mtype) && xs_startswith(mtype, "image/")) {
|
|
||||||
xs *matteid = xs_fmt("%s_%d", id, xs_list_len(matt));
|
|
||||||
xs *matte = xs_dict_new();
|
|
||||||
|
|
||||||
matte = xs_dict_append(matte, "id", matteid);
|
|
||||||
matte = xs_dict_append(matte, "type", "image");
|
|
||||||
matte = xs_dict_append(matte, "url", xs_dict_get(aobj, "url"));
|
|
||||||
matte = xs_dict_append(matte, "preview_url", xs_dict_get(aobj, "url"));
|
|
||||||
matte = xs_dict_append(matte, "remote_url", xs_dict_get(aobj, "url"));
|
|
||||||
matte = xs_dict_append(matte, "description", xs_dict_get(aobj, "name"));
|
|
||||||
|
|
||||||
matt = xs_list_append(matt, matte);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "media_attachments", matt);
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "mentions", el);
|
|
||||||
st = xs_dict_append(st, "tags", el);
|
|
||||||
st = xs_dict_append(st, "emojis", el);
|
|
||||||
|
|
||||||
xs_free(idx);
|
|
||||||
xs_free(ixc);
|
|
||||||
idx = object_likes(id);
|
|
||||||
ixc = xs_number_new(xs_list_len(idx));
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "favourites_count", ixc);
|
|
||||||
st = xs_dict_append(st, "favourited",
|
|
||||||
xs_list_in(idx, snac.md5) != -1 ? t : f);
|
|
||||||
|
|
||||||
xs_free(idx);
|
|
||||||
xs_free(ixc);
|
|
||||||
idx = object_announces(id);
|
|
||||||
ixc = xs_number_new(xs_list_len(idx));
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "reblogs_count", ixc);
|
|
||||||
st = xs_dict_append(st, "reblogged",
|
|
||||||
xs_list_in(idx, snac.md5) != -1 ? t : f);
|
|
||||||
|
|
||||||
xs_free(idx);
|
|
||||||
xs_free(ixc);
|
|
||||||
idx = object_children(id);
|
|
||||||
ixc = xs_number_new(xs_list_len(idx));
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "replies_count", ixc);
|
|
||||||
|
|
||||||
/* default in_reply_to values */
|
|
||||||
st = xs_dict_append(st, "in_reply_to_id", n);
|
|
||||||
st = xs_dict_append(st, "in_reply_to_account_id", n);
|
|
||||||
|
|
||||||
tmp = xs_dict_get(msg, "inReplyTo");
|
|
||||||
if (!xs_is_null(tmp)) {
|
|
||||||
xs *irto = NULL;
|
|
||||||
|
|
||||||
if (valid_status(object_get(tmp, &irto))) {
|
|
||||||
xs *irt_mid = mastoapi_id(irto);
|
|
||||||
st = xs_dict_set(st, "in_reply_to_id", irt_mid);
|
|
||||||
|
|
||||||
char *at = NULL;
|
|
||||||
if (!xs_is_null(at = xs_dict_get(irto, "attributedTo"))) {
|
|
||||||
xs *at_md5 = xs_md5_hex(at, strlen(at));
|
|
||||||
st = xs_dict_set(st, "in_reply_to_account_id", at_md5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "reblog", n);
|
|
||||||
st = xs_dict_append(st, "poll", n);
|
|
||||||
st = xs_dict_append(st, "card", n);
|
|
||||||
st = xs_dict_append(st, "language", n);
|
|
||||||
|
|
||||||
tmp = xs_dict_get(msg, "sourceContent");
|
|
||||||
if (xs_is_null(tmp))
|
|
||||||
tmp = "";
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "text", tmp);
|
|
||||||
|
|
||||||
tmp = xs_dict_get(msg, "updated");
|
|
||||||
if (xs_is_null(tmp))
|
|
||||||
tmp = n;
|
|
||||||
|
|
||||||
st = xs_dict_append(st, "edited_at", tmp);
|
|
||||||
|
|
||||||
out = xs_list_append(out, st);
|
|
||||||
|
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
|
4
snac.h
4
snac.h
|
@ -196,8 +196,8 @@ int send_to_inbox(snac *snac, const xs_str *inbox, const xs_dict *msg,
|
||||||
xs_val **payload, int *p_size, int timeout);
|
xs_val **payload, int *p_size, int timeout);
|
||||||
d_char *get_actor_inbox(snac *snac, char *actor);
|
d_char *get_actor_inbox(snac *snac, char *actor);
|
||||||
int send_to_actor(snac *snac, char *actor, char *msg, d_char **payload, int *p_size, int timeout);
|
int send_to_actor(snac *snac, char *actor, char *msg, d_char **payload, int *p_size, int timeout);
|
||||||
int is_msg_public(snac *snac, xs_dict *msg);
|
int is_msg_public(snac *snac, const xs_dict *msg);
|
||||||
int is_msg_for_me(snac *snac, xs_dict *msg);
|
int is_msg_for_me(snac *snac, const xs_dict *msg);
|
||||||
|
|
||||||
int process_user_queue(snac *snac);
|
int process_user_queue(snac *snac);
|
||||||
void process_queue_item(xs_dict *q_item);
|
void process_queue_item(xs_dict *q_item);
|
||||||
|
|
Loading…
Reference in a new issue