0.9: almost working
This commit is contained in:
+72
-3
@@ -3,6 +3,7 @@ use clap::Parser;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use std::process::Command;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
@@ -24,6 +25,10 @@ struct Args {
|
|||||||
/// Rename flag (whether to rename root directory of torrent, if exists)
|
/// Rename flag (whether to rename root directory of torrent, if exists)
|
||||||
#[arg(short = 'r', long = "rename", default_value_t = false)]
|
#[arg(short = 'r', long = "rename", default_value_t = false)]
|
||||||
rename: bool,
|
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> {
|
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>> {
|
fn get_torrent_type(torrent: &Path) -> Result<TorrentType, Box<dyn Error>> {
|
||||||
let f = File::open(torrent)?;
|
let f = File::open(torrent)?;
|
||||||
let value: Value = bt_bencode::from_reader(f)?;
|
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(
|
Some(_) => TorrentType::Directory(
|
||||||
value
|
value
|
||||||
.get("info")
|
.get("info")
|
||||||
.and_then(|v| v.get("name"))
|
.and_then(|v| v.get("name"))
|
||||||
.and_then(|v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
.unwrap()
|
.ok_or("torrent with multiple files should have recommended directory name")?
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
),
|
),
|
||||||
_ => TorrentType::SingleFile,
|
_ => TorrentType::SingleFile,
|
||||||
};
|
};
|
||||||
Ok(torrenttype)
|
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() {
|
fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
@@ -72,8 +129,20 @@ fn main() {
|
|||||||
println!("Destination path: {}", args.destination);
|
println!("Destination path: {}", args.destination);
|
||||||
println!("Rename: {}", args.rename);
|
println!("Rename: {}", args.rename);
|
||||||
let source = Path::new(&args.source);
|
let source = Path::new(&args.source);
|
||||||
|
let dest = Path::new(&args.destination);
|
||||||
let torrent_files = find_torrent_files(source);
|
let torrent_files = find_torrent_files(source);
|
||||||
for file in torrent_files {
|
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