use std::sync::Arc; use app_state::AppState; use calibre_db::calibre::Calibre; use clap::Parser; use cli::Cli; use config::Config; use poem::{ endpoint::EmbeddedFilesEndpoint, get, listener::TcpListener, EndpointExt, Route, Server, }; use rust_embed::RustEmbed; mod app_state; mod basic_auth; mod cli; mod config; mod data { pub mod book; } mod handlers { pub mod author; pub mod authors; pub mod books; pub mod cover; pub mod download; pub mod error; pub mod paginated; pub mod recents; pub mod series; } mod templates; #[derive(RustEmbed)] #[folder = "static"] pub struct Files; #[tokio::main] async fn main() -> Result<(), std::io::Error> { if std::env::var_os("RUST_LOG").is_none() { std::env::set_var("RUST_LOG", "debug"); } tracing_subscriber::fmt::init(); let args = Cli::parse(); let config = Config::load(&args).expect("failed to load configuration"); let calibre = Calibre::load(&config.metadata_path).expect("failed to load calibre database"); let app_state = Arc::new(AppState { calibre, config }); let app = Route::new() .at("/", get(handlers::recents::handler)) .at("/books", get(handlers::books::handler_init)) .at("/books/:cursor/:sort_order", 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), ) .at("/series", get(handlers::series::handler)) .at("/cover/:id", get(handlers::cover::handler)) .at("/book/:id/:format", get(handlers::download::handler)) .nest("/static", EmbeddedFilesEndpoint::::new()) .data(app_state); Server::new(TcpListener::bind("[::]:3000")) .name("cops-web") .run(app) .await }