Implement /owner/followers, fix bug where replies would miss mentions

master
teknomunk 1 year ago
parent b6d0d4686d
commit ea63577295

@ -152,15 +152,17 @@ static bool handle_command_test( struct cli_request* req )
if( res != 1 ) { return !!res; }
struct account* owner_account = account_from_id( owner_account_id );
struct ap_object* outbox = account_ap_outbox( owner_account );
ap_activity_write_to_FILE( outbox, stdout );
struct ap_object* obj = account_ap_followers( owner_account );
ap_activity_write_to_FILE( obj, stdout );
printf( "\n" );
ap_object_free(outbox);
ap_object_free(obj);
outbox = account_ap_outbox_page( owner_account, 0 );
ap_activity_write_to_FILE( outbox, stdout );
obj = account_ap_followers_page( owner_account, 1 );
ap_activity_write_to_FILE( obj, stdout );
printf( "\n" );
ap_object_free(outbox);
ap_object_free(obj);
account_free(owner_account);
return true;

@ -3,6 +3,7 @@
#include "http/server/request.h"
#include "model/server.h"
#include "model/ap/activity.h"
#include "view/layout.h"
@ -36,19 +37,48 @@ static bool handle_featured( struct http_request* req )
}
static bool handle_followers( struct http_request* req )
{
bool result = false;
struct account* owner_account = account_from_id(0);
http_request_send_headers( req, 200, "application/activity+json", true );
FILE* f = http_request_get_response_body(req);
#include "src/view/owner/followers.json.inc"
if( http_request_route_term(req,"") ) {
struct ap_object* obj = account_ap_followers(owner_account);
http_request_send_headers( req, 200, "application/activity+json", true );
FILE* f = http_request_get_response_body(req);
ap_activity_write_to_FILE( obj, f );
ap_object_free(obj);
} else if( http_request_route( req, "/page-" ) ) {
printf( "/page-\n" );
char* page_str = http_request_route_get_dir_or_file(req);
int page = -1;
if( !page_str ) { goto failed; }
if( 1 != sscanf(page_str,"%d",&page) ) { goto failed; }
if( page < 1 ) { goto failed; }
struct ap_object* obj = account_ap_followers_page(owner_account,page);
if( !obj ) { goto failed; }
http_request_send_headers( req, 200, "application/activity+json", true );
FILE* f = http_request_get_response_body(req);
ap_activity_write_to_FILE( obj, f );
ap_object_free(obj);
}
succeded:
result = true;
goto cleanup;
failed:
printf( "! failed\n" );
result = false;
goto cleanup;
cleanup:
account_free( owner_account );
return true;
return result;
}
static bool handle_following( struct http_request* req )
{
struct account* owner_account = account_from_id(0);
struct account* owner_account = account_from_id(owner_account_id);
http_request_send_headers( req, 200, "application/activity+json", true );
FILE* f = http_request_get_response_body(req);
@ -113,7 +143,7 @@ bool route_owner( struct http_request* req )
}
} else if( http_request_route_term( req, "/following" ) ) {
return handle_following(req);
} else if( http_request_route_term( req, "/followers" ) ) {
} else if( http_request_route( req, "/followers" ) ) {
return handle_followers(req);
} else if( http_request_route_term( req, "/collections/featured" ) ) {
return handle_featured(req);

@ -280,7 +280,6 @@ struct ap_object* account_ap_outbox_page( struct account* a, int page )
} values;
memset( &values, 0, sizeof(values) );
ffdb_trie_list( buffer, page * items_per_page, items_per_page, NULL, &values );
printf( "items: %d\n", values.count );
for( int i = 0; i < values.count; ++i ) {
int id;
int activity_id = 0;
@ -322,7 +321,9 @@ struct ap_object* account_ap_outbox_page( struct account* a, int page )
array_append( &outbox->collection_items, sizeof(r), &r );
}
free( values.items[i] );
}
free( values.items );
outbox->type = apot_ordered_collection_page;
outbox->published = time(NULL);
@ -338,6 +339,75 @@ struct ap_object* account_ap_outbox_page( struct account* a, int page )
return outbox;
}
struct ap_object* account_ap_followers( struct account* a )
{
if( a->id != 0 ) { return NULL; }
struct ap_object* o;
o = malloc(sizeof(*o));
memset(o,0,sizeof(*o));
o->type = apot_ordered_collection;
o->published = time(NULL);
o->id = aformat( "https://%s/owner/followers", g_server_name );
o->first.tag = apaot_object;
o->first.ptr = account_ap_followers_page( a, 0 );
char buffer[512];
o->total_items = ffdb_trie_count( format( buffer, 512, "data/accounts/%d/followers", a->id ) );
return o;
}
struct ap_object* account_ap_followers_page( struct account* a, int page )
{
if( a->id != 0 ) { return NULL; }
enum { items_per_page = 10 };
char buffer[512];
int total_items = ffdb_trie_count( format( buffer, 512, "data/accounts/%d/followers", a->id ) );
int page_count = ( total_items + items_per_page - 1 ) / items_per_page;
if( page >= page_count ) { return NULL; }
struct ap_object* o;
o = malloc(sizeof(*o));
memset(o,0,sizeof(*o));
struct {
char** items;
int count;
} values;
memset( &values, 0, sizeof(values) );
ffdb_trie_list( buffer, page * items_per_page, items_per_page, &values, NULL );
for( int i = 0; i < values.count; ++i ) {
int id;
if( 1 != sscanf( values.items[i], "%d", &id ) ) { continue; }
free( values.items[i] );
struct account* follower = account_from_id(id);
if( !follower ) { continue; }
struct ap_object_ptr_or_ref r;
r.tag = apaot_ref;
r.ref = strdup( follower->account_url );
array_append( &o->collection_items, sizeof(r), &r );
account_free(follower);
}
free( values.items );
o->type = apot_ordered_collection_page;
o->published = time(NULL);
o->part_of = aformat( "https://%s/owner/followers", g_server_name );
o->id = aformat( "https://%s/owner/followers/page-%d", g_server_name, page );
if( page > 0 ) {
o->prev = aformat( "https://%s/owner/followers/page-%d", g_server_name, page - 1 );
}
if( page < page_count - 1 ) {
o->next = aformat( "https://%s/owner/followers/page-%d", g_server_name, page + 1 );
}
return o;
}
struct ap_object* account_activity_pub( struct account* a )
{
return account_ap_actor(a);

@ -90,6 +90,8 @@ struct ap_object* account_activity_pub( struct account* a );
struct ap_object* account_ap_actor( struct account* a );
struct ap_object* account_ap_outbox( struct account* a );
struct ap_object* account_ap_outbox_page( struct account* a, int page );
struct ap_object* account_ap_followers( struct account* a );
struct ap_object* account_ap_followers_page( struct account* a, int page );
// Local actions
void account_add_follower( struct account* a, struct account* follower );

@ -98,6 +98,7 @@ extern struct json_enum ap_object_type_enum[];
enum ap_activity_object_type {
apaot_ref = 1,
apaot_activity = 2,
apaot_object = 2,
};
struct ap_attachement

@ -222,9 +222,8 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_activity* act )
if( act->in_reply_to ) {
struct status* parent = status_from_uri_or_fetch( act->in_reply_to );
if( parent ) {
s->in_reply_to = parent->id;
s->root_status_id = parent->root_status_id;
status_add_reply( parent, s );
status_make_reply_to( s, parent->id );
status_save(parent);
status_free(parent);
}
}

Loading…
Cancel
Save