~llndqvst/notmuch-mvrs

ae973f7bd1e1c9aa26e4889458f3da67846cbb3c — Lukas Lindqvist 8 months ago fb4a338
Add support for actually renaming emails
4 files changed, 59 insertions(+), 31 deletions(-)

M src/config.rs
M src/lib.rs
M src/main.rs
M src/mover_config.rs
M src/config.rs => src/config.rs +10 -9
@@ 6,6 6,7 @@ use toml;
pub struct ConfigShim {
    pub mover: String,
    pub db: notmuch::Database,
    pub dry_run: bool,
    pub mover_options: Vec<MoverOption>,
}



@@ 13,6 14,8 @@ pub struct ConfigShim {
struct Config {
    mover: Option<String>,
    db: PathBuf,
    #[serde(default = "bool::default")]
    dry_run: bool,
    mover_options: Option<Vec<MoverOption>>,
}



@@ 35,22 38,20 @@ impl Config {

    fn get_mover(&self) -> String {
        match &self.mover {
            Some(x) => {
                String::from(x)
            }
            None => String::from(crate::DEFAULT_MOVER)
            Some(x) => String::from(x),
            None => String::from(crate::DEFAULT_MOVER),
        }
    }
}

impl ConfigShim {
    pub fn new(p: PathBuf) -> Self {
        let c2 = Config::new(p);
        let c = Config::new(p);
        ConfigShim {
            mover: c2.get_mover(),
            db: notmuch::Database::open(&c2.db,
                                        notmuch::DatabaseMode::ReadOnly).unwrap(),
            mover_options: c2.mover_options.unwrap(),
            mover: c.get_mover(),
            db: notmuch::Database::open(&c.db, notmuch::DatabaseMode::ReadOnly).unwrap(),
            dry_run: c.dry_run,
            mover_options: c.mover_options.unwrap(),
        }
    }
}

M src/lib.rs => src/lib.rs +30 -14
@@ 1,28 1,39 @@
pub mod config;
pub mod movers;
pub mod mover_config;
pub mod movers;
pub mod notmuch_db_loader;

// use dirs::data_local_dir;
use config::{ConfigShim, MoverOption};
use mover_config::MoverConfig;
use movers::mbsync::Mbsync;
use config::{ConfigShim, MoverOption};
use movers::mover::Mover;
use std::path::PathBuf;

static CONFIG_DIR: &'static str = "notmuch-mvrs/config.toml";
static DEFAULT_MOVER: &'static str = "mbsync";

pub fn init() {
    let p = dirs::config_dir().unwrap().join(PathBuf::from(CONFIG_DIR));
    let c = load_config(p).unwrap();
    if c.dry_run {
        dry_run()
    } else {
        run();
    }
}

fn load_config(location: PathBuf) -> Result<ConfigShim, String> {
    Ok(ConfigShim::new(location))
}

fn _run_movers<T>(db: notmuch::Database, movers: Vec<MoverOption>)
fn run_movers<T>(db: &notmuch::Database, movers: Vec<MoverOption>)
where
    T: Mover<PathBuf> {
    T: Mover<PathBuf>,
{
    for m in movers {
        let p = PathBuf::from(m.target_dir);
        let mut t: MoverConfig::<T> = MoverConfig::new(&db, m.query.as_str(), p);
        let mut t: MoverConfig<T> = MoverConfig::new(db, m.query.as_str(), p);
        match t.execute() {
            Err(e) => println!("{}", e),
            Ok(k) => println!("Moved: {} items", k),


@@ 30,24 41,29 @@ where
    }
}

pub fn _run() -> Result<i32, String>{
pub fn run() {
    let p = dirs::config_dir().unwrap().join(PathBuf::from(CONFIG_DIR));
    let t = load_config(p).unwrap();
    match t.mover.as_str() {
        "mbsync" => {
            _run_movers::<Mbsync>(t.db, t.mover_options);
            Ok(1)
        },
        &_ => Err(String::from("Not a known mover"))
            run_movers::<Mbsync>(&t.db, t.mover_options);
        }
        s => eprintln!("Not a recognized mover: {}", s),
    }
    println!("Reloading database with notmuch new");
    match notmuch::AtomicOperation::new(&t.db) {
        Ok(_) => (),
        Err(e) => eprintln!("{}", e),
    };
}

fn dry_run_movers<T>(db: notmuch::Database, movers: Vec<MoverOption>)
where
    T: Mover<PathBuf> {
    T: Mover<PathBuf>,
{
    for m in movers {
        let p = PathBuf::from(m.target_dir);
        let mut t: MoverConfig::<T> = MoverConfig::new(&db, m.query.as_str(), p);
        let mut t: MoverConfig<T> = MoverConfig::new(&db, m.query.as_str(), p);
        match t.dry_execute() {
            Err(e) => eprintln!("{}", e),
            Ok(k) => println!("Processed {} items", k),


@@ 61,7 77,7 @@ pub fn dry_run() {
    match t.mover.as_str() {
        "mbsync" => {
            dry_run_movers::<Mbsync>(t.db, t.mover_options);
        },
        s => eprintln!("Not a recognized mover: {}", s)
        }
        s => eprintln!("Not a recognized mover: {}", s),
    }
}

M src/main.rs => src/main.rs +1 -1
@@ 1,5 1,5 @@
use notmuch_mvrs;

fn main() {
    (notmuch_mvrs::dry_run());
    (notmuch_mvrs::init());
}

M src/mover_config.rs => src/mover_config.rs +18 -7
@@ 14,7 14,11 @@ impl<'a, T> MoverConfig<'a, T>
where
    T: Mover<PathBuf>,
{
    pub fn new(nm_db_location: &'a notmuch::Database, query: &'a str, target_path: PathBuf) -> Self {
    pub fn new(
        nm_db_location: &'a notmuch::Database,
        query: &'a str,
        target_path: PathBuf,
    ) -> Self {
        MoverConfig {
            mover: T::new(target_path),
            nm_db: nm_db_location,


@@ 31,12 35,19 @@ where
        self.mover.dry_rename()
    }

    pub fn execute(&mut self) -> Result<i32, &str> {
    pub fn execute(&mut self) -> Result<i32, notmuch::Error> {
        let query = self.nm_db.create_query(self.query_string).unwrap();
        let messages = query.search_messages().unwrap();
        for m in messages {
            self.mover.add_file_path(m.filename());
        }
        self.mover.rename()
        let messages = match query.search_messages() {
            Ok(mq) => {
                for m in mq {
                    self.mover.add_file_path(m.filename());
                }
                Ok(self.mover.rename().unwrap())
            },
            Err(e) => {
                Err(e)
            }
        };
        messages
    }
}