diff --git a/calibre-db/src/calibre.rs b/calibre-db/src/calibre.rs index 93277fa..1eb5d2e 100644 --- a/calibre-db/src/calibre.rs +++ b/calibre-db/src/calibre.rs @@ -90,6 +90,11 @@ impl Calibre { let conn = self.pool.get()?; Author::has_more_authors(&conn, author_sort) } + + pub fn scalar_author(&self, id: u64) -> Result { + let conn = self.pool.get()?; + Author::scalar_author(&conn, id) + } } #[cfg(test)] diff --git a/calibre-db/src/data/author.rs b/calibre-db/src/data/author.rs index 7e09caa..c48af6f 100644 --- a/calibre-db/src/data/author.rs +++ b/calibre-db/src/data/author.rs @@ -47,6 +47,12 @@ impl Author { Ok(stmt.query_row(params, Self::from_row)?) } + pub fn scalar_author(conn: &Connection, id: u64) -> Result { + let mut stmt = conn.prepare("SELECT id, name, sort FROM authors WHERE id = (:id)")?; + let params = named_params! { ":id": id }; + Ok(stmt.query_row(params, Self::from_row)?) + } + pub fn has_previous_authors( conn: &Connection, sort_name: &str, diff --git a/rusty-library/src/handlers/author.rs b/rusty-library/src/handlers/author.rs new file mode 100644 index 0000000..225b9fb --- /dev/null +++ b/rusty-library/src/handlers/author.rs @@ -0,0 +1,39 @@ +use std::sync::Arc; + +use calibre_db::data::pagination::SortOrder; +use poem::{ + error::InternalServerError, + handler, + web::{Data, Html, Path}, +}; +use tera::Context; + +use crate::{ + app_state::AppState, data::book::Book, handlers::error::SqliteError, templates::TEMPLATES, +}; + +#[handler] +pub async fn handler( + id: Path, + state: Data<&Arc>, +) -> Result, poem::Error> { + let author = state.calibre.scalar_author(*id).map_err(SqliteError)?; + let books = state + .calibre + .author_books(*id, u32::MAX.into(), None, SortOrder::ASC) + .map_err(SqliteError)?; + let books = books + .iter() + .filter_map(|x| Book::full_book(x, &state)) + .collect::>(); + + let mut context = Context::new(); + context.insert("title", &author.name); + context.insert("nav", &author.name); + context.insert("books", &books); + + TEMPLATES + .render("books", &context) + .map_err(InternalServerError) + .map(Html) +} diff --git a/rusty-library/src/handlers/authors.rs b/rusty-library/src/handlers/authors.rs index 08da35a..f85ff2b 100644 --- a/rusty-library/src/handlers/authors.rs +++ b/rusty-library/src/handlers/authors.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use calibre_db::data::pagination::SortOrder; +use calibre_db::{calibre::Calibre, data::pagination::SortOrder}; use poem::{ handler, web::{Data, Html, Path}, @@ -10,25 +10,27 @@ use crate::{app_state::AppState, handlers::paginated}; #[handler] pub async fn handler_init(state: Data<&Arc>) -> Result, poem::Error> { - paginated::render( - "authors", - || state.calibre.authors(25, None, &SortOrder::ASC), - |author| author.sort.clone(), - |cursor| state.calibre.has_previous_authors(cursor), - |cursor| state.calibre.has_more_authors(cursor), - ) + authors(&state.calibre, None, &SortOrder::ASC) } #[handler] pub async fn handler( Path((cursor, sort_order)): Path<(String, SortOrder)>, state: Data<&Arc>, +) -> Result, poem::Error> { + authors(&state.calibre, Some(&cursor), &sort_order) +} + +fn authors( + calibre: &Calibre, + cursor: Option<&str>, + sort_order: &SortOrder, ) -> Result, poem::Error> { paginated::render( "authors", - || state.calibre.authors(25, Some(&cursor), &sort_order), + || calibre.authors(25, cursor, sort_order), |author| author.sort.clone(), - |cursor| state.calibre.has_previous_authors(cursor), - |cursor| state.calibre.has_more_authors(cursor), + |cursor| calibre.has_previous_authors(cursor), + |cursor| calibre.has_more_authors(cursor), ) } diff --git a/rusty-library/src/handlers/error.rs b/rusty-library/src/handlers/error.rs index 7c3a1ef..cf0b966 100644 --- a/rusty-library/src/handlers/error.rs +++ b/rusty-library/src/handlers/error.rs @@ -17,13 +17,13 @@ impl ResponseError for SqliteError { fn status(&self) -> StatusCode { match &self.0 { DataStoreError::NoResults(_) => StatusCode::NOT_FOUND, - _ => StatusCode::BAD_GATEWAY, + _ => StatusCode::INTERNAL_SERVER_ERROR, } } fn as_response(&self) -> Response { let id = Uuid::new_v4(); - let internal_msg = self.to_string(); + let internal_msg = format!("{:?}", self); let external_msg = match &self.0 { DataStoreError::NoResults(_) => "item not found", _ => "internal server error", diff --git a/rusty-library/src/handlers/recents.rs b/rusty-library/src/handlers/recents.rs index e3ce040..90047ef 100644 --- a/rusty-library/src/handlers/recents.rs +++ b/rusty-library/src/handlers/recents.rs @@ -24,7 +24,7 @@ pub async fn handler(state: Data<&Arc>) -> Result, poem:: context.insert("nav", "recent"); context.insert("books", &recent_books); TEMPLATES - .render("recents", &context) + .render("books", &context) .map_err(InternalServerError) .map(Html) } diff --git a/rusty-library/src/main.rs b/rusty-library/src/main.rs index f31870c..b453e76 100644 --- a/rusty-library/src/main.rs +++ b/rusty-library/src/main.rs @@ -18,6 +18,7 @@ mod data { pub mod book; } mod handlers { + pub mod author; pub mod authors; pub mod books; pub mod cover; @@ -50,6 +51,7 @@ async fn main() -> Result<(), std::io::Error> { .at("/", get(handlers::recents::handler)) .at("/books", get(handlers::books::handler)) .at("/authors", get(handlers::authors::handler_init)) + .at("/authors/:id", get(handlers::author::handler)) .at( "/authors/:cursor/:sort_order", get(handlers::authors::handler), diff --git a/rusty-library/src/templates.rs b/rusty-library/src/templates.rs index 371b844..800ab30 100644 --- a/rusty-library/src/templates.rs +++ b/rusty-library/src/templates.rs @@ -7,7 +7,7 @@ pub static TEMPLATES: Lazy = Lazy::new(|| { ("base", include_str!("../templates/base.html")), ("book_card", include_str!("../templates/book_card.html")), ("authors", include_str!("../templates/authors.html")), - ("recents", include_str!("../templates/recents.html")), + ("books", include_str!("../templates/books.html")), ]) .expect("failed to parse tera templates"); diff --git a/rusty-library/templates/authors.html b/rusty-library/templates/authors.html index a9a208e..c06a92b 100644 --- a/rusty-library/templates/authors.html +++ b/rusty-library/templates/authors.html @@ -1,19 +1,21 @@ {% extends "base" %} {% block title %} {% if has_previous %} -← back +← back {% endif %} {% if has_previous and has_more %}|{% endif%} {% if has_more %} -more → +more → {% endif %} {% endblock title %} {% block content %}
{% for author in authors %} -
{{ author.name }}
+ +
{{ author.name }}
+
{% endfor %}
{% endblock content %} diff --git a/rusty-library/templates/recents.html b/rusty-library/templates/books.html similarity index 100% rename from rusty-library/templates/recents.html rename to rusty-library/templates/books.html