aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock48
-rw-r--r--Cargo.toml1
-rw-r--r--src/epub.rs3
-rw-r--r--src/main.rs25
4 files changed, 70 insertions, 7 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d56d0fa..99349be 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 970f928..ea3a2c6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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(())
}