You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

69 lines
1.9 KiB

use crate::api::{CurrentUser, JsonApi, PolicyError::*};
use crate::rds_conn::RdsConn;
use crate::rds_models::*;
use rocket::form::Form;
use rocket::futures::future;
use rocket::serde::json::{json, Value};
pub async fn get_poll_dict(pid: i32, rconn: &RdsConn, namehash: &str) -> Option<Value> {
let opts = PollOption::init(pid, rconn)
.get_list()
.await
.unwrap_or_default();
if opts.is_empty() {
None
} else {
let choice = future::join_all(opts.iter().enumerate().map(|(idx, opt)| async move {
PollVote::init(pid, idx, rconn)
.has(namehash)
.await
.unwrap_or_default()
.then(|| opt)
}))
.await
.into_iter()
.flatten()
.collect::<Vec<&String>>()
.pop();
Some(json!({
"answers": future::join_all(
opts.iter().enumerate().map(|(idx, opt)| async move {
json!({
"option": opt,
"votes": PollVote::init(pid, idx, rconn).count().await.unwrap_or_default(),
})
})
).await,
"vote": choice,
}))
}
}
#[derive(FromForm)]
pub struct VoteInput {
pid: i32,
vote: String,
}
#[post("/vote", data = "<vi>")]
pub async fn vote(vi: Form<VoteInput>, user: CurrentUser, rconn: RdsConn) -> JsonApi {
user.id.ok_or(NotAllowed)?;
let pid = vi.pid;
let opts = PollOption::init(pid, &rconn).get_list().await?;
if opts.is_empty() {
Err(NotAllowed)?;
}
for idx in 0..opts.len() {
if PollVote::init(pid, idx, &rconn).has(&user.namehash).await? {
Err(NotAllowed)?;
}
}
let idx: usize = opts.iter().position(|x| x.eq(&vi.vote)).ok_or(NotAllowed)?;
PollVote::init(pid, idx, &rconn).add(&user.namehash).await?;
code0!(get_poll_dict(vi.pid, &rconn, &user.namehash).await)
}