Tabulka na novinky
Tento commit je obsažen v:
rodič
3e12aeffb9
revize
599c6ed804
7
Cargo.lock
vygenerováno
7
Cargo.lock
vygenerováno
@ -1141,6 +1141,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.28"
|
||||
@ -1810,6 +1816,7 @@ dependencies = [
|
||||
"enumflags2",
|
||||
"env_logger",
|
||||
"fancy-regex",
|
||||
"fs_extra",
|
||||
"glob",
|
||||
"html-minifier",
|
||||
"image",
|
||||
|
@ -43,6 +43,7 @@ toml = "0.8.6"
|
||||
|
||||
[build-dependencies]
|
||||
anyhow = "1.0.74"
|
||||
fs_extra = "1.3.0"
|
||||
glob = "0.3.1"
|
||||
html-minifier = "5.0.0"
|
||||
|
||||
|
12
build.rs
12
build.rs
@ -1,10 +1,10 @@
|
||||
use anyhow::Error;
|
||||
use fs_extra::dir::{copy, remove, CopyOptions};
|
||||
use glob::glob;
|
||||
use html_minifier::minify;
|
||||
use std::{
|
||||
fs::{read_to_string, File},
|
||||
io::Write,
|
||||
process::Command,
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Error> {
|
||||
@ -12,11 +12,13 @@ fn main() -> Result<(), Error> {
|
||||
println!("cargo:rerun-if-changed=migrations");
|
||||
println!("cargo:rerun-if-changed=templates");
|
||||
|
||||
Command::new("rm").args(["-rf", "templates_min"]).output()?;
|
||||
remove("templates_min")?;
|
||||
|
||||
Command::new("cp")
|
||||
.args(["-r", "templates", "templates_min"])
|
||||
.output()?;
|
||||
copy(
|
||||
"templates",
|
||||
"templates_min",
|
||||
&CopyOptions::new().copy_inside(true),
|
||||
)?;
|
||||
|
||||
let templates = glob("templates_min/**/*.html")?;
|
||||
|
||||
|
7
migrations/20231217111814_create_news.sql
Normální soubor
7
migrations/20231217111814_create_news.sql
Normální soubor
@ -0,0 +1,7 @@
|
||||
CREATE TABLE news (
|
||||
id SERIAL NOT NULL PRIMARY KEY,
|
||||
title VARCHAR(256) NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
author VARCHAR(32) NOT NULL REFERENCES users(username),
|
||||
created TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
@ -14,14 +14,12 @@ impl Board {
|
||||
name: String,
|
||||
description: String,
|
||||
) -> Result<Self, NekrochanError> {
|
||||
let banners = Json(Vec::<File>::new());
|
||||
let config = Json(ctx.cfg.board_defaults.clone());
|
||||
|
||||
let board: Board = query_as("INSERT INTO boards (id, name, description, banners, config) VALUES ($1, $2, $3, $4, $5) RETURNING *")
|
||||
let board: Board = query_as("INSERT INTO boards (id, name, description, config) VALUES ($1, $2, $3, $4) RETURNING *")
|
||||
.bind(id)
|
||||
.bind(name)
|
||||
.bind(description)
|
||||
.bind(banners)
|
||||
.bind(config)
|
||||
.fetch_one(ctx.db())
|
||||
.await?;
|
||||
|
@ -5,4 +5,5 @@ mod account;
|
||||
mod ban;
|
||||
mod banner;
|
||||
mod board;
|
||||
mod newspost;
|
||||
mod post;
|
||||
|
@ -78,6 +78,21 @@ pub struct Post {
|
||||
pub created: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(FromRow, Serialize, Deserialize)]
|
||||
pub struct Banner {
|
||||
pub id: i32,
|
||||
pub banner: Json<File>,
|
||||
}
|
||||
|
||||
#[derive(FromRow)]
|
||||
pub struct NewsPost {
|
||||
pub id: i32,
|
||||
pub title: String,
|
||||
pub content: String,
|
||||
pub author: String,
|
||||
pub created: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
pub struct File {
|
||||
pub original_name: String,
|
||||
@ -89,9 +104,3 @@ pub struct File {
|
||||
pub timestamp: i64,
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
#[derive(FromRow, Serialize, Deserialize)]
|
||||
pub struct Banner {
|
||||
pub id: i32,
|
||||
pub banner: Json<File>,
|
||||
}
|
||||
|
62
src/db/newspost.rs
Normální soubor
62
src/db/newspost.rs
Normální soubor
@ -0,0 +1,62 @@
|
||||
use sqlx::{query, query_as};
|
||||
|
||||
use super::models::NewsPost;
|
||||
use crate::{ctx::Ctx, error::NekrochanError};
|
||||
|
||||
impl NewsPost {
|
||||
pub async fn create(
|
||||
ctx: &Ctx,
|
||||
title: String,
|
||||
content: String,
|
||||
author: String,
|
||||
) -> Result<Self, NekrochanError> {
|
||||
let newspost = query_as("INSERT INTO news (title, content, author) VALUES ($1, $2, $3)")
|
||||
.bind(title)
|
||||
.bind(content)
|
||||
.bind(author)
|
||||
.fetch_one(ctx.db())
|
||||
.await?;
|
||||
|
||||
Ok(newspost)
|
||||
}
|
||||
|
||||
pub async fn read(ctx: &Ctx, id: i32) -> Result<Option<Self>, NekrochanError> {
|
||||
let newspost = query_as("SELECT * FROM news WHERE id = $1")
|
||||
.bind(id)
|
||||
.fetch_optional(ctx.db())
|
||||
.await?;
|
||||
|
||||
Ok(newspost)
|
||||
}
|
||||
|
||||
pub async fn read_all(ctx: &Ctx) -> Result<Vec<Self>, NekrochanError> {
|
||||
let newsposts = query_as("SELECT * FROM news").fetch_all(ctx.db()).await?;
|
||||
|
||||
Ok(newsposts)
|
||||
}
|
||||
|
||||
pub async fn update(
|
||||
&self,
|
||||
ctx: &Ctx,
|
||||
title: String,
|
||||
content: String,
|
||||
) -> Result<(), NekrochanError> {
|
||||
query("UPDATE news SET title = $1, content = $2 WHERE id = $3")
|
||||
.bind(title)
|
||||
.bind(content)
|
||||
.bind(self.id)
|
||||
.execute(ctx.db())
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete(&self, ctx: &Ctx) -> Result<(), NekrochanError> {
|
||||
query("DELETE FROM news WHERE id = $1")
|
||||
.bind(self.id)
|
||||
.execute(ctx.db())
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -28,7 +28,12 @@ pub async fn index(ctx: Data<Ctx>, req: HttpRequest) -> Result<HttpResponse, Nek
|
||||
let posts = Post::read_latest(&ctx).await.unwrap_or_else(|_| Vec::new());
|
||||
let files = Post::read_files(&ctx).await.unwrap_or_else(|_| Vec::new());
|
||||
|
||||
let template = IndexTemplate { tcx, boards, posts, files };
|
||||
let template = IndexTemplate {
|
||||
tcx,
|
||||
boards,
|
||||
posts,
|
||||
files,
|
||||
};
|
||||
|
||||
template_response(&template)
|
||||
}
|
||||
|
@ -283,10 +283,6 @@ summary {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.catalog {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.catalog-entry {
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
|
@ -16,7 +16,7 @@
|
||||
</div>
|
||||
<hr>
|
||||
<form method="post">
|
||||
<div class="catalog">
|
||||
<div class="center">
|
||||
{% for thread in threads %}
|
||||
{% call catalog_entry::catalog_entry(thread, loop.index, board.config.0.page_size.into()) %}
|
||||
{% endfor %}
|
||||
|
@ -10,9 +10,7 @@
|
||||
</div>
|
||||
{% if !boards.is_empty() %}
|
||||
<div class="infobox">
|
||||
<div class="infobox-head">
|
||||
Nástěnky
|
||||
</div>
|
||||
<div class="infobox-head">Nástěnky</div>
|
||||
<div class="infobox-content">
|
||||
<ul class="infobox-list">
|
||||
{% for board in boards %}
|
||||
@ -24,9 +22,7 @@
|
||||
{% endif %}
|
||||
{% if !posts.is_empty() %}
|
||||
<div class="infobox">
|
||||
<div class="infobox-head">
|
||||
Nejnovější příspěvky
|
||||
</div>
|
||||
<div class="infobox-head">Nejnovější příspěvky</div>
|
||||
<div class="infobox-content">
|
||||
<ul class="infobox-list">
|
||||
{% for post in posts %}
|
||||
@ -38,9 +34,7 @@
|
||||
{% endif %}
|
||||
{% if !files.is_empty() %}
|
||||
<div class="infobox">
|
||||
<div class="infobox-head">
|
||||
Nejnovější soubory
|
||||
</div>
|
||||
<div class="infobox-head">Nejnovější soubory</div>
|
||||
<div class="infobox-content">
|
||||
<div class="post-files multi-files">
|
||||
{% for post in files %}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Katalog nadnístěnky{% endblock %}
|
||||
{% block title %}Katalog nadnástěnky{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
@ -16,7 +16,7 @@
|
||||
</div>
|
||||
<hr>
|
||||
<form method="post">
|
||||
<div class="catalog">
|
||||
<div class="center">
|
||||
{% for thread in threads %}
|
||||
{% call catalog_entry::catalog_entry(thread, loop.index, 15) %}
|
||||
{% endfor %}
|
||||
|
Načítá se…
Odkázat v novém úkolu
Zablokovat Uživatele