aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/epub.rs3
-rw-r--r--src/main.rs9
-rw-r--r--src/xml.rs21
5 files changed, 28 insertions, 9 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0e418ac..549e18b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -937,7 +937,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "oreilly-epub"
-version = "0.1.3"
+version = "0.1.4"
dependencies = [
"anyhow",
"clap",
diff --git a/Cargo.toml b/Cargo.toml
index 198a2d6..29801ba 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "oreilly-epub"
-version = "0.1.3"
+version = "0.1.4"
edition = "2024"
license = "GPL-3.0-only"
diff --git a/src/epub.rs b/src/epub.rs
index 1336115..96b1f2c 100644
--- a/src/epub.rs
+++ b/src/epub.rs
@@ -96,6 +96,7 @@ pub async fn download_one_file(
/// Creates the EPUB archive (creates zip and includes all files in it).
pub fn create_epub_archive(
+ bookid: &str,
epub_data: &EpubResponse,
epub_root: &Path,
output_epub: &Path,
@@ -154,7 +155,7 @@ pub fn create_epub_archive(
&mut zip,
)?;
} else if entry.ourn == opf_entry.ourn {
- write_modified_opf(buf_reader, &mut zip, &epub_data.descriptions.plain)?;
+ write_modified_opf(buf_reader, &mut zip, bookid, &epub_data.descriptions.plain)?;
} else {
std::io::copy(&mut buf_reader, &mut zip)?;
}
diff --git a/src/main.rs b/src/main.rs
index 141fd12..5b0a2be 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -148,7 +148,14 @@ async fn main() -> Result<()> {
.await?;
}
println!("Generating the EPUB file...");
- create_epub_archive(&epub_data, &epub_root, &epub_path, &file_entries, &chapters)?;
+ create_epub_archive(
+ &args.bookid,
+ &epub_data,
+ &epub_root,
+ &epub_path,
+ &file_entries,
+ &chapters,
+ )?;
Ok(())
}
diff --git a/src/xml.rs b/src/xml.rs
index 239fac3..f37b169 100644
--- a/src/xml.rs
+++ b/src/xml.rs
@@ -124,6 +124,7 @@ pub fn build_epub_chapter<R: BufRead, W: Write>(
pub fn write_modified_opf<R: BufRead, W: Write>(
opf_input: R,
mut out: &mut W,
+ bookid: &str,
description: &str,
) -> Result<()> {
// Setup the XML Reader and Writer.
@@ -146,11 +147,21 @@ pub fn write_modified_opf<R: BufRead, W: Write>(
writer.write_event(Event::Start(tag_data))?;
}
Ok(Event::End(tag_data)) => {
- // Write description if end of metadata is reached without finding one.
- if tag_data.name().as_ref() == b"metadata" && !desc_found {
- writer.write_event(Event::Start(BytesStart::new("dc:description")))?;
- writer.write_event(Event::Text(BytesText::new(description)))?;
- writer.write_event(Event::End(BytesEnd::new("dc:description")))?;
+ // Extra attributes are added just before the closing metadata tag.
+ if tag_data.name().as_ref() == b"metadata" {
+ // A new dc:identifier records the O'Reilly resource ID used to obtain the book.
+ let mut start_elem = BytesStart::new("dc:identifier");
+ start_elem.push_attribute(("id", "oreilly-id"));
+ writer.write_event(Event::Start(start_elem))?;
+ let oreilly_id = &format!("urn:orm:book:{bookid}");
+ writer.write_event(Event::Text(BytesText::new(oreilly_id)))?;
+ writer.write_event(Event::End(BytesEnd::new("dc:identifier")))?;
+ // Write description if end of metadata is reached without finding one.
+ if !desc_found {
+ writer.write_event(Event::Start(BytesStart::new("dc:description")))?;
+ writer.write_event(Event::Text(BytesText::new(description)))?;
+ writer.write_event(Event::End(BytesEnd::new("dc:description")))?;
+ }
}
// Pass through unmodified.
writer.write_event(Event::End(tag_data))?;