Fix reply accounting bug, refactor route_create

master
teknomunk 1 year ago
parent 1358a5d45c
commit fc246cd4d5

@ -315,39 +315,27 @@ failed:
goto cleanup;
}
static bool route_create( struct ap_object* act )
static bool mentions_account_url( struct ap_object* obj, const char* account_url )
{
struct status* s = NULL;
bool result = false;
struct account* actor_account = NULL;
struct account* owner_account = NULL;
// Requires an object
if( act->object.tag != apaot_activity ) {
printf( "TODO: fetch activity from %s\n", act->object.ref );
goto failed;
}
struct ap_object* obj = act->object.ptr;
bool mentions_me = false;
bool account_followed = false;
// Does this activity have mention me
char owner_url[512];
snprintf( owner_url, sizeof(owner_url), "https://%s/owner/actor", g_server->domain );
for( int i = 0; i < obj->tags.count; ++i ) {
struct ap_activity_tag* tag = obj->tags.items[i];
//printf( "tag = { &=%p, .type=%d, .href=%s, .name=%s }\n", tag, tag->type, tag->href, tag->name );
if( tag->type != aptag_mention ) { continue; }
if( 0 == strcmp(tag->href, owner_url) ) {
mentions_me = true;
goto check_is_follower;
if( 0 == strcmp(tag->href, account_url) ) {
return true;
}
}
check_is_follower:
return false;
}
static bool account_actor_is_followed( struct ap_object* obj )
{
bool result = false;
struct account* actor_account = NULL;
struct account* owner_account = NULL;
// Get actor account
char* actor_uri = obj->actor;
if( !actor_uri ) {
@ -357,15 +345,46 @@ check_is_follower:
actor_account = account_from_uri_or_fetch( actor_uri );
if( !actor_account ) {
printf( "! Unable to fetch %s\n", actor_uri );
goto discard;
goto failed;
}
owner_account = account_from_id( owner_account_id );
if( account_does_follow( owner_account, actor_account->id ) ) {
account_followed = true;
goto success;
}
goto failed;
cleanup:
account_free(actor_account);
account_free(owner_account);
return result;
failed:
result = false;
goto cleanup;
success:
result = true;
goto cleanup;
}
static bool route_create( struct ap_object* act )
{
struct status* s = NULL;
bool result = false;
// Requires an object
if( act->object.tag != apaot_activity ) {
printf( "TODO: fetch activity from %s\n", act->object.ref );
goto failed;
}
struct ap_object* obj = act->object.ptr;
if( !account_followed && !mentions_me ) {
// Does this activity have mention me
char owner_url[512];
snprintf( owner_url, sizeof(owner_url), "https://%s/owner/actor", g_server->domain );
bool mentions_me = mentions_account_url(obj,owner_url);
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' );
goto discard;
@ -388,6 +407,7 @@ check_is_follower:
// TODO: create notification if user notifications are on or this is part of a watched conversation
}
if( mentions_me ) {
// Add me to mention lists
int id = owner_account_id;
@ -398,7 +418,7 @@ check_is_follower:
note->debug = 6;
note->type = nt_mention;
note->status_id = s->id;
note->account_id = actor_account->id;
note->account_id = s->account_id;
notification_save( note );
notification_free( note );
}
@ -406,14 +426,12 @@ check_is_follower:
// Add to standard timelines
status_add_to_timeline( s, public_timeline_id );
//status_add_to_timeline( s, federated_timeline_id );
status_add_to_timeline( s, actor_account->id );
status_add_to_timeline( s, s->account_id );
discard:
result = true;
goto cleanup;
cleanup:
account_free(actor_account);
account_free(owner_account);
status_free(s);
return result;
failed:

@ -93,12 +93,14 @@ static FILE* open_status_data_file( unsigned int id, const char* mode )
f = fopen( get_status_data_filename(id,filename,sizeof(filename)), mode );
if( f ) {
printf( "Opening %s\n", filename );
//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( "Opening %s\n", filename );
//printf( "Using existing location at %s\n", filename );
return f;
}
@ -216,7 +218,6 @@ void status_add_reply( struct status* s, struct status* child )
int id = child->id;
array_append( &s->replies, sizeof(id), &id );
status_save(s);
}
void status_add_mention( struct status* s, int id )
{
@ -278,21 +279,39 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
s->stub = false;
s->sensitive = act->sensitive;
// Force this status to have an id
status_save_new(s);
if( act->in_reply_to ) {
printf( "Status %d is reply to %s\n", s->id, act->in_reply_to );
int parent_id = 0;
struct status* parent = status_from_uri_or_fetch( act->in_reply_to );
if( parent ) {
status_make_reply_to( s, parent->id );
// DO NOT SAVE parent! This is done inside status_make_reply_to
parent_id = parent->id;
status_save(parent);
status_free(parent);
}
if( parent_id ) {
status_make_reply_to( s, parent_id );
s->in_reply_to = parent_id;
}
printf( "Status %d has been marked as a reply to %d (%s)\n", s->id, parent_id, act->in_reply_to );
}
if( act->quote_url ) {
int parent_id = 0;
struct status* parent = status_from_uri_or_fetch( act->quote_url );
if( parent ) {
status_make_quote_of( s, parent->id );
// DO NOT SAVE parent! This is done inside status_make_quote_of
parent_id = parent->id;
status_save(parent);
status_free(parent);
}
if( parent_id ) {
status_make_quote_of( s, parent_id );
}
}
for( int i = 0; i < s->emoji.count; ++i ) {
@ -412,6 +431,7 @@ bool status_sync( struct status* s )
{
return status_sync_from_uri( s, s->url );
}
struct ap_object* status_replies_Collection( struct status* s )
{
struct ap_object* replies = ap_object_new();
@ -459,6 +479,8 @@ struct status* status_fetch_from_uri( const char* uri )
return NULL;
}
status_save_new(s);
return s;
}
struct status* status_new_system_unfollow( int account_id )
@ -547,6 +569,7 @@ void status_assign_local_id( struct status* s )
bool status_save_new( struct status* s )
{
status_assign_local_id( s );
printf( "Assigning status id %d\n", s->id );
status_save( s );
return true;
@ -556,6 +579,7 @@ void status_save( struct status* s )
{
char filename[512];
json_write_object_layout_to_file( get_status_data_filename(s->id,filename,sizeof(filename)), "\t", status_layout, s );
printf( "Written to %s\n", filename );
// Index the status
if( s->url ) {
@ -667,6 +691,7 @@ void status_make_reply_to( struct status* s, int in_reply_to_id )
status_add_mention( s, in_reply_to->mentions.items[i] );
}
// Cleanup
status_save(in_reply_to);
status_free(in_reply_to);
}

@ -106,7 +106,6 @@ void status_flag_for_async_fetch( struct status* s );
void status_add_to_timeline( struct status* s, int timeline_id );
void status_get_context( struct status* s, void* ancestors, void* replies );
void status_add_reply( struct status* s, struct status* child );
void status_add_mention( struct status* s, int id );
void status_add_repost( struct status* s, struct status* repost );
void status_add_quote( struct status* s, struct status* quote );

Loading…
Cancel
Save