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)]
|
||||
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)]
|
||||
AccountNotFound(String),
|
||||
#[error("Příspěvek /{}/{} neexistuje.", .0, .1)]
|
||||
PostNotFound(String, i32),
|
||||
#[error("Tento ban už byl odvolán.")]
|
||||
AlreadyAppealedError,
|
||||
#[error("Žádný takový ban pro tuto IP adresu neexistuje.")]
|
||||
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)]
|
||||
BoardLockError(String),
|
||||
#[error("Toto vlákno je uzamčené.")]
|
||||
ThreadLockError,
|
||||
#[error("Nelze vytvořit odpověď na odpověď.")]
|
||||
ReplyReplyError,
|
||||
#[error("Vlákno dosáhlo limitu odpovědí.")]
|
||||
ReplyLimitError,
|
||||
#[error("Jméno nástěnky musí mít 1-32 znaků.")]
|
||||
BoardNameFormatError,
|
||||
#[error("Nástěnka /{}/ neexistuje.", .0)]
|
||||
BoardNotFound(String),
|
||||
#[error("Capcode nesmí mít více než 32 znaků.")]
|
||||
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.")]
|
||||
NoContentError,
|
||||
#[error("Příspěvek musí mít soubor.")]
|
||||
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.")]
|
||||
NoPostsError,
|
||||
#[error("Maximální počet souborů na této nástěnce je {}.", .0)]
|
||||
FileLimitError(usize),
|
||||
#[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("Pro přístup se musíš přihlásit.")]
|
||||
NotLoggedInError,
|
||||
#[error("Nadnástěnka nebyla inicializována.")]
|
||||
OverboardError,
|
||||
#[error("Server se připojil k 41 procentům.")]
|
||||
InternalError,
|
||||
#[error("Účet vlastníka nemůže být vymazán.")]
|
||||
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 {
|
||||
@ -201,46 +200,45 @@ impl From<tokio::task::JoinError> for NekrochanError {
|
||||
impl ResponseError for NekrochanError {
|
||||
fn status_code(&self) -> StatusCode {
|
||||
match self {
|
||||
NekrochanError::FileError(_, _)
|
||||
| NekrochanError::UsernameFormatError
|
||||
| NekrochanError::PasswordFormatError
|
||||
| NekrochanError::IdFormatError
|
||||
| NekrochanError::BoardNameFormatError
|
||||
| NekrochanError::DescriptionFormatError
|
||||
| NekrochanError::PostNameFormatError
|
||||
| NekrochanError::CapcodeFormatError
|
||||
| NekrochanError::EmailFormatError
|
||||
| NekrochanError::ContentFormatError
|
||||
| NekrochanError::ReplyReplyError
|
||||
| NekrochanError::NoContentError
|
||||
| NekrochanError::NoFileError
|
||||
| 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::AccountNotFound(_) => StatusCode::NOT_FOUND,
|
||||
NekrochanError::AlreadyAppealedError => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::BanNotFound => StatusCode::NOT_FOUND,
|
||||
NekrochanError::BoardLockError(_) => StatusCode::FORBIDDEN,
|
||||
NekrochanError::BoardNameFormatError => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::BoardNotFound(_) => StatusCode::NOT_FOUND,
|
||||
NekrochanError::CapcodeFormatError => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::ContentFormatError => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::DescriptionFormatError => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::EmailFormatError => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::EmptyPostError => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::FileError(_, _) => StatusCode::UNPROCESSABLE_ENTITY,
|
||||
NekrochanError::FileLimitError(_) => StatusCode::BAD_REQUEST,
|
||||
NekrochanError::FloodError => StatusCode::TOO_MANY_REQUESTS,
|
||||
NekrochanError::OverboardError | NekrochanError::InternalError => {
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
NekrochanError::HeaderError(_) => StatusCode::BAD_GATEWAY,
|
||||
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 || {
|
||||
App::new()
|
||||
.app_data(Data::new(ctx.clone()))
|
||||
.service(web::index::index)
|
||||
.service(web::board::board)
|
||||
.service(web::board_catalog::board_catalog)
|
||||
.service(web::overboard::overboard)
|
||||
.service(web::overboard_catalog::overboard_catalog)
|
||||
.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::index::index)
|
||||
.service(web::edit_posts::edit_posts)
|
||||
.service(web::login::login_get)
|
||||
.service(web::login::login_post)
|
||||
.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::accounts::accounts)
|
||||
.service(web::staff::boards::boards)
|
||||
.service(web::staff::bans::bans)
|
||||
.service(web::staff::reports::reports)
|
||||
.service(web::staff::permissions::permissions)
|
||||
.service(web::staff::banners::banners)
|
||||
.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::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::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::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_boards::update_boards)
|
||||
.service(web::staff::actions::update_permissions::update_permissions)
|
||||
.service(debug)
|
||||
.service(favicon)
|
||||
.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 crate::{ctx::Ctx, db::models::Post};
|
||||
|
||||
pub mod create_post;
|
||||
pub mod appeal_ban;
|
||||
pub mod create_post;
|
||||
pub mod edit_posts;
|
||||
pub mod report_posts;
|
||||
pub mod staff_post_actions;
|
||||
pub mod user_post_actions;
|
||||
|
@ -14,7 +14,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "board_catalog.html")]
|
||||
#[template(path = "board-catalog.html")]
|
||||
struct BoardCatalogTemplate {
|
||||
tcx: TemplateCtx,
|
||||
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 board;
|
||||
pub mod board_catalog;
|
||||
pub mod edit_posts;
|
||||
pub mod index;
|
||||
pub mod login;
|
||||
pub mod logout;
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "overboard_catalog.html")]
|
||||
#[template(path = "overboard-catalog.html")]
|
||||
struct OverboardCatalogTemplate {
|
||||
tcx: TemplateCtx,
|
||||
threads: Vec<Post>,
|
||||
|
@ -86,7 +86,7 @@ pub async fn update_board_config(
|
||||
antispam,
|
||||
antispam_ip,
|
||||
antispam_content,
|
||||
antispam_both
|
||||
antispam_both,
|
||||
};
|
||||
|
||||
board.update_config(&ctx, config).await?;
|
||||
|
@ -51,13 +51,18 @@ summary {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.edit-post {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-table input[type="text"],
|
||||
.form-table input[type="password"],
|
||||
.form-table input[type="number"],
|
||||
.form-table textarea,
|
||||
.form-table select,
|
||||
.input-wrapper {
|
||||
/* FUCK IE7 */
|
||||
.input-wrapper,
|
||||
.edit-post {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
@ -76,7 +81,8 @@ summary {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.form-table textarea {
|
||||
.form-table textarea,
|
||||
.edit-post {
|
||||
height: 8rem;
|
||||
resize: none;
|
||||
}
|
||||
@ -274,24 +280,24 @@ summary {
|
||||
}
|
||||
|
||||
.catalog {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.catalog-entry {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
height: 250px;
|
||||
overflow: scroll;
|
||||
margin: 4px;
|
||||
padding: 8px;
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
height: 250px;
|
||||
overflow: scroll;
|
||||
margin: 4px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.catalog-entry .thumb {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
max-height: 50%;
|
||||
max-width: 100%;
|
||||
max-height: 50%;
|
||||
box-shadow: 0 0 3px #000;
|
||||
margin: 4px auto;
|
||||
margin: 4px auto;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
|
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>
|
||||
</div>
|
||||
|
||||
{% if tcx.perms.owner() || tcx.perms.bans() %}
|
||||
<input class="button" type="submit" value="Odstranit vybrané">
|
||||
{% endif %}
|
||||
<input class="button" type="submit" value="Odstranit vybrané">
|
||||
</form>
|
||||
<hr>
|
||||
{% endblock %}
|
||||
|
Načítá se…
Odkázat v novém úkolu
Zablokovat Uživatele