diff --git a/Cargo.lock b/Cargo.lock index 9e82fa2..bb475c3 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -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", diff --git a/Cargo.toml b/Cargo.toml index f92aa63..71a4ff4 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/build.rs b/build.rs index 285279a..49224eb 100755 --- a/build.rs +++ b/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")?; diff --git a/migrations/20231217111814_create_news.sql b/migrations/20231217111814_create_news.sql new file mode 100644 index 0000000..05b4744 --- /dev/null +++ b/migrations/20231217111814_create_news.sql @@ -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 +); diff --git a/src/db/board.rs b/src/db/board.rs index 1be3bf6..673139b 100755 --- a/src/db/board.rs +++ b/src/db/board.rs @@ -14,14 +14,12 @@ impl Board { name: String, description: String, ) -> Result { - let banners = Json(Vec::::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?; diff --git a/src/db/mod.rs b/src/db/mod.rs index fd1cf01..2050382 100755 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -5,4 +5,5 @@ mod account; mod ban; mod banner; mod board; +mod newspost; mod post; diff --git a/src/db/models.rs b/src/db/models.rs index 7690140..a342886 100755 --- a/src/db/models.rs +++ b/src/db/models.rs @@ -78,6 +78,21 @@ pub struct Post { pub created: DateTime, } +#[derive(FromRow, Serialize, Deserialize)] +pub struct Banner { + pub id: i32, + pub banner: Json, +} + +#[derive(FromRow)] +pub struct NewsPost { + pub id: i32, + pub title: String, + pub content: String, + pub author: String, + pub created: DateTime, +} + #[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, -} diff --git a/src/db/newspost.rs b/src/db/newspost.rs new file mode 100644 index 0000000..6c82135 --- /dev/null +++ b/src/db/newspost.rs @@ -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 { + 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, 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, 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(()) + } +} diff --git a/src/web/index.rs b/src/web/index.rs index 9b3a2fe..d93cfc2 100755 --- a/src/web/index.rs +++ b/src/web/index.rs @@ -28,7 +28,12 @@ pub async fn index(ctx: Data, req: HttpRequest) -> Result
-
+
{% for thread in threads %} {% call catalog_entry::catalog_entry(thread, loop.index, board.config.0.page_size.into()) %} {% endfor %} diff --git a/templates/index.html b/templates/index.html index 1dd435a..d04bb2d 100755 --- a/templates/index.html +++ b/templates/index.html @@ -10,9 +10,7 @@
{% if !boards.is_empty() %}
-
- Nástěnky -
+
Nástěnky
    {% for board in boards %} @@ -24,9 +22,7 @@ {% endif %} {% if !posts.is_empty() %}
    -
    - Nejnovější příspěvky -
    +
    Nejnovější příspěvky
      {% for post in posts %} @@ -38,9 +34,7 @@ {% endif %} {% if !files.is_empty() %}
      -
      - Nejnovější soubory -
      +
      Nejnovější soubory
      {% for post in files %} diff --git a/templates/overboard-catalog.html b/templates/overboard-catalog.html index 7da3418..1cd866b 100755 --- a/templates/overboard-catalog.html +++ b/templates/overboard-catalog.html @@ -3,7 +3,7 @@ {% extends "base.html" %} -{% block title %}Katalog nadnístěnky{% endblock %} +{% block title %}Katalog nadnástěnky{% endblock %} {% block content %}
      @@ -16,7 +16,7 @@

      -
      +
      {% for thread in threads %} {% call catalog_entry::catalog_entry(thread, loop.index, 15) %} {% endfor %}