#include "context.h" #include "json/layout.h" #include "json/json.h" #include "format.h" #include "model/server.h" #include "collections/array.h" #include "collections/item_type/string.h" #include #include #include #include static const char* langs[] = { "und", "en", "de", "fr", "pt", "ja", }; static bool context_eat( struct json_pull_parser* jpp, int* save ) { json_pull_parser_read_value(jpp); char* key; while( key = json_pull_parser_read_object_key(jpp) ) { free(key); json_pull_parser_read_value(jpp); } if( !json_pull_parser_end_object(jpp,save) ) { return false; } return true; } static bool context_read_language( struct json_pull_parser* jpp, struct ap_activity_context* ctx, int* save ) { char* lang = json_pull_parser_read_string(jpp); if( !lang ) { return false; } ctx->language = clang_unknown; for( int i = 0; i < sizeof(langs)/sizeof(langs[0]); ++i ) { //printf( "candidate: %s ==? %s\n", langs[i], lang ); if( 0 == strcmp(langs[i],lang) ) { ctx->language = i+1; } } if( ctx->language == clang_unknown ) { printf( "unknown language: %s\n", lang ); return false; } free(lang); if( !json_pull_parser_end_object(jpp,save) ) { printf( "Object failed\n" ); return false; } return true; } static bool context_reader( struct json_pull_parser* jpp, void* field_data, struct json_object_field* layout_field_data ) { //printf( "context_reader\n" ); struct ap_activity_context* ctx = field_data; char* str = json_pull_parser_read_string(jpp); if( str ) { if( 0 != strcmp(str,"https://www.w3.org/ns/activitystreams") ) { free(str); return false; } free(str); return true; } int save; if( !json_pull_parser_begin_array(jpp,&save) ) { return false; } struct collection c = { .ptr = &ctx->extra, .vtable = &array_vtable, .itable = &string_itable, }; while( !json_pull_parser_end_array( jpp, &save ) ) { str = json_pull_parser_read_string(jpp); if( str ) { array_append_c( c, &str ); } else { int save2; if( !json_pull_parser_begin_object( jpp, &save2 ) ) { return false; } char* key = json_pull_parser_read_object_key(jpp); if( 0 == strcmp("@language",key) ) { if( !context_read_language( jpp, ctx, &save2 ) ) { return false; } } else { if( !context_eat( jpp, &save2 ) ) { return false; } } free(key); } } return true; } static bool context_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 ); struct ap_activity_context* ctx = field_data; int items = 2; if( ctx ) { items += ctx->extra.count + (ctx->language ? 1 : 0 ); } fprintf( jw->f, "[" ); json_write_string( jw->f, "https://www.w3.org/ns/activitystreams" ); fprintf( jw->f, "," ); char buffer[512]; json_write_string( jw->f, format( buffer, 512, "https://%s/schemas/litepub-0.1.jsonld", g_server->domain ) ); if( items > 2 ) { for( int i = 0; i < ctx->extra.count; ++i ) { fprintf( jw->f, "," ); json_write_string( jw->f, ctx->extra.items[i] ); } if( ctx->language ) { fprintf( jw->f, ",{ \"@language\":\"%s\"", langs[ctx->language] ); } } fprintf( jw->f, "]" ); return true; } struct json_field_type ap_activity_context_type = { .reader = context_reader, .writer = context_writer, .size = sizeof(struct ap_activity_context) };