diff --git a/Cargo.lock b/Cargo.lock index 7fa3889..c4efe4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -305,7 +305,7 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "calibre-db" -version = "0.1.1" +version = "0.1.0" dependencies = [ "r2d2", "r2d2_sqlite", @@ -1222,7 +1222,7 @@ checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "little-hesinde" -version = "0.3.5" +version = "0.3.4" dependencies = [ "axum", "calibre-db", diff --git a/calibre-db/Cargo.toml b/calibre-db/Cargo.toml index fe95390..6c8185a 100644 --- a/calibre-db/Cargo.toml +++ b/calibre-db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "calibre-db" -version = "0.1.1" +version = "0.1.0" edition = "2024" license = { workspace = true } authors = { workspace = true } diff --git a/little-hesinde/Cargo.toml b/little-hesinde/Cargo.toml index 29bc55e..042a162 100644 --- a/little-hesinde/Cargo.toml +++ b/little-hesinde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "little-hesinde" -version = "0.3.5" +version = "0.3.4" edition = "2024" license = { workspace = true } authors = { workspace = true } @@ -9,7 +9,7 @@ description = "A very simple ebook server for a calibre library, providing a htm [dependencies] axum = { version = "0.8.4", features = ["http2", "tracing"] } -calibre-db = { path = "../calibre-db/", version = "0.1.1" } +calibre-db = { path = "../calibre-db/", version = "0.1.0" } clap = { version = "4.5.40", features = ["derive", "env"] } image = { version = "0.25.6", default-features = false, features = ["jpeg", "rayon"] } mime_guess = "2.0.5" diff --git a/little-hesinde/src/api/opds.rs b/little-hesinde/src/api/opds.rs index bf47892..1efe96c 100644 --- a/little-hesinde/src/api/opds.rs +++ b/little-hesinde/src/api/opds.rs @@ -1,7 +1,6 @@ //! Handlers for OPDS feeds. pub mod authors; pub mod books; -pub mod feed; pub mod recent; pub mod search; pub mod series; diff --git a/little-hesinde/src/api/opds/authors.rs b/little-hesinde/src/api/opds/authors.rs index fff754e..50b37c6 100644 --- a/little-hesinde/src/api/opds/authors.rs +++ b/little-hesinde/src/api/opds/authors.rs @@ -12,9 +12,10 @@ use time::OffsetDateTime; use crate::{ APP_NAME, api::{ - OPDS_TAG, SortOrder, + SortOrder, authors::{self, SingleAuthorError}, error::{ErrorResponse, HttpStatus}, + OPDS_TAG, }, app_state::AppState, http_error, diff --git a/little-hesinde/src/api/opds/books.rs b/little-hesinde/src/api/opds/books.rs index cad7b60..0cb0388 100644 --- a/little-hesinde/src/api/opds/books.rs +++ b/little-hesinde/src/api/opds/books.rs @@ -12,8 +12,9 @@ use time::OffsetDateTime; use crate::{ APP_NAME, api::{ - OPDS_TAG, SortOrder, + SortOrder, error::{ErrorResponse, HttpStatus}, + OPDS_TAG, }, app_state::AppState, data::book::Book, diff --git a/little-hesinde/src/api/opds/feed.rs b/little-hesinde/src/api/opds/feed.rs deleted file mode 100644 index 43f0daa..0000000 --- a/little-hesinde/src/api/opds/feed.rs +++ /dev/null @@ -1,140 +0,0 @@ -use axum::{ - http::{StatusCode, header}, - response::{IntoResponse, Response}, -}; -use snafu::{ResultExt, Snafu}; -use time::OffsetDateTime; - -use crate::{ - APP_NAME, - api::{ - OPDS_TAG, - error::{ErrorResponse, HttpStatus}, - }, - http_error, - opds::{ - content::Content, entry::Entry, error::AsXmlError, feed::Feed, link::Link, - media_type::MediaType, relation::Relation, - }, -}; - -#[derive(Debug, Snafu)] -/// Errors that can occur when rendering the root OPDS feed. -pub enum OdpsFeedError { - /// A failure to create the OPDS feed. - #[snafu(display("Failed to create opds feed."))] - Feed { source: AsXmlError }, -} -impl HttpStatus for OdpsFeedError { - fn status_code(&self) -> StatusCode { - match self { - OdpsFeedError::Feed { source: _ } => StatusCode::INTERNAL_SERVER_ERROR, - } - } -} -http_error!(OdpsFeedError); - -/// Render all books as OPDS entries embedded in a feed. -#[utoipa::path( - get, - path = "/", - tag = OPDS_TAG, - responses( - (status = OK, content_type = "application/atom+xml"), - (status = 500, description = "Server failure.", body = ErrorResponse) - ) -)] -pub async fn handler() -> Result { - let now = OffsetDateTime::now_utc(); - - let self_link = Link { - href: "/opds".to_string(), - media_type: MediaType::Navigation, - rel: Relation::Myself, - title: None, - count: None, - }; - let books_entry = Entry { - title: "Books".to_string(), - id: format!("{APP_NAME}:books"), - updated: now, - content: Some(Content { - media_type: MediaType::Text, - content: "Index of all books".to_string(), - }), - author: None, - links: vec![Link { - href: "/opds/books".to_string(), - media_type: MediaType::Navigation, - rel: Relation::Subsection, - title: None, - count: None, - }], - }; - - let authors_entry = Entry { - title: "Authors".to_string(), - id: format!("{APP_NAME}:authors"), - updated: now, - content: Some(Content { - media_type: MediaType::Text, - content: "Index of all authors".to_string(), - }), - author: None, - links: vec![Link { - href: "/opds/authors".to_string(), - media_type: MediaType::Navigation, - rel: Relation::Subsection, - title: None, - count: None, - }], - }; - - let series_entry = Entry { - title: "Series".to_string(), - id: format!("{APP_NAME}:series"), - updated: now, - content: Some(Content { - media_type: MediaType::Text, - content: "Index of all series".to_string(), - }), - author: None, - links: vec![Link { - href: "/opds/series".to_string(), - media_type: MediaType::Navigation, - rel: Relation::Subsection, - title: None, - count: None, - }], - }; - - let recents_entry = Entry { - title: "Recent Additions".to_string(), - id: format!("{APP_NAME}:recentbooks"), - updated: now, - content: Some(Content { - media_type: MediaType::Text, - content: "Recently added books".to_string(), - }), - author: None, - links: vec![Link { - href: "/opds/recent".to_string(), - media_type: MediaType::Navigation, - rel: Relation::Subsection, - title: None, - count: None, - }], - }; - - let feed = Feed::create( - now, - &format!("{APP_NAME}:catalog"), - "Little Hesinde", - self_link, - vec![], - vec![authors_entry, series_entry, books_entry, recents_entry], - ); - let xml = feed.as_xml().context(FeedSnafu)?; - - Ok(([(header::CONTENT_TYPE, "application/atom+xml")], xml).into_response()) -} diff --git a/little-hesinde/src/api/opds/recent.rs b/little-hesinde/src/api/opds/recent.rs index 43bf133..3f0c8e9 100644 --- a/little-hesinde/src/api/opds/recent.rs +++ b/little-hesinde/src/api/opds/recent.rs @@ -11,9 +11,9 @@ use time::OffsetDateTime; use crate::{ APP_NAME, api::{ - OPDS_TAG, books::{self, RecentBooksError}, error::{ErrorResponse, HttpStatus}, + OPDS_TAG, }, app_state::AppState, http_error, diff --git a/little-hesinde/src/api/opds/search.rs b/little-hesinde/src/api/opds/search.rs index 853eb84..0dde73b 100644 --- a/little-hesinde/src/api/opds/search.rs +++ b/little-hesinde/src/api/opds/search.rs @@ -12,9 +12,9 @@ use super::books::{RenderError, render_books}; use crate::{ APP_NAME, api::{ - OPDS_TAG, error::{ErrorResponse, HttpStatus}, search::{self, SearchQueryError}, + OPDS_TAG, }, app_state::AppState, http_error, diff --git a/little-hesinde/src/api/opds/series.rs b/little-hesinde/src/api/opds/series.rs index 20a78dd..a96a2bf 100644 --- a/little-hesinde/src/api/opds/series.rs +++ b/little-hesinde/src/api/opds/series.rs @@ -12,9 +12,10 @@ use time::OffsetDateTime; use crate::{ APP_NAME, api::{ - OPDS_TAG, SortOrder, + SortOrder, error::{ErrorResponse, HttpStatus}, series::{self, SingleSeriesError}, + OPDS_TAG, }, app_state::AppState, http_error, diff --git a/little-hesinde/src/api/routes.rs b/little-hesinde/src/api/routes.rs index 61c83ef..3b648ce 100644 --- a/little-hesinde/src/api/routes.rs +++ b/little-hesinde/src/api/routes.rs @@ -16,7 +16,6 @@ pub fn router(state: AppState) -> OpenApiRouter { let store = Arc::new(state); let opds_routes = OpenApiRouter::new() - .routes(routes!(opds::feed::handler)) .routes(routes!(opds::books::handler)) .routes(routes!(opds::recent::handler)) .routes(routes!(opds::series::handler))