You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

359 lines
7.9 KiB
C

#include "../object.h"
#include "json/layout.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
extern struct json_field_type ap_signature_composite_type;
extern struct json_field_type ap_activity_source_type;
// https://www.w3.org/TR/activitystreams-vocabulary/#h-activity-types
struct json_enum ap_object_type_enum[] = {
{ "Undo", ap_Undo },
{ "Follow", ap_Follow },
{ "Delete", ap_Delete },
{ "Accept", ap_Accept },
{ "Create", ap_Create },
{ "TentativeAccept", ap_TentativeAccept },
{ "Add", ap_Add },
{ "Arrive", ap_Arrive },
{ "Ignore", ap_Ignore },
{ "Join", ap_Join },
{ "Leave", ap_Leave },
{ "Like", ap_Like },
{ "Offer", ap_Offer },
{ "Invite", ap_Invite },
{ "Reject", ap_Reject },
{ "TentativeReject", ap_TentativeReject },
{ "Remove", ap_Remove },
{ "Update", ap_Update },
{ "View", ap_View },
{ "Listen", ap_Listen },
{ "Read", ap_Read },
{ "Move", ap_Move },
{ "Travel", ap_Travel },
{ "Announce", ap_Announce },
{ "Block", ap_Block },
{ "Flag", ap_Flag },
{ "Dislike", ap_Dislike },
{ "EmojiReact", pleroma_EmojiReact },
{ "Note", ap_Note },
{ "Question", ap_Question },
{ "Document", ap_Document },
{ "Image", ap_Image },
{ "Tombstone", ap_Tombstone },
{ "Person", ap_Person },
{ "Service", ap_Service },
{ "Application", ap_Application },
{ "Group", ap_Group },
{ "Organization", ap_Organization },
{ "Collection", ap_Collection },
{ "CollectionPage", ap_CollectionPage },
{ "OrderedCollection", ap_OrderedCollection },
{ "OrderedCollectionPage", ap_OrderedCollectionPage },
// Musicbox Types
{ "Track", mb_Track },
{ "Album", mb_Album },
// Forge Types
// Schema Types
{ "PropertyValue", schema_PropertyValue },
{ NULL, 0 },
};
extern struct json_field_type ap_object_ptr_or_ref_type;
struct json_tagged_union_typelist signature_types[] = {
{
.tag_value = 1,
.offset = offsetof( struct ap_object, signature ),
.type = &ap_signature_composite_type,
},
JSON_TAGGED_UNION_TYPELIST_END,
};
extern struct json_field_type endpoints_type;
extern struct json_field_type image_type;
extern struct json_field_type capabilities_type;
#define OBJ_TYPE struct ap_public_key
static struct json_object_field ap_public_key_layout[] = {
JSON_FIELD_STRING( id, true ),
JSON_FIELD_STRING( owner, true ),
{
.key = "publicKeyPem",
.offset = offsetof( OBJ_TYPE, public_key ),
.required = true,
.type = &json_field_string,
},
JSON_FIELD_END,
};
#undef OBJ_TYPE
void ap_public_key_free( struct ap_public_key* pk )
{
if( !pk ) { return; }
free( pk->id );
free( pk->owner );
free( pk->public_key );
free( pk );
}
JSON_FIELD_TYPE_OBJECT_LAYOUT_WITH_DEFAULTS( ap_public_key );
#define OBJ_TYPE struct ap_object
struct json_object_field ap_object_layout[] = {
{
.key = "@context",
.offset = offsetof( OBJ_TYPE, ap_context ),
.required = false,
.type = &ap_activity_context_type
},
JSON_FIELD_STRING(id,false),
JSON_FIELD_STRING(actor,false),
JSON_FIELD_STRING(name,false),
JSON_FIELD_STRING(state,false),
JSON_FIELD_STRING(inbox,false),
JSON_FIELD_STRING(outbox,false),
{
.key = "preferredUsername",
.offset = offsetof( OBJ_TYPE, preferred_username ),
.required = false,
.type = &json_field_string,
},
JSON_FIELD_STRING(url,false),
{
.key = "endpoints",
.offset = 0,
.required = false,
.type = &endpoints_type,
},
JSON_FIELD_STRING( featured, false ),
JSON_FIELD_STRING( following, false ),
JSON_FIELD_STRING( followers, false ),
{
.key = "icon",
.offset = offsetof( OBJ_TYPE, avatar ),
.required = false,
.type = &image_type,
},
{
.key = "image",
.offset = offsetof( OBJ_TYPE, banner ),
.required = false,
.type = &image_type,
},
{
.key = "capabilities",
.offset = 0,
.required = false,
.type = &capabilities_type,
},
JSON_FIELD_BOOL( discoverable, false ),
{
.key = "manuallyApprovesFollowers",
.offset = offsetof( OBJ_TYPE, manually_approves_followers ),
.required = false,
.type = &json_field_bool,
},
{
.key = "publicKey",
.offset = offsetof( OBJ_TYPE, public_key ),
.required = false,
.type = &ap_public_key_type,
},
{
.key = "content",
.offset = offsetof( OBJ_TYPE, content ),
.required = false,
.type = &ap_activity_source_type
},
JSON_FIELD_STRING(conversation,false),
JSON_FIELD_DATETIME(published,false),
{
.key = "sensitive",
.offset = offsetof( OBJ_TYPE, sensitive ),
.required = false,
.type = &json_field_bool_or_null
},
{
.key = "source",
.offset = offsetof( OBJ_TYPE, source ),
.required = false,
.type = &ap_activity_source_type
},
JSON_FIELD_STRING(summary,false),
{
.key = "inReplyTo",
.offset = offsetof( OBJ_TYPE, in_reply_to ),
.required = false,
.type = &json_field_string
},
{
.key = "tag",
.offset = offsetof( OBJ_TYPE, tags ),
.required = false,
.type = &json_field_array_of,
.allow_drop_empty_array = true,
.array_item_type = &ap_activity_tag_type
},
{
.key = "alsoKnownAs",
.offset = offsetof( OBJ_TYPE, also_known_as ),
.required = false,
.allow_drop_empty_array = true,
.type = &json_field_array_of,
.array_item_type = &json_field_string,
},
JSON_FIELD_STRING(context,false),
{
.key = "attributedTo",
.required = false,
.offset = offsetof(OBJ_TYPE,attributed_to),
.type = &json_field_string,
},
JSON_FIELD_STRING( target, false ),
{
.key = "directMessage",
.offset = offsetof( OBJ_TYPE, direct_message ),
.required = false,
.type = &json_field_bool
},
{
.key = "attachment",
.offset = offsetof( OBJ_TYPE, attachments ),
.required = false,
.allow_drop_empty_array = true,
.type = &json_field_array_of,
.array_item_type = &ap_attachment_type
},
{
.key = "to",
.offset = offsetof( OBJ_TYPE, to ),
.required = false,
.allow_drop_empty_array = true,
.type = &json_field_single_or_array_of,
.array_item_type = &json_field_string,
},
{
.key = "cc",
.offset = offsetof( OBJ_TYPE, cc ),
.required = false,
.allow_drop_empty_array = true,
.type = &json_field_single_or_array_of,
.array_item_type = &json_field_string,
},
{
.key = "bcc",
.offset = offsetof( OBJ_TYPE, bcc ),
.required = false,
.allow_drop_empty_array = true,
.type = &json_field_single_or_array_of,
.array_item_type = &json_field_string,
},
{
.key = "object",
.offset = offsetof( OBJ_TYPE, object ),
.required = false,
.type = &ap_object_ptr_or_ref_type,
},
{
.key = "signature",
.offset = offsetof( OBJ_TYPE, has_signature ),
.required = false,
.type = &json_field_tagged_union,
.tagged_item_types = signature_types
},
{
.key = "first",
.offset = offsetof( OBJ_TYPE, first ),
.required = false,
.type = &ap_object_ptr_or_ref_type,
},
JSON_FIELD_STRING( next, false ),
JSON_FIELD_STRING( prev, false ),
{
.key = "partOf",
.offset = offsetof( OBJ_TYPE, part_of ),
.required = false,
.type = &json_field_string,
},
{
.key = "totalItems",
.offset = offsetof( struct ap_object, total_items ),
.required = false,
.type = &json_field_integer,
},
{
.key = "items",
.offset = offsetof( OBJ_TYPE, collection_items ),
.allow_drop_empty_array = true,
.type = &json_field_array_of,
.array_item_type = &ap_object_ptr_or_ref_type,
},
JSON_FIELD_ENUM( type, ap_object_type_enum, true ),
JSON_FIELD_END,
};
#undef OBJ_TYPE
JSON_FIELD_TYPE_OBJECT_LAYOUT_WITH_DEFAULTS( ap_object );
struct ap_object* ap_object_from_FILE( FILE* f )
{
struct ap_object* act = malloc(sizeof(struct ap_object));
memset(act,0,sizeof(*act));
if( !json_read_object_layout_from_FILE( f, ap_object_layout, act ) ) {
ap_object_free(act);
return NULL;
}
return act;
}
struct ap_object* ap_object_from_file( const char* filename )
{
FILE* f = fopen(filename,"r");
if( !f ) { return NULL; }
struct ap_object* obj = ap_object_from_FILE(f);
return obj;
}
void ap_object_write_to_FILE( struct ap_object* obj, FILE* f )
{
struct json_writer jw = {
.f = f,
.indentation = "\t",
.indent = 0,
};
if( !obj ) {
fprintf( f, "null" );
return;
}
json_write_pretty_object_layout( &jw, ap_object_layout, obj );
}