summaryrefslogtreecommitdiff
path: root/src/bin/caldav-crates.rs
blob: 258b248edc109b1619d15fa5d42a78ff6cfc744f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use {
    anyhow::{
        Result,

        anyhow,
    },
    std::env::args,
};

struct CrateKaldav {
    client: kaldav::Client,
}

impl CrateKaldav {
    fn new(url: &str, username: String, password: Option<String>) -> Self {
        println!("kaldav");

        let mut client = kaldav::Client::new(url);
        client.set_auth(Some(kaldav::Authorization { username, password, }));

        Self {
            client,
        }
    }

    fn show_content(&self) -> Result<()> {
        // This function does not do what we want, because Principal::home() does not appear to
        // work in our environment.
        // Reading https://datatracker.ietf.org/doc/html/rfc4791#section-6.2.1 reveals that the
        // CALDAV:calendar-home-set property merely SHOULD, rather than MUST, be implemented.

        let principals = self.client.principals()?;
        // eprintln!("Principals: {principals:?}");

        let mut home = None;
        println!("Attempting to find home.");
        for p in principals {
            home = p.home().ok();
            if home.is_some() {
                break;
            }
        }
        if home.is_some() {
            println!("Found home: {home:?}");
        } else {
            return Err(anyhow!("No home found in any Principal. :("));
        }

        // This function is heavily based on:
        // https://github.com/sanpii/kaldav/blob/main/examples/list_events.rs
        eprintln!("Retrieving list of calendars.");
        let calendars = self.client.calendars()?;

        for (name, calendar) in calendars {
            println!("Calendar '{}'", name);

            let objects = calendar.events()?;

            if objects.is_empty() {
                println!("  no events");
                continue;
            }

            for object in objects {
                for event in object.events {
                    println!(
                        "  {} - {}",
                        event.dtstart,
                        event.summary.unwrap_or_default()
                    );
                }
            }
        }
        Ok(())
    }
}

fn main() -> Result<()> {
    let caldav_url = args().nth(1).expect("Missing caldav url argument.");
    let username = args().nth(2).expect("Missing username argument.");
    let password = args().nth(3).expect("Missing password argument.");

    let kaldav = CrateKaldav::new(&caldav_url, username.clone(), Some(password.clone()));
    kaldav.show_content()?;

    Ok(())
}