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.

201 lines
5.4 KiB
C

#include "../activity.h"
#include "json/layout.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
static struct json_enum ap_signature_type_enum[] = {
{ "RsaSignature2017", 1 },
{ NULL, 0 },
};
static struct json_object_field ap_signature_layout[] = {
{ "type", offsetof( struct ap_signature, type ), true, &json_field_enum, ap_signature_type_enum },
{ "creator", offsetof( struct ap_signature, creator ), true, &json_field_string },
{ "created", offsetof( struct ap_signature, created ), true, &json_field_date_time },
{ "signatureValue", offsetof( struct ap_signature, value ), true, &json_field_string },
{ NULL },
};
// https://www.w3.org/TR/activitystreams-vocabulary/#h-activity-types
struct json_enum ap_activity_type_enum[] = {
{ "Undo", apat_undo },
{ "Follow", apat_follow },
{ "Delete", apat_delete },
{ "Accept", apat_accept },
{ "Create", apat_create },
{ "TentativeAccept", apat_tentative_accept },
{ "Add", apat_add },
{ "Arrive", apat_arrive },
{ "Ignore", apat_ignore },
{ "Join", apat_join },
{ "Leave", apat_leave },
{ "Like", apat_like },
{ "Offer", apat_offer },
{ "Invite", apat_invite },
{ "Reject", apat_reject },
{ "TentativeReject", apat_tentative_reject },
{ "Remove", apat_remove },
{ "Update", apat_update },
{ "View", apat_view },
{ "Listen", apat_listen },
{ "Read", apat_read },
{ "Move", apat_move },
{ "Travel", apat_travel },
{ "Announce", apat_announce },
{ "Block", apat_block },
{ "Flag", apat_flag },
{ "Dislike", apat_dislike },
{ "Question", apat_question },
{ "EmojiReact", apat_emoji_react },
{ NULL, 0 },
};
struct json_object_field activity_ref_types[] = {
{ (char*)apaot_ref, offsetof( struct ap_activity, object.ref ), false, &json_field_string },
{ (char*)apaot_activity, offsetof( struct ap_activity, object.ptr ), false, &json_field_object_pointer, ap_activity_layout },
{ NULL },
};
struct json_object_field signature_types[] = {
{ (char*)1, offsetof( struct ap_activity, signature ), false, &json_field_object_composite, ap_signature_layout },
{ NULL },
};
#define OBJ_TYPE struct ap_activity
struct json_object_field ap_activity_layout[] = {
{
.key = "@context",
.offset = offsetof( OBJ_TYPE, ap_context ),
.required = false,
.type = &ap_activity_context_type
},
JSON_FIELD_STRING(id,true),
JSON_FIELD_STRING(actor,true),
JSON_FIELD_STRING(state,false),
{
.key = "content",
.offset = offsetof( struct ap_activity, content.value ),
.required = false,
.type = &json_field_string
},
JSON_FIELD_STRING(conversation,false),
JSON_FIELD_DATETIME(published,false),
{
.key = "sensitive",
.offset = offsetof( struct ap_activity, sensitive ),
.required = false,
.type = &json_field_bool_or_null
},
{
.key = "source",
.offset = offsetof( struct ap_activity, source.value ),
.required = false,
.type = &json_field_string
},
JSON_FIELD_STRING(summary,false),
{
.key = "tag",
.offset = offsetof( struct ap_activity, tags ),
.required = false,
.type = &json_field_array_of,
.type_data = &ap_activity_tag_type
},
JSON_FIELD_STRING(context,false),
{
.key = "attributedTo",
.required = false,
.offset = offsetof(OBJ_TYPE,attributed_to),
.type = &json_field_string,
},
{ "directMessage", offsetof( struct ap_activity, direct_message ), false, &json_field_bool },
{ "attachment", offsetof( struct ap_activity, attachments ), false, &json_field_array_of, &json_field_string },
JSON_FIELD_ARRAY_OF_STRINGS(to,true),
JSON_FIELD_ARRAY_OF_STRINGS(cc,false),
JSON_FIELD_ARRAY_OF_STRINGS(bcc,false),
{ "object", offsetof( struct ap_activity, object.tag ), false, &json_field_tagged_union, &activity_ref_types },
{ "signature", offsetof( struct ap_activity, has_signature ), false, &json_field_tagged_union, &signature_types },
{ "type", offsetof( struct ap_activity, type ), true, &json_field_enum, ap_activity_type_enum },
{ NULL, 0, true, NULL, &ap_activity_type },
};
#undef OBJ_TYPE
static void ap_activity_free_shim( void* ptr )
{
ap_activity_free(ptr);
}
static void* ap_activity_alloc()
{
return (void*)ap_activity_new();
}
struct json_field_type ap_activity_type = {
.reader = json_field_object_type_reader,
.writer = json_field_object_type_writer,
.size = sizeof(struct ap_activity),
.layout = ap_activity_layout,
.alloc = ap_activity_alloc,
.free = ap_activity_free_shim,
};
struct ap_activity* ap_activity_from_FILE( FILE* f )
{
struct ap_activity* act = malloc(sizeof(struct ap_activity));
memset(act,0,sizeof(*act));
if( !json_read_object_layout_from_FILE( f, ap_activity_layout, act ) ) {
ap_activity_free(act);
return NULL;
}
return act;
}
void ap_activity_write_to_FILE( struct ap_activity* act, FILE* f )
{
struct json_writer jw = {
.f = f,
.indentation = "\t",
.indent = 0,
};
json_write_pretty_object_layout( &jw, ap_activity_layout, act );
}
void ap_activity_save( struct ap_activity* act )
{
char filename[512];
snprintf( filename, sizeof(filename), "data/activities/%d.json", act->local_id );
json_write_object_layout_to_file( filename, "\t", ap_activity_layout, act );
}
struct ap_activity* ap_activity_from_local_id( int id )
{
struct ap_activity* act = ap_activity_new();
char filename[512];
snprintf( filename, sizeof(filename), "data/activities/%d.json", id );
if( !json_read_object_layout_from_file( filename, ap_activity_layout, act ) ) {
ap_activity_free(act);
return NULL;
}
return act;
}