@ -54,10 +54,58 @@ static struct json_object_field status_layout[] = {
JSON_FIELD_ENUM ( visibility , visibility_enum , false ) ,
JSON_FIELD_DATETIME ( published , false ) ,
JSON_FIELD_INTEGER ( in_reply_to , false ) ,
JSON_FIELD_INTEGER ( quote_id , false ) ,
JSON_FIELD_INTEGER ( repost_id , false ) ,
JSON_FIELD_INTEGER ( root_status_id , false ) ,
{
. key = " in_reply_to " ,
. offset = offsetof ( OBJ_TYPE , in_reply_to . id ) ,
. required = false ,
. type = & json_field_integer ,
} ,
{
. key = " in_reply_to_url " ,
. offset = offsetof ( OBJ_TYPE , in_reply_to . url ) ,
. required = false ,
. type = & json_field_string ,
} ,
{
. key = " quote_id " ,
. offset = offsetof ( OBJ_TYPE , quote . id ) ,
. required = false ,
. type = & json_field_integer ,
} ,
{
. key = " quote_url " ,
. offset = offsetof ( OBJ_TYPE , quote . url ) ,
. required = false ,
. type = & json_field_string ,
} ,
{
. key = " repost_id " ,
. offset = offsetof ( OBJ_TYPE , repost . id ) ,
. required = false ,
. type = & json_field_integer ,
} ,
{
. key = " repost_url " ,
. offset = offsetof ( OBJ_TYPE , repost . url ) ,
. required = false ,
. type = & json_field_string ,
} ,
{
. key = " root_status_id " ,
. offset = offsetof ( OBJ_TYPE , root_status . id ) ,
. required = false ,
. type = & json_field_integer ,
} ,
{
. key = " root_status_url " ,
. offset = offsetof ( OBJ_TYPE , root_status . url ) ,
. required = false ,
. type = & json_field_string ,
} ,
JSON_FIELD_INTEGER ( reposted_status_id , false ) ,
JSON_FIELD_ARRAY_OF_STRINGS ( media , false ) ,
@ -137,6 +185,7 @@ struct status* status_from_id( unsigned int id )
if ( id = = 0 ) { return NULL ; }
struct status * s = NULL ;
bool needs_save = false ;
FILE * f = open_status_data_file ( id , " r " ) ;
if ( ! f ) { return NULL ; }
@ -175,18 +224,53 @@ struct status* status_from_id( unsigned int id )
free ( s - > media . items ) ;
memset ( & s - > media , 0 , sizeof ( s - > media ) ) ;
status_save ( s ) ;
needs_save = true ;
}
// Fix source field
if ( ! s - > source ) {
s - > source = strdup ( " " ) ;
}
// Fix remote field
if ( s - > account_id = = owner_account_id ) {
s - > remote = false ;
}
// Fix url field
if ( ! s - > remote & & ! s - > url ) {
s - > url = aformat ( " https://%s/note/%d " , g_server - > domain , s - > id ) ;
}
if ( s - > account_id = = owner_account_id ) {
s - > remote = false ;
// Fill in reference urls
if ( s - > in_reply_to . id & & ! s - > in_reply_to . url ) {
struct status * in_reply_to = status_from_id ( s - > in_reply_to . id ) ;
if ( in_reply_to & & in_reply_to - > url ) {
s - > in_reply_to . url = strdup ( in_reply_to - > url ) ;
needs_save = true ;
}
status_free ( in_reply_to ) ;
}
if ( s - > quote . id & & ! s - > quote . url ) {
struct status * quote = status_from_id ( s - > quote . id ) ;
if ( quote & & quote - > url ) {
s - > quote . url = strdup ( quote - > url ) ;
needs_save = true ;
}
status_free ( quote ) ;
}
if ( s - > root_status . id & & ( s - > root_status . id ! = s - > id ) & & ! s - > root_status . url ) {
struct status * root_status = status_from_id ( s - > root_status . id ) ;
if ( root_status & & root_status - > url ) {
s - > root_status . url = strdup ( root_status - > url ) ;
needs_save = true ;
}
status_free ( root_status ) ;
}
// Save changes
if ( needs_save ) {
status_save ( s ) ;
}
return s ;
@ -198,7 +282,8 @@ struct status* status_new_repost( struct status* s, struct account* a )
memset ( repost , 0 , sizeof ( * repost ) ) ;
repost - > account_id = a - > id ;
repost - > repost_id = s - > id ;
repost - > repost . id = s - > id ;
repost - > repost . url = strdup ( s - > url ) ;
repost - > published = time ( NULL ) ;
status_add_repost ( s , repost ) ;
@ -382,6 +467,13 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
goto failed ;
}
// Update account if it should be
if ( time ( NULL ) > = a - > next_update ) {
printf ( " * Updating account %s \n " , a - > account_url ) ;
account_sync_from_activity_pub ( a - > id , true ) ;
}
// Handle post visibility
bool is_public = false ;
for ( int i = 0 ; i < act - > to . count ; + + i ) {
@ -534,7 +626,8 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
if ( parent_id ) {
status_make_reply_to ( s , parent_id ) ;
s - > in_reply_to = parent_id ;
s - > in_reply_to . id = parent_id ;
s - > in_reply_to . url = strdup ( act - > in_reply_to ) ;
}
//printf( "Status %d has been marked as a reply to %d (%s)\n", s->id, parent_id, act->in_reply_to );
}
@ -738,7 +831,10 @@ void status_assign_local_id( struct status* s )
int head = fs_list_inc ( " data/statuses/HEAD " ) ;
s - > id = head ;
s - > root_status_id = s - > id ;
s - > root_status . id = s - > id ;
if ( s - > url ) {
s - > root_status . url = strdup ( s - > url ) ;
}
}
bool status_save_new ( struct status * s )
@ -814,6 +910,11 @@ void status_free( struct status* s )
}
free ( s - > reacts . items ) ;
free ( s - > in_reply_to . url ) ;
free ( s - > quote . url ) ;
free ( s - > repost . url ) ;
free ( s - > root_status . url ) ;
free ( s - > likes . items ) ;
free ( s - > replies . items ) ;
free ( s - > reposts . items ) ;
@ -890,13 +991,16 @@ void status_make_reply_to( struct status* s, int in_reply_to_id )
// Add this status to the other
struct status * in_reply_to = status_from_id ( in_reply_to_id ) ;
if ( ! in_reply_to ) {
s - > in_reply_to = 0 ;
s - > in_reply_to . id = 0 ;
return ;
}
// Setup this status's reply fields
s - > in_reply_to = in_reply_to_id ;
s - > root_status_id = in_reply_to - > root_status_id ;
s - > in_reply_to . id = in_reply_to_id ;
s - > root_status . id = in_reply_to - > root_status . id ;
if ( in_reply_to - > root_status . url ) {
s - > root_status . url = strdup ( in_reply_to - > root_status . url ) ;
}
// Record in parent as reply
status_add_reply ( in_reply_to , s ) ;
@ -917,12 +1021,13 @@ void status_make_quote_of( struct status* s, int id_quote_of )
{
struct status * quoted_post = status_from_id ( id_quote_of ) ;
if ( ! quoted_post ) {
s - > quote _ id = 0 ;
s - > quote . id = 0 ;
return ;
}
// Set quoted id
s - > quote_id = id_quote_of ;
s - > quote . id = id_quote_of ;
s - > quote . url = strdup ( quoted_post - > url ) ;
// Record quote in parent
status_add_quote ( quoted_post , s ) ;
@ -953,7 +1058,7 @@ void status_get_context( struct status* s, void* ancestors_ptr, void* replies_pt
memset ( replies , 0 , sizeof ( * replies ) ) ;
struct status * parent = NULL ;
for ( int i = s - > in_reply_to ; i ! = 0 ; i = parent - > in_reply_to ) {
for ( int i = s - > in_reply_to .id ; i ! = 0 ; i = parent - > in_reply_to . id ) {
parent = status_from_id ( i ) ;
if ( ! parent ) { break ; }
array_append ( ancestors , sizeof ( parent ) , & parent ) ;
@ -991,8 +1096,8 @@ void status_get_quotes( struct status* s, void* quotes_ptr )
void status_add_react ( struct status * s , const char * react , struct account * a )
{
if ( s - > repost _ id ) {
struct status * reposted_status = status_from_id ( s - > repost _ id ) ;
if ( s - > repost . id ) {
struct status * reposted_status = status_from_id ( s - > repost . id ) ;
status_add_react ( reposted_status , react , a ) ;
status_free ( reposted_status ) ;
return ;
@ -1050,8 +1155,8 @@ done:
}
void status_remove_react ( struct status * s , const char * react , struct account * a )
{
if ( s - > repost _ id ) {
struct status * reposted_status = status_from_id ( s - > repost _ id ) ;
if ( s - > repost . id ) {
struct status * reposted_status = status_from_id ( s - > repost . id ) ;
status_remove_react ( reposted_status , react , a ) ;
status_free ( reposted_status ) ;
return ;
@ -1097,8 +1202,8 @@ update_entry:
}
void status_add_like ( struct status * s , struct account * a )
{
if ( s - > repost _ id ) {
struct status * reposted_status = status_from_id ( s - > repost _ id ) ;
if ( s - > repost . id ) {
struct status * reposted_status = status_from_id ( s - > repost . id ) ;
status_add_like ( reposted_status , a ) ;
status_free ( reposted_status ) ;
return ;
@ -1136,8 +1241,8 @@ void status_add_like( struct status* s, struct account* a )
}
void status_remove_like ( struct status * s , struct account * a )
{
if ( s - > repost _ id ) {
struct status * reposted_status = status_from_id ( s - > repost _ id ) ;
if ( s - > repost . id ) {
struct status * reposted_status = status_from_id ( s - > repost . id ) ;
status_remove_like ( reposted_status , a ) ;
status_free ( reposted_status ) ;
return ;