diff --git a/migrations/2022-01-12-migration-hierarchial-statuses.rb b/migrations/2022-01-12-migration-hierarchial-statuses.rb new file mode 100644 index 0000000..93b0396 --- /dev/null +++ b/migrations/2022-01-12-migration-hierarchial-statuses.rb @@ -0,0 +1,23 @@ +#!/usr/bin/ruby + +require 'fileutils' + +Dir.children("data/statuses/").each {|child| + if /^([0-9]+)\.json$/ =~ child + id = $1.to_i + millions = id / 1000000 + thousands = id % 1000000 / 1000 + ones = id % 1000 + + target_file = "data/statuses/#{"%03d"%millions}m/#{"%03d"%thousands}k/#{"%03d"%ones}.json" + + dirname = File.dirname(target_file) + if( !File.exist?(dirname)) + puts "dirname=#{dirname}" + FileUtils.mkdir_p(dirname) + end + + puts "data/statuses/#{child} -> #{target_file}" + FileUtils.move("data/statuses/#{child}",target_file); + end +} diff --git a/src/model/account.c b/src/model/account.c index bbe7a61..5563fae 100644 --- a/src/model/account.c +++ b/src/model/account.c @@ -537,7 +537,7 @@ void account_deliver_activity( struct account* a, struct ap_activity* act, struc // Check if the sh for( int i = 0; i < oel->count; ++i ) { struct outbox_envelope* e = oel->items[i]; - if( e->shared_inbox && 0 == strcmp(e->shared_inbox,a->shared_inbox) ) { + 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 return; diff --git a/src/model/status.c b/src/model/status.c index 10c72b3..b4f8e28 100644 --- a/src/model/status.c +++ b/src/model/status.c @@ -21,6 +21,7 @@ #include #include #include +#include #define OBJ_TYPE struct status static struct json_object_field status_layout[] = { @@ -61,17 +62,46 @@ void* allocate( size_t s ) return ptr; } +static const char* get_status_data_filename( unsigned int id, char* filename, int size ) +{ + int millions = id / 1000000; + int thousands = ( id % 1000000 ) / 1000; + int ones = id % 1000; + + mkdir( format(filename,size, "data/statuses/%03dm", millions ), 0755 ); + mkdir( format(filename,size, "data/statuses/%03dm/%03dk", millions, thousands ), 0755 ); + + return format(filename,size, "data/statuses/%03dm/%03dk/%03d.json", millions, thousands, ones ); +} +static FILE* open_status_data_file( unsigned int id, const char* mode ) +{ + char filename[512]; + FILE* f = NULL; + + f = fopen( get_status_data_filename(id,filename,sizeof(filename)), mode ); + if( f ) { + printf( "Using new location at %s\n", filename ); + return f; + } + + f = fopen( format(filename,sizeof(filename), "data/statuses/%d.json", id), mode ); + if( f ) { + printf( "Using existing location at %s\n", filename ); + return f; + } +} + struct status* status_from_id( unsigned int id ) { struct status* s = NULL; - char filename[512]; - snprintf( filename, 512, "data/statuses/%d.json", id ); + FILE* f = open_status_data_file( id, "r" ); + if( !f ) { return NULL; } s = allocate(sizeof(struct status)); s->id = id; - if( !json_read_object_layout_from_file( filename, status_layout, s ) ) { + if( !json_read_object_layout_from_FILE( f, status_layout, s ) ) { printf( "Failed to load status %d\n", id ); status_free(s); return NULL; @@ -359,9 +389,7 @@ bool status_save_new( struct status* s ) void status_save( struct status* s ) { char filename[512]; - snprintf( filename, 512, "data/statuses/%d.json", s->id ); - - json_write_object_layout_to_file( filename, "\t", status_layout, s ); + json_write_object_layout_to_file( get_status_data_filename(s->id,filename,sizeof(filename)), "\t", status_layout, s ); // Index the status if( s->url ) { @@ -449,6 +477,11 @@ void status_make_reply_to( struct status* s, int in_reply_to_id ) s->in_reply_to = in_reply_to_id; s->root_status_id = in_reply_to->root_status_id; array_append( &in_reply_to->replies, sizeof(s->id), &s->id ); + + // TODO: full mention handling + int id = in_reply_to->account_id; + array_append( &s->mentions, sizeof(id), &id ); + status_save(in_reply_to); } }