Skip to content

Commit

Permalink
feat(eco): New binary "eco" and normalization of api
Browse files Browse the repository at this point in the history
  • Loading branch information
gaku-sei committed Dec 29, 2023
1 parent e061ba4 commit 0077afd
Show file tree
Hide file tree
Showing 33 changed files with 380 additions and 162 deletions.
29 changes: 20 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = ["eco-cbz", "eco-converter", "eco-merge", "eco-pack", "eco-viewer"]
members = ["eco", "eco-cbz", "eco-convert", "eco-merge", "eco-pack", "eco-view"]

[workspace.package]
rust-version = "1.73.0"
Expand All @@ -21,7 +21,10 @@ dioxus = "0.4.0"
dioxus-desktop = "0.4.0"
dunce = "1.0.4"
eco-cbz = { path = "./eco-cbz" }
eco-convert = { path = "./eco-convert" }
eco-merge = { path = "./eco-merge" }
eco-pack = { path = "./eco-pack" }
eco-view = { path = "./eco-view" }
epub = "2.1.1"
futures = "0.3.28"
glob = "0.3.1"
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,33 @@ The repository host multiple cli and gui that allows you to edit, convert, merge

## Tools (with supported format):

- `eco-converter` - cli - Convert e-books to any format (from pdf, mobi, and DRM-free azw3, to cbz only for now)
- `eco-merge` - cli - Merge e-books together when it makes sense (cbz)
- `eco-pack` - cli - pack images into an e-book file (cbz)
- `eco-viewer` - gui - A dead simple e-book reader (cbz)
- `eco convert` - cli - Convert e-books to any format (from pdf, mobi, and DRM-free azw3, to cbz only for now)
- `eco merge` - cli - Merge e-books together when it makes sense (cbz)
- `eco pack` - cli - pack images into an e-book file (cbz)
- `eco view` - gui - A dead simple e-book reader (cbz)

## Eco Converter

Converts e-books from \* to \* (only pdf, mobi, and DRM-free azw3 to cbz supported for the moment):

```bash
eco-converter "archive.azw3" --from azw3 --outdir out
eco convert "archive.azw3" --from azw3 --outdir out
```

## Eco Merge (cbz only for now)

This will look for all the e-books in `path` and which file name contains `something` and merge them into `output/merged_archive.cbz`:

```bash
eco-merge --archives-glob "path/**/*something*" --outdir "output" --name "merged_archive"
eco merge --archives-glob "path/**/*something*" --outdir "output" --name "merged_archive"
```

## Eco Pack (cbz only for now)

Takes all the `png` files under `source` and pack them into the `archive.cbz` file:

```bash
eco-pack "source/*.png" --name archive --autosplit
eco pack "source/*.png" --name archive --autosplit
```

Options include:
Expand All @@ -39,10 +39,10 @@ Options include:
- `--contrast`: change contrast
- `--brightness`: change brightness

## Eco Viewer (cbz only for now)
## Eco View (cbz only for now)

View any e-book file with this simple gui:

```bash
eco-viewer "my_archive.cbz"
eco view "my_archive.cbz"
```
2 changes: 0 additions & 2 deletions eco-cbz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ edition.workspace = true
rust-version.workspace = true

[dependencies]
clap = { workspace = true, optional = true }
camino.workspace = true
chrono = { workspace = true, features = ["serde"], optional = true }
image = { workspace = true, features = ["webp-encoder"] }
Expand All @@ -19,5 +18,4 @@ zip.workspace = true

[features]
default = []
clap = ["dep:clap"]
metadata = ["dep:chrono", "dep:serde", "dep:serde_json", "dep:serde_repr"]
6 changes: 2 additions & 4 deletions eco-cbz/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
use std::{io, result};

use zip::result::ZipError;

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("IO error {0}")]
IO(#[from] io::Error),
IO(#[from] std::io::Error),

#[error("Zip error {0}")]
Zip(#[from] ZipError),
Expand Down Expand Up @@ -46,4 +44,4 @@ pub enum Error {
MetadataValue(String),
}

pub type Result<T, E = Error> = result::Result<T, E>;
pub type Result<T, E = Error> = std::result::Result<T, E>;
15 changes: 0 additions & 15 deletions eco-cbz/src/image.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::{
fmt::Display,
io::{BufRead, Cursor, Read, Seek},
path::Path,
};
Expand All @@ -10,25 +9,11 @@ use zip::read::ZipFile;
use crate::errors::{Error, Result};

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
pub enum ReadingOrder {
Rtl,
Ltr,
}

impl Display for ReadingOrder {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Self::Ltr => "ltr",
Self::Rtl => "rtl",
}
)
}
}

#[derive(Debug, PartialEq)]
pub struct Image {
dynamic_image: DynamicImage,
Expand Down
6 changes: 2 additions & 4 deletions eco-converter/Cargo.toml → eco-convert/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
[package]
name = "eco-converter"
name = "eco-convert"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true

[dependencies]
anyhow.workspace = true
camino.workspace = true
clap.workspace = true
eco-cbz.workspace = true
eco-pack.workspace = true
html5ever = { workspace = true, optional = true }
image.workspace = true
markup5ever_rcdom = { workspace = true, optional = true }
mobi.workspace = true
pdf.workspace = true
thiserror.workspace = true
tl.workspace = true
tracing.workspace = true
tracing-subscriber.workspace = true

[features]
default = []
Expand Down
25 changes: 25 additions & 0 deletions eco-convert/src/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("io error {0}")]
Io(#[from] std::io::Error),

#[error("cbz error {0}")]
Cbz(#[from] eco_cbz::Error),

#[error("mobi error {0}")]
Mobi(#[from] mobi::MobiError),

#[error("pdf error {0}")]
Pdf(#[from] pdf::PdfError),

#[error("ts parse error {0}")]
TlParse(#[from] tl::ParseError),

#[error("pack error {0}")]
Pack(#[from] eco_pack::Error),

#[error("invalid mobi version {0}")]
InvalidMobiVersion(u32),
}

pub type Result<T, E = Error> = std::result::Result<T, E>;
77 changes: 77 additions & 0 deletions eco-convert/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#![deny(clippy::all, clippy::pedantic)]

use std::fs;

use camino::Utf8PathBuf;
use eco_cbz::image::ReadingOrder;
use eco_pack::pack_imgs_to_cbz;
use tracing::info;

pub use crate::errors::{Error, Result};
pub use crate::mobi::convert_to_imgs as mobi_to_imgs;
pub use crate::pdf::convert_to_imgs as pdf_to_imgs;

pub mod errors;
mod mobi;
mod pdf;
mod utils;

#[derive(Debug, Clone, Copy)]
pub enum Format {
Mobi,
Azw3,
Pdf,
}

#[derive(Debug)]
pub struct ConvertOptions {
/// Path to the source file
pub path: Utf8PathBuf,

/// Source format
pub from: Format,

/// Dir to output images
pub outdir: Utf8PathBuf,

/// The archive name
pub name: String,

/// Adjust images contrast
pub contrast: Option<f32>,

/// Adjust images brightness
pub brightness: Option<i32>,

/// Blur image (slow with big numbers)
pub blur: Option<f32>,

/// Automatically split landscape images into 2 pages
pub autosplit: bool,

/// Reading order
pub reading_order: ReadingOrder,
}

#[allow(clippy::missing_errors_doc)]
pub fn convert(opts: ConvertOptions) -> Result<()> {
fs::create_dir_all(&opts.outdir)?;
let imgs = match opts.from {
Format::Mobi | Format::Azw3 => mobi_to_imgs(opts.path)?,
Format::Pdf => pdf_to_imgs(opts.path)?,
};
info!("found {} imgs", imgs.len());

let cbz_writer = pack_imgs_to_cbz(
imgs,
opts.contrast,
opts.brightness,
opts.blur,
opts.autosplit,
opts.reading_order,
)?;

cbz_writer.write_to_path(opts.outdir.join(format!("{}.cbz", opts.name)))?;

Ok(())
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
use std::{fs, io::BufReader, path::Path};

use anyhow::Result;
use eco_cbz::image::Image;
use html5ever::{parse_document, tendril::TendrilSink, ParseOpts};
use markup5ever_rcdom::{Node, NodeData, RcDom};
use mobi::Mobi;
use tracing::{error, warn};

use crate::utils::base_32;
use crate::{utils::base_32, Result};

use super::MobiVersion;

#[allow(clippy::missing_errors_doc)]
pub fn convert_to_imgs(path: impl AsRef<Path>) -> Result<Vec<Image>> {
let mobi = Mobi::from_path(path)?;
// Or is it `gen_version`? Both were equal in all the files I tested.
Expand Down
6 changes: 4 additions & 2 deletions eco-converter/src/mobi/mod.rs → eco-convert/src/mobi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ pub use html5ever_parser::convert_to_imgs;
#[cfg(not(feature = "html5ever"))]
pub use tl_parser::convert_to_imgs;

use crate::Error;

#[cfg(feature = "html5ever")]
mod html5ever_parser;
#[cfg(not(feature = "html5ever"))]
Expand All @@ -15,13 +17,13 @@ enum MobiVersion {
}

impl TryFrom<u32> for MobiVersion {
type Error = anyhow::Error;
type Error = crate::Error;

fn try_from(version: u32) -> std::result::Result<Self, Self::Error> {
match version {
6 => Ok(Self::Mobi6),
8 => Ok(Self::Mobi8),
_ => anyhow::bail!("invalid version {version}"),
_ => Err(Error::InvalidMobiVersion(version)),
}
}
}
Loading

0 comments on commit 0077afd

Please sign in to comment.