Trying very hard not to miss calendar events
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Improve CLI output

Co-authored-by: Claude <noreply@anthropic.com>

+36 -9
+1 -1
crates/alarma-cli/Cargo.toml
··· 20 20 chrono = "0.4" 21 21 serde = { version = "1.0", features = ["derive"] } 22 22 serde_json = "1.0" 23 - tabled = "0.17" 23 + tabled = { version = "0.20", features = ["ansi"] }
+8 -1
crates/alarma-cli/src/commands/events.rs
··· 17 17 // Parse date range 18 18 let range = parse_datetime_range(&args.datetime_from, &args.datetime_until)?; 19 19 20 + // Get source names for display 21 + let sources = repository.list_sources()?; 22 + let source_names: std::collections::HashMap<String, String> = sources 23 + .into_iter() 24 + .map(|s| (s.uid, s.display_name)) 25 + .collect(); 26 + 20 27 // Get events 21 28 let mut events = if let Some(source_uid) = &args.source { 22 29 repository.list_events(source_uid, range)? ··· 28 35 events.sort_by_key(|e| e.start.timestamp()); 29 36 30 37 // Print results 31 - print_events(&events, args.format)?; 38 + print_events(&events, &source_names, args.format)?; 32 39 33 40 Ok(()) 34 41 }
+27 -7
crates/alarma-cli/src/output/mod.rs
··· 3 3 //! This module provides different output formats for displaying calendar data. 4 4 5 5 use alarma_core::{CalendarEvent, CalendarSource, EventTime}; 6 + use std::collections::HashMap; 6 7 use std::io; 7 8 use tabled::{settings::Style, Table, Tabled}; 8 9 ··· 38 39 } 39 40 40 41 /// Formats and prints calendar events 41 - pub fn print_events(events: &[CalendarEvent], format: OutputFormat) -> io::Result<()> { 42 + pub fn print_events( 43 + events: &[CalendarEvent], 44 + source_names: &HashMap<String, String>, 45 + format: OutputFormat, 46 + ) -> io::Result<()> { 42 47 match format { 43 - OutputFormat::Table => print_events_table(events), 48 + OutputFormat::Table => print_events_table(events, source_names), 44 49 OutputFormat::Json => print_events_json(events), 45 - OutputFormat::Simple => print_events_simple(events), 50 + OutputFormat::Simple => print_events_simple(events, source_names), 46 51 } 47 52 } 48 53 ··· 115 120 first_occurrence: String, 116 121 } 117 122 118 - fn print_events_table(events: &[CalendarEvent]) -> io::Result<()> { 123 + fn print_events_table( 124 + events: &[CalendarEvent], 125 + source_names: &HashMap<String, String>, 126 + ) -> io::Result<()> { 119 127 if events.is_empty() { 120 128 println!("No events found."); 121 129 return Ok(()); ··· 124 132 let rows: Vec<EventRow> = events 125 133 .iter() 126 134 .map(|e| { 135 + let source_display = source_names 136 + .get(&e.source_uid) 137 + .cloned() 138 + .unwrap_or_else(|| e.source_uid.clone()); 127 139 let (start_str, end_str) = format_event_times(&e.start, &e.end); 128 140 let (periodicity, first_occurrence) = if let Some(ref pattern) = e.recurrence_pattern { 129 141 let first_str = match &pattern.first_occurrence { ··· 135 147 ("-".to_string(), "-".to_string()) 136 148 }; 137 149 EventRow { 138 - source: e.source_uid.clone(), 150 + source: source_display, 139 151 summary: e.summary.clone(), 140 152 start: start_str, 141 153 end: end_str, ··· 148 160 149 161 let mut table = Table::new(rows); 150 162 table.with(Style::modern()); 163 + 151 164 println!("{}", table); 152 165 println!("\nTotal: {} event(s)", events.len()); 153 166 Ok(()) ··· 164 177 Ok(()) 165 178 } 166 179 167 - fn print_events_simple(events: &[CalendarEvent]) -> io::Result<()> { 180 + fn print_events_simple( 181 + events: &[CalendarEvent], 182 + source_names: &HashMap<String, String>, 183 + ) -> io::Result<()> { 168 184 for event in events { 185 + let source_display = source_names 186 + .get(&event.source_uid) 187 + .cloned() 188 + .unwrap_or_else(|| event.source_uid.clone()); 169 189 let (start_str, end_str) = format_event_times(&event.start, &event.end); 170 190 println!( 171 191 "[{}] {} | {} - {}", 172 - event.source_uid, event.summary, start_str, end_str 192 + source_display, event.summary, start_str, end_str 173 193 ); 174 194 if let Some(location) = &event.location { 175 195 println!(" Location: {}", location);