superdeduper/src/main.rs
Bill Thiede 7285436f7e Initial commit.
Walks over all movie directories, pulls some metadata into a hashmap and
then pretty prints it.
2019-10-27 16:51:09 -07:00

81 lines
2.0 KiB
Rust

use std::collections::HashMap;
use std::error::Error;
use std::fmt;
use std::fs::File;
use std::io::BufReader;
use std::path::Path;
use glob::glob;
use human_format::Formatter;
use human_format::Scales;
use serde::Deserialize;
const MOVIE_DIR: &str = "/home/wathiede/Movies";
#[derive(Deserialize, Debug)]
struct Resolution(usize, usize);
impl fmt::Display for Resolution {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let v = format!("{}x{}", self.0, self.1);
f.pad(&v)
}
}
#[derive(Deserialize, Debug)]
struct Metadata {
size: usize,
dimension: Resolution,
duration_text: String,
duration: f32,
}
#[derive(Deserialize, Debug)]
struct MetadataFile {
#[serde(flatten)]
metadata: HashMap<String, Metadata>,
}
fn read_metadata_from_file<P: AsRef<Path>>(path: P) -> Result<MetadataFile, Box<dyn Error>> {
// Open the file in read-only mode with buffer.
let file = File::open(path)?;
let reader = BufReader::new(file);
// Read the JSON contents of the file as an instance of `User`.
let md = serde_json::from_reader(reader)?;
// Return the `User`.
Ok(md)
}
fn main() -> Result<(), Box<dyn Error>> {
let mut movies = HashMap::new();
for md in glob(&format!("{}/*/metadata.json", MOVIE_DIR))? {
match md {
Ok(path) => {
let mdf = read_metadata_from_file(&path)?;
for (name, md) in mdf.metadata {
movies.insert(name, md);
}
}
Err(e) => eprintln!("{:?}", e),
}
}
let mut names = movies.keys().collect::<Vec<_>>();
names.sort();
let mut fmtr = Formatter::new();
fmtr.with_separator("");
fmtr.with_scales(Scales::Binary());
for name in names {
let md = &movies[name];
println!(
"{:>9} {:>8} {} {}",
md.dimension,
fmtr.format(md.size as f64),
md.duration_text,
&name[MOVIE_DIR.len() + 1..]
);
}
Ok(())
}