Start making account stubs for remote accounts that refuse to load (to reduce remote server load)

master
teknomunk 1 year ago
parent 3af41c25d3
commit 80e3284bf4

@ -53,6 +53,8 @@ static struct json_object_field account_layout[] = {
JSON_FIELD_STRING( handle, true ),
JSON_FIELD_STRING( server, true ),
JSON_FIELD_STRING( display_name, true ),
JSON_FIELD_BOOL( stub, false ),
JSON_FIELD_DATETIME( next_stub_recheck, false ),
JSON_FIELD_STRING( avatar, false ),
{
.key = "avatar",
@ -186,7 +188,14 @@ struct account* account_from_uri( const char* uri )
return NULL;
}
return account_from_id( account_id );
struct account* a = account_from_id( account_id );
// Only return non-stub accounts here. This will force a refetch attempt
if( a && a->stub ) {
account_free(a);
return NULL;
}
return a;
}
struct account* account_from_uri_or_fetch( const char* uri )
{
@ -207,14 +216,16 @@ char* webfinger_query( const char* handle, const char* rel, const char* type );
struct account* account_from_webfinger( const char* handle )
{
int id;
if( !hash_index_get( "data/accounts/webfinger", handle, &id ) ) {
char* account_uri = webfinger_query( handle, "self", "application/activity+json" );
struct account* a = account_from_uri_or_fetch( account_uri );
free(account_uri);
return a;
if( hash_index_get( "data/accounts/webfinger", handle, &id ) ) {
return account_from_id(id);
}
return account_from_id(id);
char* account_uri = webfinger_query( handle, "self", "application/activity+json" );
if( !account_uri ) { return NULL; }
struct account* a = account_from_uri_or_fetch( account_uri );
free(account_uri);
return a;
}
struct ap_account* account_activity_pub_data( struct account* a )
@ -350,15 +361,17 @@ bool account_sync_from_activity_pub( unsigned int account_id )
struct ap_account* ap = ap_account_from_file(
format( filename, 512, "data/accounts/%d/ap.json", account_id )
);
struct account* a = malloc(sizeof(struct account));
memset(a,0,sizeof(*a));
a->id = account_id;
if( !ap ) {
printf( "! Failed to sync account %d from %s\n", account_id, filename );
printf( "? Failed to sync account %d from %s, creating stub\n", account_id, filename );
return false;
}
printf( "ap = " ); ap_account_debug_dump(ap);
struct account* a = malloc(sizeof(struct account));
memset(a,0,sizeof(*a));
a->id = account_id;
a->handle = strdup(ap->preferredUsername);
if( ap->name ) {
a->display_name = strdup(ap->name);
@ -456,11 +469,34 @@ struct account* account_fetch_from_uri( const char* uri )
create_account_skeleton(account_id);
struct account* a = NULL;
a = account_from_id(account_id);
// Fetch the ActivityPub actor data if we don't already have it
char filename[512];
FILE* f = fopen( format( filename, 512, "data/accounts/%d/ap.json", account_id ), "r" );
if( !f ) {
if( !pull_remote_file( filename, uri ) ) { return NULL; }
if( a && a->stub && ( time(NULL) < a->next_stub_recheck ) ) { goto next; }
if( pull_remote_file( filename, uri ) ) { goto next; }
// Mark as stub
if( !a ) {
a = malloc(sizeof(*a));
memset(a,0,sizeof(*a));
}
a->id = account_id;
a->account_url = strdup(uri);
a->stub = true;
a->next_stub_recheck = time(NULL) + 3600; // minimum 1 hour between checks
a->display_name = aformat( "stub-%d", a->id );
account_save(a);
account_index_webfinger(a);
account_free(a);
return NULL;
next:
/* nop */;
} else {
fclose(f);
}

@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
struct crypto_keys;
struct status;
@ -31,6 +32,8 @@ struct account
char* handle;
char* server;
char* display_name;
bool stub;
time_t next_stub_recheck;
int account_type;
char* account_url;

@ -16,9 +16,9 @@ struct link
};
#define OBJ_TYPE struct link
static struct json_object_field link_layout[] = {
JSON_FIELD_STRING( href, true ),
JSON_FIELD_STRING( rel, true ),
JSON_FIELD_STRING( type, true ),
JSON_FIELD_STRING( href, false ),
JSON_FIELD_STRING( rel, false ),
JSON_FIELD_STRING( type, false ),
JSON_FIELD_END,
};
#undef OBJ_TYPE
@ -95,12 +95,16 @@ char* webfinger_query( const char* handle, const char* rel, const char* type )
char* value = NULL;
for( int i = 0; i < r.links.count; ++i ) {
if( 0 == strcmp( rel, r.links.items[i]->rel ) ) {
if( 0 == strcmp( type, r.links.items[i]->type ) ) {
free(value);
value = strdup(r.links.items[i]->href);
}
if( !r.links.items[i]->rel ) { goto next; }
if( !r.links.items[i]->type ) { goto next; }
if( 0 != strcmp( rel, r.links.items[i]->rel ) ) { goto next; }
if( 0 == strcmp( type, r.links.items[i]->type ) ) {
free(value);
value = strdup(r.links.items[i]->href);
}
next:
link_free(r.links.items[i]);
}
free(r.links.items);

Loading…
Cancel
Save