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.

227 lines
5.9 KiB
C

#include "mastodon_api.h"
#include "http_server/http_request.h"
#include "form.h"
#include "json/json.h"
#include "model/status.h"
#include "model/account.h"
#include "model/notification.h"
#include "model/timeline.h"
#include "model/server.h"
#include "controller/pleroma_api.h"
#include "api/client_apps.h"
#include "api/status.h"
#include "api/notice.h"
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum timeline_ids {
tli_owner = 0,
tli_public = 1,
tli_home = 2,
};
bool handle_timeline( struct http_request* req, int timeline_id )
{
bool hide_muted = true;
unsigned int limit = 32;
int max_id = INT_MAX;
int since_id = 0;
// handle query parameters
if( http_request_route( req, "?" ) ) {
const char* key;
while( key = http_request_route_query_key(req) ) {
const char* value = http_request_route_query_value(req);
//printf( "%s = %s\n", key, value );
if( !value ) {
} else if( 0 == strcmp(key,"limit") ) {
int new_limit;
sscanf(value,"%d",&new_limit);
if( new_limit < limit ) {
limit = new_limit;
}
} else if( 0 == strcmp(key,"with_muted") ) {
hide_muted = false;
} else if( 0 == strcmp(key,"since_id") ) {
sscanf(value,"%d",&since_id);
} else if( 0 == strcmp(key,"max_id") ) {
sscanf(value,"%d",&max_id);
}
//printf( "Filter: limit=%d, max_id=%d, since_id=%d\n", limit, max_id, since_id );
}
}
struct timeline* tl = timeline_from_id( timeline_id );
2 years ago
if( !tl ) {
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
fprintf( f, "[]" );
return true;
}
struct status* ss[limit];
int count = timeline_load_statuses( tl, 0, limit, ss );
for( int i = 0; i < count; ++i ) {
if( ss[i]->id <= since_id ) {
count = i;
break;
}
}
int base = 0;
for( int i = 0; i < count; ++i ) {
if( ss[i]->id >= max_id ) {
base = i + 1;
}
}
//printf( "limit=%d, since_id=%d, base=%d\n", limit, since_id, base );
//printf( "count=%d\n", count - base );
show_statuses( req, &ss[base], count - base );
for( int i = 0; i < count; ++i ) {
status_free( ss[i] );
}
timeline_free(tl);
return true;
}
bool handle_mastodon_api_show_account( struct http_request* req, struct account* a )
{
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
api_account_write_as_json(a,f);
return true;
}
bool http_request_route_id( struct http_request* req, int* id )
{
char* id_str = http_request_route_get_dir_or_file(req);
if( !id_str || !*id_str ) { return false; }
*id = -1;
sscanf( id_str, "%d", id );
free(id_str);
if( *id == -1 ) { return false; }
return true;
}
bool route_mastodon_api( struct http_request* req )
{
if( http_request_route_term( req, "apps" ) ) {
if( http_request_route_method( req, "POST" ) ) {
return handle_mastodon_api_apps(req);
}
} else if( http_request_route( req, "timelines/public" ) ) {
return handle_timeline( req, tli_public );
} else if( http_request_route( req, "instance" ) ) {
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
#include "src/view/api/instance_data.json.inc"
return true;
}
if( !check_bearer_token(req) ) { return false; }
if( http_request_route( req, "pleroma" ) ) {
return route_pleroma_api( req );
}
if( http_request_route( req, "notifications" ) ) {
return handle_notifications(req);
} else if( http_request_route( req, "filters" ) ) {
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
fprintf( f, "[]" );
return true;
} else 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 ) {
return false;
}
if( http_request_route( req, "context" ) ) {
show_status_context( req, s );
} else {
show_status( req, s );
}
status_free(s);
return true;
}
} else if( http_request_route_method( req, "POST" ) ) {
2 years ago
struct account* owner = account_from_id(0);
bool res = handle_post(req, owner);
account_free(owner);
return res;
}
} else if( http_request_route( req, "timelines/" ) ) {
if( http_request_route( req, "home" ) ) {
return handle_timeline( req, tli_home );
} else if( http_request_route( req, "public" ) ) {
return handle_timeline( req, tli_public );
}
} else if( http_request_route( req, "apps/" ) ) {
if( http_request_route( req, "verify_credentials" ) ) {
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
#include "src/view/api/verify_credentials.json.inc"
return true;
}
} else if( http_request_route( req, "accounts/" ) ) {
if( http_request_route( req, "verify_credentials" ) ) {
struct account* owner = account_from_id(0);
bool res = handle_mastodon_api_show_account( req, owner );
account_free(owner);
return res;
} else if( http_request_route( req, "relationships" ) ) {
http_request_send_headers( req, 200, "application/json", true );
FILE* f = http_request_get_response_body( req );
fprintf( f, "[]" );
return true;
} else if( http_request_route( req, "statuses" ) ) {
return handle_timeline( req, tli_owner );
}
int id = 0;
if( http_request_route_id( req, &id ) ) {
struct account* a = account_from_id( id );
if( !a ) { return false; }
if( http_request_route( req, "statuses" ) ) {
2 years ago
bool res = handle_timeline( req, id );
account_free(a);
return res;
} else {
2 years ago
bool res = handle_mastodon_api_show_account( req, a );
account_free(a);
return res;
}
} else if( id == 0 ) {
2 years ago
struct account* owner = account_from_id(0);
bool res = handle_mastodon_api_show_account( req, owner );
account_free(owner);
return res;
}
}
return false;
}