Working correctly to fetch 1 Nextcloud calendar
This commit is contained in:
parent
20a74ac7a4
commit
16d6fc375d
3 changed files with 406 additions and 24 deletions
|
|
@ -39,6 +39,27 @@ delete_missing = false
|
||||||
# Date range configuration
|
# Date range configuration
|
||||||
date_range = { days_ahead = 30, days_back = 30, sync_all_events = false }
|
date_range = { days_ahead = 30, days_back = 30, sync_all_events = false }
|
||||||
|
|
||||||
|
[import]
|
||||||
|
# Target server configuration (e.g., Nextcloud)
|
||||||
|
[import.target_server]
|
||||||
|
# Nextcloud CalDAV URL
|
||||||
|
url = "https://cloud.soliverez.com.ar/remote.php/dav/calendars/alvaro/"
|
||||||
|
# Username for Nextcloud authentication
|
||||||
|
username = "alvaro"
|
||||||
|
# Password for Nextcloud authentication (use app-specific password)
|
||||||
|
password = "D7F2o-fFoqp-j2ttJ-t4etE-yz3oS"
|
||||||
|
# Whether to use HTTPS (recommended)
|
||||||
|
use_https = true
|
||||||
|
# Request timeout in seconds
|
||||||
|
timeout = 30
|
||||||
|
|
||||||
|
# Target calendar configuration
|
||||||
|
[import.target_calendar]
|
||||||
|
# Target calendar name
|
||||||
|
name = "trabajo-alvaro"
|
||||||
|
enabled = true
|
||||||
|
|
||||||
|
|
||||||
# Optional filtering configuration
|
# Optional filtering configuration
|
||||||
[filters]
|
[filters]
|
||||||
# Keywords to filter events by (events containing any of these will be included)
|
# Keywords to filter events by (events containing any of these will be included)
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,12 @@ use anyhow::Result;
|
||||||
/// Main configuration structure
|
/// Main configuration structure
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
/// Server configuration
|
/// Source server configuration (e.g., Zoho)
|
||||||
pub server: ServerConfig,
|
pub server: ServerConfig,
|
||||||
/// Calendar configuration
|
/// Source calendar configuration
|
||||||
pub calendar: CalendarConfig,
|
pub calendar: CalendarConfig,
|
||||||
|
/// Import configuration (e.g., Nextcloud as target)
|
||||||
|
pub import: Option<ImportConfig>,
|
||||||
/// Filter configuration
|
/// Filter configuration
|
||||||
pub filters: Option<FilterConfig>,
|
pub filters: Option<FilterConfig>,
|
||||||
/// Sync configuration
|
/// Sync configuration
|
||||||
|
|
@ -49,6 +51,47 @@ pub struct CalendarConfig {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Import configuration for unidirectional sync to target server
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ImportConfig {
|
||||||
|
/// Target server configuration
|
||||||
|
pub target_server: ImportTargetServerConfig,
|
||||||
|
/// Target calendar configuration
|
||||||
|
pub target_calendar: ImportTargetCalendarConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Target server configuration for Nextcloud or other CalDAV servers
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ImportTargetServerConfig {
|
||||||
|
/// Target CalDAV server URL
|
||||||
|
pub url: String,
|
||||||
|
/// Username for authentication
|
||||||
|
pub username: String,
|
||||||
|
/// Password for authentication
|
||||||
|
pub password: String,
|
||||||
|
/// Whether to use HTTPS
|
||||||
|
pub use_https: bool,
|
||||||
|
/// Timeout in seconds
|
||||||
|
pub timeout: u64,
|
||||||
|
/// Custom headers to send with requests
|
||||||
|
pub headers: Option<std::collections::HashMap<String, String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Target calendar configuration
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct ImportTargetCalendarConfig {
|
||||||
|
/// Target calendar name
|
||||||
|
pub name: String,
|
||||||
|
/// Target calendar display name
|
||||||
|
pub display_name: Option<String>,
|
||||||
|
/// Target calendar color
|
||||||
|
pub color: Option<String>,
|
||||||
|
/// Target calendar timezone
|
||||||
|
pub timezone: Option<String>,
|
||||||
|
/// Whether this calendar is enabled for import
|
||||||
|
pub enabled: bool,
|
||||||
|
}
|
||||||
|
|
||||||
/// Filter configuration for events
|
/// Filter configuration for events
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct FilterConfig {
|
pub struct FilterConfig {
|
||||||
|
|
@ -97,6 +140,7 @@ impl Default for Config {
|
||||||
Self {
|
Self {
|
||||||
server: ServerConfig::default(),
|
server: ServerConfig::default(),
|
||||||
calendar: CalendarConfig::default(),
|
calendar: CalendarConfig::default(),
|
||||||
|
import: None,
|
||||||
filters: None,
|
filters: None,
|
||||||
sync: SyncConfig::default(),
|
sync: SyncConfig::default(),
|
||||||
}
|
}
|
||||||
|
|
@ -128,6 +172,40 @@ impl Default for CalendarConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ImportConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
target_server: ImportTargetServerConfig::default(),
|
||||||
|
target_calendar: ImportTargetCalendarConfig::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ImportTargetServerConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
url: "https://nextcloud.example.com/remote.php/dav/calendars/user".to_string(),
|
||||||
|
username: String::new(),
|
||||||
|
password: String::new(),
|
||||||
|
use_https: true,
|
||||||
|
timeout: 30,
|
||||||
|
headers: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ImportTargetCalendarConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
name: "Imported-Events".to_string(),
|
||||||
|
display_name: None,
|
||||||
|
color: None,
|
||||||
|
timezone: None,
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for SyncConfig {
|
impl Default for SyncConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
|
||||||
301
src/main.rs
301
src/main.rs
|
|
@ -58,6 +58,10 @@ struct Cli {
|
||||||
/// Use specific calendar URL instead of discovering from config
|
/// Use specific calendar URL instead of discovering from config
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
calendar_url: Option<String>,
|
calendar_url: Option<String>,
|
||||||
|
|
||||||
|
/// Show detailed import-relevant information for calendars
|
||||||
|
#[arg(long)]
|
||||||
|
import_info: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
|
@ -126,24 +130,299 @@ async fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run_sync(config: Config, cli: &Cli) -> CalDavResult<()> {
|
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 {
|
if cli.list_calendars {
|
||||||
// List calendars and exit
|
// List calendars and exit
|
||||||
info!("Listing available calendars from server");
|
info!("Listing available calendars from server");
|
||||||
|
|
||||||
// Get calendars directly from the client
|
if cli.import_info {
|
||||||
let calendars = sync_engine.client.discover_calendars().await?;
|
println!("🔍 Import Analysis Report");
|
||||||
println!("Found {} calendars:", calendars.len());
|
println!("========================\n");
|
||||||
|
|
||||||
|
// Show source calendars (current configuration)
|
||||||
|
println!("📤 SOURCE CALENDARS (Zoho/Current Server)");
|
||||||
|
println!("==========================================");
|
||||||
|
|
||||||
|
// Get calendars from the source server - handle errors gracefully
|
||||||
|
let source_calendars = match SyncEngine::new(config.clone()).await {
|
||||||
|
Ok(sync_engine) => {
|
||||||
|
match sync_engine.client.discover_calendars().await {
|
||||||
|
Ok(calendars) => {
|
||||||
|
Some(calendars)
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("⚠️ Failed to discover source calendars: {}", e);
|
||||||
|
println!("Source server may be unavailable or credentials may be incorrect.\n");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("⚠️ Failed to connect to source server: {}", e);
|
||||||
|
println!("Source server configuration may need checking.\n");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let target_calendar_name = &config.calendar.name;
|
||||||
|
|
||||||
|
if let Some(ref calendars) = source_calendars {
|
||||||
|
println!("Found {} source calendars:", calendars.len());
|
||||||
|
println!("Current source calendar: {}\n", target_calendar_name);
|
||||||
|
|
||||||
|
for (i, calendar) in calendars.iter().enumerate() {
|
||||||
|
let is_target = calendar.name == *target_calendar_name
|
||||||
|
|| calendar.display_name.as_ref().map_or(false, |dn| dn == target_calendar_name);
|
||||||
|
|
||||||
|
// Calendar header with target indicator
|
||||||
|
if is_target {
|
||||||
|
println!(" {}. {} 🎯 [CURRENT SOURCE]", i + 1, calendar.display_name.as_ref().unwrap_or(&calendar.name));
|
||||||
|
} else {
|
||||||
|
println!(" {}. {}", i + 1, calendar.display_name.as_ref().unwrap_or(&calendar.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic information
|
||||||
|
println!(" Name: {}", calendar.name);
|
||||||
|
println!(" URL: {}", calendar.url);
|
||||||
|
|
||||||
|
if let Some(ref display_name) = calendar.display_name {
|
||||||
|
println!(" Display Name: {}", display_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import-relevant information
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supported components - crucial for export compatibility
|
||||||
|
let components = &calendar.supported_components;
|
||||||
|
println!(" Supported Components: {}", components.join(", "));
|
||||||
|
|
||||||
|
// Export suitability analysis
|
||||||
|
let supports_events = components.contains(&"VEVENT".to_string());
|
||||||
|
let supports_todos = components.contains(&"VTODO".to_string());
|
||||||
|
let supports_journals = components.contains(&"VJOURNAL".to_string());
|
||||||
|
|
||||||
|
println!(" 📤 Export Analysis:");
|
||||||
|
println!(" Event Support: {}", if supports_events { "✅ Yes" } else { "❌ No" });
|
||||||
|
println!(" Task Support: {}", if supports_todos { "✅ Yes" } else { "❌ No" });
|
||||||
|
println!(" Journal Support: {}", if supports_journals { "✅ Yes" } else { "❌ No" });
|
||||||
|
|
||||||
|
// Server type detection
|
||||||
|
if calendar.url.contains("/zoho/") || calendar.url.contains("zoho.com") {
|
||||||
|
println!(" Server Type: 🔵 Zoho");
|
||||||
|
println!(" CalDAV Standard: ⚠️ Partially Compliant");
|
||||||
|
println!(" Special Features: Zoho-specific APIs available");
|
||||||
|
} else {
|
||||||
|
println!(" Server Type: 🔧 Generic CalDAV");
|
||||||
|
println!(" CalDAV Standard: ✅ Likely Compliant");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("⚠️ Could not retrieve source calendars");
|
||||||
|
println!("Please check your source server configuration:\n");
|
||||||
|
println!(" URL: {}", config.server.url);
|
||||||
|
println!(" Username: {}", config.server.username);
|
||||||
|
println!(" Calendar: {}\n", config.calendar.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show target import calendars if configured
|
||||||
|
if let Some(ref import_config) = config.import {
|
||||||
|
println!("📥 TARGET IMPORT CALENDARS (Nextcloud/Destination)");
|
||||||
|
println!("=================================================");
|
||||||
|
|
||||||
|
println!("Configured target server: {}", import_config.target_server.url);
|
||||||
|
println!("Configured target calendar: {}\n", import_config.target_calendar.name);
|
||||||
|
|
||||||
|
// Create a temporary config for the target server
|
||||||
|
let mut target_config = config.clone();
|
||||||
|
target_config.server.url = import_config.target_server.url.clone();
|
||||||
|
target_config.server.username = import_config.target_server.username.clone();
|
||||||
|
target_config.server.password = import_config.target_server.password.clone();
|
||||||
|
target_config.server.timeout = import_config.target_server.timeout;
|
||||||
|
target_config.server.use_https = import_config.target_server.use_https;
|
||||||
|
target_config.server.headers = import_config.target_server.headers.clone();
|
||||||
|
|
||||||
|
println!("Attempting to connect to target server...");
|
||||||
|
|
||||||
|
// Try to connect to target server and list calendars
|
||||||
|
match SyncEngine::new(target_config).await {
|
||||||
|
Ok(target_sync_engine) => {
|
||||||
|
println!("✅ Successfully connected to target server!");
|
||||||
|
match target_sync_engine.client.discover_calendars().await {
|
||||||
|
Ok(target_calendars) => {
|
||||||
|
println!("Found {} target calendars:", target_calendars.len());
|
||||||
|
|
||||||
|
for (i, calendar) in target_calendars.iter().enumerate() {
|
||||||
|
let is_target = calendar.name == import_config.target_calendar.name
|
||||||
|
|| calendar.display_name.as_ref().map_or(false, |dn| *dn == import_config.target_calendar.name);
|
||||||
|
|
||||||
|
// Calendar header with target indicator
|
||||||
|
if is_target {
|
||||||
|
println!(" {}. {} 🎯 [IMPORT TARGET]", i + 1, calendar.display_name.as_ref().unwrap_or(&calendar.name));
|
||||||
|
} else {
|
||||||
|
println!(" {}. {}", i + 1, calendar.display_name.as_ref().unwrap_or(&calendar.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic information
|
||||||
|
println!(" Name: {}", calendar.name);
|
||||||
|
println!(" URL: {}", calendar.url);
|
||||||
|
|
||||||
|
if let Some(ref display_name) = calendar.display_name {
|
||||||
|
println!(" Display Name: {}", display_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import-relevant information
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Supported components - crucial for import compatibility
|
||||||
|
let components = &calendar.supported_components;
|
||||||
|
println!(" Supported Components: {}", components.join(", "));
|
||||||
|
|
||||||
|
// Import suitability analysis
|
||||||
|
let supports_events = components.contains(&"VEVENT".to_string());
|
||||||
|
let supports_todos = components.contains(&"VTODO".to_string());
|
||||||
|
let supports_journals = components.contains(&"VJOURNAL".to_string());
|
||||||
|
|
||||||
|
println!(" 📥 Import Analysis:");
|
||||||
|
println!(" Event Support: {}", if supports_events { "✅ Yes" } else { "❌ No" });
|
||||||
|
println!(" Task Support: {}", if supports_todos { "✅ Yes" } else { "❌ No" });
|
||||||
|
println!(" Journal Support: {}", if supports_journals { "✅ Yes" } else { "❌ No" });
|
||||||
|
|
||||||
|
// Server type detection
|
||||||
|
if calendar.url.contains("/remote.php/dav/calendars/") {
|
||||||
|
println!(" Server Type: ☁️ Nextcloud");
|
||||||
|
println!(" CalDAV Standard: ✅ RFC 4791 Compliant");
|
||||||
|
println!(" Recommended: ✅ High compatibility");
|
||||||
|
println!(" Special Features: Full SabreDAV support");
|
||||||
|
} else {
|
||||||
|
println!(" Server Type: 🔧 Generic CalDAV");
|
||||||
|
println!(" CalDAV Standard: ✅ Likely Compliant");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional Nextcloud-specific checks
|
||||||
|
if calendar.url.contains("/remote.php/dav/calendars/") && supports_events {
|
||||||
|
println!(" ✅ Ready for Nextcloud event import");
|
||||||
|
} else if !supports_events {
|
||||||
|
println!(" ⚠️ This calendar doesn't support events - not suitable for import");
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import compatibility summary
|
||||||
|
let target_calendar = target_calendars.iter()
|
||||||
|
.find(|c| c.name == import_config.target_calendar.name
|
||||||
|
|| c.display_name.as_ref().map_or(false, |dn| *dn == import_config.target_calendar.name));
|
||||||
|
|
||||||
|
if let Some(target_cal) = target_calendar {
|
||||||
|
let supports_events = target_cal.supported_components.contains(&"VEVENT".to_string());
|
||||||
|
let is_nextcloud = target_cal.url.contains("/remote.php/dav/calendars/");
|
||||||
|
|
||||||
|
println!("📋 IMPORT READINESS SUMMARY");
|
||||||
|
println!("============================");
|
||||||
|
println!("Target Calendar: {}", target_cal.display_name.as_ref().unwrap_or(&target_cal.name));
|
||||||
|
println!("Supports Events: {}", if supports_events { "✅ Yes" } else { "❌ No" });
|
||||||
|
println!("Server Type: {}", if is_nextcloud { "☁️ Nextcloud" } else { "🔧 Generic CalDAV" });
|
||||||
|
|
||||||
|
if supports_events {
|
||||||
|
if is_nextcloud {
|
||||||
|
println!("Overall Status: ✅ Excellent - Nextcloud with full event support");
|
||||||
|
} else {
|
||||||
|
println!("Overall Status: ✅ Good - Generic CalDAV with event support");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("Overall Status: ❌ Not suitable - No event support");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("⚠️ Target calendar '{}' not found on server", import_config.target_calendar.name);
|
||||||
|
println!("Available calendars:");
|
||||||
|
for calendar in &target_calendars {
|
||||||
|
println!(" - {}", calendar.display_name.as_ref().unwrap_or(&calendar.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("❌ Failed to discover calendars on target server: {}", e);
|
||||||
|
println!("The server connection was successful, but calendar discovery failed.");
|
||||||
|
println!("Please check your import configuration:");
|
||||||
|
println!(" URL: {}", import_config.target_server.url);
|
||||||
|
println!(" Username: {}", import_config.target_server.username);
|
||||||
|
println!(" Target Calendar: {}", import_config.target_calendar.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
println!("❌ Failed to connect to target server: {}", e);
|
||||||
|
println!("Please check your import configuration:");
|
||||||
|
println!(" URL: {}", import_config.target_server.url);
|
||||||
|
println!(" Username: {}", import_config.target_server.username);
|
||||||
|
println!(" Target Calendar: {}", import_config.target_calendar.name);
|
||||||
|
|
||||||
|
// Provide guidance based on the error
|
||||||
|
if e.to_string().contains("401") || e.to_string().contains("Unauthorized") {
|
||||||
|
println!("");
|
||||||
|
println!("💡 Troubleshooting tips:");
|
||||||
|
println!(" - Check username and password");
|
||||||
|
println!(" - For Nextcloud with 2FA, use app-specific passwords");
|
||||||
|
println!(" - Verify the URL format: https://your-nextcloud.com/remote.php/dav/calendars/username/");
|
||||||
|
} else if e.to_string().contains("404") || e.to_string().contains("Not Found") {
|
||||||
|
println!("");
|
||||||
|
println!("💡 Troubleshooting tips:");
|
||||||
|
println!(" - Verify the Nextcloud URL is correct");
|
||||||
|
println!(" - Check if CalDAV is enabled in Nextcloud settings");
|
||||||
|
println!(" - Ensure the username is correct (case-sensitive)");
|
||||||
|
} else if e.to_string().contains("timeout") || e.to_string().contains("connection") {
|
||||||
|
println!("");
|
||||||
|
println!("💡 Troubleshooting tips:");
|
||||||
|
println!(" - Check network connectivity");
|
||||||
|
println!(" - Verify the Nextcloud server is accessible");
|
||||||
|
println!(" - Try increasing timeout value in configuration");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
println!("📥 No import target configured");
|
||||||
|
println!("To configure import target, add [import] section to config.toml:");
|
||||||
|
println!("");
|
||||||
|
println!("[import]");
|
||||||
|
println!("[import.target_server]");
|
||||||
|
println!("url = \"https://your-nextcloud.com/remote.php/dav/calendars/user\"");
|
||||||
|
println!("username = \"your-username\"");
|
||||||
|
println!("password = \"your-password\"");
|
||||||
|
println!("[import.target_calendar]");
|
||||||
|
println!("name = \"Imported-Zoho-Events\"");
|
||||||
|
println!("enabled = true");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Regular calendar listing (original behavior) - only if not import_info
|
||||||
|
let sync_engine = SyncEngine::new(config.clone()).await?;
|
||||||
|
let calendars = sync_engine.client.discover_calendars().await?;
|
||||||
|
|
||||||
|
println!("Found {} calendars:", calendars.len());
|
||||||
for (i, calendar) in calendars.iter().enumerate() {
|
for (i, calendar) in calendars.iter().enumerate() {
|
||||||
println!(" {}. {}", i + 1, calendar.display_name.as_ref().unwrap_or(&calendar.name));
|
println!(" {}. {}", i + 1, calendar.display_name.as_ref().unwrap_or(&calendar.name));
|
||||||
println!(" Name: {}", calendar.name);
|
println!(" Name: {}", calendar.name);
|
||||||
println!(" URL: {}", calendar.url);
|
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 {
|
if let Some(ref color) = calendar.color {
|
||||||
println!(" Color: {}", color);
|
println!(" Color: {}", color);
|
||||||
}
|
}
|
||||||
|
|
@ -156,10 +435,14 @@ async fn run_sync(config: Config, cli: &Cli) -> CalDavResult<()> {
|
||||||
println!(" Supported Components: {}", calendar.supported_components.join(", "));
|
println!(" Supported Components: {}", calendar.supported_components.join(", "));
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create sync engine for other operations
|
||||||
|
let mut sync_engine = SyncEngine::new(config.clone()).await?;
|
||||||
|
|
||||||
if cli.list_events {
|
if cli.list_events {
|
||||||
// List events and exit
|
// List events and exit
|
||||||
info!("Listing events from calendar: {}", config.calendar.name);
|
info!("Listing events from calendar: {}", config.calendar.name);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue