diff --git a/Cargo.toml b/Cargo.toml index 3377256..97d3af9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,4 +20,5 @@ toml = "0.5.8" reqwest = { version = "0.11", features = ["stream", "multipart"] } new_mime_guess = "3.0.2" headers = "0.3.5" -url = {version = "2.2.2", features = ["serde"]} \ No newline at end of file +url = {version = "2.2.2", features = ["serde"]} +askama = "0.10" \ No newline at end of file diff --git a/src/cdn/mod.rs b/src/cdn/mod.rs index f7860d2..03f48df 100644 --- a/src/cdn/mod.rs +++ b/src/cdn/mod.rs @@ -6,10 +6,15 @@ use sqlx::{Error, MySqlPool}; use crate::config::ConfVars; +use self::templates::{DirTemplate, HtmlTemplate}; + mod sql; +mod templates; pub fn routes() -> Router { Router::new() + .route("/", get(users)) + .route("/:user/", get(memes)) .route("/:user/:filename", get(image)) .boxed() } @@ -48,4 +53,28 @@ async fn image(Path((user, filename)): Path<(String, String)>, Extension(db_pool _ => Err(StatusCode::INTERNAL_SERVER_ERROR), }, } +} + +async fn users(Extension(db_pool): Extension, Extension(vars): Extension) -> Result { + let q = sql::get_users(&db_pool).await; + match q { + Ok(users) => Ok(HtmlTemplate(DirTemplate { + entries: users, + prefix: vars.cdn, + suffix: "/".to_string(), + })), + Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR), + } +} + +async fn memes(Path(user): Path, Extension(db_pool): Extension) -> Result { + let q = sql::get_memes(user, &db_pool).await; + match q { + Ok(memes) => Ok(HtmlTemplate(DirTemplate { + entries: memes, + prefix: ".".to_string(), + suffix: "".to_string(), + })), + Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR), + } } \ No newline at end of file diff --git a/src/cdn/sql.rs b/src/cdn/sql.rs index cc50cdd..ab8e7f4 100644 --- a/src/cdn/sql.rs +++ b/src/cdn/sql.rs @@ -2,10 +2,22 @@ use sqlx::{MySqlPool, Result, Row, mysql::MySqlRow}; pub async fn get_cid(user: String, filename: String, pool: &MySqlPool) -> Result { - let q: String = sqlx::query("SELECT cid FROM memes WHERE user = ? AND filename = ? ORDER BY id DESC").bind(user).bind(filename) .map(|row: MySqlRow| row.get("cid")) .fetch_one(pool).await?; - Ok(q) + Ok(q) +} +pub async fn get_memes(user: String, pool: &MySqlPool) -> Result> { + let q: Vec = sqlx::query("SELECT filename FROM memes WHERE user = ? ORDER BY filename").bind(user) + .map(|row: MySqlRow| row.get("filename")) + .fetch_all(pool).await?; + Ok(q) +} + +pub async fn get_users(pool: &MySqlPool) -> Result> { + let q: Vec = sqlx::query("SELECT id FROM users ORDER BY id") + .map(|row: MySqlRow| row.get("id")) + .fetch_all(pool).await?; + Ok(q) } \ No newline at end of file diff --git a/src/cdn/templates.rs b/src/cdn/templates.rs new file mode 100644 index 0000000..ad41fd7 --- /dev/null +++ b/src/cdn/templates.rs @@ -0,0 +1,30 @@ +use askama::Template; +use axum::response::{IntoResponse, Html}; +use axum::body::{Full, Bytes}; +use axum::http::{Response, StatusCode}; +use std::convert::Infallible; + +pub struct HtmlTemplate(pub T); + +impl IntoResponse for HtmlTemplate + where + T: Template, +{ + type Body = Full; + type BodyError = Infallible; + + fn into_response(self) -> Response { + match self.0.render() { + Ok(html) => Html(html).into_response(), + Err(_) => (StatusCode::INTERNAL_SERVER_ERROR, "").into_response() + } + } +} + +#[derive(Template)] +#[template(path = "dir.html")] +pub struct DirTemplate { + pub entries: Vec, + pub prefix: String, + pub suffix: String, +} \ No newline at end of file diff --git a/templates/dir.html b/templates/dir.html new file mode 100644 index 0000000..b9b8f47 --- /dev/null +++ b/templates/dir.html @@ -0,0 +1,11 @@ + + + + + + + {% for entry in entries %} + {{entry}}
+ {% endfor %} + + \ No newline at end of file