diff options
| author | A Farzat <a@farzat.xyz> | 2026-11-04 15:25:31 +0300 |
|---|---|---|
| committer | A Farzat <a@farzat.xyz> | 2026-11-04 15:35:27 +0300 |
| commit | 3d54b73266646f73e855a175dbfd86ca2d50ba96 (patch) | |
| tree | 07708ce988d1d70b2d79af360338398a640975ad | |
| parent | 1020098497c37b7acfe3ff70845db58c3de22f98 (diff) | |
| download | oreilly-epub-0.1.4.tar.gz oreilly-epub-0.1.4.zip | |
Store the O'Reilly bookid as EPUB metadata instead of relying solely on
the filename. Preserving the original bookid makes it possible to look
up additional information from the upstream O'Reilly resource later,
even if the EPUB is renamed or imported into a library manager.
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/epub.rs | 3 | ||||
| -rw-r--r-- | src/main.rs | 9 | ||||
| -rw-r--r-- | src/xml.rs | 21 |
5 files changed, 28 insertions, 9 deletions
@@ -937,7 +937,7 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "oreilly-epub" -version = "0.1.3" +version = "0.1.4" dependencies = [ "anyhow", "clap", @@ -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(()) } @@ -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))?; |
