@ -1,8 +1,9 @@
# include "mastodon_api.h"
# include "http _server/http_ request.h"
# include "http /server/ request.h"
# include "form.h"
# include "json/json.h"
# include "http/query.h"
# include "model/status.h"
# include "model/account.h"
@ -16,6 +17,7 @@
# include "api/status.h"
# include "api/notice.h"
# include <stddef.h>
# include <limits.h>
# include <stdio.h>
# include <stdlib.h>
@ -29,14 +31,32 @@ enum timeline_ids {
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 ;
struct params_t {
int since_id ;
int max_id ;
int limit ;
bool hide_muted ;
} params = {
. since_id = 0 ,
. limit = 32 ,
. max_id = INT_MAX ,
. hide_muted = true ,
} ;
static struct http_query_fields fields [ ] = {
{ " since_id " , offsetof ( struct params_t , since_id ) , qf_string } ,
{ " limit " , offsetof ( struct params_t , limit ) , qf_integer } ,
{ " max_id " , offsetof ( struct params_t , max_id ) , qf_integer } ,
{ " hide_muted " , offsetof ( struct params_t , hide_muted ) , qf_bool } ,
{ NULL } ,
} ;
// handle query parameters
// TODO: split this off into a generic filter handling
if ( http_request_route ( req , " ? " ) ) {
http_query_parse ( req , fields , & params ) ;
}
/*
const char * key ;
while ( key = http_request_route_query_key ( req ) ) {
const char * value = http_request_route_query_value ( req ) ;
@ -57,7 +77,9 @@ bool handle_timeline( struct http_request* req, int timeline_id )
}
//printf( "Filter: limit=%d, max_id=%d, since_id=%d\n", limit, max_id, since_id );
}
}
} */
if ( params . limit > 32 ) { params . limit = 32 ; }
struct timeline * tl = timeline_from_id ( timeline_id ) ;
if ( ! tl ) {
@ -67,24 +89,30 @@ bool handle_timeline( struct http_request* req, int timeline_id )
return true ;
}
struct status * ss [ limit ] ;
int count = timeline_load_statuses ( tl , 0 , limit , ss ) ;
struct status * ss [ params . limit ] ;
struct status * items [ params . limit ] ;
struct {
struct status * * items ;
int count ;
} show = {
. items = items ,
. count = 0
} ;
int count = timeline_load_statuses ( tl , 0 , params . limit , ss ) ;
// Filter
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 ;
}
struct status * s = ss [ i ] ;
if ( s - > id < = params . since_id ) { continue ; }
if ( s - > id > = params . max_id ) { continue ; } ;
show . items [ show . count ] = s ;
show . count + = 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 ) ;
show_statuses ( req , show . items , show . count ) ;
for ( int i = 0 ; i < count ; + + i ) {
status_free ( ss [ i ] ) ;
@ -105,47 +133,6 @@ bool handle_mastodon_api_show_account( struct http_request* req, struct account*
return true ;
}
struct query_fields
{
const char * field_name ;
int offset ;
void ( * handle ) ( void * ptr , const char * value ) ;
} ;
# include <stddef.h>
void qf_string ( void * ptr , const char * value )
{
* ( const char * * ) ptr = value ;
}
void qf_integer ( void * ptr , const char * value )
{
* ( int * ) ptr = atoi ( value ) ;
}
void qf_bool ( void * ptr , const char * value )
{
if ( 0 = = strcmp ( value , " true " ) ) {
* ( bool * ) ptr = true ;
}
}
void parse_query ( struct http_request * req , struct query_fields * fields , void * ptr )
{
char * data = ptr ;
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 ) ;
for ( struct query_fields * i = fields ; i - > field_name ; + + i ) {
if ( 0 = = strcmp ( i - > field_name , key ) ) {
i - > handle ( & data [ i - > offset ] , value ) ;
}
}
}
}
static bool handle_search ( struct http_request * req )
{
struct params_t
@ -157,7 +144,7 @@ static bool handle_search( struct http_request* req )
} params ;
memset ( & params , 0 , sizeof ( params ) ) ;
static struct query_fields fields [ ] = {
static struct http_ query_fields fields [ ] = {
{ " q " , offsetof ( struct params_t , q ) , qf_string } ,
{ " limit " , offsetof ( struct params_t , limit ) , qf_integer } ,
{ " resolve " , offsetof ( struct params_t , resolve ) , qf_bool } ,
@ -165,18 +152,7 @@ static bool handle_search( struct http_request* req )
{ NULL } ,
} ;
parse_query ( req , fields , & params ) ;
printf ( " params = { \n "
" \t .q = %s \n "
" \t .limit = %d \n "
" \t .resolve = %c \n "
" \t .following = %c \n " ,
params . q ,
params . limit ,
params . resolve ? ' T ' : ' F ' ,
params . following ? ' T ' : ' F '
) ;
http_query_parse ( req , fields , & params ) ;
http_request_send_headers ( req , 200 , " application/json " , true ) ;
FILE * f = http_request_get_response_body ( req ) ;
@ -191,6 +167,8 @@ static bool handle_search( struct http_request* req )
api_account_write_as_json ( a , f ) ;
fprintf ( f , " ] " ) ;
account_free ( a ) ;
return true ;
}