diff --git a/main.rs b/main.rs index a803016..e143ce4 100644 --- a/main.rs +++ b/main.rs @@ -3,8 +3,23 @@ use std::fs; // To list files use std::fs::File; use std::io::BufReader; use std::io::BufRead; +use std::process::Command; -fn birthdate (filename: String) -> String { +/* Execute notify program */ +fn notify (text: &String) { + if cfg!(target_os = "windows") { + println!("OS not suported"); + } else { + let _ = Command::new("notify-send") + .arg("Anniversaires") + .arg(text) + .output() + .expect("failed to execute process"); + } +} + +/* Extract birthdate String from vcf file */ +fn birthdate (filename: &String) -> String { let file = File::open(filename).expect("file not found!"); let reader = BufReader::new(file); for line in reader.lines() { @@ -16,24 +31,65 @@ fn birthdate (filename: String) -> String { return "".to_string() } +/* Extract full name from vcf file */ +fn fullname (filename: &String) -> String { + let file = File::open(filename).expect("file not found!"); + let reader = BufReader::new(file); + for line in reader.lines() { + let l:String = line.unwrap(); + if l.starts_with("FN:") { + return l[3..].to_string(); + } + } + return "".to_string() +} + +/* Test if date a is before b in civil year */ +fn before_in_civil_year (a :&NaiveDate, b: &NaiveDate) -> bool{ + a.month()*100 + a.day() < b.month()*100 + b.day() +} + fn main() { /* Where are the vcf files */ let vcf_dir = "/home/ilya/.contacts/contacts"; /* How much day before */ - let delta_d:u8 = 10; - - let now = Local::now(); + let delta_d = 10; + + let tz_today = Local::today(); + let today = NaiveDate::from_ymd(tz_today.year(), tz_today.month(), tz_today.day()); let paths = fs::read_dir(vcf_dir).unwrap(); + let mut output:String = "".to_string(); + for path in paths { + /* Get date string from vcf file */ let filename :String = path.unwrap().path().into_os_string().into_string().unwrap(); - let bdate:String = birthdate(filename); + let bdate:String = birthdate(&filename); if bdate == "" { continue } - //println!("{}", bdate); - println!("{}",UTC::Date(bdate)); + /* Parse the date */ + let mut date = match bdate.len() { + 8 => Some(NaiveDate::parse_from_str(&bdate.to_string(), "%Y%m%d").unwrap()), + 10 => Some(NaiveDate::parse_from_str(&bdate.to_string(), "%Y-%m-%d").unwrap()), + _ => None, + }.expect("Date is of no known format"); + + /* set to y+1 to make it a future date, or to y */ + if before_in_civil_year(&date, &today) { + date = date.with_year(today.year()+1).unwrap() + } else { + date = date.with_year(today.year()).unwrap() + } + + let bdate = UTC.from_local_date(&date).single().unwrap(); + + /* It is time to be alerted */ + if bdate.num_days_from_ce() - tz_today.num_days_from_ce() <= delta_d { + output = format!("{}{}/{} {}\n", output, date.day(), date.month(), fullname(&filename)); + } } + notify(&output); }