Fix handling polls with unknown voter counts

https://botsin.space/@muffinista/101947647800341192
This commit is contained in:
blankie 2023-11-24 18:42:46 +11:00
parent f408c5206c
commit 2df649af8e
Signed by: blankie
GPG Key ID: CC15FC822C7F61F5
4 changed files with 19 additions and 9 deletions

View File

@ -13,12 +13,13 @@ add_subdirectory(thirdparty/lexbor)
#pkg_check_modules(HIREDIS REQUIRED hiredis)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
if (CMAKE_BUILD_TYPE MATCHES "Debug|RelWithDebInfo")
if (NOT FLAGS)
list(APPEND FLAGS -fsanitize=undefined,thread)
endif()
# https://sourceforge.net/p/valgrind/mailman/valgrind-users/thread/Ygze8PzaQAYWlKDj%40wildebeest.org/
list(APPEND FLAGS -gdwarf-4)
list(APPEND DEFINITIONS JSON_DIAGNOSTICS=1)
endif()
# https://t.me/NightShadowsHangout/670691
@ -39,4 +40,5 @@ set_target_properties(${PROJECT_NAME}
)
target_include_directories(${PROJECT_NAME} PRIVATE thirdparty ${HIREDIS_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json CURL::libcurl httplib::httplib lexbor_static ${HIREDIS_LINK_LIBRARIES})
target_compile_definitions(${PROJECT_NAME} PRIVATE ${DEFINITIONS})
target_compile_options(${PROJECT_NAME} PRIVATE ${FLAGS})

View File

@ -79,7 +79,12 @@ void from_json(const json& j, PollOption& option) {
void from_json(const json& j, Poll& poll) {
poll.expires_at = parse_rfc3339(j.at("expires_at").get_ref<const std::string&>());
j.at("expired").get_to(poll.expired);
j.at("voters_count").get_to(poll.voters_count);
if (!j.at("voters_count").is_null()) {
j.at("voters_count").get_to(poll.voters_count);
} else {
poll.voters_count = -1;
}
j.at("votes_count").get_to(poll.votes_count);
j.at("options").get_to(poll.options);
j.at("emojis").get_to(poll.emojis);
}

View File

@ -65,7 +65,8 @@ struct PollOption {
struct Poll {
time_t expires_at;
bool expired;
uint64_t voters_count;
int64_t voters_count; // negative if unknown
uint64_t votes_count;
std::vector<PollOption> options;
std::vector<Emoji> emojis;
};

View File

@ -461,6 +461,7 @@ static inline Element serialize_media(const Media& media) {
}
static inline Element serialize_poll(const httplib::Request& req, const Poll& poll) {
uint64_t voters_count = poll.voters_count >= 0 ? static_cast<uint64_t>(poll.voters_count) : poll.votes_count;
Element div("div");
auto pick_form = [](uint64_t count, const char* singular, const char* plural) {
@ -469,8 +470,8 @@ static inline Element serialize_poll(const httplib::Request& req, const Poll& po
div.nodes.reserve(poll.options.size() + 1);
for (const PollOption& option : poll.options) {
std::string percentage = poll.voters_count
? std::to_string(option.votes_count * 100 / poll.voters_count) + '%'
std::string percentage = voters_count
? std::to_string(option.votes_count * 100 / voters_count) + '%'
: "0%";
div.nodes.push_back(Element("div", {{"class", "poll-option"}, {"title", std::to_string(option.votes_count) + pick_form(option.votes_count, " vote", " votes")}}, {
@ -479,10 +480,11 @@ static inline Element serialize_poll(const httplib::Request& req, const Poll& po
}));
}
Element p("p", {
std::to_string(poll.voters_count), " ", pick_form(poll.voters_count, "voter", "voters"),
" / ",
});
Element p("p", poll.voters_count >= 0
? std::vector<Node>({std::to_string(voters_count), " ", pick_form(voters_count, "voter", "voters")})
: std::vector<Node>({std::to_string(poll.votes_count), " ", pick_form(poll.votes_count, "vote", "votes")})
);
p.nodes.push_back(" / ");
if (poll.expired) {
p.nodes.push_back("Expired");
} else {