-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
560 additions
and
442 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,38 @@ | ||
# Project Dependencies | ||
Package: riprip | ||
Version: 0.2.9 | ||
Generated: 2024-09-06 02:45:24 UTC | ||
Version: 0.2.10 | ||
Generated: 2024-10-18 02:34:12 UTC | ||
|
||
| Package | Version | Author(s) | License | | ||
| ---- | ---- | ---- | ---- | | ||
| [ahash](https://github.com/tkaitchuck/ahash) | 0.8.11 | [Tom Kaitchuck](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [argyle](https://github.com/Blobfolio/argyle) | 0.8.1 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [argyle](https://github.com/Blobfolio/argyle) | 0.10.0 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [block-buffer](https://github.com/RustCrypto/utils) | 0.10.4 | RustCrypto Developers | Apache-2.0 or MIT | | ||
| [bytecount](https://github.com/llogiq/bytecount) | 0.6.8 | [Andre Bogus](mailto:[email protected]) and [Joshua Landau](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [cdtoc](https://github.com/Blobfolio/cdtoc) | 0.5.0 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [cdtoc](https://github.com/Blobfolio/cdtoc) | 0.5.1 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [cfg-if](https://github.com/alexcrichton/cfg-if) | 1.0.0 | [Alex Crichton](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [crc32fast](https://github.com/srijs/rust-crc32fast) | 1.4.2 | [Sam Rijs](mailto:[email protected]) and [Alex Crichton](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [crypto-common](https://github.com/RustCrypto/traits) | 0.1.6 | RustCrypto Developers | Apache-2.0 or MIT | | ||
| [ctrlc](https://github.com/Detegr/rust-ctrlc.git) | 3.4.5 | [Antti Keränen](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [dactyl](https://github.com/Blobfolio/dactyl) | 0.7.3 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [dactyl](https://github.com/Blobfolio/dactyl) | 0.7.4 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [digest](https://github.com/RustCrypto/traits) | 0.10.7 | RustCrypto Developers | Apache-2.0 or MIT | | ||
| [faster-hex](https://github.com/NervosFoundation/faster-hex) | 0.9.0 | [zhangsoledad](mailto:[email protected]) | MIT | | ||
| [faster-hex](https://github.com/NervosFoundation/faster-hex) | 0.10.0 | [zhangsoledad](mailto:[email protected]) | MIT | | ||
| [fastrand](https://github.com/smol-rs/fastrand) | 2.1.1 | [Stjepan Glavina](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [fyi_msg](https://github.com/Blobfolio/fyi) | 0.14.0 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [fyi_msg](https://github.com/Blobfolio/fyi) | 1.1.1 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [generic-array](https://github.com/fizyk20/generic-array.git) | 0.14.7 | [Bartłomiej Kamiński](mailto:[email protected]) and [Aaron Trent](mailto:[email protected]) | MIT | | ||
| [itoa](https://github.com/dtolnay/itoa) | 1.0.11 | [David Tolnay](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [libcdio-sys](https://github.com/MonterraByte/libcdio-sys) | 0.5.1 | [Joaquim Monteiro](mailto:[email protected]) | GPL-3.0+ | | ||
| [log](https://github.com/rust-lang/log) | 0.4.22 | The Rust Project Developers | Apache-2.0 or MIT | | ||
| [minreq](https://github.com/neonmoe/minreq) | 2.12.0 | [Jens Pitkanen](mailto:[email protected]) | ISC | | ||
| [once_cell](https://github.com/matklad/once_cell) | 1.19.0 | [Aleksey Kladov](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [oxford_join](https://github.com/Blobfolio/oxford_join) | 0.2.10 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [riprip_core](https://github.com/Blobfolio/riprip) | 0.2.9 | [Josh Stoik](mailto:[email protected]) | WTFPL | | ||
| [once_cell](https://github.com/matklad/once_cell) | 1.20.2 | [Aleksey Kladov](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [oxford_join](https://github.com/Blobfolio/oxford_join) | 0.4.0 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [riprip_core](https://github.com/Blobfolio/riprip) | 0.2.10 | [Josh Stoik](mailto:[email protected]) | WTFPL | | ||
| [serde](https://github.com/serde-rs/serde) | 1.0.210 | [Erick Tryzelaar](mailto:[email protected]) and [David Tolnay](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [sha1](https://github.com/RustCrypto/hashes) | 0.10.6 | RustCrypto Developers | Apache-2.0 or MIT | | ||
| [tempfile](https://github.com/Stebalien/tempfile) | 3.12.0 | [Steven Allen](mailto:[email protected]), The Rust Project Developers, [Ashley Mannix](mailto:[email protected]), and [Jason White](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [terminal_size](https://github.com/eminence/terminal-size) | 0.3.0 | [Andrew Chin](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [tempfile](https://github.com/Stebalien/tempfile) | 3.13.0 | [Steven Allen](mailto:[email protected]), The Rust Project Developers, [Ashley Mannix](mailto:[email protected]), and [Jason White](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [terminal_size](https://github.com/eminence/terminal-size) | 0.4.0 | [Andrew Chin](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [trimothy](https://github.com/Blobfolio/trimothy) | 0.3.1 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [typenum](https://github.com/paholg/typenum) | 1.17.0 | [Paho Lurie-Gregg](mailto:[email protected]) and [Andre Bogus](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [unicode-width](https://github.com/unicode-rs/unicode-width) | 0.1.13 | [kwantam](mailto:[email protected]) and [Manish Goregaokar](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [utc2k](https://github.com/Blobfolio/utc2k) | 0.9.1 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [unicode-width](https://github.com/unicode-rs/unicode-width) | 0.2.0 | [kwantam](mailto:[email protected]) and [Manish Goregaokar](mailto:[email protected]) | Apache-2.0 or MIT | | ||
| [utc2k](https://github.com/Blobfolio/utc2k) | 0.10.0 | [Blobfolio, LLC.](mailto:[email protected]) | WTFPL | | ||
| [zerocopy](https://github.com/google/zerocopy) | 0.7.35 | [Joshua Liebow-Feeser](mailto:[email protected]) | Apache-2.0, BSD-2-Clause, or MIT | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "riprip" | ||
version = "0.2.9" | ||
version = "0.2.10" | ||
license = "WTFPL" | ||
authors = ["Josh Stoik <[email protected]>"] | ||
edition = "2021" | ||
|
@@ -125,15 +125,18 @@ label = "<NUM>" | |
description = "Rip one or more specific tracks (rather than the whole disc). Multiple tracks can be separated by commas (2,3), specified as an inclusive range (2-3), and/or given their own -t/--track (-t 2 -t 3). Track 0 can be used to rip the HTOA, if any. [default: the whole disc]" | ||
duplicate = true | ||
|
||
[build-dependencies] | ||
argyle = "0.10.*" | ||
|
||
[dependencies] | ||
argyle = "0.8.*" | ||
argyle = "0.10.*" | ||
ctrlc = "=3.4.5" | ||
dactyl = "0.7.*" | ||
oxford_join = "0.2.*" | ||
utc2k = "0.9.*" | ||
oxford_join = "0.4.*" | ||
utc2k = "0.10.*" | ||
|
||
[dependencies.fyi_msg] | ||
version = "0.14.*" | ||
version = "1.1.*" | ||
features = [ "progress" ] | ||
|
||
[dependencies.riprip_core] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/*! | ||
# Rip Rip: Build | ||
*/ | ||
|
||
use argyle::KeyWordsBuilder; | ||
use std::path::PathBuf; | ||
|
||
|
||
|
||
/// # Set Up CLI Arguments. | ||
pub fn main() { | ||
let mut builder = KeyWordsBuilder::default(); | ||
builder.push_keys([ | ||
"--backward", "--backwards", | ||
"--flip-flop", | ||
"-h", "--help", | ||
"--no-resume", | ||
"--no-rip", | ||
"--no-summary", | ||
"--reset", | ||
"--status", | ||
"--strict", | ||
"--sync", | ||
"-v", "--verbose", | ||
"-V", "--version", | ||
]); | ||
builder.push_keys_with_values([ | ||
"-c", "--cache", | ||
"-d", "--dev", | ||
"--confidence", | ||
"-o", "--offset", | ||
"-p", "--pass", "--passes", | ||
"-r", "--reread", "--rereads", | ||
"-t", "--track", "--tracks", | ||
]); | ||
builder.save(out_path("argyle.rs")); | ||
} | ||
|
||
/// # Output Path. | ||
/// | ||
/// Append the sub-path to OUT_DIR and return it. | ||
fn out_path(stub: &str) -> PathBuf { | ||
std::fs::canonicalize(std::env::var("OUT_DIR").expect("Missing OUT_DIR.")) | ||
.expect("Missing OUT_DIR.") | ||
.join(stub) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
/*! | ||
# Rip Rip Hooray: CLI | ||
*/ | ||
|
||
use argyle::Argument; | ||
use dactyl::traits::BytesToUnsigned; | ||
use riprip_core::{ | ||
Disc, | ||
DriveVendorModel, | ||
ReadOffset, | ||
RipRipError, | ||
RipOptions, | ||
}; | ||
|
||
|
||
|
||
/// # Options Return Type. | ||
/// | ||
/// This is awful, but not quite awful enough to warrant a struct. Haha. | ||
pub(super) type Parsed = ( | ||
RipOptions, | ||
Disc, | ||
Option<DriveVendorModel>, | ||
bool, | ||
bool, | ||
bool, | ||
); | ||
|
||
|
||
|
||
/// # Parse Options. | ||
pub(super) fn parse() -> Result<Parsed, RipRipError> { | ||
let args = argyle::args() | ||
.with_keywords(include!(concat!(env!("OUT_DIR"), "/argyle.rs"))); | ||
|
||
let mut opts = RipOptions::default(); | ||
let mut no_rip = false; | ||
let mut no_summary = false; | ||
let mut status = false; | ||
let mut cache = None; | ||
let mut dev = None; | ||
let mut offset = None; | ||
let mut tracks = String::new(); | ||
for arg in args { | ||
match arg { | ||
Argument::Key("--backward" | "--backwards") => { | ||
opts = opts.with_backwards(true); | ||
}, | ||
Argument::Key("--flip-flop") => { | ||
opts = opts.with_flip_flop(true); | ||
}, | ||
Argument::Key("-h" | "--help") => return Err(RipRipError::PrintHelp), | ||
Argument::Key("--no-resume") => { opts = opts.with_resume(false); }, | ||
Argument::Key("--no-rip") => { no_rip = true; }, | ||
Argument::Key("--no-summary") => { no_summary = true; }, | ||
Argument::Key("--reset") => { opts = opts.with_reset(true); }, | ||
Argument::Key("--status") => { status = true; }, | ||
Argument::Key("--strict") => { opts = opts.with_strict(true); }, | ||
Argument::Key("--sync") => { opts = opts.with_sync(true); }, | ||
Argument::Key("-v" | "--verbose") => { opts = opts.with_verbose(true); }, | ||
Argument::Key("-V" | "--version") => return Err(RipRipError::PrintVersion), | ||
|
||
Argument::KeyWithValue("-c" | "--cache", s) => { | ||
let s = parse_rip_option_cache(s)?; | ||
cache.replace(s); | ||
}, | ||
Argument::KeyWithValue("-d" | "--dev", s) => { dev.replace(s); }, | ||
Argument::KeyWithValue("-o" | "--offset", s) => { | ||
let s = ReadOffset::try_from(s.trim().as_bytes()) | ||
.map_err(|_| RipRipError::CliParse("-o/--offset"))?; | ||
offset.replace(s); | ||
}, | ||
Argument::KeyWithValue("-p" | "--pass" | "--passes", s) => { | ||
let s = u8::btou(s.trim().as_bytes()) | ||
.ok_or(RipRipError::CliParse("-p/--passes"))?; | ||
opts = opts.with_passes(s); | ||
}, | ||
Argument::KeyWithValue("-r" | "--reread" | "--rereads", s) => { | ||
let (a, b) = parse_rip_option_reread(s.as_bytes())?; | ||
opts = opts.with_rereads(a, b); | ||
}, | ||
Argument::KeyWithValue("-t" | "--track" | "--tracks", s) => { | ||
if ! tracks.is_empty() { tracks.push(','); } | ||
tracks.push_str(&s); | ||
}, | ||
|
||
_ => {}, | ||
} | ||
} | ||
|
||
// Figure out the disc and drive. | ||
let disc = Disc::new(dev)?; | ||
let drivevendormodel = disc.drive_vendor_model(); | ||
|
||
// Set up some drive-dependent things. | ||
if let Some(v) = cache.or_else(|| drivevendormodel.and_then(|vm| vm.detect_cache())) { | ||
opts = opts.with_cache(v); | ||
} | ||
if let Some(v) = offset.or_else(|| drivevendormodel.and_then(|vm| vm.detect_offset())) { | ||
opts = opts.with_offset(v); | ||
} | ||
|
||
// If we just want the status or didn't receive any -t, add everything. | ||
if status || tracks.is_empty() { | ||
let toc = disc.toc(); | ||
if toc.htoa().is_some() { opts = opts.with_track(0); } | ||
for t in toc.audio_tracks() { opts = opts.with_track(t.number()); } | ||
} | ||
// Otherwise parse what we gathered earlier. | ||
else { opts = parse_rip_option_tracks(&disc, opts, &tracks)?; } | ||
|
||
Ok(( | ||
opts, | ||
disc, | ||
drivevendormodel, | ||
no_rip, | ||
no_summary, | ||
status, | ||
)) | ||
} | ||
|
||
|
||
|
||
/// # Parse Cache Size. | ||
fn parse_rip_option_cache(cache: String) -> Result<u16, RipRipError> { | ||
let cache = cache.into_bytes(); | ||
cache.iter() | ||
.position(|&b| matches!(b, b'm' | b'M')) | ||
.map_or_else( | ||
|| u16::btou(cache.trim_ascii()), | ||
|pos| u16::btou(cache[..pos].trim_ascii()).and_then(|v| v.checked_mul(1024)), | ||
) | ||
.ok_or(RipRipError::CliParse("-c/--cache")) | ||
} | ||
|
||
/// # Parse Re-read Option. | ||
fn parse_rip_option_reread(v: &[u8]) -> Result<(u8, u8), RipRipError> { | ||
// Default. | ||
let mut a = 2; | ||
let mut b = 2; | ||
|
||
// If there's a comma, there could be up to two values. Keep the | ||
// default if either is omitted. | ||
let v = v.trim_ascii(); | ||
if let Some(pos) = v.iter().position(|b| b','.eq(b)) { | ||
let tmp = &v[..pos]; | ||
if ! tmp.is_empty() { | ||
a = u8::btou(tmp).ok_or(RipRipError::CliParse("-r/--rereads"))?; | ||
} | ||
let tmp = &v[pos + 1..]; | ||
if ! tmp.is_empty() { | ||
b = u8::btou(tmp).ok_or(RipRipError::CliParse("-r/--rereads"))?; | ||
} | ||
} | ||
// A number by itself affects only the first part. | ||
else { | ||
a = u8::btou(v).ok_or(RipRipError::CliParse("-r/--rereads"))?; | ||
} | ||
|
||
Ok((a, b)) | ||
} | ||
|
||
/// # Parse Rip Tracks. | ||
fn parse_rip_option_tracks(disc: &Disc, mut opts: RipOptions, tracks: &str) | ||
-> Result<RipOptions, RipRipError> { | ||
for v in tracks.split(',') { | ||
let v = v.as_bytes().trim_ascii(); | ||
if v.is_empty() { continue; } | ||
|
||
// It might be a range. | ||
if let Some(pos) = v.iter().position(|b| b'-'.eq(b)) { | ||
// Split. | ||
let a = v[..pos].trim_ascii(); | ||
let b = v[pos + 1..].trim_ascii(); | ||
if a.is_empty() || b.is_empty() { | ||
return Err(RipRipError::CliParse("-t/--tracks")); | ||
} | ||
|
||
// Decode. | ||
let a = u8::btou(a).ok_or(RipRipError::CliParse("-t/--tracks"))?; | ||
let b = u8::btou(b).ok_or(RipRipError::CliParse("-t/--tracks"))?; | ||
|
||
// Add them all! | ||
if a <= b { | ||
for idx in a..=b { opts = opts.with_track(idx); } | ||
} | ||
else { return Err(RipRipError::CliParse("-t/--tracks")); } | ||
} | ||
// Otherwise it should be a single index. | ||
else { | ||
let v = u8::btou(v).ok_or(RipRipError::CliParse("-t/--tracks"))?; | ||
opts = opts.with_track(v); | ||
} | ||
} | ||
|
||
// Make sure the desired tracks are actually on the disc. | ||
let toc = disc.toc(); | ||
if opts.has_tracks() { | ||
for idx in opts.tracks() { | ||
// Make sure the track is valid. | ||
let good = | ||
if idx == 0 { toc.htoa().is_some() } | ||
else { toc.audio_track(usize::from(idx)).is_some() }; | ||
if ! good { return Err(RipRipError::NoTrack(idx)); } | ||
} | ||
} | ||
// If no tracks were specified, DO IT ALL. | ||
else { | ||
if toc.htoa().is_some() { opts = opts.with_track(0); } | ||
for t in toc.audio_tracks() { opts = opts.with_track(t.number()); } | ||
} | ||
|
||
Ok(opts) | ||
} |
Oops, something went wrong.