107 lines
2.9 KiB
Rust
107 lines
2.9 KiB
Rust
|
use poem::{handler, web::WithContentType, IntoResponse};
|
||
|
use time::OffsetDateTime;
|
||
|
|
||
|
use crate::{
|
||
|
handlers::error::HandlerError,
|
||
|
opds::{
|
||
|
content::Content, entry::Entry, feed::Feed, link::Link, media_type::MediaType,
|
||
|
relation::Relation,
|
||
|
},
|
||
|
};
|
||
|
|
||
|
#[handler]
|
||
|
pub async fn handler() -> Result<WithContentType<String>, poem::Error> {
|
||
|
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: "rusty:books".to_string(),
|
||
|
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: "rusty:authors".to_string(),
|
||
|
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: "rusty:series".to_string(),
|
||
|
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: "rusty:recentbooks".to_string(),
|
||
|
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,
|
||
|
"rusty:catalog",
|
||
|
"Rusty-Library",
|
||
|
self_link,
|
||
|
vec![],
|
||
|
vec![authors_entry, series_entry, books_entry, recents_entry],
|
||
|
);
|
||
|
let xml = feed.as_xml().map_err(HandlerError::OpdsError)?;
|
||
|
|
||
|
Ok(xml.with_content_type("application/atom+xml"))
|
||
|
}
|