fix: upload difficulty via web form

This commit is contained in:
Aravinth Manivannan 2023-01-26 18:25:01 +05:30
parent 7b4fa1e54c
commit f6030577a0
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
5 changed files with 57 additions and 8 deletions

View file

@ -79,6 +79,9 @@ pub enum ServiceError {
#[display(fmt = "Campaign doesn't exist")]
CampaignDoesntExist,
#[display(fmt = "Not a number: only numeral data is accepted")]
NotANumber,
}
#[derive(Serialize, Deserialize)]
@ -123,6 +126,7 @@ impl ResponseError for ServiceError {
ServiceError::PasswordsDontMatch => StatusCode::BAD_REQUEST,
ServiceError::CampaignDoesntExist => StatusCode::NOT_FOUND,
ServiceError::NotANumber => StatusCode::BAD_REQUEST,
}
}
}

View file

@ -30,7 +30,7 @@ pub struct Bench {
ctx: RefCell<Context>,
}
pub const BENCH: TemplateFile = TemplateFile::new("new_campaign", "bench/index.html");
pub const BENCH: TemplateFile = TemplateFile::new("new_bench", "bench/index.html");
impl CtxError for Bench {
fn with_error(&self, e: &ReadableError) -> String {

View file

@ -23,6 +23,7 @@ use actix_web::{web, HttpResponse, Responder};
use tera::Context;
use crate::api::v1::admin::campaigns::{runners, AddCapmaign};
use crate::errors::*;
use crate::AppData;
pub use super::*;
@ -60,23 +61,46 @@ impl NewCampaign {
path = "PAGES.panel.campaigns.new",
wrap = "crate::pages::get_page_check_login()"
)]
#[tracing::instrument(name = "New campaign form", skip(data))]
pub async fn new_campaign(data: AppData) -> PageResult<impl Responder, NewCampaign> {
let new_campaign = NewCampaign::new(&data.settings).render();
let html = ContentType::html();
Ok(HttpResponse::Ok().content_type(html).body(new_campaign))
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct FormAddCampaign {
pub name: String,
pub difficulties: String,
}
impl FormAddCampaign {
fn parse(self) -> ServiceResult<AddCapmaign> {
let name = self.name;
let mut difficulties = Vec::new();
for d in self.difficulties.split(',') {
let d = d.parse::<i32>().map_err(|_| ServiceError::NotANumber)?;
difficulties.push(d);
}
Ok(AddCapmaign { name, difficulties })
}
}
#[actix_web_codegen_const_routes::post(
path = "PAGES.panel.campaigns.new",
wrap = "crate::pages::get_page_check_login()"
)]
#[tracing::instrument(name = "New campaign form submit", skip(data, id))]
pub async fn new_campaign_submit(
id: Identity,
payload: web::Json<AddCapmaign>,
payload: web::Form<FormAddCampaign>,
data: AppData,
) -> PageResult<impl Responder, NewCampaign> {
let username = id.identity().unwrap();
let mut payload = payload.into_inner();
let mut payload = payload
.into_inner()
.parse()
.map_err(|e| PageError::new(NewCampaign::new(&data.settings), e))?;
runners::add_runner(&username, &mut payload, &data)
.await
@ -117,14 +141,23 @@ mod tests {
let (_, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let new = AddCapmaign {
let mut difficulties = String::new();
for d in DIFFICULTIES.iter() {
if difficulties.is_empty() {
difficulties = format!("{d}");
} else {
difficulties = format!("{difficulties},{d}");
}
}
println!("{difficulties}");
let new = super::FormAddCampaign {
name: CAMPAIGN_NAME.into(),
difficulties: DIFFICULTIES.into(),
difficulties,
};
let new_resp = test::call_service(
&app,
post_request!(&new, crate::PAGES.panel.campaigns.new)
post_request!(&new, crate::PAGES.panel.campaigns.new, FORM)
.cookie(cookies)
.to_request(),
)

View file

@ -1,6 +1,6 @@
<h1>Create new campaigns</h1>
<form
action="<.= page.panel.campaigns.new .>"
action="{{ page.panel.campaigns.new }}"
method="POST"
class="new-campaign__form"
accept-charset="utf-8"
@ -17,5 +17,17 @@
type="text"
/>
</label>
<label class="form__label" for="difficulties">
Difficulties (comma separated, for example: 555,1111,2222)
<input
class="form__input"
name="difficulties"
placeholder="Comma separated difficulty list, for example: 5000,6000,7000"
required
id="difficulties"
type="text"
/>
</label>
<button class="form__submit" type="submit">Create Campaign</button>
</form>

View file

@ -4,7 +4,7 @@
<div class="nav__header">
<a class="nav__logo-container" href="{{ page.home }}">
<img src="{{ assets.logo.path }}" alt="{{ assets.logo.name }}" class="nav__logo" />
<p class="nav__logo-text">{{ assets.logo.name }}</p>
<p class="nav__logo-text">mCaptcha Survey</p>
</a>
<label class="nav__hamburger-menu" for="nav__toggle">
<span class="nav__hamburger-inner"></span>