#include "Account.h" #include "json/json.h" #include "json/layout.h" #include "util/format.h" #include "model/account.h" #include "view/api/Relationship.h" #include #define OBJ_TYPE struct account static struct json_object_field pleroma_layout[] = { JSON_FIELD_FIXED_BOOL( accepts_chat_messages, false ), JSON_FIELD_EMPTY_ARRAY( also_known_as, true ), { .key = "ap_id", .offset = offsetof( OBJ_TYPE, account_url ), .type = &json_field_string, }, JSON_FIELD_FIXED_NULL( background_image ), JSON_FIELD_FIXED_NULL( favicon ), JSON_FIELD_FIXED_BOOL( deactivated, false ), JSON_FIELD_FIXED_BOOL( hide_favorites, true ), JSON_FIELD_FIXED_BOOL( hide_followers, false ), JSON_FIELD_FIXED_BOOL( hide_followers_count, false ), JSON_FIELD_FIXED_BOOL( hide_follows, false ), JSON_FIELD_FIXED_BOOL( hide_follows_count, false ), JSON_FIELD_FIXED_BOOL( is_admin, false ), // is_admin TODO: change to callback JSON_FIELD_FIXED_BOOL( is_confirmed, true ), JSON_FIELD_FIXED_BOOL( is_moderator, false ), { .key = "relationship", .offset = 0, .type = &api_Relationship_to_owner, }, JSON_FIELD_FIXED_BOOL( skip_thread_containment, false ), JSON_FIELD_EMPTY_ARRAY( tags, true ), JSON_FIELD_END, }; static struct json_object_field source_pleroma_layout[] = { JSON_FIELD_FIXED_STRING( actor_type, "Person", true ), JSON_FIELD_FIXED_BOOL( discoverable, false ), JSON_FIELD_END }; static struct json_object_field source_layout[] = { JSON_FIELD_EMPTY_ARRAY( fields, true ), JSON_FIELD_FIXED_STRING( note, "", true ), { .key = "pleroma", .offset = 0, .type = &json_field_object_composite, .composite_layout = source_pleroma_layout, }, JSON_FIELD_FIXED_BOOL( sensitive, false ), JSON_FIELD_END }; static bool acct_callback( void* field_data, bool is_read, char** res ) { struct account* a = field_data; if( !is_read ) { if( a->server ) { *res = aformat( "%s@%s", a->handle, a->server ); } else { *res = strdup( a->handle ); } return true; } return false; } static bool display_name_callback( void* field_data, bool is_read, char** res ) { struct account* a = field_data; if( !is_read ) { *res = strdup( a->display_name ? a->display_name : a->handle ); return true; } return false; } static bool fqn_callback( void* field_data, bool is_read, char** res ) { struct account* a = field_data; if( !is_read ) { *res = aformat( "%s@%s", a->handle, a->server ); return true; } return false; } bool int_to_string_callback( void* field_data, bool is_read, char** res ) { int* field = field_data; if( is_read ) { return 1 == sscanf( *res, "%d", field ); } else { *res = aformat( "%018u", *field ); return true; } return false; } struct json_object_field api_Account_layout[] = { { .key = "acct", .offset = 0, .type = &json_field_callback_string, .string_callback = acct_callback, }, { .key = "avatar", .required = true, .offset = offsetof( OBJ_TYPE, avatar.url ), .type = &json_field_string }, { .key = "avatar_static", .required = true, .offset = offsetof( OBJ_TYPE, avatar.static_url ), .type = &json_field_string }, JSON_FIELD_BOOL( bot, true ), JSON_FIELD_FIXED_STRING( created_at, "2022-03-18T19:33:06.000Z", true ), { .key = "display_name", .offset = 0, .type = &json_field_callback_string, .string_callback = display_name_callback, }, JSON_FIELD_EMPTY_ARRAY( emojis, true ), JSON_FIELD_EMPTY_ARRAY( fields, true ), JSON_FIELD_INTEGER( followers_count, true ), JSON_FIELD_INTEGER( following_count, true ), { .key = "fqn", .offset = 0, .type = &json_field_callback_string, .string_callback = fqn_callback, }, { .key = "header", .offset = offsetof( OBJ_TYPE, banner ), .type = &json_field_string }, { .key = "header_static", .offset = offsetof( OBJ_TYPE, banner ), .type = &json_field_string }, { .key = "id", .offset = offsetof( OBJ_TYPE, id ), .type = &json_field_callback_string, .string_callback = int_to_string_callback, }, JSON_FIELD_BOOL( locked, true ), JSON_FIELD_STRING( note, true ), { .key = "pleroma", .offset = 0, .type = &json_field_object_composite, .composite_layout = pleroma_layout, }, { .key = "source", .offset = 0, .type = &json_field_object_composite, .composite_layout = source_layout, }, { .key = "statuses_count", .offset = offsetof( OBJ_TYPE, status_count ), .type = &json_field_integer, }, { .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 api_Account_writer( struct json_writer* jw, const char* field_name, void* field_data, struct json_reflection* layout_field_data, int offset ) { int account_id = *(int*)field_data; struct account* a = account_from_id(account_id); if( !a ) { return false; } //struct account* owner_account = account_from_id( owner_account_id ); json_write_field_name(jw,field_name); json_write_pretty_object_layout( jw, api_Account_layout, a ); //account_free(owner_account); account_free(a); return true; } struct json_field_type api_Account_type = { .writer = api_Account_writer, .size = sizeof(int), .layout = api_Account_layout, }; void api_Account_write( struct account* a, FILE* f, int indent ) { struct json_writer jw = { .f = f, .indentation = "\t", .indent = indent, }; json_write_pretty_object_layout( &jw, api_Account_layout, a ); }