diff --git a/src/collections b/src/collections index 44a552b..7ffee88 160000 --- a/src/collections +++ b/src/collections @@ -1 +1 @@ -Subproject commit 44a552b831da2c1d9556fe909b6c77614f99a59e +Subproject commit 7ffee8875d10e1d3a52c5f8817112d235bec53bf diff --git a/src/controller/api/timeline.c b/src/controller/api/timeline.c index 8bde667..c80abe3 100644 --- a/src/controller/api/timeline.c +++ b/src/controller/api/timeline.c @@ -123,9 +123,12 @@ done: return true; } -bool handle_timeline( struct http_request* req, int timeline_id ) +bool handle_timeline( struct http_request* req, int account_id ) { - struct timeline* tl = timeline_from_id( timeline_id ); + //struct timeline* tl = timeline_from_id( timeline_id ); + struct account* a = account_from_id( account_id ); + struct timeline* tl = account_get_timeline( a ); + account_free(a); bool res = handle_timeline_internal(req,tl); timeline_free(tl); diff --git a/src/controller/inbox.c b/src/controller/inbox.c index 871475e..5704d04 100644 --- a/src/controller/inbox.c +++ b/src/controller/inbox.c @@ -409,7 +409,7 @@ static bool route_create( struct ap_object* act ) bool account_followed = account_actor_is_followed(obj); if( !mentions_me && !account_followed ) { // Discard without action - //printf( "Discarding create. account_followed=%c, mentions_me=%c\n", account_followed ? 'T' : 'F', mentions_me ? 'T' : 'F' ); + printf( "Discarding create. account_followed=%c, mentions_me=%c\n", account_followed ? 'T' : 'F', mentions_me ? 'T' : 'F' ); goto discard; } @@ -452,13 +452,16 @@ static bool route_create( struct ap_object* act ) //status_add_to_timeline( s, federated_timeline_id ); status_add_to_timeline( s, s->account_id ); + //printf( "route_create.complete\n" ); discard: + //printf( "route_create.discard\n" ); result = true; goto cleanup; cleanup: status_free(s); return result; failed: + //printf( "route_create.failed\n" ); if( !g_server->develop ) { goto discard; } result = false; goto cleanup; diff --git a/src/ffdb b/src/ffdb index 87d5d24..45f1653 160000 --- a/src/ffdb +++ b/src/ffdb @@ -1 +1 @@ -Subproject commit 87d5d2462561348fd8efaa096aba620e93552a8d +Subproject commit 45f1653cd4243ca46a36105f3528b95968a087d5 diff --git a/src/model/account.c b/src/model/account.c index 0fbeaae..d301769 100644 --- a/src/model/account.c +++ b/src/model/account.c @@ -166,6 +166,40 @@ void account_reindex() } } +static const char* get_account_path( unsigned int id, char* filename, int size ) +{ + struct stat s; + + // Check old-style path + snprintf( filename, size, "data/accounts/%d", id ); + if( 0 == stat( filename, &s ) ) { + //printf( "Using path %s for account %d\n", filename, id ); + return filename; + } + + // Check new-style path + int millions = id / 1000000; + int thousands = ( id % 1000000 ) / 1000; + int ones = id % 1000; + + mkdir( format(filename,size, "data/accounts/%03dm", millions ), 0755 ); + mkdir( format(filename,size, "data/accounts/%03dm/%03dk", millions, thousands ), 0755 ); + + snprintf( filename,size, "data/accounts/%03dm/%03dk/%03d", millions, thousands, ones ); + //printf( "Checking %s\n", filename ); + if( 0 == stat(filename,&s) ) { + //printf( "Using path %s for account %d\n", filename, id ); + return filename; + } + + printf( "No account path found for %d\n", id ); + return NULL; +} +const char* account_get_path( unsigned int id, char* buffer, int size ) +{ + return get_account_path( id, buffer, size ); +} + static struct account* account_load_from_id( int id, int recurse_limit ) { if( recurse_limit <= 0 ) { @@ -180,22 +214,24 @@ static struct account* account_load_from_id( int id, int recurse_limit ) return new_system_account(); } - char filename[512]; + // Get account path + char path[512]; + if( !get_account_path( id, path, sizeof(path) ) ) { + printf( "No account path for %d\n", id ); + return NULL; + } struct account* a = account_new(); a->id = id; - snprintf( filename, 512, "data/accounts/%d/data.json", id ); + char filename[512]; + snprintf( filename, 512, "%s/data.json", path ); if( !json_read_object_layout_from_file( filename, account_layout, a ) ) { + printf( "Could not load data file from %s\n", filename ); account_free(a); a = account_new(); a->id = id; - - snprintf( filename, 512, "data/accounts/%d.json", id ); - if( !json_read_object_layout_from_file( filename, account_layout, a ) ) { - account_free(a); - return NULL; - } + return NULL; } if( a->replaced_by && a->replaced_by != a->id ) { @@ -309,13 +345,15 @@ struct account* account_from_uri( const char* uri ) struct account* a = account_from_id( account_id ); // Only return non-stub accounts here. This will force a refetch attempt - if( a && a->stub ) { - printf( "This account is a stub\n" ); - account_free(a); - return NULL; - } + if( a ) { + if( a->stub ) { + printf( "This account is a stub\n" ); + account_free(a); + return NULL; + } - index_uri_to_account_id( a->account_url, a->id ); + index_uri_to_account_id( a->account_url, a->id ); + } return a; } @@ -357,8 +395,11 @@ struct account* account_from_webfinger( const char* handle, const char* default_ struct crypto_keys* account_get_public_key( struct account* a, const char* key_name ) { + char path[512]; + get_account_path( a->id, path,sizeof(path) ); + char filename[512]; - FILE* f = fopen( format( filename, sizeof(filename), "data/accounts/%d/%s.pem", a->id, key_name ), "r" ); + FILE* f = fopen( format( filename, sizeof(filename), "%s/%s.pem", path, key_name ), "r" ); if( !f ) { //printf( "Failed to open file %s\n", filename ); return NULL; @@ -381,14 +422,28 @@ struct crypto_keys* account_get_private_key( struct account* a ) static void create_account_skeleton( int account_id ) { + char filename[512]; char b[512]; + //* + // Check new-style path + int millions = account_id / 1000000; + int thousands = ( account_id % 1000000 ) / 1000; + int ones = account_id % 1000; + + mkdir( format(filename,512, "data/accounts/%03dm", millions ), 0755 ); + mkdir( format(filename,512, "data/accounts/%03dm/%03dk", millions, thousands ), 0755 ); + mkdir( format(filename,512, "data/accounts/%03dm/%03dk/%03d", millions, thousands, ones ), 0755 ); + /*/ + // Use old-style path + snprintf( filename,512, "data/accounts/%d", account_id ); + //*/ + // Make sure the account directory exists - mkdir( format( b, 512, "data/accounts/%d", account_id ), 0755 ); - mkdir( format( b, 512, "data/accounts/%d/timeline", account_id ), 0755 ); - mkdir( format( b, 512, "data/accounts/%d/timeline/pinned", account_id ), 0755 ); + mkdir( format( b, 512, "%s/timeline", filename), 0755 ); + mkdir( format( b, 512, "%s/timeline/pinned", filename ), 0755 ); - fs_list_set( format( b, 512, "data/accounts/%d/timeline/HEAD", account_id ), 0 ); + //fs_list_set( format( b, 512, format( b, 512, "%s//timeline/HEAD", account_id ), 0 ); } struct account* account_fetch_from_uri( const char* uri ) @@ -400,10 +455,9 @@ struct account* account_fetch_from_uri( const char* uri ) account_id = fs_list_inc( "data/accounts/HEAD" ); index_uri_to_account_id( uri, account_id ); + create_account_skeleton(account_id); } - create_account_skeleton(account_id); - struct account* a = NULL; a = account_from_id(account_id); if( a ) { @@ -425,8 +479,10 @@ struct account* account_fetch_from_uri( const char* uri ) } // Fetch the ActivityPub actor data if we don't already have it + char path[512]; + get_account_path(account_id,path,512); char filename[512]; - snprintf( filename,sizeof(filename), "data/accounts/%d/ap.json", account_id ); + snprintf( filename,sizeof(filename), "%s/ap.json", path ); pull_remote_file_if_older( filename, uri, 60*60*24*3 ); FILE* f = fopen( filename, "r" ); @@ -490,8 +546,11 @@ void account_free( struct account* a ) void account_save( struct account* a ) { + char path[512]; + get_account_path( a->id, path, 512 ); + char filename[512]; - snprintf( filename, 512, "data/accounts/%d/data.json", a->id ); + snprintf( filename, 512, "%s/data.json", path ); printf( "Saving to filename %s\n", filename ); json_write_object_layout_to_file( filename, "\t", account_layout, a ); @@ -576,19 +635,23 @@ reindex: void account_add_follower( struct account* a, struct account* follower ) { + char path[512]; + // Insert an entry for this follower (only does something if not already set) char filename[512]; char key[32]; + get_account_path(a->id,path,512); ffdb_trie_set( - format( filename, sizeof(filename), "data/accounts/%d/followers", a->id ), + format( filename, sizeof(filename), "%s/followers", path ), format(key,sizeof(key),"%d", follower->id), "T" ); a->followers_count = ffdb_trie_count(filename); account_save(a); + get_account_path(follower->id,path,512); ffdb_trie_set( - format( filename, sizeof(filename), "data/accounts/%d/following", follower->id ), + format( filename, sizeof(filename), "%s/following", path ), format(key,sizeof(key),"%d", a->id), "T" ); @@ -608,10 +671,12 @@ void account_add_follower( struct account* a, struct account* follower ) } bool account_is_follower( struct account* a, struct account* possible_follower ) { + char path[512]; + get_account_path(a->id,path,512); char filename[512]; char key[32]; char* value = ffdb_trie_get( - format( filename, sizeof(filename), "data/accounts/%d/followers", a->id ), + format( filename, sizeof(filename), "%s/followers", path ), format( key, sizeof(key), "%d", possible_follower->id ) ); if( !value ) { @@ -621,6 +686,22 @@ bool account_is_follower( struct account* a, struct account* possible_follower ) free(value); return res; } +struct timeline* account_get_timeline( struct account* a ) +{ + char path[512]; + if( !get_account_path( a->id, path, sizeof(path) ) ) + { + return NULL; + } + + char timeline_path[512]; + snprintf( timeline_path,512, "%s/timeline", path ); + printf( "Using timeline path %s\n", timeline_path ); + + struct timeline* tl = timeline_from_path(timeline_path); + if( !tl ) { printf( "! Failed to create timeline object!\n" ); } + return tl; +} void account_remove_follower( struct account* a, struct account* follower ) { if( !account_is_follower( a, follower ) ) { @@ -628,16 +709,19 @@ void account_remove_follower( struct account* a, struct account* follower ) } // Remove the follow + char path[512]; char filename[512]; char key[32]; + get_account_path(a->id,path,512); ffdb_trie_remove( - format( filename, sizeof(filename), "data/accounts/%d/followers", a->id ), + format( filename, sizeof(filename), "%s/followers", path ), format( key, sizeof(key), "%d", follower->id ) ); a->followers_count = ffdb_trie_count(filename); + get_account_path(follower->id,path,512); ffdb_trie_remove( - format( filename, sizeof(filename), "data/accounts/%d/following", follower->id ), + format( filename, sizeof(filename), "%s/following", path ), format( key, sizeof(key), "%d", a->id ) ); follower->following_count = ffdb_trie_count(filename); @@ -680,13 +764,19 @@ static void account_list( const char* filename, int offset, int limit, struct in void account_list_followers( struct account* a, int offset, int limit, void* id_array ) { + char path[512]; + get_account_path(a->id,path,512); + char filename[512]; - account_list( format( filename, sizeof(filename), "data/accounts/%d/followers", a->id ), offset, limit, id_array ); + account_list( format( filename, sizeof(filename), "%s/followers", path ), offset, limit, id_array ); } void account_list_following( struct account* a, int offset, int limit, void* id_array ) { + char path[512]; + get_account_path(a->id,path,512); + char filename[512]; - account_list( format( filename, sizeof(filename), "data/accounts/%d/following", a->id ), offset, limit, id_array ); + account_list( format( filename, sizeof(filename), "%s/following", path ), offset, limit, id_array ); } void account_move( struct account* old_account, const char* new_uri ) { @@ -738,9 +828,12 @@ bool account_does_follow( struct account* a, int account_id ) char index[512]; char key[32]; + char path[512]; + account_get_path( a->id, path, 512 ); + // Make sure the account to unfollow has previously been followed char* value = ffdb_trie_get( - format(index,512,"data/accounts/%d/following", a->id), + format(index,512,"%s/following", path), format(key,32,"%d", account_id) ); @@ -753,8 +846,11 @@ bool account_does_follow( struct account* a, int account_id ) void account_pin_status( struct account* a, struct status* s ) { + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; - snprintf( buffer,sizeof(buffer), "data/accounts/%d/timeline/pinned", a->id ); + snprintf( buffer,sizeof(buffer), "%s/timeline/pinned", path ); s->pinned = true; struct timeline* pinned = timeline_from_path( buffer ); @@ -780,8 +876,11 @@ void account_pin_status( struct account* a, struct status* s ) } void account_unpin_status( struct account* a, struct status* s ) { + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; - snprintf( buffer,sizeof(buffer), "data/accounts/%d/timeline/pinned", a->id ); + snprintf( buffer,sizeof(buffer), "%s/timeline/pinned", path ); s->pinned = false; struct timeline* pinned = timeline_from_path( buffer ); diff --git a/src/model/account.h b/src/model/account.h index 26821a7..57903c8 100644 --- a/src/model/account.h +++ b/src/model/account.h @@ -10,6 +10,7 @@ struct status; struct ap_object; struct outbox_envelope; struct outbox_envelope_list; +struct timeline; enum { system_account_id = INT_MAX, @@ -120,6 +121,8 @@ struct crypto_keys* account_get_private_key( struct account* a ); void account_list_followers( struct account* a, int offset, int limit, void* id_array ); void account_list_following( struct account* a, int offset, int limit, void* id_array ); bool account_is_follower( struct account* a, struct account* possible_follower ); +struct timeline* account_get_timeline( struct account* a ); +const char* account_get_path( unsigned int id, char* buffer, int size ); // Activity pub data struct ap_object* account_ap_actor( struct account* a ); diff --git a/src/model/account/ap_data.c b/src/model/account/ap_data.c index 065877f..c2caa61 100644 --- a/src/model/account/ap_data.c +++ b/src/model/account/ap_data.c @@ -21,7 +21,7 @@ struct ap_object* account_activity_pub( struct account* a ) { // Pass thru remote activity pub actor data if present char filename[512]; - struct ap_object* obj = ap_object_from_file( format( filename, 512, "data/accounts/%d/ap.json", a->id ) ); + //struct ap_object* obj = ap_object_from_file( format( filename, 512, "data/accounts/%d/ap.json", a->id ) ); if( obj ) { return obj; } return account_ap_actor(a); @@ -108,16 +108,23 @@ struct ap_object* account_ap_outbox( struct account* a ) outbox->id = aformat( "https://%s/outbox", g_server->domain ); outbox->first.tag = apaot_ref; outbox->first.ref = aformat( "https://%s/outbox/page-0", g_server->domain ); + + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; - outbox->total_items = ffdb_trie_count( format( buffer, 512, "data/accounts/%d/timeline", a->id ) ); + outbox->total_items = ffdb_trie_count( format( buffer, 512, "%s/timeline", path ) ); return outbox; } struct ap_object* account_ap_outbox_page( struct account* a, int page ) { enum { items_per_page = 10 }; + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; - int total_items = ffdb_trie_count( format( buffer, 512, "data/accounts/%d/timeline", a->id ) ); + int total_items = ffdb_trie_count( format( buffer, 512, "%s/timeline", path ) ); int page_count = ( total_items + items_per_page - 1 ) / items_per_page; if( page >= page_count ) { return NULL; } @@ -251,8 +258,12 @@ struct ap_object* account_ap_followers( struct account* a ) o->id = aformat( "https://%s/owner/followers", g_server->domain ); o->first.tag = apaot_object; o->first.ptr = account_ap_followers_page( a, 0 ); + + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; - o->total_items = ffdb_trie_count( format( buffer, 512, "data/accounts/%d/followers", a->id ) ); + o->total_items = ffdb_trie_count( format( buffer, 512, "%sd/followers", path ) ); return o; } @@ -265,8 +276,11 @@ struct ap_object* account_ap_followers_page( struct account* a, int page ) char page_format[512]; snprintf( page_format, 512, "https://%s/owner/followers/page-%%d", g_server->domain ); + char path[512]; + account_get_path( a->id, path, 512 ); + char trie_filename[512]; - snprintf( trie_filename, 512, "data/accounts/%d/followers", a->id ); + snprintf( trie_filename, 512, "%s/followers", path ); return account_list_page( page, part_of, page_format, trie_filename ); } @@ -282,8 +296,12 @@ struct ap_object* account_ap_following( struct account* a ) o->id = aformat( "https://%s/owner/following", g_server->domain ); o->first.tag = apaot_object; o->first.ptr = account_ap_following_page( a, 0 ); + + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; - o->total_items = ffdb_trie_count( format( buffer, 512, "data/accounts/%d/following", a->id ) ); + o->total_items = ffdb_trie_count( format( buffer, 512, "%s/following", path ) ); return o; } @@ -296,8 +314,11 @@ struct ap_object* account_ap_following_page( struct account* a, int page ) char page_format[512]; snprintf( page_format, 512, "https://%s/owner/following/page-%%d", g_server->domain ); + char path[512]; + account_get_path( a->id, path, 512 ); + char trie_filename[512]; - snprintf( trie_filename, 512, "data/accounts/%d/following", a->id ); + snprintf( trie_filename, 512, "%s/following", path ); return account_list_page( page, part_of, page_format, trie_filename ); } @@ -308,9 +329,12 @@ struct ap_object* account_ap_featured( struct account* a ) o->type = ap_OrderedCollection; o->ap_context.language = clang_undefined; //o->published = time(NULL); + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; o->id = aformat( "https://%s/owner/collections/featured", g_server->domain ); - o->total_items = ffdb_trie_count( format( buffer,512, "data/accounts/%d/timeline/pinned", a->id ) ); + o->total_items = ffdb_trie_count( format( buffer,512, "%s/timeline/pinned", path ) ); o->ordered_items.items = malloc(1); if( o->total_items > 0 ) { @@ -321,12 +345,15 @@ struct ap_object* account_ap_featured( struct account* a ) } struct ap_object* account_ap_featured_page( struct account* a, int page ) { + char path[512]; + account_get_path( a->id, path, 512 ); + char buffer[512]; - snprintf( buffer,512, "data/accounts/%d/timeline/pinned", a->id ); + snprintf( buffer,512, "%s/timeline/pinned", path ); struct timeline* tl = timeline_from_path( buffer ); if( !tl ) { return NULL; } - int total_items = ffdb_trie_count( format( buffer,512, "data/accounts/%d/timeline/pinned", a->id ) ); + int total_items = ffdb_trie_count( format( buffer,512, "%s/timeline/pinned", path ) ); enum { items_per_page = 20 }; const int total_pages = ( total_items + items_per_page - 1 ) / items_per_page; diff --git a/src/model/account/ap_sync.c b/src/model/account/ap_sync.c index 1950ecf..3d65306 100644 --- a/src/model/account/ap_sync.c +++ b/src/model/account/ap_sync.c @@ -19,8 +19,11 @@ struct ap_object* account_get_activity_pub_data( struct account* a ) { if( !a ) { return NULL; } + char path[512]; + account_get_path( a->id, path, 512 ); + char filename[512]; - snprintf( filename, 512, "data/accounts/%d/ap.json", a->id ); + snprintf( filename, 512, "%s/ap.json", path ); printf( "ap_object_from_file( %s )\n", filename ); if( a->account_id ) { @@ -177,7 +180,9 @@ bool account_sync_from_activity( struct account* a, struct ap_object* obj ) char* id = strdup(obj->public_key->id); char* key_id = NULL; strtok_r( id, "#", &key_id ); - FILE* key_pem = fopen( format(filename,sizeof(filename),"data/accounts/%d/%s.pem", a->id, key_id), "w" ); + char path[512]; + account_get_path( a->id, path, 512 ); + FILE* key_pem = fopen( format(filename,sizeof(filename),"%s/%s.pem", path, key_id), "w" ); if( !key_pem ) { printf( "Unable to save public key to %s\n", filename ); } else { diff --git a/src/model/account/fed_act.c b/src/model/account/fed_act.c index 667fc1d..7a7d192 100644 --- a/src/model/account/fed_act.c +++ b/src/model/account/fed_act.c @@ -31,6 +31,7 @@ void account_deliver_activity( struct account* a, struct ap_object* act, struct if( e->shared_inbox && a->shared_inbox && 0 == strcmp(e->shared_inbox,a->shared_inbox) ) { //printf( "\tUsing shared inbox %s already in delivery list\n", a->shared_inbox ); // This account will get the message delivered thru the shared inbox + e->count += 1; return; } } @@ -38,6 +39,7 @@ void account_deliver_activity( struct account* a, struct ap_object* act, struct struct outbox_envelope* env = outbox_envelope_new(); env->activity_id = act->local_id; + env->count = 1; if( a->shared_inbox ) { env->shared_inbox = strdup(a->shared_inbox); printf( "Delivering activity %s to account %s via shared inbox %s\n", act->id, a->account_url, a->shared_inbox ); @@ -57,8 +59,11 @@ void account_deliver_activity_to_followers( struct account* a, struct ap_object* } keys; memset( &keys, 0, sizeof(keys) ); + char path[512]; + account_get_path( a->id, path, 512 ); + char filename[512]; - snprintf( filename, sizeof(filename), "data/accounts/%d/followers", a->id ); + snprintf( filename, sizeof(filename), "%s/followers", path ); // TODO: handle shared inbox delivery int pages = (a->followers_count+31) / 32; @@ -171,7 +176,10 @@ void account_follow( struct account* a, struct account* to_follow ) account_add_follower( to_follow, a ); // Record the activity so it an Undo can be issued in the future - mkdir( format(filename,sizeof(filename),"data/accounts/%d/follow-activities", a->id), 0755 ); + char path[512]; + account_get_path( a->id, path, 512 ); + + mkdir( format(filename,sizeof(filename),"%s/follow-activities", path), 0755 ); ffdb_trie_set(filename, format(key,32,"%d", to_follow->id ), format(value,32,"%d", act_id ) ); // Save account data @@ -184,9 +192,12 @@ void account_unfollow( struct account* a, struct account* to_unfollow ) char index[512]; char key[32]; + char path[512]; + account_get_path( a->id, path, 512 ); + // Make sure the account to unfollow has previously been followed char* res = ffdb_trie_get( - format(index,512,"data/accounts/%d/follow-activities", a->id), + format(index,512,"%s/follow-activities", path), format(key,32,"%d", to_unfollow->id) ); if( !res ) { diff --git a/src/model/activity.c b/src/model/activity.c index a198b48..e872a10 100644 --- a/src/model/activity.c +++ b/src/model/activity.c @@ -5,6 +5,7 @@ #include "util/format.h" #include "ffdb/fs_list.h" #include "collections/array.h" +#include "collections/sort/bubble.h" #include "ap/object.h" // Model @@ -390,6 +391,20 @@ static void deliver_to( struct outbox_envelope_list* oel, struct ap_object* act, } } +static int compare_envelope_counts( struct collection it, void* a, void* b ) +{ + struct outbox_envelope* ea = a; + struct outbox_envelope* eb = b; + + if( ea->count < eb->count ) { + return -1; + } else if( ea->count > eb->count ) { + return 1; + } else { + return 0; + } +} + void activity_deliver( struct ap_object* act ) { printf( "activity_deliver( act = %s )\n", act->id ); @@ -407,6 +422,17 @@ void activity_deliver( struct ap_object* act ) deliver_to( &oel, act, act->bcc.items[i] ); } + // Sort so that oel[0] has the lowest count and oel[size-1] has the highest + struct collection c; + static struct item_type_vtable itable = { + .size = sizeof(oel.items[0]), + .compare = compare_envelope_counts, + }; + c.ptr = &oel; + c.vtable = &array_vtable; + c.itable = &itable; + collection_sort_bubble( c, false ); + printf( "Delivering to %d inboxes\n", oel.count ); outbox_envelope_list_save(&oel); outbox_envelope_list_free_composite(&oel); diff --git a/src/model/crypto/http_sign.c b/src/model/crypto/http_sign.c index 618259e..8086dd2 100644 --- a/src/model/crypto/http_sign.c +++ b/src/model/crypto/http_sign.c @@ -269,9 +269,14 @@ struct hsv_result http_signature_validate( struct ap_envelope* env, const char* // Get the public key keys = account_get_public_key( actor, key_name ); if( !keys ) { - printf( "! Failed to find public key for actor=%s (id=%d), key_name=%s\n", actor->account_url, actor->id, key_name ); - result.error = HSV_NO_PUBKEY; - goto failed; + account_sync_from_activity_pub( actor->id, true ); + + keys = account_get_public_key( actor, key_name ); + if( !keys ) { + printf( "! Failed to find public key for actor=%s (id=%d), key_name=%s\n", actor->account_url, actor->id, key_name ); + result.error = HSV_NO_PUBKEY; + goto failed; + } } } diff --git a/src/model/outbox_envelope.h b/src/model/outbox_envelope.h index de2790d..2565128 100644 --- a/src/model/outbox_envelope.h +++ b/src/model/outbox_envelope.h @@ -12,6 +12,7 @@ struct outbox_envelope bool sent; time_t retry_after; int retries; + int count; }; struct outbox_envelope* outbox_envelope_new(); diff --git a/src/model/status.c b/src/model/status.c index 8bd24ce..75f41ba 100644 --- a/src/model/status.c +++ b/src/model/status.c @@ -741,11 +741,21 @@ void status_delete( struct status* s ) }; for( int i = 0; i < sizeof(ids)/sizeof(ids[0]); ++i ) { - struct timeline* tl = timeline_from_id( ids[i] ); + struct account* a = account_from_id( ids[i] ); + if( !a ) { + printf( "No account for id %d\n", ids[i] ); + continue; + } + + struct timeline* tl = account_get_timeline(a); if( tl ) { timeline_remove_post( tl, s ); timeline_free(tl); + } else { + printf( "No timeline for account %d\n", ids[i] ); } + + account_free(a); } char filename[512]; @@ -756,11 +766,17 @@ void status_delete( struct status* s ) status_free(s); } -void status_add_to_timeline( struct status* s, int timeline_id ) +void status_add_to_timeline( struct status* s, int account_id ) { - struct timeline* tl = timeline_from_id(timeline_id); + //printf( "status_add_to_timeline( s, account_id=%d )\n", account_id ); + struct account* a = account_from_id( account_id ); + + //printf( "Adding status %d to timeline for %s (%d/%d)\n", s->id, a->account_id, account_id, a->id ); + struct timeline* tl = account_get_timeline(a); timeline_add_post( tl, s ); timeline_free(tl); + + account_free(a); } void status_make_reply_to( struct status* s, int in_reply_to_id ) diff --git a/src/model/timeline.c b/src/model/timeline.c index db72e94..d5de29f 100644 --- a/src/model/timeline.c +++ b/src/model/timeline.c @@ -23,15 +23,6 @@ struct timeline* timeline_new() memset(tl,0,sizeof(*tl)); return tl; } -struct timeline* timeline_from_id( int id ) -{ - struct timeline* tl = timeline_new(); - - tl->id = id; - tl->path = aformat( "data/accounts/%d/timeline", tl->id ); - - return tl; -} struct timeline* timeline_from_path( const char* path ) { struct timeline* tl = timeline_new(); @@ -84,6 +75,7 @@ int timeline_load_statuses( struct timeline* tl, int offset_from_head, int count } void timeline_add_post( struct timeline* tl, struct status* s ) { + //printf( "- timeline_add_post( tl=%s, s=%d )\n", tl->path, s->id ); char key[512]; rfc3339_time_string( s->published, key, sizeof(key) ); diff --git a/src/model/timeline.h b/src/model/timeline.h index 35d0a72..f921d35 100644 --- a/src/model/timeline.h +++ b/src/model/timeline.h @@ -7,7 +7,6 @@ struct timeline char* path; }; -struct timeline* timeline_from_id( int id ); struct timeline* timeline_from_path( const char* path ); struct timeline* timeline_new(); void timeline_free( struct timeline* tl );