fix: upload difficulty via web form
This commit is contained in:
parent
7b4fa1e54c
commit
f6030577a0
5 changed files with 57 additions and 8 deletions
|
@ -79,6 +79,9 @@ pub enum ServiceError {
|
||||||
|
|
||||||
#[display(fmt = "Campaign doesn't exist")]
|
#[display(fmt = "Campaign doesn't exist")]
|
||||||
CampaignDoesntExist,
|
CampaignDoesntExist,
|
||||||
|
|
||||||
|
#[display(fmt = "Not a number: only numeral data is accepted")]
|
||||||
|
NotANumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -123,6 +126,7 @@ impl ResponseError for ServiceError {
|
||||||
ServiceError::PasswordsDontMatch => StatusCode::BAD_REQUEST,
|
ServiceError::PasswordsDontMatch => StatusCode::BAD_REQUEST,
|
||||||
|
|
||||||
ServiceError::CampaignDoesntExist => StatusCode::NOT_FOUND,
|
ServiceError::CampaignDoesntExist => StatusCode::NOT_FOUND,
|
||||||
|
ServiceError::NotANumber => StatusCode::BAD_REQUEST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub struct Bench {
|
||||||
ctx: RefCell<Context>,
|
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 {
|
impl CtxError for Bench {
|
||||||
fn with_error(&self, e: &ReadableError) -> String {
|
fn with_error(&self, e: &ReadableError) -> String {
|
||||||
|
|
|
@ -23,6 +23,7 @@ use actix_web::{web, HttpResponse, Responder};
|
||||||
use tera::Context;
|
use tera::Context;
|
||||||
|
|
||||||
use crate::api::v1::admin::campaigns::{runners, AddCapmaign};
|
use crate::api::v1::admin::campaigns::{runners, AddCapmaign};
|
||||||
|
use crate::errors::*;
|
||||||
use crate::AppData;
|
use crate::AppData;
|
||||||
|
|
||||||
pub use super::*;
|
pub use super::*;
|
||||||
|
@ -60,23 +61,46 @@ impl NewCampaign {
|
||||||
path = "PAGES.panel.campaigns.new",
|
path = "PAGES.panel.campaigns.new",
|
||||||
wrap = "crate::pages::get_page_check_login()"
|
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> {
|
pub async fn new_campaign(data: AppData) -> PageResult<impl Responder, NewCampaign> {
|
||||||
let new_campaign = NewCampaign::new(&data.settings).render();
|
let new_campaign = NewCampaign::new(&data.settings).render();
|
||||||
let html = ContentType::html();
|
let html = ContentType::html();
|
||||||
Ok(HttpResponse::Ok().content_type(html).body(new_campaign))
|
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(
|
#[actix_web_codegen_const_routes::post(
|
||||||
path = "PAGES.panel.campaigns.new",
|
path = "PAGES.panel.campaigns.new",
|
||||||
wrap = "crate::pages::get_page_check_login()"
|
wrap = "crate::pages::get_page_check_login()"
|
||||||
)]
|
)]
|
||||||
|
#[tracing::instrument(name = "New campaign form submit", skip(data, id))]
|
||||||
pub async fn new_campaign_submit(
|
pub async fn new_campaign_submit(
|
||||||
id: Identity,
|
id: Identity,
|
||||||
payload: web::Json<AddCapmaign>,
|
payload: web::Form<FormAddCampaign>,
|
||||||
data: AppData,
|
data: AppData,
|
||||||
) -> PageResult<impl Responder, NewCampaign> {
|
) -> PageResult<impl Responder, NewCampaign> {
|
||||||
let username = id.identity().unwrap();
|
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)
|
runners::add_runner(&username, &mut payload, &data)
|
||||||
.await
|
.await
|
||||||
|
@ -117,14 +141,23 @@ mod tests {
|
||||||
let (_, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
|
let (_, _, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
|
||||||
let cookies = get_cookie!(signin_resp);
|
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(),
|
name: CAMPAIGN_NAME.into(),
|
||||||
difficulties: DIFFICULTIES.into(),
|
difficulties,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_resp = test::call_service(
|
let new_resp = test::call_service(
|
||||||
&app,
|
&app,
|
||||||
post_request!(&new, crate::PAGES.panel.campaigns.new)
|
post_request!(&new, crate::PAGES.panel.campaigns.new, FORM)
|
||||||
.cookie(cookies)
|
.cookie(cookies)
|
||||||
.to_request(),
|
.to_request(),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<h1>Create new campaigns</h1>
|
<h1>Create new campaigns</h1>
|
||||||
<form
|
<form
|
||||||
action="<.= page.panel.campaigns.new .>"
|
action="{{ page.panel.campaigns.new }}"
|
||||||
method="POST"
|
method="POST"
|
||||||
class="new-campaign__form"
|
class="new-campaign__form"
|
||||||
accept-charset="utf-8"
|
accept-charset="utf-8"
|
||||||
|
@ -17,5 +17,17 @@
|
||||||
type="text"
|
type="text"
|
||||||
/>
|
/>
|
||||||
</label>
|
</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>
|
<button class="form__submit" type="submit">Create Campaign</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<div class="nav__header">
|
<div class="nav__header">
|
||||||
<a class="nav__logo-container" href="{{ page.home }}">
|
<a class="nav__logo-container" href="{{ page.home }}">
|
||||||
<img src="{{ assets.logo.path }}" alt="{{ assets.logo.name }}" class="nav__logo" />
|
<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>
|
</a>
|
||||||
<label class="nav__hamburger-menu" for="nav__toggle">
|
<label class="nav__hamburger-menu" for="nav__toggle">
|
||||||
<span class="nav__hamburger-inner"></span>
|
<span class="nav__hamburger-inner"></span>
|
||||||
|
|
Loading…
Reference in a new issue