feat: Add --list-events debugging improvements and timezone support

- Remove debug event limit to display all events
- Add timezone information to event listing output
- Update DEVELOPMENT.md with latest changes and debugging cycle documentation
- Enhance event parsing with timezone support
- Simplify CalDAV client structure and error handling

Changes improve debugging capabilities for CalDAV event retrieval and provide
better timezone visibility when listing calendar events.
This commit is contained in:
Alvaro Soliverez 2025-10-13 11:02:55 -03:00
parent 37e9bc2dc1
commit f81022a16b
11 changed files with 2039 additions and 136 deletions

View file

@ -2,8 +2,9 @@ use anyhow::Result;
use clap::Parser;
use tracing::{info, warn, error, Level};
use tracing_subscriber;
use caldav_sync::{Config, SyncEngine, CalDavResult};
use caldav_sync::{Config, CalDavResult, SyncEngine};
use std::path::PathBuf;
use chrono::{Utc, Duration};
#[derive(Parser)]
#[command(name = "caldav-sync")]
@ -11,7 +12,7 @@ use std::path::PathBuf;
#[command(version)]
struct Cli {
/// Configuration file path
#[arg(short, long, default_value = "config/default.toml")]
#[arg(short, long, default_value = "config/config.toml")]
config: PathBuf,
/// CalDAV server URL (overrides config file)
@ -45,6 +46,18 @@ struct Cli {
/// List events and exit
#[arg(long)]
list_events: bool,
/// List available calendars and exit
#[arg(long)]
list_calendars: bool,
/// Use specific CalDAV approach (report-simple, propfind-depth, simple-propfind, multiget, report-filter, ical-export, zoho-export, zoho-events-list, zoho-events-direct)
#[arg(long)]
approach: Option<String>,
/// Use specific calendar URL instead of discovering from config
#[arg(long)]
calendar_url: Option<String>,
}
#[tokio::main]
@ -116,10 +129,84 @@ async fn run_sync(config: Config, cli: &Cli) -> CalDavResult<()> {
// Create sync engine
let mut sync_engine = SyncEngine::new(config.clone()).await?;
if cli.list_calendars {
// List calendars and exit
info!("Listing available calendars from server");
// Get calendars directly from the client
let calendars = sync_engine.client.discover_calendars().await?;
println!("Found {} calendars:", calendars.len());
for (i, calendar) in calendars.iter().enumerate() {
println!(" {}. {}", i + 1, calendar.display_name.as_ref().unwrap_or(&calendar.name));
println!(" Name: {}", calendar.name);
println!(" URL: {}", calendar.url);
if let Some(ref display_name) = calendar.display_name {
println!(" Display Name: {}", display_name);
}
if let Some(ref color) = calendar.color {
println!(" Color: {}", color);
}
if let Some(ref description) = calendar.description {
println!(" Description: {}", description);
}
if let Some(ref timezone) = calendar.timezone {
println!(" Timezone: {}", timezone);
}
println!(" Supported Components: {}", calendar.supported_components.join(", "));
println!();
}
return Ok(());
}
if cli.list_events {
// List events and exit
info!("Listing events from calendar: {}", config.calendar.name);
// Use the specific approach if provided
if let Some(ref approach) = cli.approach {
info!("Using specific approach: {}", approach);
// Use the provided calendar URL if available, otherwise discover calendars
let calendar_url = if let Some(ref url) = cli.calendar_url {
url.clone()
} else {
let calendars = sync_engine.client.discover_calendars().await?;
if let Some(calendar) = calendars.iter().find(|c| c.name == config.calendar.name || c.display_name.as_ref().map_or(false, |n| n == &config.calendar.name)) {
calendar.url.clone()
} else {
warn!("Calendar '{}' not found", config.calendar.name);
return Ok(());
}
};
let now = Utc::now();
let start_date = now - Duration::days(30);
let end_date = now + Duration::days(30);
match sync_engine.client.get_events_with_approach(&calendar_url, start_date, end_date, Some(approach.clone())).await {
Ok(events) => {
println!("Found {} events using approach {}:", events.len(), approach);
for event in events {
let start_tz = event.start_tzid.as_deref().unwrap_or("UTC");
let end_tz = event.end_tzid.as_deref().unwrap_or("UTC");
println!(" - {} ({} {} to {} {})",
event.summary,
event.start.format("%Y-%m-%d %H:%M"),
start_tz,
event.end.format("%Y-%m-%d %H:%M"),
end_tz
);
}
}
Err(e) => {
error!("Failed to get events with approach {}: {}", approach, e);
}
}
return Ok(());
}
// Perform a sync to get events
let sync_result = sync_engine.sync_full().await?;
info!("Sync completed: {} events processed", sync_result.events_processed);
@ -129,10 +216,14 @@ async fn run_sync(config: Config, cli: &Cli) -> CalDavResult<()> {
println!("Found {} events:", events.len());
for event in events {
println!(" - {} ({} to {})",
let start_tz = event.start_tzid.as_deref().unwrap_or("UTC");
let end_tz = event.end_tzid.as_deref().unwrap_or("UTC");
println!(" - {} ({} {} to {} {})",
event.summary,
event.start.format("%Y-%m-%d %H:%M"),
event.end.format("%Y-%m-%d %H:%M")
start_tz,
event.end.format("%Y-%m-%d %H:%M"),
end_tz
);
}