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.

219 lines
5.2 KiB
C

#include "pleroma_api.h"
#include "model/account.h"
#include "model/status.h"
#include "model/notification.h"
#include "view/api/Notification.h"
#include "src/controller/api/client_apps.h"
#include "src/controller/api/status.h"
#include "http/cgi.h"
#include "http/server/request.h"
#include "json/json.h"
#include "json/layout.h"
#include <stdlib.h>
#include <string.h>
bool http_request_route_id( struct http_request* req, int* id );
// Route: /api/v1/pleroma/statuses/%d{s->id}/quotes
void show_status_quotes( struct http_request* req, struct status* s )
{
struct {
struct status** items;
int count;
} quotes;
status_get_quotes( s, &quotes );
printf( "Got %d statuses\n", quotes.count );
show_statuses( req, quotes.items, quotes.count );
}
// Route: /api/v1/pleroma/statuses/reactions/
static bool handle_reactions( struct http_request* req, struct status* s )
{
int method = -1;
if( http_request_route_method( req, "PUT" ) ) {
method = 1;
} else if( http_request_route_method( req, "DELETE" ) ) {
method = 0;
}
if( method != -1 ) {
char* react_cgi = http_request_route_get_dir_or_file( req );
char* react = cgi_unescape(react_cgi);
free(react_cgi);
// Make sure there is a reaction here
if( !*react ) {
return false;
}
struct account* owner = account_from_id( owner_account_id );
if( method ) {
status_add_react( s, react, owner );
} else {
status_remove_react( s, react, owner );
}
free(react);
account_free(owner);
show_status( req, s );
return true;
} else if( http_request_route_method( req, "GET" ) ) {
printf( "TODO: get who react information\n" );
return false;
}
return false;
}
// Route: /api/v1/pleroma/statuses
static bool route_status( struct http_request* req, struct status* s )
{
printf( __FILE__ " route_status. Remaining: '%s'\n", http_request_get_remaining_path(req) );
if( http_request_route( req, "reactions/" ) ) {
return handle_reactions( req, s );
} else if( http_request_route_term( req, "quotes" ) ) {
printf( __FILE__ " quotes\n" );
show_status_quotes( req, s );
return true;
}
return false;
}
// Route: /api/pleroma/frontend_configurations
static bool handle_frontend_configurations( struct http_request* req )
{
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
#include "src/view/api/frontend_config.json.inc"
return true;
}
// Route: /api/pleroma
bool route_pleroma_api2( struct http_request* req )
{
if( http_request_route( req, "/frontend_configurations" ) ) {
return handle_frontend_configurations(req);
}
return false;
}
// Route: GET /api/v1/pleroma/birthdays
bool handle_pleroma_birthdays( struct http_request* req )
{
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
fprintf( f, "[]" );
return true;
}
// Route: POST /api/v1/pleroma/notifications/read
struct read_notification_params_t
{
char* max_id;
char* id;
};
bool handle_read_notification( struct http_request* req )
{
struct read_notification_params_t params;
memset(&params,0,sizeof(params));
#define OBJ_TYPE struct read_notification_params_t
static struct json_object_field params_layout[] = {
JSON_FIELD_STRING( max_id, false ),
JSON_FIELD_STRING( id, false ),
JSON_FIELD_END
};
#undef OBJ_TYPE
FILE* req_body = http_request_get_request_data(req);
json_read_object_layout_from_FILE( req_body, params_layout, &params );
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body(req);
if( params.max_id ) {
int max_id = 0;
fprintf( f, "[" );
bool is_first = true;
if( 1 == sscanf( params.max_id, "%012d", &max_id ) ) {
for( int i = 0; i < 80; ++i ) {
struct notification* n = notification_from_id( max_id - i );
if( !n ) { break; }
if( n->is_seen ) { goto done_one_max_id; }
n->is_seen = true;
if( !is_first ) {
fprintf( f, ",\n" );
}
is_first = false;
api_Notification_write( n, f, 1 );
notification_save(n);
done_one_max_id:
notification_free(n);
}
}
fprintf( f, "]" );
} else if( params.id ) {
int id = 0;
if( 1 == sscanf( params.id, "%012d", &id ) ) {
struct notification* n = notification_from_id(id);
if( !n ) { goto done_id; };
n->is_seen = true;
api_Notification_write( n, f, 0 );
notification_save(n);
done_id:
notification_free(n);
}
}
free(params.id);
free(params.max_id);
return true;
}
// Route: /api/v1/pleroma
bool route_pleroma_api( struct http_request* req )
{
printf( "route: route_pleroma_api\n" );
if( http_request_route( req, "/statuses" ) ) {
printf( "route: statuses\n" );
if( http_request_route( req, "/" ) ) {
int id = -1;
if( http_request_route_id( req, &id ) ) {
struct status* s = status_from_id(id);
if( !s ) {
printf( "Status %d not found\n", id );
return false;
}
bool result = route_status( req, s );
status_free(s);
return result;
}
}
} else if( http_request_route( req, "/birthdays" ) ) {
return handle_pleroma_birthdays(req);
} else if( http_request_route( req, "/notifications/read" ) ) {
if( http_request_route_method( req, "POST" ) ) {
return handle_read_notification(req);
}
}
return false;
}