0.9: almost working
This commit is contained in:
+72
-3
@@ -3,6 +3,7 @@ use clap::Parser;
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::Command;
|
||||
use walkdir::WalkDir;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
@@ -24,6 +25,10 @@ struct Args {
|
||||
/// Rename flag (whether to rename root directory of torrent, if exists)
|
||||
#[arg(short = 'r', long = "rename", default_value_t = false)]
|
||||
rename: bool,
|
||||
|
||||
/// Do no harm, only print actions
|
||||
#[arg(short = 'n', long = "dry-run", default_value_t = false)]
|
||||
dry_run: bool,
|
||||
}
|
||||
|
||||
fn find_torrent_files(start_path: &Path) -> Vec<PathBuf> {
|
||||
@@ -50,19 +55,71 @@ enum TorrentType {
|
||||
fn get_torrent_type(torrent: &Path) -> Result<TorrentType, Box<dyn Error>> {
|
||||
let f = File::open(torrent)?;
|
||||
let value: Value = bt_bencode::from_reader(f)?;
|
||||
let torrenttype = match value.get("info").unwrap().get("files") {
|
||||
let torrenttype = match value
|
||||
.get("info")
|
||||
.ok_or("torrent sould have 'info' section")?
|
||||
.get("files")
|
||||
{
|
||||
Some(_) => TorrentType::Directory(
|
||||
value
|
||||
.get("info")
|
||||
.and_then(|v| v.get("name"))
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap()
|
||||
.ok_or("torrent with multiple files should have recommended directory name")?
|
||||
.to_owned(),
|
||||
),
|
||||
_ => TorrentType::SingleFile,
|
||||
};
|
||||
Ok(torrenttype)
|
||||
}
|
||||
fn make_destination(torrent: &Path, source: &Path, dest: &Path) -> PathBuf {
|
||||
let filename = Path::new(
|
||||
torrent
|
||||
.file_stem()
|
||||
.expect("torrent file should have '.torrent' extension"),
|
||||
);
|
||||
let rel_path = torrent
|
||||
.parent()
|
||||
.expect("torrent file should have a parent directory")
|
||||
.strip_prefix(source)
|
||||
.expect("torrent file should have prefix equal to source");
|
||||
[dest, rel_path, filename].iter().collect()
|
||||
}
|
||||
|
||||
fn exec_transmission_remote(
|
||||
source: &Path,
|
||||
dest: &Path,
|
||||
torrent_type: &TorrentType,
|
||||
rename: bool,
|
||||
dry_run: bool,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
let mut command = Command::new("transmission-remote");
|
||||
command
|
||||
.arg("--json")
|
||||
.arg("--add")
|
||||
.arg(source)
|
||||
.arg("--download-dir")
|
||||
.arg(dest);
|
||||
if rename {
|
||||
if let TorrentType::Directory(old_name) = torrent_type {
|
||||
command
|
||||
.arg("--rename")
|
||||
.arg(dest)
|
||||
.arg("--path")
|
||||
.arg(old_name);
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"Running {:?} with {:?}",
|
||||
command.get_program(),
|
||||
command.get_args()
|
||||
);
|
||||
if !dry_run {
|
||||
let output = command.output()?;
|
||||
println!("Result: {:?}", output);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
@@ -72,8 +129,20 @@ fn main() {
|
||||
println!("Destination path: {}", args.destination);
|
||||
println!("Rename: {}", args.rename);
|
||||
let source = Path::new(&args.source);
|
||||
let dest = Path::new(&args.destination);
|
||||
let torrent_files = find_torrent_files(source);
|
||||
for file in torrent_files {
|
||||
println!("{:?}", get_torrent_type(&file));
|
||||
// println!("{:?}", get_torrent_type(&file));
|
||||
// println!("{:?}", make_destination(&file, source, dest));
|
||||
let torrent_type = get_torrent_type(&file).unwrap();
|
||||
let destination = make_destination(&file, source, dest);
|
||||
exec_transmission_remote(
|
||||
&file,
|
||||
&destination,
|
||||
&torrent_type,
|
||||
args.rename,
|
||||
args.dry_run,
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user