Convert all api responses from text templates to JSON layouts, fix memory leaks, discard more unsupported Activities, server owner banner
parent
aec2cd8ad8
commit
cc9e32b7dc
@ -1,26 +0,0 @@
|
||||
{
|
||||
"account": %( api_Account_write( a, f, 1 ); ),
|
||||
"created_at": "2022-12-12T15:31:54.000Z",
|
||||
"id": "%d{n->id}",
|
||||
"pleroma": {
|
||||
"is_muted": false,
|
||||
"is_seen": false
|
||||
},
|
||||
%( if(s) { )
|
||||
"status": %( api_status_write_as_json(s,f); ),
|
||||
%( } )
|
||||
%( if( n->type == nt_react ) { )
|
||||
"emoji": %( json_write_string( f, n->react ); ),
|
||||
%( } )
|
||||
"type": "%(
|
||||
switch(n->type) {
|
||||
case nt_favorite: fprintf(f,"favourite"); break;
|
||||
case nt_follow: fprintf(f,"follow"); break;
|
||||
case nt_like: fprintf(f,"favourite"); break;
|
||||
case nt_unfollow:
|
||||
case nt_block:
|
||||
case nt_mention: fprintf(f,"mention"); break;
|
||||
case nt_react: fprintf(f,"pleroma:emoji_reaction"); break;
|
||||
default: fprintf(f,"unknown-%d",n->type); break;
|
||||
}; )"
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
#include "Notification.h"
|
||||
|
||||
#include "json/json.h"
|
||||
#include "json/layout.h"
|
||||
#include "format.h"
|
||||
|
||||
#include "model/notification.h"
|
||||
|
||||
#include "view/api/Status.h"
|
||||
#include "view/api/Account.h"
|
||||
|
||||
bool int_to_string_callback( void* field_data, bool is_read, char** res );
|
||||
|
||||
static struct json_enum type_enum[] = {
|
||||
{ "favourite", nt_favorite },
|
||||
{ "follow", nt_follow },
|
||||
{ "favourite", nt_like },
|
||||
{ "mention", nt_unfollow },
|
||||
{ "mention", nt_block },
|
||||
{ "mention", nt_mention },
|
||||
{ "pleroma:emoji_raction", nt_react },
|
||||
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
#define OBJ_TYPE struct notification
|
||||
static struct json_object_field Notification_Pleroma_layout[] = {
|
||||
JSON_FIELD_FIXED_BOOL( is_muted, false ),
|
||||
JSON_FIELD_FIXED_BOOL( is_seen, false ),
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
static struct json_object_field api_Notification_layout[] = {
|
||||
{
|
||||
.key = "account",
|
||||
.offset = offsetof( OBJ_TYPE, account_id ),
|
||||
.type = &api_Account_type,
|
||||
},
|
||||
JSON_FIELD_DATETIME( created_at, true ),
|
||||
{
|
||||
.key = "id",
|
||||
.offset = offsetof( OBJ_TYPE, id ),
|
||||
.type = &json_field_callback_string,
|
||||
.string_callback = int_to_string_callback
|
||||
},
|
||||
{
|
||||
.key = "pleroma",
|
||||
.offset = 0,
|
||||
.type = &json_field_object_composite,
|
||||
.composite_layout = Notification_Pleroma_layout,
|
||||
},
|
||||
{
|
||||
.key = "status",
|
||||
.offset = offsetof( OBJ_TYPE, status_id ),
|
||||
.required = false,
|
||||
.type = &api_Status_type,
|
||||
},
|
||||
{
|
||||
.key = "emoji",
|
||||
.offset = offsetof( OBJ_TYPE, react ),
|
||||
.required = false,
|
||||
.type = &json_field_string,
|
||||
},
|
||||
JSON_FIELD_ENUM( type, type_enum, true ),
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
#undef OBJ_TYPE
|
||||
|
||||
void api_Notification_write( struct notification* note, FILE* f, int indent )
|
||||
{
|
||||
struct json_writer jw = {
|
||||
.f = f,
|
||||
.indentation = "\t",
|
||||
.indent = indent,
|
||||
};
|
||||
/*
|
||||
switch( n->type ) {
|
||||
case nt_unfollow:
|
||||
s = status_new_system_unfollow( n->ref_account_id );
|
||||
break;
|
||||
case nt_block:
|
||||
s = status_new_system_block( n->ref_account_id );
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
json_write_pretty_object_layout( &jw, api_Notification_layout, note );
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
struct notification;
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
void api_Notification_write( struct notification* note, FILE* f, int indent );
|
||||
|
@ -0,0 +1,430 @@
|
||||
#include "Status.h"
|
||||
|
||||
#include "json/json.h"
|
||||
#include "json/layout.h"
|
||||
#include "format.h"
|
||||
|
||||
#include "model/status.h"
|
||||
#include "model/status/react.h"
|
||||
#include "model/account.h"
|
||||
|
||||
#include "view/api/Account.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
bool int_to_string_callback( void* field_data, bool is_read, char** res );
|
||||
bool int_non_zero( void* field_data, bool is_read, bool* val )
|
||||
{
|
||||
if( !is_read ) {
|
||||
*val = *(int*)field_data > 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
extern struct json_object_field api_Status_layout[];
|
||||
|
||||
static bool write_in_reply_to( struct json_writer* jw, const char* field_name, void* field_data, struct json_object_field* layout_field_data )
|
||||
{
|
||||
struct status* s = field_data;
|
||||
struct status* in_reply_to = status_from_id( s->in_reply_to );
|
||||
if( in_reply_to ) {
|
||||
json_write_field_name(jw,"in_reply_to_account_id");
|
||||
fprintf( jw->f, "\"%d\"", in_reply_to->account_id );
|
||||
jw->need_comma = true;
|
||||
|
||||
json_write_indention(jw);
|
||||
json_write_field_name(jw,"in_reply_to_id");
|
||||
fprintf( jw->f, "%d", in_reply_to->id );
|
||||
} else {
|
||||
json_write_field_name(jw,"in_reply_to_account_id");
|
||||
fprintf( jw->f, "null" );
|
||||
jw->need_comma = true;
|
||||
|
||||
json_write_indention(jw);
|
||||
json_write_field_name(jw,"in_reply_to_id");
|
||||
fprintf( jw->f, "null" );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct json_field_type in_reply_to = {
|
||||
.writer = write_in_reply_to,
|
||||
};
|
||||
|
||||
|
||||
static bool write_status_reference( struct json_writer* jw, const char* field_name, void* field_data, struct json_object_field* layout_field_data )
|
||||
{
|
||||
json_write_field_name(jw,field_name);
|
||||
int id = *(int*)field_data;
|
||||
struct status* s = status_from_id(id);
|
||||
if( !s ) {
|
||||
fprintf( jw->f, "null" );
|
||||
} else {
|
||||
json_write_pretty_object_layout( jw, api_Status_layout, s );
|
||||
status_free(s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
static struct json_field_type Status_reference_type = {
|
||||
.writer = write_status_reference,
|
||||
};
|
||||
|
||||
bool does_react_include_me( void* field_data, bool is_read, bool* val )
|
||||
{
|
||||
struct status_react* sr = field_data;
|
||||
for( int i = 0; i < sr->accounts.count; ++i ) {
|
||||
if( sr->accounts.items[i] == owner_account_id ) {
|
||||
*val = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*val = false;
|
||||
return true;
|
||||
}
|
||||
static struct json_object_field MediaAttachment_Pleroma_layout[] = {
|
||||
JSON_FIELD_FIXED_STRING( mime_type, "image/png", true ),
|
||||
JSON_FIELD_END
|
||||
};
|
||||
static struct json_object_field MediaAttachment_layout[] = {
|
||||
JSON_FIELD_FIXED_STRING( blurhash, "eRH.A}xs0Kxv00xYR,R+t5R+9Gt6xaNG%%2-;xaM{NGRjD%%Rjs:xaxu", true ),
|
||||
JSON_FIELD_FIXED_NULL( description ),
|
||||
{
|
||||
.key = "id",
|
||||
.offset = 0,
|
||||
.type = &json_field_string,
|
||||
},
|
||||
{
|
||||
.key = "pleroma",
|
||||
.offset = 0,
|
||||
.type = &json_field_object_composite,
|
||||
.composite_layout = MediaAttachment_Pleroma_layout,
|
||||
},
|
||||
{
|
||||
.key = "preview_url",
|
||||
.offset = 0,
|
||||
.type = &json_field_string,
|
||||
},
|
||||
{
|
||||
.key = "remote_url",
|
||||
.offset = 0,
|
||||
.type = &json_field_string,
|
||||
},
|
||||
{
|
||||
.key = "text_url",
|
||||
.offset = 0,
|
||||
.type = &json_field_string,
|
||||
},
|
||||
JSON_FIELD_FIXED_STRING( type, "image", true ),
|
||||
{
|
||||
.key = "url",
|
||||
.offset = 0,
|
||||
.type = &json_field_string,
|
||||
},
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
|
||||
static struct json_field_type MediaAttachment_type = {
|
||||
.layout = MediaAttachment_layout,
|
||||
.reader = json_field_object_composite_reader,
|
||||
.writer = json_field_object_composite_writer,
|
||||
.size = sizeof(char*),
|
||||
};
|
||||
|
||||
#define OBJ_TYPE struct account
|
||||
bool account_acct_callback( void* field_data, bool is_read, char** res )
|
||||
{
|
||||
if( is_read ) { return false; }
|
||||
|
||||
struct account* a = field_data;
|
||||
*res = aformat( "%s@%s", a->handle, a->server );
|
||||
return true;
|
||||
}
|
||||
static struct json_object_field api_Mention_layout[] = {
|
||||
{
|
||||
.key = "acct",
|
||||
.offset = 0,
|
||||
.type = &json_field_callback_string,
|
||||
.string_callback = account_acct_callback,
|
||||
},
|
||||
{
|
||||
.key = "id",
|
||||
.offset = offsetof( OBJ_TYPE, id ),
|
||||
.type = &json_field_callback_string,
|
||||
.string_callback = int_to_string_callback,
|
||||
},
|
||||
{
|
||||
.key = "url",
|
||||
.offset = offsetof( OBJ_TYPE, account_url ),
|
||||
.type = &json_field_string
|
||||
},
|
||||
{
|
||||
.key = "username",
|
||||
.offset = offsetof( OBJ_TYPE, handle ),
|
||||
.type = &json_field_string,
|
||||
},
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
#undef OBJ_TYPE
|
||||
|
||||
static bool Mention_from_id_writer( struct json_writer* jw, const char* field_name, void* field_data, struct json_object_field* layout_field_data )
|
||||
{
|
||||
json_write_field_name(jw,field_name);
|
||||
int id = *(int*)field_data;
|
||||
struct account* a = account_from_id(id);
|
||||
if( !a ) {
|
||||
fprintf( jw->f, "null" );
|
||||
} else {
|
||||
json_write_pretty_object_layout( jw, api_Mention_layout, a);
|
||||
account_free(a);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct json_field_type Mention_type = {
|
||||
.writer = Mention_from_id_writer,
|
||||
.size = sizeof(int),
|
||||
};
|
||||
|
||||
#define OBJ_TYPE struct status_react
|
||||
static struct json_object_field emoji_react_layout[] = {
|
||||
{
|
||||
.key = "count",
|
||||
.offset = offsetof( OBJ_TYPE, accounts.count ),
|
||||
.type = &json_field_integer,
|
||||
},
|
||||
{
|
||||
.key = "me",
|
||||
.offset = 0,
|
||||
.type = &json_field_bool_callback,
|
||||
.bool_callback = does_react_include_me,
|
||||
},
|
||||
{
|
||||
.key = "name",
|
||||
.offset = offsetof( OBJ_TYPE, code ),
|
||||
.type = &json_field_string,
|
||||
},
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
#undef OBJ_TYPE
|
||||
|
||||
static struct json_field_type EmojiReact_type = {
|
||||
.layout = emoji_react_layout,
|
||||
.reader = json_field_object_type_reader,
|
||||
.writer = json_field_object_type_writer,
|
||||
.size = sizeof(struct status_react*),
|
||||
};
|
||||
|
||||
bool render_source_callback( void* field_data, bool is_read, char** res )
|
||||
{
|
||||
struct status* s = field_data;
|
||||
if( !s->content ) {
|
||||
s->content = status_render_source(s);
|
||||
}
|
||||
*res = strdup(s->content);
|
||||
return true;
|
||||
}
|
||||
|
||||
#define OBJ_TYPE struct status
|
||||
static struct json_object_field content_layout[] = {
|
||||
{
|
||||
.key = "text/plain",
|
||||
.offset = 0,
|
||||
.type = &json_field_callback_string,
|
||||
.string_callback = render_source_callback,
|
||||
},
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
static struct json_object_field pleroma_layout[] = {
|
||||
{
|
||||
.key = "content",
|
||||
.offset = 0,
|
||||
.type = &json_field_object_composite,
|
||||
.composite_layout = content_layout,
|
||||
},
|
||||
{
|
||||
.key = "conversation_id",
|
||||
.offset = offsetof( OBJ_TYPE, root_status_id ),
|
||||
.type = &json_field_integer,
|
||||
},
|
||||
JSON_FIELD_FIXED_NULL( direct_conversation_id ), // Maybe this is breaking things in the home feed?
|
||||
{
|
||||
.key = "emoji_reactions",
|
||||
.offset = offsetof( OBJ_TYPE, reacts ),
|
||||
.type = &json_field_array_of,
|
||||
.array_item_type = &EmojiReact_type,
|
||||
},
|
||||
JSON_FIELD_FIXED_NULL( expires_at ),
|
||||
/*%(
|
||||
if( in_reply_to_account ) { )
|
||||
"in_reply_to_account_acct": "%s{in_reply_to_account->handle}@%s{in_reply_to_account->server}",
|
||||
"local": %s{ s->remote ? "false" : "true" },
|
||||
"parent_visible": true,%(
|
||||
} else { )
|
||||
"in_reply_to_account_acct": null,
|
||||
"local": %s{ s->remote ? "false" : "true" },
|
||||
"parent_visible": false,%(
|
||||
} )
|
||||
*/
|
||||
JSON_FIELD_FIXED_NULL( pinned_at ),
|
||||
/*
|
||||
"spoiler_text": {
|
||||
"text/plain": ""
|
||||
},
|
||||
*/
|
||||
JSON_FIELD_FIXED_BOOL( thread_muted, false ),
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
struct json_object_field api_Status_layout[] = {
|
||||
{
|
||||
.key = "account",
|
||||
.required = true,
|
||||
.offset = offsetof( OBJ_TYPE, account_id ),
|
||||
.type = &api_Account_type,
|
||||
},
|
||||
JSON_FIELD_FIXED_NULL( application ),
|
||||
JSON_FIELD_FIXED_BOOL( bookmarked, false ),
|
||||
JSON_FIELD_FIXED_NULL( card ),
|
||||
{
|
||||
.key = "content",
|
||||
.offset = 0,
|
||||
.type = &json_field_callback_string,
|
||||
.string_callback = render_source_callback,
|
||||
},
|
||||
{
|
||||
.key = "crated_at",
|
||||
.required = true,
|
||||
.offset = offsetof( OBJ_TYPE, published ),
|
||||
.type = &json_field_date_time
|
||||
},
|
||||
JSON_FIELD_FIXED_NULL( edited_at ),
|
||||
JSON_FIELD_EMPTY_ARRAY( emoji, true ),
|
||||
{
|
||||
.key = "favourited",
|
||||
.required = true,
|
||||
.offset = 0,
|
||||
.type = &json_field_fixed_bool,
|
||||
.fixed_bool = false,
|
||||
},
|
||||
{
|
||||
.key = "favourited_count",
|
||||
.required = true,
|
||||
.offset = offsetof( OBJ_TYPE, likes.count ),
|
||||
.type = &json_field_integer,
|
||||
},
|
||||
{
|
||||
.key = "id",
|
||||
.required = true,
|
||||
.offset = offsetof( OBJ_TYPE, id ),
|
||||
.type = &json_field_callback_string,
|
||||
.string_callback = int_to_string_callback,
|
||||
},
|
||||
{
|
||||
.key = "@in_reply_to_inline",
|
||||
.required = true,
|
||||
.offset = 0,
|
||||
.type = &in_reply_to,
|
||||
},
|
||||
JSON_FIELD_FIXED_NULL( language ),
|
||||
{
|
||||
.key = "media_attachments",
|
||||
.offset = offsetof( OBJ_TYPE, media ),
|
||||
.type = &json_field_array_of,
|
||||
.array_item_type = &MediaAttachment_type,
|
||||
},
|
||||
{
|
||||
.key = "mentions",
|
||||
.offset = offsetof( OBJ_TYPE, mentions ),
|
||||
.type = &json_field_array_of,
|
||||
.array_item_type = &Mention_type,
|
||||
},
|
||||
JSON_FIELD_FIXED_BOOL( muted, false ),
|
||||
JSON_FIELD_FIXED_BOOL( pinned, false ),
|
||||
{
|
||||
.key = "pleroma",
|
||||
.offset = 0,
|
||||
.type = &json_field_object_composite,
|
||||
.composite_layout = pleroma_layout,
|
||||
},
|
||||
JSON_FIELD_FIXED_NULL( poll ),
|
||||
{
|
||||
.key = "reblog",
|
||||
.offset = offsetof(OBJ_TYPE, repost_id),
|
||||
.type = &Status_reference_type,
|
||||
},
|
||||
{
|
||||
.key = "reblogged",
|
||||
.offset = offsetof( OBJ_TYPE, reposts.count ),
|
||||
.type = &json_field_bool_callback,
|
||||
.bool_callback = int_non_zero,
|
||||
},
|
||||
{
|
||||
.key = "reblogs_count",
|
||||
.offset = offsetof( OBJ_TYPE, reposts.count ),
|
||||
.type = &json_field_integer,
|
||||
},
|
||||
{
|
||||
.key = "replies_count",
|
||||
.offset = offsetof( OBJ_TYPE, replies.count ),
|
||||
.type = &json_field_integer,
|
||||
},
|
||||
JSON_FIELD_FIXED_BOOL( sensitive, false ),
|
||||
JSON_FIELD_FIXED_STRING( spoiler_text, "", true ),
|
||||
JSON_FIELD_EMPTY_ARRAY( tags, true ),
|
||||
JSON_FIELD_FIXED_NULL( text ),
|
||||
{
|
||||
.key = "uri",
|
||||
.offset = offsetof( OBJ_TYPE, url ),
|
||||
.type = &json_field_string,
|
||||
},
|
||||
JSON_FIELD_STRING( url, true ),
|
||||
JSON_FIELD_FIXED_STRING( visibility, "public", true ),
|
||||
JSON_FIELD_END,
|
||||
};
|
||||
#undef OBJ_TYPE
|
||||
|
||||
static bool api_Status_writer( struct json_writer* jw, const char* field_name, void* field_data, struct json_object_field* layout_field_data )
|
||||
{
|
||||
int status_id = *(int*)field_data;
|
||||
|
||||
struct status* s = status_from_id(status_id);
|
||||
struct status* system_status = NULL;
|
||||
if( !s ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
json_write_field_name(jw,field_name);
|
||||
|
||||
if( s->stub ) {
|
||||
system_status = status_new_system_stub( s );
|
||||
json_write_pretty_object_layout( jw, api_Status_layout, system_status );
|
||||
status_free(system_status);
|
||||
} else {
|
||||
json_write_pretty_object_layout( jw, api_Status_layout, s );
|
||||
}
|
||||
|
||||
status_free(s);
|
||||
|
||||
return true;
|
||||
}
|
||||
struct json_field_type api_Status_type = {
|
||||
.writer = api_Status_writer,
|
||||
.size = sizeof(int),
|
||||
.layout = api_Status_layout,
|
||||
};
|
||||
|
||||
void api_Status_write( struct status* s, FILE* f, int indent )
|
||||
{
|
||||
struct json_writer jw = {
|
||||
.f = f,
|
||||
.indentation = "\t",
|
||||
.indent = indent,
|
||||
};
|
||||
|
||||
struct status* system_status = NULL;
|
||||
if( s->stub ) {
|
||||
system_status = status_new_system_stub( s );
|
||||
s = system_status;
|
||||
}
|
||||
|
||||
json_write_pretty_object_layout( &jw, api_Status_layout, s );
|
||||
status_free(system_status);
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct json_field_type;
|
||||
struct status;
|
||||
extern struct json_field_type api_Status_type;
|
||||
|
||||
void api_Status_write( struct status* s, FILE* f, int indent );
|
||||
|
@ -1,102 +0,0 @@
|
||||
{
|
||||
"account": %( api_Account_write(account,f,1); ),
|
||||
"application": null,
|
||||
"bookmarked": false,
|
||||
"card": null,
|
||||
"content": %( json_write_string(f,status_render_source(s)); ),
|
||||
"created_at": %( json_write_date_time_string( s->published, f ); ),
|
||||
"edited_at": null,
|
||||
"emojis": [],
|
||||
"favourited": false,
|
||||
"favourites_count": %d{ s->likes.count },
|
||||
"id": "%d{ s->id }",%(
|
||||
if( in_reply_to ) { )
|
||||
"in_reply_to_account_id": "%d{ in_reply_to->account_id }",
|
||||
"in_reply_to_id": "%d{in_reply_to->id}",%(
|
||||
} else { )
|
||||
"in_reply_to_account_id": null,
|
||||
"in_reply_to_id": null,%(
|
||||
} )
|
||||
"language": null,
|
||||
"media_attachments": [%( for( int i = 0; i < s->media.count; ++i ) { )
|
||||
{
|
||||
"blurhash": "eRH.A}xs0Kxv00xYR,R+t5R+9Gt6xaNG%%2-;xaM{NGRjD%%Rjs:xaxu",
|
||||
"description": null,
|
||||
"id": "%d{s->id}.media[%d{i}]",
|
||||
"pleroma": {
|
||||
"mime_type": "image/png"
|
||||
},
|
||||
"preview_url": "%s{s->media.items[i]}",
|
||||
"remote_url": "%s{s->media.items[i]}",
|
||||
"text_url": "%s{s->media.items[i]}",
|
||||
"type": "image",
|
||||
"url": "%s{s->media.items[i]}"
|
||||
}%s{ i < s->media.count - 1 ? "," : "" }
|
||||
%( } )],
|
||||
"mentions": [%( for( int i = 0; i < s->mentions.count; ++i ) { )
|
||||
%( struct account* mention = account_from_id( s->mentions.items[i] ); )
|
||||
%s{ i != 0 ? "," : "" }{
|
||||
"acct": "%s{mention->handle}@%s{mention->server}",
|
||||
"id": "%d{mention->id}",
|
||||
"url": "%s{mention->account_url}",
|
||||
"username": "%s{mention->handle}"
|
||||
}
|
||||
%( account_free(mention); )
|
||||
%( } )],
|
||||
"muted": false,
|
||||
"pinned": false,
|
||||
"pleroma": {
|
||||
"content": {
|
||||
"text/plain": %( json_write_string(f,s->source ? s->source : ""); )
|
||||
},
|
||||
"conversation_id": %d{s->root_status_id},
|
||||
"direct_conversation_id": null,
|
||||
"emoji_reactions": [%( for( int i = 0; i < s->reacts.count; ++i ) { struct status_react* sr = s->reacts.items[i];)
|
||||
%(
|
||||
bool includes_me( struct status_react* sr ) {
|
||||
for( int i = 0; i < sr->accounts.count; ++i ) {
|
||||
if( sr->accounts.items[i] == owner_account_id ) { return true; }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
)
|
||||
{
|
||||
"count": %d{ sr->accounts.count },
|
||||
"me": %s{ includes_me(sr) ? "true" : "false" },
|
||||
"name": %( json_write_string( f, sr->code ); )
|
||||
}%s{ i != s->reacts.count-1 ? "," : "" }
|
||||
%( } )],
|
||||
"expires_at": null,%(
|
||||
if( in_reply_to_account ) { )
|
||||
"in_reply_to_account_acct": "%s{in_reply_to_account->handle}@%s{in_reply_to_account->server}",
|
||||
"local": %s{ s->remote ? "false" : "true" },
|
||||
"parent_visible": true,%(
|
||||
} else { )
|
||||
"in_reply_to_account_acct": null,
|
||||
"local": %s{ s->remote ? "false" : "true" },
|
||||
"parent_visible": false,%(
|
||||
} )
|
||||
"pinned_at": null,
|
||||
"spoiler_text": {
|
||||
"text/plain": ""
|
||||
},
|
||||
"thread_muted": false
|
||||
},
|
||||
"poll": null,
|
||||
%(
|
||||
if( repost ) { )
|
||||
"reblog": %( api_status_write_as_json( repost, f ); ),%(
|
||||
} else { )
|
||||
"reblog": null,%(
|
||||
} )
|
||||
"reblogged": %s{ s->reposts.count > 0 ? "true": "false" },
|
||||
"reblogs_count": %d{ s->reposts.count },
|
||||
"replies_count": 0,
|
||||
"sensitive": false,
|
||||
"spoiler_text": "",
|
||||
"tags": [],
|
||||
"text": null,
|
||||
"uri": "%s{s->url}",
|
||||
"url": "%s{s->url}",
|
||||
"visibility": "public"
|
||||
}
|
Loading…
Reference in new issue