aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ai_embedders.rs6
-rw-r--r--src/main.rs52
2 files changed, 45 insertions, 13 deletions
diff --git a/src/ai_embedders.rs b/src/ai_embedders.rs
index b30d890..e8e6c8b 100644
--- a/src/ai_embedders.rs
+++ b/src/ai_embedders.rs
@@ -7,7 +7,7 @@ use crate::{Config, BatchEmbedder, MetricElem};
#[repr(transparent)]
#[derive(Serialize, Deserialize)]
-pub(crate) struct Imgbedding (Vec<f32>); // TODO das hier zu einem const size slice machen
+pub(crate) struct Imgbedding (Vec<f32>);
impl MetricElem for Imgbedding {
fn dist(&self, other: &Self) -> f64 {
self.0.iter().zip(other.0.iter())
@@ -73,10 +73,10 @@ impl BatchEmbedder for ContentEmbedder<'_> {
.stdout(Stdio::piped())
.spawn()?;
- Ok(BufReader::new(child.stdout.unwrap())
+ BufReader::new(child.stdout.unwrap())
.lines()
.progress_count(paths.len().try_into().unwrap())
.map(|l| Ok::<_, anyhow::Error>(serde_json::from_str(&l?)?))
- .try_collect()?)
+ .try_collect()
}
}
diff --git a/src/main.rs b/src/main.rs
index 6524de7..1872e31 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,7 +4,7 @@ use anyhow::Result;
use clap::Parser;
use priority_queue::PriorityQueue;
use sha2::{Sha512_256, Digest};
-use std::{cmp::Ordering, collections::HashMap, fs, io, path::PathBuf};
+use std::{cmp::Ordering, collections::HashMap, fs, io, io::Write, path::PathBuf};
use embedders::*;
use pure_embedders::*;
@@ -23,9 +23,26 @@ enum Embedder {
#[derive(Debug, Parser)]
struct Args {
- #[arg(short, long, default_value = "hue")]
+ /// Characteristic to sort by
+ #[arg(short, long, default_value = "content")]
embedder: Embedder,
+ /// Symlink the sorted images into this directory
+ #[arg(short = 'o', long)]
+ symlink_dir: Option<PathBuf>,
+
+ /// Copy the sorted images into this directory. TODO uses COW when available
+ #[arg(short = 's', long)]
+ copy_dir: Option<PathBuf>,
+
+ /// Write sorted paths into stdout, one per line
+ #[arg(short = 'c', long)]
+ stdout: bool,
+
+ /// Write sorted paths into stdout, null-separated. Overrides -c
+ #[arg(short = '0', long)]
+ stdout0: bool,
+
images: Vec<PathBuf>,
}
@@ -123,7 +140,7 @@ fn hash_file(p: &PathBuf) -> Result<[u8; 32]> {
Ok(hasher.finalize().into_iter().collect::<Vec<u8>>().try_into().unwrap())
}
-fn process_embedder<E>(mut e: E, args: Args, cfg: &Config) -> Result<Vec<PathBuf>>
+fn process_embedder<E>(mut e: E, args: &Args, cfg: &Config) -> Result<Vec<PathBuf>>
where E: BatchEmbedder
{
if args.images.is_empty() {
@@ -169,20 +186,35 @@ fn process_embedder<E>(mut e: E, args: Args, cfg: &Config) -> Result<Vec<PathBuf
Ok(tsp_path.iter().map(|i| args.images[*i].clone()).collect())
}
+fn symlink_into(tsp: &[PathBuf], target: &PathBuf) -> Result<()> {todo!()}
+fn copy_into(tsp: &[PathBuf], target: &PathBuf) -> Result<()> {todo!()}
+
fn main() -> Result<()> {
let cfg = get_config()?;
let args = Args::parse();
let tsp_path = match args.embedder {
- Embedder::Brightness => process_embedder(BrightnessEmbedder, args, &cfg),
- Embedder::Hue => process_embedder(HueEmbedder, args, &cfg),
- Embedder::Color => process_embedder(ColorEmbedder, args, &cfg),
- Embedder::Content => process_embedder(ContentEmbedder::new(&cfg), args, &cfg),
+ Embedder::Brightness => process_embedder(BrightnessEmbedder, &args, &cfg),
+ Embedder::Hue => process_embedder(HueEmbedder, &args, &cfg),
+ Embedder::Color => process_embedder(ColorEmbedder, &args, &cfg),
+ Embedder::Content => process_embedder(ContentEmbedder::new(&cfg), &args, &cfg),
}?;
- for p in tsp_path {
- println!("{:?}", p);
- }
+ args.symlink_dir.into_iter().try_for_each(|p| symlink_into(&tsp_path, &p))?;
+ args.copy_dir .into_iter().try_for_each(|p| copy_into(&tsp_path, &p))?;
+
+ let path_delim = if args.stdout0 { Some(0) }
+ else if args.stdout { Some(10) }
+ else { None };
+
+ path_delim.into_iter().try_for_each(|delim| {
+ let mut o = io::BufWriter::new(io::stdout().lock());
+ for p in &tsp_path {
+ o.write(p.as_os_str().to_str().unwrap().as_bytes())?;
+ o.write(&[delim])?;
+ }
+ o.flush()
+ })?;
Ok(())
}