birthday-reminder/main.rs

96 lines
2.9 KiB
Rust
Raw Normal View History

2021-09-17 15:57:48 +00:00
use chrono::*; // For date
use std::fs; // To list files
use std::fs::File;
use std::io::BufReader;
use std::io::BufRead;
2021-09-18 12:28:11 +00:00
use std::process::Command;
2021-09-17 15:57:48 +00:00
2021-09-18 12:28:11 +00:00
/* 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 {
2021-09-17 15:57:48 +00:00
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("BDAY") {
return l[5..].to_string();
}
}
return "".to_string()
}
2021-09-18 12:28:11 +00:00
/* 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()
}
2021-09-17 15:57:48 +00:00
fn main() {
/* Where are the vcf files */
let vcf_dir = "/home/ilya/.contacts/contacts";
/* How much day before */
2021-09-18 12:28:11 +00:00
let delta_d = 10;
let tz_today = Local::today();
let today = NaiveDate::from_ymd(tz_today.year(), tz_today.month(), tz_today.day());
2021-09-17 15:57:48 +00:00
let paths = fs::read_dir(vcf_dir).unwrap();
2021-09-18 12:28:11 +00:00
let mut output:String = "".to_string();
2021-09-17 15:57:48 +00:00
for path in paths {
2021-09-18 12:28:11 +00:00
/* Get date string from vcf file */
2021-09-17 15:57:48 +00:00
let filename :String = path.unwrap().path().into_os_string().into_string().unwrap();
2021-09-18 12:28:11 +00:00
let bdate:String = birthdate(&filename);
2021-09-17 15:57:48 +00:00
if bdate == "" {
continue
}
2021-09-18 12:28:11 +00:00
/* 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));
}
2021-09-17 15:57:48 +00:00
}
2021-09-18 12:28:11 +00:00
notify(&output);
2021-09-17 15:57:48 +00:00
}