|
|
|
@ -10,6 +10,7 @@
|
|
|
|
|
// Model
|
|
|
|
|
#include "model/server.h"
|
|
|
|
|
#include "model/status.h"
|
|
|
|
|
#include "model/status/poll.h"
|
|
|
|
|
#include "model/status/react.h"
|
|
|
|
|
#include "model/account.h"
|
|
|
|
|
#include "model/media.h"
|
|
|
|
@ -18,6 +19,7 @@
|
|
|
|
|
// View
|
|
|
|
|
#include "view/api/Account.h"
|
|
|
|
|
#include "view/api/Status.h"
|
|
|
|
|
#include "view/api/Poll.h"
|
|
|
|
|
|
|
|
|
|
// Controller
|
|
|
|
|
#include "controller/api/client_apps.h"
|
|
|
|
@ -381,3 +383,122 @@ failed:
|
|
|
|
|
result = false;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Route: /api/v1/polls/%d{id}/votes
|
|
|
|
|
bool handle_votes( struct http_request* req, struct status* s )
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
struct account* owner = account_from_id( owner_account_id );
|
|
|
|
|
|
|
|
|
|
// Enforce preconditions
|
|
|
|
|
if( !s ) { goto failed; }
|
|
|
|
|
if( !owner ) { goto failed; }
|
|
|
|
|
if( !s->poll ) { goto failed; }
|
|
|
|
|
|
|
|
|
|
printf( "Processing poll votes...\n" );
|
|
|
|
|
|
|
|
|
|
struct params_t
|
|
|
|
|
{
|
|
|
|
|
struct {
|
|
|
|
|
char** items;
|
|
|
|
|
int count;
|
|
|
|
|
} choices;
|
|
|
|
|
} params;
|
|
|
|
|
memset(¶ms,0,sizeof(params));
|
|
|
|
|
#define OBJ_TYPE struct params_t
|
|
|
|
|
static struct json_object_field layout[] = {
|
|
|
|
|
JSON_FIELD_ARRAY_OF_STRINGS( choices, true ),
|
|
|
|
|
JSON_FIELD_END,
|
|
|
|
|
};
|
|
|
|
|
#undef OBJ_TYPE
|
|
|
|
|
|
|
|
|
|
FILE* data = http_request_get_request_data( req );
|
|
|
|
|
if( !json_read_object_layout_from_FILE( data, layout, ¶ms ) ) {
|
|
|
|
|
printf( "Unable to read params\n" );
|
|
|
|
|
goto failed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct {
|
|
|
|
|
int* items;
|
|
|
|
|
int count;
|
|
|
|
|
} choices_ints;
|
|
|
|
|
memset(&choices_ints,0,sizeof(choices_ints));
|
|
|
|
|
|
|
|
|
|
// Make sure all options selected exist before voting
|
|
|
|
|
for( int i = 0; i < params.choices.count; ++i ) {
|
|
|
|
|
int idx = atoi(params.choices.items[i]);
|
|
|
|
|
array_append( &choices_ints, sizeof(idx), &idx );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( status_poll_add_vote( s, owner, &choices_ints ) ) {
|
|
|
|
|
status_save(s);
|
|
|
|
|
|
|
|
|
|
http_request_send_headers( req, 200, "application/json", true );
|
|
|
|
|
FILE* f = http_request_get_response_body( req );
|
|
|
|
|
api_Poll_write( s->poll, f, 0 );
|
|
|
|
|
|
|
|
|
|
goto success;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printf( "Unable to add votes\n" );
|
|
|
|
|
goto failed;
|
|
|
|
|
cleanup:
|
|
|
|
|
for( int i = 0; i < params.choices.count; ++i ) {
|
|
|
|
|
free( params.choices.items[i] );
|
|
|
|
|
}
|
|
|
|
|
free(params.choices.items );
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
success:
|
|
|
|
|
result = true;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
failed:
|
|
|
|
|
result = false;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Route: /api/v1/polls/%d{id}/
|
|
|
|
|
bool route_polls( struct http_request* req )
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
struct status* s = NULL;
|
|
|
|
|
|
|
|
|
|
if( http_request_route_term( req, "" ) ) {
|
|
|
|
|
if( http_request_route_method( req, "POST" ) ) {
|
|
|
|
|
|
|
|
|
|
if( !check_authentication_header(req) ) { return false; }
|
|
|
|
|
|
|
|
|
|
struct account* owner = account_from_id(owner_account_id);
|
|
|
|
|
bool res = handle_post(req, owner);
|
|
|
|
|
account_free(owner);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( !http_request_route( req, "/" ) ) { return false; }
|
|
|
|
|
|
|
|
|
|
int id = -1;
|
|
|
|
|
if( !http_request_route_id( req, &id ) ) { goto failed; }
|
|
|
|
|
s = status_from_id(id);
|
|
|
|
|
if( !s ) { goto failed; }
|
|
|
|
|
|
|
|
|
|
// Make sure the status has a poll
|
|
|
|
|
if( !s->poll ) { goto failed; }
|
|
|
|
|
|
|
|
|
|
if( http_request_route_term( req, "votes" ) ) {
|
|
|
|
|
if( handle_votes( req, s ) ) { goto success; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
goto failed;
|
|
|
|
|
cleanup:
|
|
|
|
|
status_free(s);
|
|
|
|
|
return result;
|
|
|
|
|
success:
|
|
|
|
|
result = true;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
failed:
|
|
|
|
|
result = false;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|