summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakka <jakkadoujin@gmail.com>2025-06-15 16:29:07 +0300
committerjakka <jakkadoujin@gmail.com>2025-06-15 16:29:07 +0300
commit6d9e1300a2769fe4c0f4b290122143f52fc7a3ef (patch)
treeb898543945cfa69a689561bcf38637f68271fc83
parentd239e5dbe1c35553c7663b8079719f327a1ddfaa (diff)
finished writing basic functionalityv0.0.1
-rw-r--r--Cargo.lock271
-rw-r--r--Cargo.toml13
-rw-r--r--src/db.rs3
-rw-r--r--src/main.rs103
4 files changed, 350 insertions, 40 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6e747e3..4b25df9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -71,12 +71,56 @@ dependencies = [
]
[[package]]
+name = "anstream"
+version = "0.6.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
+dependencies = [
+ "anstyle",
+ "anstyle-parse",
+ "anstyle-query",
+ "anstyle-wincon",
+ "colorchoice",
+ "is_terminal_polyfill",
+ "utf8parse",
+]
+
+[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
+name = "anstyle-parse"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
+dependencies = [
+ "utf8parse",
+]
+
+[[package]]
+name = "anstyle-query"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "anstyle-wincon"
+version = "3.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
+dependencies = [
+ "anstyle",
+ "once_cell_polyfill",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
name = "anyhow"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -359,8 +403,19 @@ version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
dependencies = [
+ "anstream",
"anstyle",
"clap_lex",
+ "strsim",
+]
+
+[[package]]
+name = "clap_complete"
+version = "4.5.54"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aad5b1b4de04fead402672b48897030eec1f3bfe1550776322f59f6d6e6a5677"
+dependencies = [
+ "clap",
]
[[package]]
@@ -379,6 +434,22 @@ dependencies = [
]
[[package]]
+name = "colorchoice"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
+
+[[package]]
+name = "core-foundation"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -762,6 +833,24 @@ dependencies = [
]
[[package]]
+name = "hyper-rustls"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "399c78f9338483cb7e630c8474b07268983c6bd5acee012e4211f9f7bb21b070"
+dependencies = [
+ "futures-util",
+ "http",
+ "hyper",
+ "log",
+ "rustls",
+ "rustls-native-certs",
+ "rustls-pki-types",
+ "tokio",
+ "tokio-rustls",
+ "webpki-roots 0.26.11",
+]
+
+[[package]]
name = "hyper-timeout"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -838,6 +927,12 @@ dependencies = [
]
[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
+
+[[package]]
name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -929,6 +1024,7 @@ dependencies = [
"futures",
"http",
"hyper",
+ "hyper-rustls",
"libsql-hrana",
"libsql-sqlite3-parser",
"libsql-sys",
@@ -1175,6 +1271,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
+name = "once_cell_polyfill"
+version = "1.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
+
+[[package]]
+name = "openssl-probe"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
+
+[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1408,6 +1516,7 @@ version = "0.0.1"
dependencies = [
"anyhow",
"clap",
+ "clap_complete",
"directories",
"flac-bound",
"futures-util",
@@ -1418,6 +1527,7 @@ dependencies = [
"pin-utils",
"symphonia",
"tokio",
+ "tokio-util",
]
[[package]]
@@ -1456,6 +1566,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
+name = "ring"
+version = "0.17.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "getrandom 0.2.16",
+ "libc",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
name = "rustc-demangle"
version = "0.1.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1481,6 +1605,62 @@ dependencies = [
]
[[package]]
+name = "rustls"
+version = "0.22.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
+dependencies = [
+ "log",
+ "ring",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-native-certs"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
+dependencies = [
+ "openssl-probe",
+ "rustls-pemfile",
+ "rustls-pki-types",
+ "schannel",
+ "security-framework",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
+dependencies = [
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-webpki"
+version = "0.102.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
+dependencies = [
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
+]
+
+[[package]]
name = "rustversion"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1493,12 +1673,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
+name = "schannel"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
+dependencies = [
+ "windows-sys 0.59.0",
+]
+
+[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
+name = "security-framework"
+version = "2.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
+dependencies = [
+ "bitflags 2.9.1",
+ "core-foundation",
+ "core-foundation-sys",
+ "libc",
+ "security-framework-sys",
+]
+
+[[package]]
+name = "security-framework-sys"
+version = "2.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1577,6 +1789,18 @@ dependencies = [
]
[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
name = "symphonia"
version = "0.5.4"
dependencies = [
@@ -1724,6 +1948,17 @@ dependencies = [
]
[[package]]
+name = "tokio-rustls"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
+dependencies = [
+ "rustls",
+ "rustls-pki-types",
+ "tokio",
+]
+
+[[package]]
name = "tokio-stream"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1906,6 +2141,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
+
+[[package]]
name = "uuid"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2006,6 +2253,24 @@ dependencies = [
]
[[package]]
+name = "webpki-roots"
+version = "0.26.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9"
+dependencies = [
+ "webpki-roots 1.0.0",
+]
+
+[[package]]
+name = "webpki-roots"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2280,3 +2545,9 @@ dependencies = [
"quote",
"syn",
]
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
diff --git a/Cargo.toml b/Cargo.toml
index 7de5ff6..8426d2e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -4,20 +4,20 @@ version = "0.0.1"
edition = "2024"
repository = "https://github.com/justjakka/reencoder/"
license = "BSD-3-Clause"
+authors = ["jakka"]
+description = "A tool for keeping your flacs up-to-date"
[dependencies]
anyhow = "1.0.98"
-clap = { version = "4.5.40", default-features = false, features = [
- "cargo",
- "std",
-] }
+clap = { version = "4.5.40", features = ["cargo", "help", "std"] }
+clap_complete = "4.5.54"
directories = "6.0.0"
flac-bound = { version = "0.5.0", features = [
"libflac-noogg",
], default-features = false }
futures-util = "0.3.31"
i24 = "2.1.0"
-libsql = { version = "0.9.10", default-features = false, features = [
+libsql = { version = "0.9.10", features = [
"core",
"sync",
] }
@@ -27,5 +27,6 @@ pin-utils = "0.1.0"
symphonia = { version = "0.5.4", path = "../Symphonia/symphonia", default-features = false, features = [
"flac",
] }
-tokio = { version = "1.45.1", features = ["macros", "rt", "rt-multi-thread"] }
+tokio = { version = "1.45.1", features = ["macros", "rt", "rt-multi-thread", "signal"] }
+tokio-util = "0.7.15"
#symphonia = { git = "https://github.com/pdeljanov/Symphonia.git", branch = "dev-0.6", default-features = false, features = ["flac"] }
diff --git a/src/db.rs b/src/db.rs
index ae3bf51..93d6d7e 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -110,7 +110,8 @@ impl Database {
pub async fn clean_files(&self) -> Result<()> {
let mut tasks = tokio::task::JoinSet::new();
self.0.execute(DEDUPE_DB, ()).await?;
- while let Ok(Some(row)) = self.0.query(FETCH_FILES, ()).await?.next().await {
+ let mut query_res = self.0.query(FETCH_FILES, ()).await?;
+ while let Ok(Some(row)) = query_res.next().await {
let path = Path::new(row.get_str(0)?).canonicalize()?;
let conn = self.0.clone();
tasks.spawn(async move {
diff --git a/src/main.rs b/src/main.rs
index 09bb966..d660f0a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,82 +1,119 @@
mod db;
mod files;
mod flac;
-use anyhow::Error;
-use clap::{Arg, ArgAction, command, value_parser};
+use anyhow::Result;
+use clap::{Arg, ArgAction, Command, ValueHint, command, value_parser};
+use clap_complete::{Generator, Shell, generate};
use std::path::PathBuf;
-fn main() -> Result<(), Error> {
- let matches = command!()
- .help_expected(true)
+fn build_cli() -> Command {
+ command!()
.arg(
Arg::new("path")
- .short('p')
- .long("path")
- .value_parser(value_parser!(PathBuf))
- .help("Path for indexing/reencoding"),
+ .help("Path for indexing/reencoding")
+ .action(ArgAction::Set)
+ .value_hint(ValueHint::DirPath)
+ .value_parser(value_parser!(PathBuf)),
)
.arg(
Arg::new("index")
.short('i')
.long("index")
- .action(ArgAction::SetTrue)
+ .help("Only index files")
.requires("path")
- .help("Only index files"),
+ .action(ArgAction::SetTrue),
)
.arg(
Arg::new("doit")
.long("doit")
- .action(ArgAction::SetTrue)
+ .help("Actually reencode files")
.conflicts_with("index")
- .help("Actually reencode"),
+ .action(ArgAction::SetTrue),
)
.arg(
Arg::new("clean")
.short('c')
.long("clean")
- .action(ArgAction::SetTrue)
- .help("Clean and dedupe database"),
+ .help("Clean and dedupe database")
+ .action(ArgAction::SetTrue),
)
.arg(
Arg::new("threads")
.short('t')
.long("threads")
+ .help("Set number of reencoding threads")
+ .action(ArgAction::Set)
+ .value_hint(ValueHint::Other)
.value_parser(value_parser!(usize))
- .default_value("4")
- .help("Set number of reencoding threads (default: 4)"),
+ .default_value("4"),
)
.arg(
Arg::new("db")
+ .short('d')
.long("db")
- .value_parser(value_parser!(PathBuf))
- .help("Path to database file"),
+ .help("Path to databse file")
+ .action(ArgAction::Set)
+ .value_hint(ValueHint::FilePath)
+ .value_parser(value_parser!(PathBuf)),
)
- .get_matches();
+ .arg(
+ Arg::new("shell")
+ .short('g')
+ .long("generate")
+ .help("Generate shell completions")
+ .action(ArgAction::Set)
+ .value_parser(value_parser!(Shell)),
+ )
+}
+
+fn print_completions<G: Generator>(generator: G, cmd: &mut Command) {
+ generate(
+ generator,
+ cmd,
+ cmd.get_name().to_string(),
+ &mut std::io::stdout(),
+ );
+}
+
+fn main() -> Result<()> {
+ let args = build_cli().get_matches();
+
+ if let Some(generator) = args.get_one::<Shell>("shell").copied() {
+ let mut cmd = build_cli();
+ eprintln!("Generating completion file for {generator}...");
+ print_completions(generator, &mut cmd);
+ return Ok(());
+ }
- let threads = *matches.get_one::<usize>("threads").unwrap();
let runtime = tokio::runtime::Builder::new_multi_thread()
- .max_blocking_threads(threads)
+ .max_blocking_threads(*args.get_one::<usize>("threads").unwrap())
.enable_all()
.build()?;
runtime.block_on(async move {
- let conn = if let Some(path) = matches.get_one::<PathBuf>("db") {
+ let conn = if let Some(path) = args.get_one::<PathBuf>("db") {
db::Database::new(path).await?
} else {
db::open_default_db().await?
};
- let path = matches.get_one::<PathBuf>("path");
- if matches.get_flag("index") {
- let folderpath = path.unwrap();
- files::index_files_recursively(folderpath, &conn).await
- } else if matches.get_flag("doit") {
- files::reencode_files(&conn, path).await
- } else if matches.get_flag("clean") {
- conn.clean_files().await
- } else {
+ let path = args.get_one::<PathBuf>("path");
+
+ if !args.get_flag("index") && !args.get_flag("clean") && !args.get_flag("doit") {
let count = files::count_reencode_files(&conn, path).await.unwrap();
println!("Files to reencode:\t{count}");
- Ok(())
}
+
+ if args.get_flag("index") {
+ files::index_files_recursively(path.unwrap(), &conn).await?;
+ }
+
+ if args.get_flag("clean") {
+ conn.clean_files().await?;
+ }
+
+ if args.get_flag("doit") {
+ files::reencode_files(&conn, path).await?;
+ }
+ Ok::<(), anyhow::Error>(())
})?;
Ok(())