|
|
|
#include "status.h"
|
|
|
|
|
|
|
|
#include "json/json.h"
|
|
|
|
|
|
|
|
#include "http/server/request.h"
|
|
|
|
#include "model/status.h"
|
|
|
|
#include "model/status/react.h"
|
|
|
|
#include "model/account.h"
|
|
|
|
#include "model/timeline.h"
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
void write_json_escaped( FILE* f, const char* str );
|
|
|
|
|
|
|
|
void api_status_write_as_json( struct status* s, FILE* f )
|
|
|
|
{
|
|
|
|
struct account* account = account_from_id( s->account_id );
|
|
|
|
|
|
|
|
#include "src/view/api/status.json.inc"
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
account_free(account);
|
|
|
|
}
|
|
|
|
|
|
|
|
void show_status( struct http_request* req, struct status* s )
|
|
|
|
{
|
|
|
|
http_request_send_headers( req, 200, "application/json", true );
|
|
|
|
FILE* f = http_request_get_response_body( req );
|
|
|
|
|
|
|
|
api_status_write_as_json(s,f);
|
|
|
|
}
|
|
|
|
void show_status_context( struct http_request* req, struct status* s )
|
|
|
|
{
|
|
|
|
http_request_send_headers( req, 200, "application/json", true );
|
|
|
|
FILE* f = http_request_get_response_body( req );
|
|
|
|
|
|
|
|
fprintf( f, "{\"ancestors\":[],\"descendants\":[]}" );
|
|
|
|
}
|
|
|
|
|
|
|
|
void show_statuses( struct http_request* req, struct status** ss, int count )
|
|
|
|
{
|
|
|
|
http_request_send_headers( req, 200, "application/json", true );
|
|
|
|
FILE* f = http_request_get_response_body( req );
|
|
|
|
|
|
|
|
fprintf( f, "[" );
|
|
|
|
for( int i = 0; i < count; ++i ) {
|
|
|
|
if( i > 0 ) {
|
|
|
|
fprintf( f, "," );
|
|
|
|
}
|
|
|
|
api_status_write_as_json(ss[i],f);
|
|
|
|
}
|
|
|
|
fprintf( f, "]" );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool handle_post( struct http_request* req, struct account* a )
|
|
|
|
{
|
|
|
|
bool result = false;
|
|
|
|
struct status* s = NULL;
|
|
|
|
|
|
|
|
FILE* data = http_request_get_request_data( req );
|
|
|
|
|
|
|
|
// {"media_ids":[],"sensitive":false,"status":"Test","visibility":"public","spoiler_text":""}
|
|
|
|
struct json_pull_parser* jpp = json_pull_parser_new( data );
|
|
|
|
if( !jpp ) { return false; }
|
|
|
|
int save;
|
|
|
|
if( !json_pull_parser_begin_object( jpp, &save ) ) { return false; }
|
|
|
|
|
|
|
|
s = malloc(sizeof(struct status));
|
|
|
|
memset(s,0,sizeof(*s));
|
|
|
|
|
|
|
|
char* key;
|
|
|
|
while( key = json_pull_parser_read_object_key(jpp) ) {
|
|
|
|
if( 0 == strcmp(key,"media_ids") ) {
|
|
|
|
json_pull_parser_read_value(jpp);
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"sensitive") ) {
|
|
|
|
json_pull_parser_read_bool(jpp,&s->sensitive);
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"status") ) {
|
|
|
|
s->source = json_pull_parser_read_string(jpp);
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"visibility") ) {
|
|
|
|
free(json_pull_parser_read_string(jpp));
|
|
|
|
|
|
|
|
} else if( 0 == strcmp(key,"spoiler_text") ) {
|
|
|
|
free(json_pull_parser_read_string(jpp));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
json_pull_parser_read_value(jpp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(key);
|
|
|
|
|
|
|
|
if( !json_pull_parser_end_object(jpp, &save ) ) { goto failed; }
|
|
|
|
|
|
|
|
status_save_new(s);
|
|
|
|
|
|
|
|
// Add to owner timeline, public timeline and home timelines
|
|
|
|
for( int i = 0; i < 3; ++i ) {
|
|
|
|
struct timeline* tl = timeline_from_id(i);
|
|
|
|
timeline_add_post( tl, s );
|
|
|
|
timeline_free(tl);
|
|
|
|
}
|
|
|
|
|
|
|
|
http_request_send_headers( req, 200, "application/json", true );
|
|
|
|
FILE* f = http_request_get_response_body(req);
|
|
|
|
api_status_write_as_json(s,f);
|
|
|
|
result = true;
|
|
|
|
cleanup:
|
|
|
|
free(s->content);
|
|
|
|
free(s);
|
|
|
|
return result;
|
|
|
|
failed:
|
|
|
|
result = false;
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|