diff options
| -rw-r--r-- | Cargo.lock | 48 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/epub.rs | 3 | ||||
| -rw-r--r-- | src/main.rs | 25 |
4 files changed, 70 insertions, 7 deletions
@@ -285,6 +285,27 @@ dependencies = [ ] [[package]] +name = "directories" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] name = "displaydoc" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -760,6 +781,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] +name = "libredox" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +dependencies = [ + "libc", +] + +[[package]] name = "litemap" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -879,11 +909,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] name = "oreilly-epub" version = "0.1.0" dependencies = [ "anyhow", "clap", + "directories", "ogrim", "quick-xml", "relative-path", @@ -1104,6 +1141,17 @@ dependencies = [ ] [[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.18", +] + +[[package]] name = "relative-path" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -15,3 +15,4 @@ serde_json = "1.0.149" tokio = { version = "1.49.0", features = ["full"] } url = { version = "2.5.8", features = ["serde"] } zip = { version = "8.1.0", default-features = false, features = ["deflate"] } +directories = "6.0.0" diff --git a/src/epub.rs b/src/epub.rs index 79ac11e..4f31784 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -74,6 +74,9 @@ pub fn create_epub_archive( file_entries: &[FileEntry], chapters: &HashMap<String, Chapter>, ) -> Result<()> { + if let Some(parent_dir) = output_epub.parent() { + std::fs::create_dir_all(parent_dir)?; + } let out_file = std::fs::File::create(output_epub)?; let mut zip = ZipWriter::new(out_file); diff --git a/src/main.rs b/src/main.rs index c7de6ee..2255b18 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,13 +4,13 @@ mod models; mod xml; use std::collections::HashMap; -use std::path::Path; use crate::epub::{create_epub_archive, download_all_files}; use crate::http_client::build_authenticated_client; use crate::models::{Chapter, EpubResponse, FileEntry, Paginated, SpineItem, TocNode}; use anyhow::{Context, Result}; use clap::Parser; +use directories::{BaseDirs, UserDirs}; use reqwest::Client; /// Download and generate an EPUB from Safari Books Online. @@ -88,9 +88,21 @@ where #[tokio::main] async fn main() -> Result<()> { + // Obtain relevant XDG base directories. + let base_dirs = BaseDirs::new().context("Could not get XDG base directories.")?; + let data_root = base_dirs.data_dir().join("oreilly-epub"); + // Parse the command line arguments let args = Args::parse(); + // Obtain the path to the destination EPUB file. + let user_dirs = UserDirs::new().context("Could not get XDG user directories.")?; + let epub_path = user_dirs + .download_dir() + .unwrap_or(&user_dirs.home_dir().join("Downloads")) + .join("oreilly-epub") + .join(format!("{}.epub", args.bookid)); + println!("Welcome to SafariBooks Rust Port!"); println!("Target Book ID: {}", args.bookid); @@ -115,14 +127,13 @@ async fn main() -> Result<()> { let spine_items: Vec<SpineItem> = fetch_all_pages(&client, epub_data.spine.clone()).await?; let toc_vec: Vec<TocNode> = fetch_direct_array(&client, &epub_data.table_of_contents).await?; - let dest_root = format!("Books/{}/epub_root", args.bookid); - let dest_root = Path::new(&dest_root); + let epub_root = data_root.join("files").join(&args.bookid); if !args.skip_download { - download_all_files(&client, &file_entries, dest_root).await?; + println!("Downloading files from the server..."); + download_all_files(&client, &file_entries, &epub_root).await?; } - let epub_path = format!("Books/{0}/{0}.epub", args.bookid); - let epub_path = Path::new(&epub_path); - create_epub_archive(&epub_data, dest_root, epub_path, &file_entries, &chapters)?; + println!("Generating the EPUB file..."); + create_epub_archive(&epub_data, &epub_root, &epub_path, &file_entries, &chapters)?; Ok(()) } |
