From 9e27168c6eb855109afe16bc5bb07b08a1f0ebae Mon Sep 17 00:00:00 2001 From: teknomunk Date: Tue, 12 Sep 2023 22:31:59 -0500 Subject: [PATCH] Implement poll model --- src/model/status.c | 12 +++++++ src/model/status/poll.c | 53 +++++++++++++++++++++++++++++ src/model/status/poll.h | 11 ++++-- src/view/api/Poll.c | 75 +++++++++++++++++++++++++++++++++++++++++ src/view/api/Poll.h | 6 ++++ src/view/api/Status.c | 7 +++- 6 files changed, 161 insertions(+), 3 deletions(-) create mode 100644 src/model/status/poll.c create mode 100644 src/view/api/Poll.c create mode 100644 src/view/api/Poll.h diff --git a/src/model/status.c b/src/model/status.c index 4a4fceb..1962149 100644 --- a/src/model/status.c +++ b/src/model/status.c @@ -68,6 +68,12 @@ static struct json_object_field status_layout[] = { JSON_FIELD_ARRAY_OF_TYPE( emoji, false, emoji_type ), JSON_FIELD_ARRAY_OF_STRINGS( tags, false ), + { + .key = "poll", + .offset = offsetof( OBJ_TYPE, poll ), + .type = &status_poll_type, + }, + JSON_FIELD_BOOL( sensitive, true ), JSON_FIELD_END @@ -140,6 +146,10 @@ struct status* status_from_id( unsigned int id ) return NULL; } + if( s->poll ) { + printf( "Has poll data\n" ); + } + // Convert media to media2 if( s->media.count != 0 ) { for( int i = 0; i < s->media.count; ++i ) { @@ -731,6 +741,8 @@ void status_free( struct status* s ) } free(s->tags.items); + status_poll_free( s->poll ); + free(s); } void status_delete( struct status* s ) diff --git a/src/model/status/poll.c b/src/model/status/poll.c new file mode 100644 index 0000000..a1798e3 --- /dev/null +++ b/src/model/status/poll.c @@ -0,0 +1,53 @@ +#include "poll.h" + +#include "model/emoji.h" + +#include +#include +#include + +#define OBJ_TYPE struct status_poll_option +struct json_object_field status_poll_option_layout[] = { + JSON_FIELD_STRING( title, true ), + JSON_FIELD_ARRAY_OF_INTS( votes, false ), + JSON_FIELD_END, +}; +#undef OBJ_TYPE +JSON_FIELD_TYPE_OBJECT_LAYOUT_WITH_DEFAULTS( status_poll_option ); + +#define OBJ_TYPE struct status_poll +struct json_object_field status_poll_layout[] = { + JSON_FIELD_INTEGER( id, false ), + JSON_FIELD_BOOL( multiple_choice, false ), + JSON_FIELD_DATETIME( expires_at, false ), + JSON_FIELD_BOOL( voted, false ), + JSON_FIELD_ARRAY_OF_TYPE( options, false, status_poll_option_type ), + JSON_FIELD_ARRAY_OF_TYPE( emoji, false, emoji_type ), + JSON_FIELD_END, +}; +#undef OBJ_TYPE +JSON_FIELD_TYPE_OBJECT_LAYOUT_WITH_DEFAULTS( status_poll ); + +void status_poll_option_free( struct status_poll_option* o ) +{ + if( !o ) { return; } + + free(o); +} +void status_poll_free( struct status_poll* p ) +{ + if( !p ) { return; } + + for( int i = 0; i < p->options.count; ++i ) { + status_poll_option_free( p->options.items[i] ); + } + free( p->options.items ); + + for( int i = 0; i < p->emoji.count; ++i ) { + emoji_free( p->emoji.items[i] ); + } + free( p->emoji.items ); + + free(p); +} + diff --git a/src/model/status/poll.h b/src/model/status/poll.h index be772fd..3d04188 100644 --- a/src/model/status/poll.h +++ b/src/model/status/poll.h @@ -1,5 +1,7 @@ #pragma once +#include "json/layout.h" +#include #include struct emoji; @@ -16,12 +18,13 @@ struct status_poll_option struct status_poll { + int id; time_t expires_at; bool multiple_choice; - int votes_seen; + int votes_count; bool voted; struct { - struct status_poll_option* items; + struct status_poll_option** items; int count; } options; @@ -31,3 +34,7 @@ struct status_poll } emoji; }; +extern struct json_field_type status_poll_type; +void status_poll_option_free( struct status_poll_option* o ); +void status_poll_free( struct status_poll* p ); + diff --git a/src/view/api/Poll.c b/src/view/api/Poll.c new file mode 100644 index 0000000..a1fef66 --- /dev/null +++ b/src/view/api/Poll.c @@ -0,0 +1,75 @@ +#include "Poll.h" + +#include "model/status/poll.h" + +#include "json/layout.h" + +extern struct json_field_type api_Emoji_type; + +#define OBJ_TYPE struct status_poll_option +struct json_object_field api_PollOption_layout[] = { + JSON_FIELD_STRING( title, false ), + { + .key = "votes_count", + .offset = offsetof( OBJ_TYPE, votes.count ), + .required = true, + .type = &json_field_integer, + }, + JSON_FIELD_END, +}; +#undef OBJ_TYPE + +struct json_field_type api_PollOption_type = { + .reader = json_field_object_type_reader, + .writer = json_field_object_type_writer, + .size = sizeof( struct status* ), + .layout = api_PollOption_layout, + .type_string = "Poll::Option", +}; + +bool int_to_string_callback( void* field_data, bool is_read, char** res ); + +#define OBJ_TYPE struct status_poll +struct json_object_field api_Poll_layout[] = { + { + .key = "id", + .offset = offsetof( OBJ_TYPE, id ), + .type = &json_field_callback_string, + .string_callback = int_to_string_callback, + }, + JSON_FIELD_DATETIME( expires_at, false ), + JSON_FIELD_FIXED_BOOL( expired, false ), + { + .key = "multiple", + .offset = offsetof( OBJ_TYPE, multiple_choice ), + .required = true, + .type = &json_field_bool, + }, + JSON_FIELD_INTEGER( votes_count, true ), + JSON_FIELD_FIXED_NULL( voters_count ), + JSON_FIELD_BOOL( voted, true ), + { + .key = "options", + .offset = offsetof( OBJ_TYPE, options ), + .type = &json_field_array_of, + .array_item_type = &api_PollOption_type, + }, + { + .key = "emojis", + .offset = offsetof( OBJ_TYPE, emoji ), + .required = true, + .type = &json_field_array_of, + .array_item_type = &api_Emoji_type, + }, + JSON_FIELD_END, +}; +#undef OBJ_TYPE + +struct json_field_type api_Poll_type = { + .reader = json_field_object_type_reader, + .writer = json_field_object_type_writer, + .size = sizeof( struct status* ), + .layout = api_Poll_layout, + .type_string = "Poll", +}; + diff --git a/src/view/api/Poll.h b/src/view/api/Poll.h new file mode 100644 index 0000000..3b76236 --- /dev/null +++ b/src/view/api/Poll.h @@ -0,0 +1,6 @@ +#pragma once + + +struct json_field_type; +extern struct json_field_type api_Poll_type; + diff --git a/src/view/api/Status.c b/src/view/api/Status.c index 9e235df..cc64798 100644 --- a/src/view/api/Status.c +++ b/src/view/api/Status.c @@ -8,6 +8,7 @@ #include "view/api/Account.h" #include "view/api/Tag.h" +#include "view/api/Poll.h" #include "json/json.h" #include "json/layout.h" @@ -518,7 +519,11 @@ struct json_object_field api_Status_layout[] = { .type = &json_field_object_composite, .composite_layout = pleroma_layout, }, - JSON_FIELD_FIXED_NULL( poll ), + { + .key = "poll", + .offset = offsetof( OBJ_TYPE, poll ), + .type = &api_Poll_type, + }, { .key = "reblog", .offset = offsetof(OBJ_TYPE, repost_id),