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.

118 lines
2.3 KiB
C

#include "timeline.h"
// Submodules
#include "http/server/request.h"
#include "http/query.h"
// Model
#include "model/timeline.h"
#include "model/status.h"
// Controller
#include "controller/api/status.h"
#include <string.h>
bool handle_timeline( struct http_request* req, int timeline_id )
{
struct params_t {
int since_id;
int max_id;
int limit;
bool hide_muted;
bool pinned;
} params = {
.since_id = 0,
.limit = 32,
.max_id = 2147483647,
.hide_muted = true,
.pinned = false,
};
#define OBJ_TYPE struct params_t
static struct http_query_fields fields[] = {
HTTP_QUERY_FIELD_INT( since_id )
HTTP_QUERY_FIELD_INT( limit )
HTTP_QUERY_FIELD_INT( max_id )
HTTP_QUERY_FIELD_BOOL( hide_muted )
HTTP_QUERY_FIELD_BOOL( pinned )
HTTP_QUERY_FIELD_END
};
#undef OBJ_TYPE
// handle query parameters
if( http_request_route( req, "?" ) ) {
http_query_parse( req, fields, &params );
}
if( params.limit > 100 ) { params.limit = 100; }
struct timeline* tl = timeline_from_id( timeline_id );
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[params.limit];
memset(ss,0,sizeof(ss));
struct status* items[params.limit];
struct {
struct status** items;
int count;
} show = {
.items = items,
.count = 0
};
int offset = 0;
int count = 0;
int max_loops = 5;
load_statuses:
//printf( "loading offset=%d,limit=%d\n", offset, params.limit );
count = timeline_load_statuses( tl, offset, params.limit, ss );
//printf( "count=%d\n", count );
if( count == 0 ) { goto done; }
// Filter
for( int i = 0; i < count; ++i ) {
struct status* s = ss[i];
if( s->id <= params.since_id ) { goto filtered; }
if( s->id >= params.max_id ) { goto filtered; }
if( s->pinned != params.pinned ) { goto filtered; }
show.items[show.count] = s;
show.count += 1;
if( 0 ) {
filtered:
status_free(s);
//printf( "Filtered out %d\n", s->id );
}
}
// Try to load more statuses
if( count < params.limit ) {
offset += params.limit;
params.limit -= show.count;
if( max_loops > 0 ) {
max_loops -= 1;
goto load_statuses;
}
}
done:
show_statuses( req, show.items, show.count );
for( int i = 0; i < show.count; ++i ) {
status_free( show.items[i] );
}
timeline_free(tl);
return true;
}