Automatically pull data for polls

master
teknomunk 8 months ago
parent 9e27168c6e
commit 91ad748f89

@ -1 +1 @@
Subproject commit 70380d76001d6f7c82206fec5e0575fd3eb8b0d7
Subproject commit 4257ba45412070f3d6a7ac2bd42b4f488b4c5761

@ -17,6 +17,8 @@ enum {
owner_account_id = 0,
home_timeline_id = 1,
public_timeline_id = 2,
poll_vote_unknown_id = 3,
};
struct string_pair

@ -321,6 +321,64 @@ void status_add_quote( struct status* s, struct status* quote )
array_append( &s->quotes, sizeof(id), &id );
status_save(s);
}
static void sync_poll( struct status* s, void* poll_data_ptr )
{
struct {
struct ap_object_ptr_or_ref* items;
int count;
} *poll_data = poll_data_ptr;
// Pull in options
for( int i = 0; i < poll_data->count; ++i ) {
if( poll_data->items[i].tag == apaot_ref ) {
printf( "TODO: automatically dereference poll option data at %s\n", poll_data->items[i].ref );
} else if( poll_data->items[i].tag != apaot_object ) {
continue;
}
printf( "Processing option[%d]\n", i );
struct ap_object* option = poll_data->items[i].ptr;
// Expand options if there aren't enough already
struct status_poll_option* o;
if( s->poll->options.count <= i ) {
o = malloc(sizeof(*o));
memset(o,0,sizeof(*o));
array_append( &s->poll->options, sizeof(o), &o );
}
o = s->poll->options.items[i];
// Update option title
if( option->name ) {
if( o->title ) {
free( o->title );
}
o->title = strdup(option->name);
printf( "Option[%d] is %s\n", i, o->title );
}
// Pull out vote counts
if( option->replies.tag == apaot_object ) {
printf( "Syncing reply count..\n" );
struct ap_object* replies = option->replies.ptr;
while( s->poll->options.items[i]->votes.count < replies->total_items ) {
int id = poll_vote_unknown_id;
array_append( &o->votes, sizeof(id), &id );
}
}
}
// Rebuild votes_count
s->poll->votes_count = 0;
for( int i = 0; i < s->poll->options.count; ++i ) {
s->poll->votes_count += s->poll->options.items[i]->votes.count;
}
}
// TODO: Move to src/model/status/ap_sync.c
bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
{
if( !act->actor && act->attributed_to ) {
@ -399,6 +457,35 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
}
}
// TODO: move this out to another function to use same code for any_of and one_of
if( act->one_of.count > 0 ) {
if( !s->poll ) {
struct status_poll* poll;
poll = malloc(sizeof(*poll));
memset(poll,0,sizeof(*poll));
poll->id = 1;
poll->multiple_choice = false;
s->poll = poll;
}
sync_poll( s, &act->one_of );
} else if( act->any_of.count > 0 ) {
if( !s->poll ) {
struct status_poll* poll;
poll = malloc(sizeof(*poll));
memset(poll,0,sizeof(*poll));
poll->id = 1;
poll->multiple_choice = true;
s->poll = poll;
}
sync_poll( s, &act->any_of );
}
for( int i = 0; i < s->emoji.count; ++i ) {
emoji_free( s->emoji.items[i] );
}
@ -425,7 +512,7 @@ bool status_sync_from_activity_pub( struct status* s, struct ap_object* act )
array_append( &s->emoji, sizeof(e), &e );
} else if( tag->type == aptag_hashtag && tag->name ) {
char* tag_name = safe_strdup( &tag->name[1] );
array_append( &s->tags, sizeof(tag_name), &tag_name );
status_add_tag( s, tag_name );
}
}

Loading…
Cancel
Save