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",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fs_extra"
|
||||||
|
version = "1.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.28"
|
version = "0.3.28"
|
||||||
@ -1810,6 +1816,7 @@ dependencies = [
|
|||||||
"enumflags2",
|
"enumflags2",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"fancy-regex",
|
"fancy-regex",
|
||||||
|
"fs_extra",
|
||||||
"glob",
|
"glob",
|
||||||
"html-minifier",
|
"html-minifier",
|
||||||
"image",
|
"image",
|
||||||
|
@ -43,6 +43,7 @@ toml = "0.8.6"
|
|||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
anyhow = "1.0.74"
|
anyhow = "1.0.74"
|
||||||
|
fs_extra = "1.3.0"
|
||||||
glob = "0.3.1"
|
glob = "0.3.1"
|
||||||
html-minifier = "5.0.0"
|
html-minifier = "5.0.0"
|
||||||
|
|
||||||
|
12
build.rs
12
build.rs
@ -1,10 +1,10 @@
|
|||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
|
use fs_extra::dir::{copy, remove, CopyOptions};
|
||||||
use glob::glob;
|
use glob::glob;
|
||||||
use html_minifier::minify;
|
use html_minifier::minify;
|
||||||
use std::{
|
use std::{
|
||||||
fs::{read_to_string, File},
|
fs::{read_to_string, File},
|
||||||
io::Write,
|
io::Write,
|
||||||
process::Command,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
@ -12,11 +12,13 @@ fn main() -> Result<(), Error> {
|
|||||||
println!("cargo:rerun-if-changed=migrations");
|
println!("cargo:rerun-if-changed=migrations");
|
||||||
println!("cargo:rerun-if-changed=templates");
|
println!("cargo:rerun-if-changed=templates");
|
||||||
|
|
||||||
Command::new("rm").args(["-rf", "templates_min"]).output()?;
|
remove("templates_min")?;
|
||||||
|
|
||||||
Command::new("cp")
|
copy(
|
||||||
.args(["-r", "templates", "templates_min"])
|
"templates",
|
||||||
.output()?;
|
"templates_min",
|
||||||
|
&CopyOptions::new().copy_inside(true),
|
||||||
|
)?;
|
||||||
|
|
||||||
let templates = glob("templates_min/**/*.html")?;
|
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,
|
name: String,
|
||||||
description: String,
|
description: String,
|
||||||
) -> Result<Self, NekrochanError> {
|
) -> Result<Self, NekrochanError> {
|
||||||
let banners = Json(Vec::<File>::new());
|
|
||||||
let config = Json(ctx.cfg.board_defaults.clone());
|
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(id)
|
||||||
.bind(name)
|
.bind(name)
|
||||||
.bind(description)
|
.bind(description)
|
||||||
.bind(banners)
|
|
||||||
.bind(config)
|
.bind(config)
|
||||||
.fetch_one(ctx.db())
|
.fetch_one(ctx.db())
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -5,4 +5,5 @@ mod account;
|
|||||||
mod ban;
|
mod ban;
|
||||||
mod banner;
|
mod banner;
|
||||||
mod board;
|
mod board;
|
||||||
|
mod newspost;
|
||||||
mod post;
|
mod post;
|
||||||
|
@ -78,6 +78,21 @@ pub struct Post {
|
|||||||
pub created: DateTime<Utc>,
|
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)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
pub struct File {
|
pub struct File {
|
||||||
pub original_name: String,
|
pub original_name: String,
|
||||||
@ -89,9 +104,3 @@ pub struct File {
|
|||||||
pub timestamp: i64,
|
pub timestamp: i64,
|
||||||
pub size: usize,
|
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 posts = Post::read_latest(&ctx).await.unwrap_or_else(|_| Vec::new());
|
||||||
let files = Post::read_files(&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)
|
template_response(&template)
|
||||||
}
|
}
|
||||||
|
@ -283,10 +283,6 @@ summary {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.catalog-entry {
|
.catalog-entry {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="catalog">
|
<div class="center">
|
||||||
{% for thread in threads %}
|
{% for thread in threads %}
|
||||||
{% call catalog_entry::catalog_entry(thread, loop.index, board.config.0.page_size.into()) %}
|
{% call catalog_entry::catalog_entry(thread, loop.index, board.config.0.page_size.into()) %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -10,9 +10,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if !boards.is_empty() %}
|
{% if !boards.is_empty() %}
|
||||||
<div class="infobox">
|
<div class="infobox">
|
||||||
<div class="infobox-head">
|
<div class="infobox-head">Nástěnky</div>
|
||||||
Nástěnky
|
|
||||||
</div>
|
|
||||||
<div class="infobox-content">
|
<div class="infobox-content">
|
||||||
<ul class="infobox-list">
|
<ul class="infobox-list">
|
||||||
{% for board in boards %}
|
{% for board in boards %}
|
||||||
@ -24,9 +22,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if !posts.is_empty() %}
|
{% if !posts.is_empty() %}
|
||||||
<div class="infobox">
|
<div class="infobox">
|
||||||
<div class="infobox-head">
|
<div class="infobox-head">Nejnovější příspěvky</div>
|
||||||
Nejnovější příspěvky
|
|
||||||
</div>
|
|
||||||
<div class="infobox-content">
|
<div class="infobox-content">
|
||||||
<ul class="infobox-list">
|
<ul class="infobox-list">
|
||||||
{% for post in posts %}
|
{% for post in posts %}
|
||||||
@ -38,9 +34,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if !files.is_empty() %}
|
{% if !files.is_empty() %}
|
||||||
<div class="infobox">
|
<div class="infobox">
|
||||||
<div class="infobox-head">
|
<div class="infobox-head">Nejnovější soubory</div>
|
||||||
Nejnovější soubory
|
|
||||||
</div>
|
|
||||||
<div class="infobox-content">
|
<div class="infobox-content">
|
||||||
<div class="post-files multi-files">
|
<div class="post-files multi-files">
|
||||||
{% for post in files %}
|
{% for post in files %}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Katalog nadnístěnky{% endblock %}
|
{% block title %}Katalog nadnástěnky{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="catalog">
|
<div class="center">
|
||||||
{% for thread in threads %}
|
{% for thread in threads %}
|
||||||
{% call catalog_entry::catalog_entry(thread, loop.index, 15) %}
|
{% call catalog_entry::catalog_entry(thread, loop.index, 15) %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
Načítá se…
Odkázat v novém úkolu
Zablokovat Uživatele