Upravování příspěvků + úklid
Tento commit je obsažen v:
rodič
eb33ad9a19
revize
1eeffc71c6
206
src/error.rs
206
src/error.rs
@ -4,85 +4,84 @@ use thiserror::Error;
|
|||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum NekrochanError {
|
pub enum NekrochanError {
|
||||||
#[error("Chyba při zpracovávání souboru '{}': {}", .0, .1)]
|
|
||||||
FileError(String, &'static str),
|
|
||||||
#[error("Uživatelské jméno musí mít 1-32 znaků.")]
|
|
||||||
UsernameFormatError,
|
|
||||||
#[error("Heslo musí mít alespoň 8 znaků.")]
|
|
||||||
PasswordFormatError,
|
|
||||||
#[error("ID musí mít 1-16 znaků.")]
|
|
||||||
IdFormatError,
|
|
||||||
#[error("Jméno nástěnky musí mít 1-32 znaků.")]
|
|
||||||
BoardNameFormatError,
|
|
||||||
#[error("Popis musí mít 1-128 znaků.")]
|
|
||||||
DescriptionFormatError,
|
|
||||||
#[error("Jméno nesmí mít více než 32 znaků.")]
|
|
||||||
PostNameFormatError,
|
|
||||||
#[error("Capcode nesmí mít více než 32 znaků.")]
|
|
||||||
CapcodeFormatError,
|
|
||||||
#[error("E-mail nesmí mít více než 256 znaků.")]
|
|
||||||
EmailFormatError,
|
|
||||||
#[error("Obsah nesmí mít více než 10000 znaků.")]
|
|
||||||
ContentFormatError,
|
|
||||||
#[error("Nástěnka /{}/ neexistuje.", .0)]
|
|
||||||
BoardNotFound(String),
|
|
||||||
#[error("Účet '{}' neexistuje.", .0)]
|
#[error("Účet '{}' neexistuje.", .0)]
|
||||||
AccountNotFound(String),
|
AccountNotFound(String),
|
||||||
#[error("Příspěvek /{}/{} neexistuje.", .0, .1)]
|
#[error("Tento ban už byl odvolán.")]
|
||||||
PostNotFound(String, i32),
|
AlreadyAppealedError,
|
||||||
#[error("Žádný takový ban pro tuto IP adresu neexistuje.")]
|
#[error("Žádný takový ban pro tuto IP adresu neexistuje.")]
|
||||||
BanNotFound,
|
BanNotFound,
|
||||||
#[error("Nedostatečná oprávnění.")]
|
|
||||||
InsufficientPermissionError,
|
|
||||||
#[error("Nesprávné přihlašovací údaje.")]
|
|
||||||
IncorrectCredentialError,
|
|
||||||
#[error("Neplatná strana.")]
|
|
||||||
InvalidPageError,
|
|
||||||
#[error("Neplatný autentizační token. Vymaž soubory cookie.")]
|
|
||||||
InvalidAuthError,
|
|
||||||
#[error("Pro přístup se musíš přihlásit.")]
|
|
||||||
NotLoggedInError,
|
|
||||||
#[error("Účet vlastníka nemůže být vymazán.")]
|
|
||||||
OwnerDeletionError,
|
|
||||||
#[error("Reverzní proxy nevrátilo vyžadovanou hlavičku '{}'.", .0)]
|
|
||||||
HeaderError(&'static str),
|
|
||||||
#[error("Nástěnka /{}/ je uzamčená.", .0)]
|
#[error("Nástěnka /{}/ je uzamčená.", .0)]
|
||||||
BoardLockError(String),
|
BoardLockError(String),
|
||||||
#[error("Toto vlákno je uzamčené.")]
|
#[error("Jméno nástěnky musí mít 1-32 znaků.")]
|
||||||
ThreadLockError,
|
BoardNameFormatError,
|
||||||
#[error("Nelze vytvořit odpověď na odpověď.")]
|
#[error("Nástěnka /{}/ neexistuje.", .0)]
|
||||||
ReplyReplyError,
|
BoardNotFound(String),
|
||||||
#[error("Vlákno dosáhlo limitu odpovědí.")]
|
#[error("Capcode nesmí mít více než 32 znaků.")]
|
||||||
ReplyLimitError,
|
CapcodeFormatError,
|
||||||
|
#[error("Obsah nesmí mít více než 10000 znaků.")]
|
||||||
|
ContentFormatError,
|
||||||
|
#[error("Popis musí mít 1-128 znaků.")]
|
||||||
|
DescriptionFormatError,
|
||||||
|
#[error("E-mail nesmí mít více než 256 znaků.")]
|
||||||
|
EmailFormatError,
|
||||||
|
#[error("Příspěvek musí mít obsah nebo soubor.")]
|
||||||
|
EmptyPostError,
|
||||||
|
#[error("Chyba při zpracovávání souboru '{}': {}", .0, .1)]
|
||||||
|
FileError(String, &'static str),
|
||||||
|
#[error("Maximální počet souborů na této nástěnce je {}.", .0)]
|
||||||
|
FileLimitError(usize),
|
||||||
|
#[error("Tvůj příspěvek vypadá jako spam.")]
|
||||||
|
FloodError,
|
||||||
|
#[error("Reverzní proxy nevrátilo vyžadovanou hlavičku '{}'.", .0)]
|
||||||
|
HeaderError(&'static str),
|
||||||
|
#[error("ID musí mít 1-16 znaků.")]
|
||||||
|
IdFormatError,
|
||||||
|
#[error("Nesprávné řešení CAPTCHA.")]
|
||||||
|
IncorrectCaptchaError,
|
||||||
|
#[error("Nesprávné přihlašovací údaje.")]
|
||||||
|
IncorrectCredentialError,
|
||||||
|
#[error("Nesprávné heslo pro příspěvek #{}.", .0)]
|
||||||
|
IncorrectPasswordError(i32),
|
||||||
|
#[error("Nedostatečná oprávnění.")]
|
||||||
|
InsufficientPermissionError,
|
||||||
|
#[error("Server se připojil k 41 procentům.")]
|
||||||
|
InternalError,
|
||||||
|
#[error("Neplatný autentizační token. Vymaž soubory cookie.")]
|
||||||
|
InvalidAuthError,
|
||||||
|
#[error("Neplatná strana.")]
|
||||||
|
InvalidPageError,
|
||||||
#[error("Příspěvek musí mít obsah.")]
|
#[error("Příspěvek musí mít obsah.")]
|
||||||
NoContentError,
|
NoContentError,
|
||||||
#[error("Příspěvek musí mít soubor.")]
|
#[error("Příspěvek musí mít soubor.")]
|
||||||
NoFileError,
|
NoFileError,
|
||||||
#[error("Příspěvek musí mít obsah nebo soubor.")]
|
|
||||||
EmptyPostError,
|
|
||||||
#[error("Na této nástěnce se musí vyplnit CAPTCHA.")]
|
|
||||||
RequiredCaptchaError,
|
|
||||||
#[error("Nesprávné řešení CAPTCHA.")]
|
|
||||||
IncorrectCaptchaError,
|
|
||||||
#[error("Tato CAPTCHA neexistuje nebo už byla vyřešena.")]
|
|
||||||
SolvedCaptchaError,
|
|
||||||
#[error("Nebyly vybrány žádné příspěvky.")]
|
#[error("Nebyly vybrány žádné příspěvky.")]
|
||||||
NoPostsError,
|
NoPostsError,
|
||||||
#[error("Maximální počet souborů na této nástěnce je {}.", .0)]
|
#[error("Pro přístup se musíš přihlásit.")]
|
||||||
FileLimitError(usize),
|
NotLoggedInError,
|
||||||
#[error("Nesprávné heslo pro příspěvek #{}.", .0)]
|
|
||||||
IncorrectPasswordError(i32),
|
|
||||||
#[error("Tento ban už byl odvolán.")]
|
|
||||||
AlreadyAppealedError,
|
|
||||||
#[error("Tento ban nelze odvolat.")]
|
|
||||||
UnappealableError,
|
|
||||||
#[error("Tvůj příspěvek vypadá jako spam.")]
|
|
||||||
FloodError,
|
|
||||||
// 500
|
|
||||||
#[error("Nadnástěnka nebyla inicializována.")]
|
#[error("Nadnástěnka nebyla inicializována.")]
|
||||||
OverboardError,
|
OverboardError,
|
||||||
#[error("Server se připojil k 41 procentům.")]
|
#[error("Účet vlastníka nemůže být vymazán.")]
|
||||||
InternalError,
|
OwnerDeletionError,
|
||||||
|
#[error("Heslo musí mít alespoň 8 znaků.")]
|
||||||
|
PasswordFormatError,
|
||||||
|
#[error("Jméno nesmí mít více než 32 znaků.")]
|
||||||
|
PostNameFormatError,
|
||||||
|
#[error("Příspěvek /{}/{} neexistuje.", .0, .1)]
|
||||||
|
PostNotFound(String, i32),
|
||||||
|
#[error("Vlákno dosáhlo limitu odpovědí.")]
|
||||||
|
ReplyLimitError,
|
||||||
|
#[error("Nelze vytvořit odpověď na odpověď.")]
|
||||||
|
ReplyReplyError,
|
||||||
|
#[error("Na této nástěnce se musí vyplnit CAPTCHA.")]
|
||||||
|
RequiredCaptchaError,
|
||||||
|
#[error("Tato CAPTCHA neexistuje nebo už byla vyřešena.")]
|
||||||
|
SolvedCaptchaError,
|
||||||
|
#[error("Toto vlákno je uzamčené.")]
|
||||||
|
ThreadLockError,
|
||||||
|
#[error("Tento ban nelze odvolat.")]
|
||||||
|
UnappealableError,
|
||||||
|
#[error("Uživatelské jméno musí mít 1-32 znaků.")]
|
||||||
|
UsernameFormatError,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<askama::Error> for NekrochanError {
|
impl From<askama::Error> for NekrochanError {
|
||||||
@ -201,46 +200,45 @@ impl From<tokio::task::JoinError> for NekrochanError {
|
|||||||
impl ResponseError for NekrochanError {
|
impl ResponseError for NekrochanError {
|
||||||
fn status_code(&self) -> StatusCode {
|
fn status_code(&self) -> StatusCode {
|
||||||
match self {
|
match self {
|
||||||
NekrochanError::FileError(_, _)
|
NekrochanError::AccountNotFound(_) => StatusCode::NOT_FOUND,
|
||||||
| NekrochanError::UsernameFormatError
|
NekrochanError::AlreadyAppealedError => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::PasswordFormatError
|
NekrochanError::BanNotFound => StatusCode::NOT_FOUND,
|
||||||
| NekrochanError::IdFormatError
|
NekrochanError::BoardLockError(_) => StatusCode::FORBIDDEN,
|
||||||
| NekrochanError::BoardNameFormatError
|
NekrochanError::BoardNameFormatError => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::DescriptionFormatError
|
NekrochanError::BoardNotFound(_) => StatusCode::NOT_FOUND,
|
||||||
| NekrochanError::PostNameFormatError
|
NekrochanError::CapcodeFormatError => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::CapcodeFormatError
|
NekrochanError::ContentFormatError => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::EmailFormatError
|
NekrochanError::DescriptionFormatError => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::ContentFormatError
|
NekrochanError::EmailFormatError => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::ReplyReplyError
|
NekrochanError::EmptyPostError => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::NoContentError
|
NekrochanError::FileError(_, _) => StatusCode::UNPROCESSABLE_ENTITY,
|
||||||
| NekrochanError::NoFileError
|
NekrochanError::FileLimitError(_) => StatusCode::BAD_REQUEST,
|
||||||
| NekrochanError::EmptyPostError
|
|
||||||
| NekrochanError::RequiredCaptchaError
|
|
||||||
| NekrochanError::SolvedCaptchaError
|
|
||||||
| NekrochanError::NoPostsError
|
|
||||||
| NekrochanError::FileLimitError(_)
|
|
||||||
| NekrochanError::AlreadyAppealedError
|
|
||||||
| NekrochanError::UnappealableError => StatusCode::BAD_REQUEST,
|
|
||||||
NekrochanError::BoardNotFound(_)
|
|
||||||
| NekrochanError::AccountNotFound(_)
|
|
||||||
| NekrochanError::PostNotFound(_, _)
|
|
||||||
| NekrochanError::BanNotFound
|
|
||||||
| NekrochanError::InvalidPageError
|
|
||||||
| NekrochanError::InvalidAuthError => StatusCode::NOT_FOUND,
|
|
||||||
NekrochanError::InsufficientPermissionError
|
|
||||||
| NekrochanError::ReplyLimitError
|
|
||||||
| NekrochanError::ThreadLockError
|
|
||||||
| NekrochanError::BoardLockError(_)
|
|
||||||
| NekrochanError::OwnerDeletionError => StatusCode::FORBIDDEN,
|
|
||||||
NekrochanError::IncorrectCredentialError
|
|
||||||
| NekrochanError::NotLoggedInError
|
|
||||||
| NekrochanError::IncorrectCaptchaError
|
|
||||||
| NekrochanError::IncorrectPasswordError(_) => StatusCode::UNAUTHORIZED,
|
|
||||||
NekrochanError::HeaderError(_) => StatusCode::BAD_GATEWAY,
|
|
||||||
NekrochanError::FloodError => StatusCode::TOO_MANY_REQUESTS,
|
NekrochanError::FloodError => StatusCode::TOO_MANY_REQUESTS,
|
||||||
NekrochanError::OverboardError | NekrochanError::InternalError => {
|
NekrochanError::HeaderError(_) => StatusCode::BAD_GATEWAY,
|
||||||
StatusCode::INTERNAL_SERVER_ERROR
|
NekrochanError::IdFormatError => StatusCode::BAD_REQUEST,
|
||||||
}
|
NekrochanError::IncorrectCaptchaError => StatusCode::UNAUTHORIZED,
|
||||||
|
NekrochanError::IncorrectCredentialError => StatusCode::UNAUTHORIZED,
|
||||||
|
NekrochanError::IncorrectPasswordError(_) => StatusCode::UNAUTHORIZED,
|
||||||
|
NekrochanError::InsufficientPermissionError => StatusCode::FORBIDDEN,
|
||||||
|
NekrochanError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
NekrochanError::InvalidAuthError => StatusCode::UNAUTHORIZED,
|
||||||
|
NekrochanError::InvalidPageError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::NoContentError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::NoFileError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::NoPostsError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::NotLoggedInError => StatusCode::UNAUTHORIZED,
|
||||||
|
NekrochanError::OverboardError => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
|
NekrochanError::OwnerDeletionError => StatusCode::FORBIDDEN,
|
||||||
|
NekrochanError::PasswordFormatError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::PostNameFormatError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::PostNotFound(_, _) => StatusCode::NOT_FOUND,
|
||||||
|
NekrochanError::ReplyLimitError => StatusCode::FORBIDDEN,
|
||||||
|
NekrochanError::ReplyReplyError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::RequiredCaptchaError => StatusCode::UNAUTHORIZED,
|
||||||
|
NekrochanError::SolvedCaptchaError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::ThreadLockError => StatusCode::FORBIDDEN,
|
||||||
|
NekrochanError::UnappealableError => StatusCode::BAD_REQUEST,
|
||||||
|
NekrochanError::UsernameFormatError => StatusCode::BAD_REQUEST,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
src/main.rs
42
src/main.rs
@ -61,41 +61,43 @@ async fn run() -> Result<(), Error> {
|
|||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(Data::new(ctx.clone()))
|
.app_data(Data::new(ctx.clone()))
|
||||||
.service(web::index::index)
|
|
||||||
.service(web::board::board)
|
.service(web::board::board)
|
||||||
.service(web::board_catalog::board_catalog)
|
.service(web::board_catalog::board_catalog)
|
||||||
.service(web::overboard::overboard)
|
.service(web::index::index)
|
||||||
.service(web::overboard_catalog::overboard_catalog)
|
.service(web::edit_posts::edit_posts)
|
||||||
.service(web::thread::thread)
|
|
||||||
.service(web::actions::create_post::create_post)
|
|
||||||
.service(web::actions::user_post_actions::user_post_actions)
|
|
||||||
.service(web::actions::staff_post_actions::staff_post_actions)
|
|
||||||
.service(web::actions::report_posts::report_posts)
|
|
||||||
.service(web::actions::appeal_ban::appeal_ban)
|
|
||||||
.service(web::login::login_get)
|
.service(web::login::login_get)
|
||||||
.service(web::login::login_post)
|
.service(web::login::login_post)
|
||||||
.service(web::logout::logout)
|
.service(web::logout::logout)
|
||||||
|
.service(web::overboard::overboard)
|
||||||
|
.service(web::overboard_catalog::overboard_catalog)
|
||||||
|
.service(web::thread::thread)
|
||||||
|
.service(web::actions::appeal_ban::appeal_ban)
|
||||||
|
.service(web::actions::create_post::create_post)
|
||||||
|
.service(web::actions::edit_posts::edit_posts)
|
||||||
|
.service(web::actions::report_posts::report_posts)
|
||||||
|
.service(web::actions::staff_post_actions::staff_post_actions)
|
||||||
|
.service(web::actions::user_post_actions::user_post_actions)
|
||||||
.service(web::staff::account::account)
|
.service(web::staff::account::account)
|
||||||
.service(web::staff::accounts::accounts)
|
.service(web::staff::accounts::accounts)
|
||||||
.service(web::staff::boards::boards)
|
|
||||||
.service(web::staff::bans::bans)
|
.service(web::staff::bans::bans)
|
||||||
.service(web::staff::reports::reports)
|
|
||||||
.service(web::staff::permissions::permissions)
|
|
||||||
.service(web::staff::banners::banners)
|
.service(web::staff::banners::banners)
|
||||||
.service(web::staff::board_config::board_config)
|
.service(web::staff::board_config::board_config)
|
||||||
|
.service(web::staff::boards::boards)
|
||||||
|
.service(web::staff::permissions::permissions)
|
||||||
|
.service(web::staff::reports::reports)
|
||||||
|
.service(web::staff::actions::add_banners::add_banners)
|
||||||
.service(web::staff::actions::change_password::change_password)
|
.service(web::staff::actions::change_password::change_password)
|
||||||
.service(web::staff::actions::transfer_ownership::transfer_ownership)
|
.service(web::staff::actions::create_account::create_account)
|
||||||
|
.service(web::staff::actions::create_board::create_board)
|
||||||
.service(web::staff::actions::delete_account::delete_account)
|
.service(web::staff::actions::delete_account::delete_account)
|
||||||
.service(web::staff::actions::remove_accounts::remove_accounts)
|
.service(web::staff::actions::remove_accounts::remove_accounts)
|
||||||
.service(web::staff::actions::create_account::create_account)
|
|
||||||
.service(web::staff::actions::remove_boards::remove_boards)
|
|
||||||
.service(web::staff::actions::update_boards::update_boards)
|
|
||||||
.service(web::staff::actions::create_board::create_board)
|
|
||||||
.service(web::staff::actions::remove_bans::remove_bans)
|
|
||||||
.service(web::staff::actions::update_permissions::update_permissions)
|
|
||||||
.service(web::staff::actions::remove_banners::remove_banners)
|
.service(web::staff::actions::remove_banners::remove_banners)
|
||||||
.service(web::staff::actions::add_banners::add_banners)
|
.service(web::staff::actions::remove_bans::remove_bans)
|
||||||
|
.service(web::staff::actions::remove_boards::remove_boards)
|
||||||
|
.service(web::staff::actions::transfer_ownership::transfer_ownership)
|
||||||
.service(web::staff::actions::update_board_config::update_board_config)
|
.service(web::staff::actions::update_board_config::update_board_config)
|
||||||
|
.service(web::staff::actions::update_boards::update_boards)
|
||||||
|
.service(web::staff::actions::update_permissions::update_permissions)
|
||||||
.service(debug)
|
.service(debug)
|
||||||
.service(favicon)
|
.service(favicon)
|
||||||
.service(Files::new("/static", "./static"))
|
.service(Files::new("/static", "./static"))
|
||||||
|
55
src/web/actions/edit_posts.rs
Normální soubor
55
src/web/actions/edit_posts.rs
Normální soubor
@ -0,0 +1,55 @@
|
|||||||
|
use actix_web::{post, web::Data, HttpRequest, HttpResponse};
|
||||||
|
use std::{collections::HashMap, fmt::Write};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ctx::Ctx,
|
||||||
|
db::models::Post,
|
||||||
|
error::NekrochanError,
|
||||||
|
markup::markup,
|
||||||
|
qsform::QsForm,
|
||||||
|
web::{tcx::TemplateCtx, template_response},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{get_posts_from_ids, ActionTemplate};
|
||||||
|
|
||||||
|
#[post("/actions/edit-posts")]
|
||||||
|
pub async fn edit_posts(
|
||||||
|
ctx: Data<Ctx>,
|
||||||
|
req: HttpRequest,
|
||||||
|
QsForm(edits): QsForm<HashMap<String, String>>,
|
||||||
|
) -> Result<HttpResponse, NekrochanError> {
|
||||||
|
let tcx = TemplateCtx::new(&ctx, &req).await?;
|
||||||
|
|
||||||
|
if !(tcx.perms.owner() || tcx.perms.edit_posts()) {
|
||||||
|
return Err(NekrochanError::InsufficientPermissionError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let ids = edits.keys().map(|s| s.to_owned()).collect::<Vec<String>>();
|
||||||
|
|
||||||
|
let posts = get_posts_from_ids(&ctx, ids)
|
||||||
|
.await
|
||||||
|
.into_iter()
|
||||||
|
.map(|post| (format!("{}/{}", post.board, post.id), post))
|
||||||
|
.collect::<HashMap<String, Post>>();
|
||||||
|
|
||||||
|
let mut response = String::new();
|
||||||
|
let mut posts_edited = 0;
|
||||||
|
|
||||||
|
for (key, content_nomarkup) in edits {
|
||||||
|
let post = &posts[&key];
|
||||||
|
let content_nomarkup = content_nomarkup.trim();
|
||||||
|
let content = markup(&ctx, &post.board, post.thread, content_nomarkup).await?;
|
||||||
|
|
||||||
|
post.update_content(&ctx, content, content_nomarkup.into())
|
||||||
|
.await?;
|
||||||
|
posts_edited += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if posts_edited != 0 {
|
||||||
|
writeln!(&mut response, "[Úspěch] Upraveny příspěvky: {posts_edited}").ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
let template = ActionTemplate { tcx, response };
|
||||||
|
|
||||||
|
template_response(&template)
|
||||||
|
}
|
@ -3,8 +3,9 @@ use askama::Template;
|
|||||||
use super::tcx::TemplateCtx;
|
use super::tcx::TemplateCtx;
|
||||||
use crate::{ctx::Ctx, db::models::Post};
|
use crate::{ctx::Ctx, db::models::Post};
|
||||||
|
|
||||||
pub mod create_post;
|
|
||||||
pub mod appeal_ban;
|
pub mod appeal_ban;
|
||||||
|
pub mod create_post;
|
||||||
|
pub mod edit_posts;
|
||||||
pub mod report_posts;
|
pub mod report_posts;
|
||||||
pub mod staff_post_actions;
|
pub mod staff_post_actions;
|
||||||
pub mod user_post_actions;
|
pub mod user_post_actions;
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "board_catalog.html")]
|
#[template(path = "board-catalog.html")]
|
||||||
struct BoardCatalogTemplate {
|
struct BoardCatalogTemplate {
|
||||||
tcx: TemplateCtx,
|
tcx: TemplateCtx,
|
||||||
board: Board,
|
board: Board,
|
||||||
|
41
src/web/edit_posts.rs
Normální soubor
41
src/web/edit_posts.rs
Normální soubor
@ -0,0 +1,41 @@
|
|||||||
|
use actix_web::{post, web::Data, HttpRequest, HttpResponse};
|
||||||
|
use askama::Template;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ctx::Ctx,
|
||||||
|
db::models::Post,
|
||||||
|
error::NekrochanError,
|
||||||
|
qsform::QsForm,
|
||||||
|
web::{actions::get_posts_from_ids, template_response, TemplateCtx},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct EditPostsForm {
|
||||||
|
pub posts: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "edit-posts.html")]
|
||||||
|
struct EditPostsTemplate {
|
||||||
|
tcx: TemplateCtx,
|
||||||
|
posts: Vec<Post>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/edit-posts")]
|
||||||
|
pub async fn edit_posts(
|
||||||
|
ctx: Data<Ctx>,
|
||||||
|
req: HttpRequest,
|
||||||
|
QsForm(form): QsForm<EditPostsForm>,
|
||||||
|
) -> Result<HttpResponse, NekrochanError> {
|
||||||
|
let tcx = TemplateCtx::new(&ctx, &req).await?;
|
||||||
|
|
||||||
|
if !(tcx.perms.owner() || tcx.perms.edit_posts()) {
|
||||||
|
return Err(NekrochanError::InsufficientPermissionError);
|
||||||
|
}
|
||||||
|
|
||||||
|
let posts = get_posts_from_ids(&ctx, form.posts).await;
|
||||||
|
let template = EditPostsTemplate { tcx, posts };
|
||||||
|
|
||||||
|
template_response(&template)
|
||||||
|
}
|
@ -4,6 +4,7 @@ use askama::Template;
|
|||||||
pub mod actions;
|
pub mod actions;
|
||||||
pub mod board;
|
pub mod board;
|
||||||
pub mod board_catalog;
|
pub mod board_catalog;
|
||||||
|
pub mod edit_posts;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
pub mod login;
|
pub mod login;
|
||||||
pub mod logout;
|
pub mod logout;
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
#[template(path = "overboard_catalog.html")]
|
#[template(path = "overboard-catalog.html")]
|
||||||
struct OverboardCatalogTemplate {
|
struct OverboardCatalogTemplate {
|
||||||
tcx: TemplateCtx,
|
tcx: TemplateCtx,
|
||||||
threads: Vec<Post>,
|
threads: Vec<Post>,
|
||||||
|
@ -86,7 +86,7 @@ pub async fn update_board_config(
|
|||||||
antispam,
|
antispam,
|
||||||
antispam_ip,
|
antispam_ip,
|
||||||
antispam_content,
|
antispam_content,
|
||||||
antispam_both
|
antispam_both,
|
||||||
};
|
};
|
||||||
|
|
||||||
board.update_config(&ctx, config).await?;
|
board.update_config(&ctx, config).await?;
|
||||||
|
@ -51,13 +51,18 @@ summary {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edit-post {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.form-table input[type="text"],
|
.form-table input[type="text"],
|
||||||
.form-table input[type="password"],
|
.form-table input[type="password"],
|
||||||
.form-table input[type="number"],
|
.form-table input[type="number"],
|
||||||
.form-table textarea,
|
.form-table textarea,
|
||||||
.form-table select,
|
.form-table select,
|
||||||
.input-wrapper {
|
.input-wrapper,
|
||||||
/* FUCK IE7 */
|
.edit-post {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -76,7 +81,8 @@ summary {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-table textarea {
|
.form-table textarea,
|
||||||
|
.edit-post {
|
||||||
height: 8rem;
|
height: 8rem;
|
||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
20
templates/edit-posts.html
Normální soubor
20
templates/edit-posts.html
Normální soubor
@ -0,0 +1,20 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Upravit příspěvky{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<h1 class="title">Upravit příspěvky</h1>
|
||||||
|
<hr>
|
||||||
|
<form method="post" action="/actions/edit-posts">
|
||||||
|
{% for post in posts %}
|
||||||
|
<div class="box">
|
||||||
|
<b>Příspěvek #{{ post.id }} na /{{ post.board }}/</b>
|
||||||
|
<textarea class="edit-post" name="{{ post.board }}/{{ post.id }}">{{ post.content_nomarkup }}</textarea>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
{% endfor %}
|
||||||
|
<input class="button" type="submit" value="Upravit">
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
@ -39,9 +39,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if tcx.perms.owner() || tcx.perms.bans() %}
|
|
||||||
<input class="button" type="submit" value="Odstranit vybrané">
|
<input class="button" type="submit" value="Odstranit vybrané">
|
||||||
{% endif %}
|
|
||||||
</form>
|
</form>
|
||||||
<hr>
|
<hr>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
Načítá se…
Odkázat v novém úkolu
Zablokovat Uživatele