Nekrocuck

This commit is contained in:
2025-09-28 12:59:09 +02:00
commit a2d093954d
402 changed files with 13763 additions and 0 deletions

21
templates/action.html Normal file
View File

@@ -0,0 +1,21 @@
{% extends "base.html" %}
{% block title %}Výsledek{% endblock %}
{% block content %}
<div class="container">
<h1 class="title">Výsledek</h1>
<table class="data-table">
<tr><th>Výsledek</th></tr>
<tr>
<td>
{% if !response.is_empty() %}
{{ response|linebreaksbr|safe }}
{% else %}
Nic se nezměnilo.
{% endif %}
</td>
</tr>
</table>
</div>
{% endblock %}

67
templates/banned.html Normal file
View File

@@ -0,0 +1,67 @@
{% extends "base.html" %}
{% block title %}Máš ban!{% endblock %}
{% block content %}
<div class="container">
<h1 class="title">Zabanován!!!</h1>
<table class="data-table">
<tr><th>Máš ban!</th></tr>
<tr>
<td>
<b>
Byl jsi zabanován&#32;
{% if let Some(board) = ban.board %}
z /{{ board }}/
{% else %}
ze všech nástěněk
{% endif %}
&#32;z následujícího důvodu:
</b>
<div class="post-content box">
{{ ban.reason }}
</div>
<span>Udělil <i>{{ ban.issued_by }}</i></span>
<br>
<br>
<span>
Tvůj ban platí pro IP adresu/rozsah <b>{{ ban.ip_range }}</b> a&#32;
{% if let Some(expires) = ban.expires %}
vyprší <time datetime="{{ expires }}">{{ expires|czech_datetime }}.</time>
{% else %}
je <b>trvalý.</b>
{% endif %}
</span>
{% if ban.appealable %}
<br>
<br>
{% if let Some(appeal) = ban.appeal %}
<b>Tvé odvolání:</b>
<div class="post-content">
{{ appeal }}
</div>
{% else %}
<b>Můžeš se pokusit svůj ban odvolat:</b>
<form method="post" action="/actions/appeal-ban">
<input name="id" type="hidden" value="{{ ban.id }}">
<table class="form-table">
<tr>
<td class="label">Odvolání</td>
<td><textarea name="appeal"></textarea></td>
</tr>
<tr>
<td colspan="2">
<input class="button" type="submit" value="Odeslat">
</td>
</tr>
</table>
</form>
{% endif %}
{% endif %}
</td>
</tr>
</table>
</div>
{% endblock %}

63
templates/base.html Normal file
View File

@@ -0,0 +1,63 @@
{% import "./macros/board-links.html" as board_links %}
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}</title>
<meta name="description" content="{{ tcx.cfg.site.description }}">
<link rel="stylesheet" href="/static/themes/{% block theme %}{{ tcx.cfg.site.theme }}{% endblock %}">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div id="top"></div>
<div class="board-links header">
<span class="link-group"><a href="/">domov</a></span>
{% call board_links::board_links() %}
<span class="link-group">
<a href="/overboard">nadnástěnka</a>
<span class="link-separator"></span>
<a href="/news">novinky</a>
</span>
{% for group in tcx.cfg.site.links %}
<span class="link-group">
{% for (link, href) in group %}
<a href="{{ href }}">{{ link }}</a>
{% if !loop.last %}
<span class="link-separator"></span>
{% endif %}
{% endfor %}
</span>
{% endfor %}
<span class="float-r">
{% if let Some(report_count) = tcx.report_count %}
<span class="link-group"><a href="/staff/reports">Hlášení: {{ report_count }}</a></span>
{% endif %}
{% if tcx.account.is_some() %}
<span class="link-group">
<a href="/logout">odhlásit se</a>
<span class="link-separator"></span>
<a href="/staff/account">účet</a>
</span>
{% else %}
<span class="link-group"><a href="/login">přihlásit se</a></span>
{% endif %}
</span>
</div>
<div class="main">
{% block content %}{% endblock %}
<div class="footer">
<div class="box inline-block">Všechny příspěvky na této stránce byly vytvořeny náhodnými uživateli.</div>
</div>
</div>
<div id="bottom"></div>
<script src="/static/js/jquery.min.js" defer=""></script>
<script src="/static/js/autofill.js" defer=""></script>
<script src="/static/js/expand.js" defer=""></script>
<script src="/static/js/hover.js" defer=""></script>
<script src="/static/js/quote.js" defer=""></script>
<script src="/static/js/time.js" defer=""></script>
{% block scripts %}{% endblock %}
</body>
</html>

View File

@@ -0,0 +1,42 @@
{% import "./macros/catalog-entry.html" as catalog_entry %}
{% import "./macros/post-actions.html" as post_actions %}
{% extends "base.html" %}
{% block theme %}{{ board.config.0.board_theme }}{% endblock %}
{% block title %}Katalog (/{{ board.id }}/){% endblock %}
{% block content %}
<div class="container">
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">Katalog (<a href="/boards/{{ board.id }}">/{{ board.id }}/</a>)</h1>
<p class="description">{{ board.description }}</p>
<a href="/boards/{{ board.id }}">Index</a>
</div>
</div>
<hr>
<form method="get" action="/search">
<input name="board" type="hidden" value="{{ board.id }}">
<table class="form-table">
<tr>
<td>
<input name="query" type="text">
</td>
<td>
<input class="button" type="submit" value="Hledat">
</td>
</tr>
</table>
</form>
<hr>
<form method="post">
<div class="center">
{% for thread in threads %}
{% call catalog_entry::catalog_entry(thread, loop.index, board.config.0.page_size.into()) %}
{% endfor %}
</div>
<hr>
{% call post_actions::post_actions() %}
</form>
{% endblock %}

58
templates/board.html Normal file
View File

@@ -0,0 +1,58 @@
{% import "./macros/pagination.html" as pagination %}
{% import "./macros/post-actions.html" as post_actions %}
{% import "./macros/post-form.html" as post_form %}
{% import "./macros/post.html" as post %}
{% extends "base.html" %}
{% block theme %}{{ board.config.0.board_theme }}{% endblock %}
{% block title %}/{{ board.id }}/ - {{ board.name }}{% endblock %}
{% block scripts %}
<script src="/static/js/captcha.js" defer=""></script>
<script src="/static/js/post-form.js" defer=""></script>
{% endblock %}
{% block content %}
<div class="container">
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">/{{ board.id }}/ - {{ board.name }}</h1>
<p class="description">{{ board.description }}</p>
<a href="/boards/{{ board.id }}/catalog">Katalog</a>
<br>
<br>
<a class="box inline-block open-post-form" href="#post-form">[Nové vlákno]</a>
<br>
<br>
</div>
{% call post_form::post_form(board, false, 0) %}
</div>
<hr>
<form method="post">
{% for (thread, replies) in threads %}
<div class="thread">
{% call post::post(board, thread, false) %}
{% let count = replies.len() %}
{% if count > 5 %}
<p class="posts-omitted">
{% let omitted = count - 5 %}
{{ "Vynechán|Vynechány|Vynecháno"|czech_plural(omitted) }} {{ omitted }} {{ "příspěvek|příspěvky|příspěvků"|czech_plural(omitted) }}. <a href="{{ thread.post_url_notarget() }}">Zobrazit celé vlákno.</a>
</p>
{% for reply_post in replies.iter().rev().take(5).rev() %}
{% call post::post(board, reply_post, true) %}
<br>
{% endfor %}
{% else %}
{% for reply_post in replies %}
{% call post::post(board, reply_post, true) %}
<br>
{% endfor %}
{% endif %}
</div>
<hr>
{% endfor %}
{% call pagination::pagination("/boards/{}"|format(board.id), pages, page) %}
<hr>
{% call post_actions::post_actions(tcx.perms) %}
</form>
{% endblock %}

20
templates/edit-posts.html Normal file
View File

@@ -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-box" name="{{ post.board }}/{{ post.id }}">{{ post.content_nomarkup }}</textarea>
</div>
<hr>
{% endfor %}
<input class="button full-width" type="submit" value="Upravit">
</form>
</div>
{% endblock %}

31
templates/error.html Normal file
View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="cs">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chyba</title>
{# Error pages are yotsuba (they just are, okay?) #}
{# Go ahead and edit this manually if you actually care #}
<link rel="stylesheet" href="/static/themes/yotsuba.css">
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div id="top"></div>
<div class="main">
<div class="container">
<h1 class="title">Je konec...</h1>
<table class="data-table center">
<tr><th>Chyba {{ error_code }}</th></tr>
{% if !error_message.is_empty() %}
<tr><td>{{ error_message }}</td></tr>
{% endif %}
</table>
</div>
<div class="footer">
<div class="box inline-block">Všechny příspěvky na této stránce byly vytvořeny náhodnými uživateli.</div>
</div>
</div>
<div id="bottom"></div>
</body>
</html>

65
templates/index.html Normal file
View File

@@ -0,0 +1,65 @@
{% import "./macros/board-links.html" as board_links %}
{% extends "base.html" %}
{% block title %}{{ tcx.cfg.site.name }}{% endblock %}
{% block content %}
<div class="container">
<div class="center">
<h1 class="title">{{ tcx.cfg.site.name }}</h1>
<p class="description">{{ tcx.cfg.site.description }}</p>
<p class="board-links big">{% call board_links::board_links() %}</p>
</div>
{% if let Some(news) = news %}
<table class="data-table">
<tr>
<th>Novinky</th>
</tr>
<tr>
<td>
<div class="box">
<h2 class="headline">
<span>{{ news.title }}</span>
<span class="float-r">
{{ news.author }} - <time datetime="{{ news.created }}">{{ news.created|czech_datetime }}</time>
</span>
</h2>
<hr>
<div class="post-content">{{ news.content|safe }}</div>
</div>
</td>
</tr>
<tr>
<td>
<a href="/news">Zobrazit všechny novinky...</a>
</td>
</tr>
</table>
{% endif %}
<table class="data-table fixed-table center">
<tr>
<th>Nástěnky</th>
<th>Statistika</th>
</tr>
<tr>
<td>
<ul class="board-list">
{% for board in boards %}
<li><a href="/boards/{{ board.id }}">/{{ board.id }}/ - {{ board.name }}</a></li>
{% endfor %}
</ul>
</td>
<td>
{% let board_count = tcx.boards.len() %}
Celkem {{ "byl vytvořen|byly vytvořeny|bylo vytvořeno"|czech_plural(stats.post_count) }}&#32;
<b>{{ stats.post_count }}</b> {{ "příspěvek|příspěvky|příspěvků"|czech_plural(stats.post_count) }}&#32;
na <b>{{ board_count }}</b> {{ "nástěnce|nástěnkách|nástěnkách"|czech_plural(board_count) }}.
<br>
Aktuálně {{ "je nahrán|jsou nahrány|je nahráno"|czech_plural(stats.file_count) }} <b>{{ stats.file_count }}</b>&#32;
{{ "soubor|soubory|souborů"|czech_plural(stats.file_count) }}, celkem <b>{{ stats.file_size|filesizeformat }}</b>.
</td>
</tr>
</table>
</div>
{% endblock %}

29
templates/ip-posts.html Normal file
View File

@@ -0,0 +1,29 @@
{% import "./macros/post-actions.html" as post_actions %}
{% import "./macros/post.html" as post %}
{% import "./macros/static-pagination.html" as static_pagination %}
{% extends "base.html" %}
{% block title %}Příspěvky od [{{ ip }}]{% endblock %}
{% block content %}
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">Příspěvky od [{{ ip }}]</h1>
</div>
<hr>
<form method="post">
<div class="thread">
{% for post in posts %}
<b>Příspěvek z <a href="/boards/{{ post.board }}">/{{ post.board }}/</a></b>
<br>
{% call post::post(boards[post.board.as_str()], post, true) %}
<br>
{% endfor %}
</div>
<hr>
{% call static_pagination::static_pagination("/ip-posts/{}"|format(ip), page, false) %}
<hr>
{% call post_actions::post_actions() %}
</form>
{% endblock %}

24
templates/login.html Normal file
View File

@@ -0,0 +1,24 @@
{% extends "base.html" %}
{% block title %}Přihlásit se{% endblock %}
{% block content %}
<div class="container">
<h1 class="title">Přihlásit se</h1>
<form method="post" action="/login">
<table class="form-table">
<tr>
<td class="label">Jméno</td>
<td><input name="username" type="text" required=""></td>
</tr>
<tr>
<td class="label">Heslo</td>
<td><input name="password" type="password" required=""></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Přihlásit se"></td>
</tr>
</table>
</form>
</div>
{% endblock %}

View File

@@ -0,0 +1,8 @@
{% macro board_links() %}
<span class="link-group">
{% for board_link in tcx.boards %}
<a href="/boards/{{ board_link }}">{{ board_link }}</a>
{% if !loop.last %}<span class="link-separator"></span>{% endif %}
{% endfor %}
</span>
{% endmacro %}

View File

@@ -0,0 +1,23 @@
{% macro catalog_entry(post, index, page_size) %}
<div class="box catalog-entry">
<input name="posts[]" type="checkbox" value="{{ post.board }}/{{ post.id }}">&#32;
<b>/{{ post.board }}/{{ post.id }}</b>
{% if let Some(file) = post.files.0.get(0) %}
<a href="{{ post.post_url_notarget() }}">
<img class="thumb" src="{{ file.thumb_url() }}">
</a>
{% else %}
<p><b><a href="{{ post.post_url_notarget() }}">[Link]</a></b></p>
{% endif %}
<b>
<span>R: {{ post.replies }} / P: {{ index|get_page(page_size) }}</span>&#32;
{% if post.sticky %}
<img class="icon" src="/static/icons/sticky.png">&#32;
{% endif %}
{% if post.locked %}
<img class="icon" src="/static/icons/locked.png">&#32;
{% endif %}
</b>
<div class="post-content">{{ post.content|add_yous(post.board, tcx.yous)|safe }}</div>
</div>
{% endmacro %}

View File

@@ -0,0 +1,25 @@
{% macro pagination(base, pages, current) %}
<div class="pagination box inline-block">
{% if current == 1 %}
[Předchozí]
{% else %}
[<a href="{{ base }}?page={{ current - 1 }}">Předchozí</a>]
{% endif %}
&#32;
{% for page in 1..(pages + 1) %}
{% if page == current %}
[<b><a href="{{ base }}?page={{ page }}">{{ page }}</a></b>]
{% else %}
[<a href="{{ base }}?page={{ page }}">{{ page }}</a>]
{% endif %}
&#32;
{% endfor %}
{% if current == pages %}
[Další]
{% else %}
[<a href="{{ base }}?page={{ current + 1 }}">Další</a>]
{% endif %}
</div>
{% endmacro %}

View File

@@ -0,0 +1,224 @@
{% macro post_actions() %}
<details>
<summary class="box">Uživatelské akce</summary>
<table class="form-table">
<tr>
<td class="label">Odstranit příspěvky</td>
<td>
<div class="input-wrapper">
<input name="remove_posts" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Odstranit soubory</td>
<td>
<div class="input-wrapper">
<input name="remove_files" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Přidat/odstranit spoiler</td>
<td>
<div class="input-wrapper">
<input name="toggle_spoiler" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Heslo</td>
<td><input name="post_password" type="password"></td>
</tr>
<tr>
<td colspan="2">
<input
class="button"
type="submit"
formaction="/actions/user-post-actions"
value="Odeslat"
>
</td>
</tr>
</table>
<table class="form-table">
<tr>
<td class="label">Důvod hlášení</td>
<td><input name="report_reason" type="text"></td>
</tr>
<tr>
<td colspan="2">
<input
class="button"
type="submit"
formaction="/actions/report-posts"
value="Nahlásit"
>
</td>
</tr>
</table>
</details>
<br>
{% if tcx.perms.owner() || tcx.perms.edit_posts() || tcx.perms.manage_posts() || tcx.perms.reports() || tcx.perms.bans() %}
<details>
<summary class="box">Uklízečské akce</summary>
<table class="form-table">
{% if tcx.perms.owner() || tcx.perms.manage_posts() %}
<tr>
<td class="label">Odstranit příspěvky</td>
<td>
<div class="input-wrapper">
<input name="staff_remove_posts" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Odstranit soubory</td>
<td>
<div class="input-wrapper">
<input name="staff_remove_files" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Přidat/odstranit spoiler</td>
<td>
<div class="input-wrapper">
<input name="staff_toggle_spoiler" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Odstranit od IP na nástěnce</td>
<td>
<div class="input-wrapper">
<input name="remove_by_ip_board" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Odstranit od IP globálně</td>
<td>
<div class="input-wrapper">
<input name="remove_by_ip_global" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Připnout/odepnout</td>
<td>
<div class="input-wrapper">
<input name="toggle_sticky" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Uzamknout/odemknout</td>
<td>
<div class="input-wrapper">
<input name="toggle_lock" type="checkbox">
</div>
</td>
</tr>
{% endif %}
{% if tcx.perms.owner() || tcx.perms.reports() %}
<tr>
<td class="label">Odstranit hlášení</td>
<td>
<div class="input-wrapper">
<input name="remove_reports" type="checkbox">
</div>
</td>
</tr>
{% endif %}
{% if tcx.perms.owner() || tcx.perms.bans() %}
<tr>
<td class="label">Zabanovat uživatele</td>
<td>
<div class="input-wrapper">
<input name="ban_user" type="checkbox">
</div>
</td>
</tr>
{% if tcx.perms.owner() || tcx.perms.reports() %}
<tr>
<td class="label">Zabanovat nahlašovatele</td>
<td>
<div class="input-wrapper">
<input name="ban_reporters" type="checkbox">
</div>
</td>
</tr>
{% endif %}
<tr>
<td class="label">Globální ban</td>
<td>
<div class="input-wrapper">
<input name="global_ban" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Neodvolatelný ban</td>
<td>
<div class="input-wrapper">
<input name="unappealable_ban" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Důvod banu</td>
<td><textarea name="ban_reason"></textarea></td>
</tr>
<tr>
<td class="label">Délka banu <span class="small">(dny, 0 = trvalý)</span></td>
<td><input name="ban_duration" type="number" min="0" value="0"></td>
</tr>
<tr>
<td class="label">Rozsah banu</td>
<td>
<select name="ban_range">
<option value="ip" selected="selected">IP adresa</option>
<option value="lan">LAN</option>
<option value="isp">ISP</option>
</select>
</td>
</tr>
{% endif %}
{% if tcx.perms.owner() || (tcx.perms.edit_posts() && tcx.perms.view_ips()) %}
<td class="label">Vytrolit uživatele</td>
<td>
<div class="input-wrapper">
<input name="troll_user" type="checkbox">
</div>
</td>
{% endif %}
<tr>
<td colspan="2">
<input
class="button"
type="submit"
formaction="/actions/staff-post-actions"
value="Odeslat"
>
</td>
</tr>
</table>
{% if tcx.perms.owner() || tcx.perms.edit_posts() %}
<table class="form-table">
<tr>
<td>
<input
class="button"
type="submit"
formaction="/edit-posts"
value="Upravit příspěvky"
>
</td>
</tr>
</table>
{% endif %}
</details>
{% endif %}
{% endmacro %}

View File

@@ -0,0 +1,105 @@
{% macro post_form(board, reply, reply_to) %}
<form id="post-form" method="post" enctype="multipart/form-data" action="/actions/create-post" autocomplete="off" data-visible="false">
<input name="board" type="hidden" value="{{ board.id }}">
{% if reply %}
<input name="thread" type="hidden" value="{{ reply_to }}">
{% endif %}
<table class="form-table">
<tr>
<td id="post-form-handle" class="label center" colspan="2">
{% if reply %}
Nová odpověď
{% else %}
Nové vlákno
{% endif %}
<a class="close-post-form float-r" href="#">[X]</a>
</td>
</tr>
<tr>
<td class="label">Jméno</td>
<td>
<input name="post_name" type="text" placeholder="{{ board.config.0.anon_name }}">
</td>
</tr>
<tr>
<td class="label">Email</td>
<td>
<input name="email" type="text">
</td>
</tr>
<tr>
<td class="label">Obsah</td>
<td>
<textarea id="content" name="content" {% if (!reply && board.config.0.require_thread_content) || (reply && board.config.0.require_reply_content) %}required=""{% endif %}></textarea>
</td>
</tr>
{% if !(tcx.perms.bypass_captcha() || tcx.perms.owner()) %}
{% let difficulty %}
{% if reply %}
{% let difficulty = board.config.0.reply_captcha.as_str() %}
{% else %}
{% let difficulty = board.config.0.thread_captcha.as_str() %}
{% endif %}
{% if (!reply && board.config.0.thread_captcha != "off") || (reply && board.config.0.reply_captcha != "off") %}
<tr>
<td class="label">
CAPTCHA<br>
<span class="small">(vyprší za 10 min.)</span>
<noscript><span class="small">(VYŽADUJE JAVASCRIPT)</span></noscript>
</td>
<td>
<div class="input-wrapper">
<table class="full-width">
<input id="captcha-id" name="captcha_id" type="hidden">
<tr>
<td>
<button id="get-captcha" type="button" class="button" data-board="{{ board.id }}" data-reply="{{ reply }}">Získat CAPTCHA</button>
</td>
<td>
<input name="captcha_solution" type="text" placeholder="Řešení" value="" required="">
</tr>
</tr>
<tr><td colspan="2"><div id="captcha"></div></tr>
</table>
</div>
</td>
</tr>
{% endif %}
{% endif %}
<tr>
<td class="label">
{% if board.config.0.file_limit > 1 %}
Soubory <span class="small">(max {{ board.config.0.file_limit }})</span>
{% else %}
Soubor
{% endif %}
</td>
<td>
<div class="input-wrapper">
<input name="files[]" type="file"{% if board.config.0.file_limit > 1 %} multiple="multiple"{% endif %}{% if (!reply && board.config.0.require_thread_file) || (reply && board.config.0.require_reply_file) %} required=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Spoiler?</td>
<td>
<div class="input-wrapper">
<input class="full-width" name="spoiler_files" type="checkbox">
</div>
</td>
</tr>
<tr>
<td class="label">Heslo</td>
<td><input name="post_password" type="password" required=""></td>
</tr>
<tr>
{% if reply %}
<td colspan="2"><input class="button" type="submit" value="Nová odpověď"></td>
{% else %}
<td colspan="2"><input class="button" type="submit" value="Nové vlákno"></td>
{% endif %}
</tr>
</table>
</form>
{% endmacro %}

View File

@@ -0,0 +1,82 @@
{% macro post(board, post, boxed) %}
<div id="{{ post.id }}" class="post{% if boxed %} box{% endif %}" data-board="{{ board.id }}">
<div class="post-header">
<input name="posts[]" type="checkbox" value="{{ post.board }}/{{ post.id }}">&#32;
{% if tcx.perms.owner() || tcx.perms.view_ips() %}
<b><a title="Více příspěvků od uživatele [{{ post.ip }}]" href="/ip-posts/{{ post.ip }}">[+]</a></b>&#32;
{% endif %}
{% if let Some(email) = post.email %}
<a class="name" rel="nofollow" href="mailto:{{ email }}">{{ post.name }}</a>&#32;
{% else %}
<span class="name">{{ post.name }}</span>&#32;
{% endif %}
{% if let Some(tripcode) = post.tripcode %}
<span class="tripcode">{{ tripcode }}</span>&#32;
{% endif %}
{% if let Some(capcode) = post.capcode %}
<span title="Tento uživatel to dělá ZDARMA!" class="capcode">## {{ capcode }} <img class="icon" src="/favicon.ico"></span>&#32;
{% endif %}
{% if tcx.ip == post.ip %}
{# Technically not a tripcode or something but same styling #}
<i class="tripcode">(Ty)</i>&#32;
{% endif %}
{% if board.config.0.flags %}
<img title="Země: {{ post.country }}" class="icon" src="/static/flags/{{ post.country }}.png">&#32;
{% endif %}
{% if board.config.0.flags_reg %}
{% if let Some(region) = post.region %}
<img title="Region: {{ region }}" class="icon" src="/static/flags/reg/{{ region }}.png">&#32;
{% endif %}
{% endif %}
<time datetime="{{ post.created }}">{{ post.created|czech_datetime }}</time>&#32;
{% if board.config.0.user_ids %}
<span class="user-id" style="background-color: #{{ post.user_id }};">{{ post.user_id }}</span>&#32;
{% endif %}
<span class="post-number">
<a href="{{ post.post_url() }}">Č.</a>
<a class="quote-link" href="{{ post.thread_url() }}#post-form" data-thread-url="{{ post.thread_url() }}">{{ post.id }}</a>&#32;
</span>
{% if post.sticky %}
<img title="Připnuto" class="icon" src="/static/icons/sticky.png">&#32;
{% endif %}
{% if post.locked %}
<img title="Uzamčeno" class="icon" src="/static/icons/locked.png">&#32;
{% endif %}
{% if !boxed %}
<a href="{{ post.post_url_notarget() }}">[Otevřít]</a>&#32;
{% endif %}
</div>
{% if !post.files.0.is_empty() %}
<div class="post-files{% if post.files.0.len() > 1 %} float-none-a{% endif %}">
{% for file in post.files.0 %}
<div class="post-file">
<a title="Stáhnout {{ file.original_name }}" download="{{ file.original_name }}" href="{{ file.file_url() }}">
{% if file.spoiler %}
[Spoiler]
{% else %}
{{ file.original_name|truncate(20) }}
{% endif %}
</a>
<br>
({{ file.size|filesizeformat }}, {{ file.width }}x{{ file.height }})
<br>
<a class="expandable" target="_blank" href="{{ file.file_url() }}">
<img class="thumb" src="{{ file.thumb_url() }}">
</a>
</div>
{% endfor %}
</div>
{% endif %}
<div class="post-content">{{ post.content|add_yous(post.board, tcx.yous)|safe }}</div>
<div class="clearfix"></div>
{% if !post.quotes.is_empty() %}
<div class="small">
Odpovědi:&#32;
{% for quote in post.quotes %}
<a class="quote" href="{{ post.thread_url() }}#{{ quote }}">&gt;&gt;{{ quote }}</a>&#32;
{% endfor %}
</div>
{% endif %}
</div>
{% endmacro %}

View File

@@ -0,0 +1,26 @@
{% macro staff_nav() %}
<div class="pagination box inline-block">
[<a href="/staff/account">Účet</a>]&#32;
[<a href="/staff/accounts">Účty</a>]&#32;
{% if tcx.perms.owner() || tcx.perms.board_config() || tcx.perms.banners() %}
[<a href="/staff/boards">Nástěnky</a>]&#32;
{% endif %}
{% if tcx.perms.owner() || tcx.perms.bans() %}
[<a href="/staff/bans">Bany</a>]&#32;
{% endif %}
{% if tcx.perms.owner() || tcx.perms.banners() %}
[<a href="/staff/banners">Bannery</a>]&#32;
{% endif %}
{% if tcx.perms.owner() || tcx.perms.reports() %}
[<a href="/staff/reports">Hlášení</a>]&#32;
{% endif %}
{% if tcx.perms.owner() || tcx.perms.news() %}
[<a href="/staff/news">Novinky</a>]&#32;
{% endif %}
</div>
{% endmacro %}

View File

@@ -0,0 +1,22 @@
{% macro static_pagination(base, current, chain) %}
<div class="pagination box inline-block">
{% if current == 1 %}
[Předchozí]
{% else %}
{% if chain %}
[<a href="{{ base }}&page={{ current - 1 }}">Předchozí</a>]
{% else %}
[<a href="{{ base }}?page={{ current - 1 }}">Předchozí</a>]
{% endif %}
{% endif %}
&#32;
{% if chain %}
[<b><a href="{{ base }}&page={{ current }}">{{ current }}</a></b>]&#32;
[<a href="{{ base }}&page={{ current + 1 }}">Další</a>]
{% else %}
[<b><a href="{{ base }}?page={{ current }}">{{ current }}</a></b>]&#32;
[<a href="{{ base }}?page={{ current + 1 }}">Další</a>]
{% endif %}
</div>
{% endmacro %}

24
templates/news.html Normal file
View File

@@ -0,0 +1,24 @@
{% extends "base.html" %}
{% block title %}Novinky{% endblock %}
{% block content %}
<div class="container">
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">Novinky</h1>
</div>
{% for newspost in news %}
<div class="news box">
<h2 class="headline">
<span>{{ newspost.title }}</span>
<span class="float-r">
{{ newspost.author }} - <time datetime="{{ newspost.created }}">{{ newspost.created|czech_datetime }}</time>
</span>
</h2>
<hr>
<div class="post-content">{{ newspost.content|safe }}</div>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -0,0 +1,40 @@
{% import "./macros/catalog-entry.html" as catalog_entry %}
{% import "./macros/post-actions.html" as post_actions %}
{% extends "base.html" %}
{% block title %}Katalog nadnástěnky{% endblock %}
{% block content %}
<div class="container">
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">Katalog nadnástěnky</h1>
<p class="description">Nově naťuknutá vlákna ze všech nástěnek</p>
<a href="/overboard">Index</a>
</div>
</div>
<hr>
<form method="get" action="/search">
<table class="form-table">
<tr>
<td>
<input name="query" type="text">
</td>
<td>
<input class="button" type="submit" value="Hledat">
</td>
</tr>
</table>
</form>
<hr>
<form method="post">
<div class="center">
{% for thread in threads %}
{% call catalog_entry::catalog_entry(thread, loop.index, crate::GENERIC_PAGE_SIZE) %}
{% endfor %}
</div>
<hr>
{% call post_actions::post_actions() %}
</form>
{% endblock %}

47
templates/overboard.html Normal file
View File

@@ -0,0 +1,47 @@
{% import "./macros/pagination.html" as pagination %}
{% import "./macros/post-actions.html" as post_actions %}
{% import "./macros/post.html" as post %}
{% extends "base.html" %}
{% block title %}Index nadnástěnky{% endblock %}
{% block content %}
<div class="container">
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">Index nadnástěnky</h1>
<p class="description">Nově naťuknutá vlákna ze všech nástěnek</p>
<a href="/overboard/catalog">Katalog</a>
</div>
</div>
<hr>
<form method="post">
{% for (thread, replies) in threads %}
<div class="thread">
<b>Vlákno z <a href="/boards/{{ thread.board }}">/{{ thread.board }}/</a></b>
{% call post::post(boards[thread.board.as_str()], thread, false) %}
{% let count = replies.len() %}
{% if count > 5 %}
<p class="posts-omitted">
{% let omitted = count - 5 %}
{{ "Vynechán|Vynechány|Vynecháno"|czech_plural(omitted) }} {{ omitted }} {{ "příspěvek|příspěvky|příspěvků"|czech_plural(omitted) }}. <a href="{{ thread.post_url_notarget() }}">Zobrazit celé vlákno.</a>
</p>
{% for reply_post in replies.iter().rev().take(5).rev() %}
{% call post::post(boards[reply_post.board.as_str()], reply_post, true) %}
<br>
{% endfor %}
{% else %}
{% for reply_post in replies %}
{% call post::post(boards[reply_post.board.as_str()], reply_post, true) %}
<br>
{% endfor %}
{% endif %}
</div>
<hr>
{% endfor %}
{% call pagination::pagination("/overboard", pages, page) %}
<hr>
{% call post_actions::post_actions() %}
</form>
{% endblock %}

3
templates/page.html Normal file
View File

@@ -0,0 +1,3 @@
{% extends "base.html" %}
{% block title %}{{ tcx.cfg.site.name }} ({{ name }}){% endblock %}
{% block content %}{{ content|safe }}{% endblock %}

47
templates/search.html Normal file
View File

@@ -0,0 +1,47 @@
{% import "./macros/post-actions.html" as post_actions %}
{% import "./macros/post.html" as post %}
{% import "./macros/static-pagination.html" as static_pagination %}
{% extends "base.html" %}
{% block title %}
Vyhledávání ({% if let Some(board) = board_opt %}/{{ board.id }}/{% else %}nadnástěnka{% endif %})
{% endblock %}
{% block content %}
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">
Výsledky pro "{{ query }}" (
{% if let Some(board) = board_opt %}
<a href="/boards/{{ board.id }}">/{{ board.id }}/</a>
{% else %}
nadnástěnka
{% endif %}
)
</h1>
</div>
<hr>
<form method="post">
<div class="thread">
{% for post in posts %}
{% if let Some(board) = board_opt %}
{% call post::post(board, post, true) %}
{% else %}
<b>Příspěvek z <a href="/boards/{{ post.board }}">/{{ post.board }}/</a></b>
<br>
{% call post::post(boards[post.board.as_str()], post, true) %}
{% endif %}
<br>
{% endfor %}
</div>
<hr>
{% if let Some(board) = board_opt %}
{% call static_pagination::static_pagination("/search?board={}&query={}"|format(board.id, query|urlencode_strict), page, true) %}
{% else %}
{% call static_pagination::static_pagination("/search?query={}"|format(query|urlencode_strict), page, true) %}
{% endif %}
<hr>
{% call post_actions::post_actions() %}
</form>
{% endblock %}

View File

@@ -0,0 +1,67 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Účet ({{ account.username }}){% endblock %}
{% block content %}
<h1 class="title">Účet ({{ account.username }})</h1>
{% call staff_nav::staff_nav() %}
<hr>
<h2>Změnit heslo</h2>
<form method="post" action="/staff/actions/change-password">
<table class="form-table">
<tr>
<td class="label">Staré heslo</td>
<td><input name="old_password" type="password" required=""></td>
</tr>
<tr>
<td class="label">Nové heslo</td>
<td><input name="new_password" type="password" required=""></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Změnit heslo"></td>
</tr>
</table>
</form>
<hr>
{% if tcx.perms.owner() %}
<h2>Předat vlastnictví</h2>
<form method="post" action="/staff/actions/transfer-ownership">
<table class="form-table">
<tr>
<td class="label">Účet</td>
<td><input name="account" type="text" required=""></td>
</tr>
<tr>
<td class="label">Potvrdit</td>
<td>
<div class="input-wrapper">
<input name="confirm" type="checkbox" required="">
</div>
</td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Předat vlastnictví"></td>
</tr>
</table>
</form>
<hr>
{% endif %}
<h2>Vymazat účet</h2>
<form method="post" action="/staff/actions/delete-account">
<table class="form-table">
<tr>
<td class="label">Potvrdit</td>
<td>
<div class="input-wrapper">
<input name="confirm" type="checkbox" required="">
</div>
</td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Vymazat účet"></td>
</tr>
</table>
</form>
{% endblock %}

View File

@@ -0,0 +1,56 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Účty{% endblock %}
{% block content %}
<h1 class="title">Účty</h1>
{% call staff_nav::staff_nav() %}
<hr>
<h2>Účty</h2>
<form method="post" action="/staff/actions/remove-accounts">
<div class="table-wrap">
<table class="data-table center">
<tr>
<th></th>
<th>Jméno</th>
<th>Vlastník</th>
<th>Vytvořen</th>
<th>Oprávnění</th>
</tr>
{% for account in accounts %}
<tr>
<td><input name="accounts[]" type="checkbox" value="{{ account.username }}" {% if !tcx.perms.owner() %}disabled=""{% endif %}></td>
<td>{{ account.username }}</td>
<td>{% if account.owner %}Ano{% else %}Ne{% endif %}</td>
<td><time datetime="{{ account.created }}">{{ account.created|czech_datetime }}</time></td>
<td>{{ account.permissions.0 }} <a href="/staff/permissions/{{ account.username }}">[Zobrazit]</a></td>
</tr>
{% endfor %}
</table>
</div>
{% if tcx.perms.owner() %}
<input class="button" type="submit" value="Odstranit vybrané">
{% endif %}
</form>
{% if tcx.perms.owner() %}
<hr>
<h2>Vytvořit účet</h2>
<form method="post" action="/staff/actions/create-account">
<table class="form-table">
<tr>
<td class="label">Jméno</td>
<td><input name="username" type="text" required=""></td>
</tr>
<tr>
<td class="label">Heslo</td>
<td><input name="account_password" type="password" required=""></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Vytvořit účet"></td>
</tr>
</table>
</form>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,45 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Bannery{% endblock %}
{% block content %}
<h1 class="title">Bannery</h1>
{% call staff_nav::staff_nav() %}
<hr>
<h2>Bannery</h2>
<form method="post" action="/staff/actions/remove-banners">
<div class="table-wrap">
<table class="data-table center">
<tr>
<th></th>
<th>Banner</th>
</tr>
{% for banner in banners %}
<tr>
<td><input name="banners[]" type="checkbox" value="{{ banner.id }}"></td>
<td>
<img class="banner" src="{{ banner.banner.file_url() }}">
</td>
</tr>
{% endfor %}
</table>
</div>
<input class="button" type="submit" value="Odstranit vybrané">
</form>
<hr>
<h2>Přidat bannery</h2>
<form method="post" enctype="multipart/form-data" action="/staff/actions/add-banners">
<table class="form-table">
<tr>
<td class="label">Bannery</td>
<td><div class="input-wrapper"><input name="files[]" type="file" multiple="multiple" required=""></div></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Přidat bannery"></td>
</tr>
</table>
</form>
{% endblock %}

54
templates/staff/bans.html Normal file
View File

@@ -0,0 +1,54 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Bany{% endblock %}
{% block content %}
<h1 class="title">Bany</h1>
{% call staff_nav::staff_nav() %}
<hr>
<h2>Bany</h2>
<form method="post" action="/staff/actions/remove-bans">
<div class="table-wrap">
<table class="data-table center">
<tr>
<th></th>
<th>IP</th>
<th>Nástěnka</th>
<th>Důvod</th>
<th>Udělil</th>
<th>Odvolatelný</th>
<th>Odvolání</th>
<th>Udělěn</th>
<th>Vyprší</th>
</tr>
{% for ban in bans %}
<tr>
<td><input name="bans[]" type="checkbox" value="{{ ban.id }}"></td>
<td title="{{ ban.ip_range }}">
{% if ban.ip_range.network() == ban.ip_range.broadcast() %}
{{ ban.ip_range.ip() }}
{% else %}
{{ ban.ip_range.network() }}-{{ ban.ip_range.broadcast() }}
{% endif %}
</td>
<td>{% if let Some(board) = ban.board %}/{{ board }}/{% else %}<i>Všechny</i>{% endif %}</td>
<td><div class="post-content">{{ ban.reason }}</div></td>
<td>{{ ban.issued_by }}</td>
<td>{% if ban.appealable %}Ano{% else %}Ne{% endif %}</td>
<td>{% if let Some(appeal) = ban.appeal %}<div class="post-content">{{ appeal }}</div>{% else %}-{% endif %}</td>
<td><time datetime="{{ ban.created }}">{{ ban.created|czech_datetime }}</time></td>
{% if let Some(expires) = ban.expires %}
<td><time datetime="{{ expires }}">{{ expires|czech_datetime }}</time></td>
{% else %}
<td>Nikdy</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
<input class="button" type="submit" value="Odstranit vybrané">
</form>
{% endblock %}

View File

@@ -0,0 +1,196 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Nastavení (/{{ board.id }}/){% endblock %}
{% block content %}
<h1 class="title">Nastavení (/{{ board.id }}/)</h1>
{% call staff_nav::staff_nav() %}
<hr>
<form method="post" action="/staff/actions/update-board-config">
<input name="board" type="hidden" value="{{ board.id }}">
<table class="form-table">
<tr>
<td class="label">Uzamknout nástěnku</td>
<td>
<div class="input-wrapper">
<input name="locked" type="checkbox" {% if board.config.0.locked %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Výchozí jméno</td>
<td><input name="anon_name" type="text" value="{{ board.config.0.anon_name }}" required=""></td>
</tr>
<tr>
<td class="label">Velikost stránky</td>
<td><input name="page_size" type="number" min="1" value="{{ board.config.0.page_size }}" required=""></td>
</tr>
<tr>
<td class="label">Počet stránek</td>
<td><input name="page_count" type="number" min="1" value="{{ board.config.0.page_count }}" required=""></td>
</tr>
<tr>
<td class="label">Limit souborů</td>
<td><input name="file_limit" type="number" min="1" value="{{ board.config.0.file_limit }}" required=""></td>
</tr>
<tr>
<td class="label">Limit naťuknutí</td>
<td><input name="bump_limit" type="number" min="0" value="{{ board.config.0.bump_limit }}" required=""></td>
</tr>
<tr>
<td class="label">Limit odpovědí</td>
<td><input name="reply_limit" type="number" min="0" value="{{ board.config.0.reply_limit }}" required=""></td>
</tr>
<tr>
<td class="label">Identifikátory (anti-samefag)</td>
<td>
<div class="input-wrapper">
<input name="user_ids" type="checkbox" {% if board.config.0.user_ids %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Vlajky</td>
<td>
<div class="input-wrapper">
<input name="flags" type="checkbox" {% if board.config.0.flags %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Vlajky Regionů</td>
<td>
<div class="input-wrapper">
<input name="flags_reg" type="checkbox" {% if board.config.0.flags_reg %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">CAPTCHA (vlákno)</td>
<td>
<select name="thread_captcha">
<option value="off" {% if board.config.0.thread_captcha == "off" %}selected="selected"{% endif %}>
Žádná
</option>
<option value="easy" {% if board.config.0.thread_captcha == "easy" %}selected="selected"{% endif %}>
Lehká
</option>
<option value="medium" {% if board.config.0.thread_captcha == "medium" %}selected="selected"{% endif %}>
Střední
</option>
<option value="hard" {% if board.config.0.thread_captcha == "hard" %}selected="selected"{% endif %}>
Obtížná
</option>
</select>
</td>
</tr>
<tr>
<td class="label">CAPTCHA (odpověď)</td>
<td>
<select name="reply_captcha">
<option value="off" {% if board.config.0.reply_captcha == "off" %}selected="selected"{% endif %}>
Žádná
</option>
<option value="easy" {% if board.config.0.reply_captcha == "easy" %}selected="selected"{% endif %}>
Lehká
</option>
<option value="medium" {% if board.config.0.reply_captcha == "medium" %}selected="selected"{% endif %}>
Střední
</option>
<option value="hard" {% if board.config.0.reply_captcha == "hard" %}selected="selected"{% endif %}>
Obtížná
</option>
</select>
</td>
</tr>
<tr>
<td class="label">Motiv nástěnky</td>
<td><input name="board_theme" type="text" value="{{ board.config.0.board_theme }}" required=""></td>
</tr>
<tr>
<td class="label">Vyžadovat obsah ve vlákně</td>
<td>
<div class="input-wrapper">
<input name="require_thread_content" type="checkbox" {% if board.config.0.require_thread_content %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Vyžadovat soubor ve vlákně</td>
<td>
<div class="input-wrapper">
<input name="require_thread_file" type="checkbox" {% if board.config.0.require_thread_file %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Vyžadovat obsah v odpovědi</td>
<td>
<div class="input-wrapper">
<input name="require_reply_content" type="checkbox" {% if board.config.0.require_reply_content %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Vyžadovat soubor v odpovědi</td>
<td>
<div class="input-wrapper">
<input name="require_reply_file" type="checkbox" {% if board.config.0.require_reply_file %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Antispam</td>
<td>
<div class="input-wrapper">
<input name="antispam" type="checkbox" {% if board.config.0.antispam %}checked=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Interval antispamu (IP)</td>
<td><input name="antispam_ip" type="number" min="0" value="{{ board.config.0.antispam_ip }}" required=""></td>
</tr>
<tr>
<td class="label">Interval antispamu (Obsah)</td>
<td><input name="antispam_content" type="number" min="0" value="{{ board.config.0.antispam_content }}" required=""></td>
</tr>
<tr>
<td class="label">Interval antispamu (IP+Obsah)</td>
<td><input name="antispam_both" type="number" min="0" value="{{ board.config.0.antispam_both }}" required=""></td>
</tr>
<tr>
<td class="label">Interval mezi vlákny (IP)</td>
<td><input name="thread_cooldown" type="number" min="0" value="{{ board.config.0.antispam_both }}" required=""></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Uložit"></td>
</tr>
</table>
</form>
{% endblock %}

View File

@@ -0,0 +1,75 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Nástěnky{% endblock %}
{% block content %}
<h1 class="title">Nástěnky</h1>
{% call staff_nav::staff_nav() %}
<hr>
<h2>Nástěnky</h2>
<form method="post">
<div class="table-wrap">
<table class="data-table center">
<tr>
<th></th>
<th>ID</th>
<th>Jméno</th>
<th>Popis</th>
<th>Vytvořena</th>
<th>Nastavení</th>
</tr>
{% for board in boards %}
<tr>
<td><input name="boards[]" type="checkbox" value="{{ board.id }}"></td>
<td>/{{ board.id }}/</td>
<td>{{ board.name }}</td>
<td>{{ board.description }}</td>
<td><time datetime="{{ board.created }}">{{ board.created|czech_datetime }}</time></td>
<td>{% if tcx.perms.owner() || tcx.perms.board_config() %}<a href="/staff/board-config/{{ board.id }}">[Zobrazit]</a>{% else %}-{% endif %}</td>
</tr>
{% endfor %}
</table>
</div>
{% if tcx.perms.owner() %}
<input class="button" type="submit" formaction="/staff/actions/remove-boards" value="Odstranit vybrané" formnovalidate>
<hr>
<table class="form-table">
<tr>
<td class="label">Jméno</td>
<td><input name="name" type="text" required=""></td>
</tr>
<tr>
<td class="label">Popis</td>
<td><input name="description" type="text"></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" formaction="/staff/actions/update-boards" value="Upravit vybrané"></td>
</tr>
</table>
{% endif %}
</form>
<hr>
<h2>Vytvořit nástěnku</h2>
<form method="post" action="/staff/actions/create-board">
<table class="form-table">
<tr>
<td class="label">ID</td>
<td><input name="id" type="text" required=""></td>
</tr>
<tr>
<td class="label">Jméno</td>
<td><input name="name" type="text" required=""></td>
</tr>
<tr>
<td class="label">Popis</td>
<td><input name="description" type="text"></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Vytvořit nástěnku"></td>
</tr>
</table>
</form>
{% endblock %}

View File

@@ -0,0 +1,26 @@
{% extends "base.html" %}
{% block title %}Upravit příspěvky{% endblock %}
{% block content %}
<div class="container">
<h1 class="title">Upravit novinky</h1>
<hr>
<form method="post" action="/staff/actions/edit-news">
{% for newspost in news %}
<div class="box">
<h2 class="headline">
<span>{{ newspost.title }}</span>
<span class="float-r">
{{ newspost.author }} - <time datetime="{{ newspost.created }}">{{ newspost.created|czech_datetime }}</time>
</span>
</h2>
<hr>
<textarea class="edit-box" name="{{ newspost.id }}">{{ newspost.content_nomarkup }}</textarea>
</div>
<hr>
{% endfor %}
<input class="button full-width" type="submit" value="Upravit">
</form>
</div>
{% endblock %}

51
templates/staff/news.html Normal file
View File

@@ -0,0 +1,51 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Novinky{% endblock %}
{% block content %}
<h1 class="title">Novinky</h1>
{% call staff_nav::staff_nav() %}
<hr>
<h2>Novinky</h2>
<form method="post">
<div class="table-wrap">
<table class="data-table center">
<tr>
<th></th>
<th>Titulek</th>
<th>Autor</th>
<th>Datum</th>
</tr>
{% for newspost in news %}
<tr>
<td><input name="news[]" type="checkbox" value="{{ newspost.id }}"></td>
<td>{{ newspost.title }}</td>
<td>{{ newspost.author }}</td>
<td><time datetime="{{ newspost.created }}">{{ newspost.created|czech_datetime }}</time></td>
</tr>
{% endfor %}
</table>
</div>
<input class="button" type="submit" formaction="/staff/actions/remove-news" value="Odstranit vybrané">&#32;
<input class="button" type="submit" formaction="/staff/edit-news" value="Upravit vybrané">
</form>
<hr>
<h2>Vytvořit novinky</h2>
<form method="post" action="/staff/actions/create-news">
<table class="form-table">
<tr>
<td class="label">Titulek</td>
<td><input name="title" type="text" required=""></td>
</tr>
<tr>
<td class="label">Obsah</td>
<td><textarea name="content" required=""></textarea></td>
</tr>
<tr>
<td colspan="2"><input class="button" type="submit" value="Vytvořit novinky"></td>
</tr>
</table>
</form>
{% endblock %}

View File

@@ -0,0 +1,179 @@
{% import "../macros/staff-nav.html" as staff_nav %}
{% extends "base.html" %}
{% block title %}Oprávnění ({{ account.username }}){% endblock %}
{% block content %}
<h1 class="title">Oprávnění ({{ account.username }})</h1>
{% call staff_nav::staff_nav() %}
<hr>
{% if account.perms().owner() %}
<h2 class="title">Tento uživatel je vlastník, změny nebudou mít žádný vliv.</h2>
<hr>
{% endif %}
<form method="post" action="/staff/actions/update-permissions">
<input name="account" type="hidden" value="{{ account.username }}">
<table class="form-table">
<tr>
<td class="label">Upravit příspěvky</td>
<td>
<div class="input-wrapper">
<input name="edit_posts" type="checkbox"{% if account.perms().edit_posts() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Spravovat příspěvky</td>
<td>
<div class="input-wrapper">
<input name="manage_posts" type="checkbox"{% if account.perms().manage_posts() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Používat capcode</td>
<td>
<div class="input-wrapper">
<input name="capcodes" type="checkbox"{% if account.perms().capcodes() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Vlastní capcode</td>
<td>
<div class="input-wrapper">
<input name="custom_capcodes" type="checkbox"{% if account.perms().custom_capcodes() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Záznamy</td>
<td>
<div class="input-wrapper">
<input name="staff_log" type="checkbox"{% if account.perms().staff_log() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Hlášení</td>
<td>
<div class="input-wrapper">
<input name="reports" type="checkbox"{% if account.perms().reports() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Bany</td>
<td>
<div class="input-wrapper">
<input name="bans" type="checkbox"{% if account.perms().bans() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Bannery</td>
<td>
<div class="input-wrapper">
<input name="banners" type="checkbox"{% if account.perms().banners() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Nastavení nástěnek</td>
<td>
<div class="input-wrapper">
<input name="board_config" type="checkbox"{% if account.perms().board_config() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Novinky</td>
<td>
<div class="input-wrapper">
<input name="news" type="checkbox"{% if account.perms().news() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Uklízečtext (pravý redtext)</td>
<td>
<div class="input-wrapper">
<input name="jannytext" type="checkbox"{% if account.perms().jannytext() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Zobrazit IP adresy</td>
<td>
<div class="input-wrapper">
<input name="view_ips" type="checkbox"{% if account.perms().view_ips() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Obejít ban</td>
<td>
<div class="input-wrapper">
<input name="bypass_bans" type="checkbox"{% if account.perms().bypass_bans() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Obejít uzamčení nástěnky</td>
<td>
<div class="input-wrapper">
<input name="bypass_board_lock" type="checkbox"{% if account.perms().bypass_board_lock() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Obejít uzamčení vlákna</td>
<td>
<div class="input-wrapper">
<input name="bypass_thread_lock" type="checkbox"{% if account.perms().bypass_thread_lock() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Obejít CAPTCHA</td>
<td>
<div class="input-wrapper">
<input name="bypass_captcha" type="checkbox"{% if account.perms().bypass_captcha() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
<tr>
<td class="label">Obejít antispam</td>
<td>
<div class="input-wrapper">
<input name="bypass_antispam" type="checkbox"{% if account.perms().bypass_antispam() %} checked=""{% endif %}{% if !tcx.perms.owner() %} disabled=""{% endif %}>
</div>
</td>
</tr>
{% if tcx.perms.owner() %}
<tr>
<td colspan="2"><input class="button" type="submit" value="Uložit"></td>
</tr>
{% endif %}
</table>
</form>
{% endblock %}

View File

@@ -0,0 +1,40 @@
{% import "../macros/post-actions.html" as post_actions %}
{% import "../macros/post.html" as post %}
{% import "../macros/staff-nav.html" as staff_nav %}
{% import "../macros/static-pagination.html" as static_pagination %}
{% extends "base.html" %}
{% block title %}Hlášení{% endblock %}
{% block content %}
<div class="center">
<h1 class="title">Hlášení</h1>
<p class="description greentext">&gt;Ukliď to!!!</p>
</div>
{% call staff_nav::staff_nav() %}
<hr>
<form method="post">
{% for post in posts %}
<b>Příspěvek z <a href="/boards/{{ post.board }}">/{{ post.board }}/</a></b>
<br>
{% call post::post(boards[post.board.as_str()], post, true) %}
<table class="data-table inline-block m-0">
<tr>
<th>IP adresa</th>
<th>Důvod hlášení</th>
</tr>
{% for report in post.reports.0 %}
<tr>
<td><b>{{ report.reporter_ip }}</b> (<img class="icon" src="/static/flags/{{ report.reporter_country }}.png">)</td>
<td>{{ report.reason }}</td>
</tr>
{% endfor %}
</table>
<hr>
{% endfor %}
{% call static_pagination::static_pagination("/staff/reports", page, false) %}
<hr>
{% call post_actions::post_actions() %}
</form>
{% endblock %}

55
templates/thread.html Normal file
View File

@@ -0,0 +1,55 @@
{% import "./macros/post-actions.html" as post_actions %}
{% import "./macros/post-form.html" as post_form %}
{% import "./macros/post.html" as post %}
{% extends "base.html" %}
{% block theme %}{{ board.config.0.board_theme }}{% endblock %}
{% block title %}/{{ board.id }}/ - {{ thread.content_nomarkup|inline_post }}{% endblock %}
{% block scripts %}
<script src="/static/js/captcha.js" defer=""></script>
<script src="/static/js/live.js" defer=""></script>
<script src="/static/js/post-form.js" defer=""></script>
{% endblock %}
{% block content %}
<div class="container">
<div class="center">
<img class="banner" src="/random-banner">
<h1 class="title">/{{ board.id }}/ - {{ board.name }}</h1>
<p class="description">{{ board.description }}</p>
<a href="/boards/{{ board.id }}/catalog">Katalog</a>
<br>
<br>
<a class="box inline-block open-post-form" href="#post-form">[Nová odpověď]</a>
<br>
<br>
</div>
{% call post_form::post_form(board, true, thread.id) %}
</div>
<hr>
<div class="pagination box inline-block">
<a href="/boards/{{ board.id }}">[Zpět]</a>&#32;
<a href="#bottom">[Dolů]</a>&#32;
<a href="/boards/{{ board.id }}/catalog">[Katalog]</a>
</div>
<hr>
<form method="post">
<div class="thread">
{% call post::post(board, thread, false) %}
{% for reply_post in replies %}
{% call post::post(board, reply_post, true) %}
<br>
{% endfor %}
</div>
<hr>
<div class="pagination box inline-block">
<a href="/boards/{{ board.id }}">[Zpět]</a>&#32;
<a href="#top">[Nahoru]</a>&#32;
<a href="/boards/{{ board.id }}/catalog">[Katalog]</a>
</div>
<hr>
{% call post_actions::post_actions() %}
</form>
{% endblock %}