docs: Split documentation into separate files
- Move development details to DEVELOPMENT.md - Move contributing guidelines to CONTRIBUTING.md - Add LICENSE file with MIT license - Add CONTRIBUTORS.md for attribution - Update README.md to focus on user-facing information - Improve documentation structure and navigation
This commit is contained in:
parent
8362ebe44b
commit
37e9bc2dc1
5 changed files with 826 additions and 122 deletions
358
CONTRIBUTING.md
Normal file
358
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,358 @@
|
||||||
|
# Contributing to CalDAV Calendar Synchronizer
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to the CalDAV Calendar Synchronizer! This document provides guidelines and information for contributors.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Rust 1.70 or newer
|
||||||
|
- Git
|
||||||
|
- Basic familiarity with CalDAV protocol
|
||||||
|
- Understanding of async/await in Rust
|
||||||
|
|
||||||
|
### Development Setup
|
||||||
|
|
||||||
|
1. **Fork and Clone**
|
||||||
|
```bash
|
||||||
|
# Fork the repository on your Forgejo instance
|
||||||
|
git clone ssh://git@gitea.soliverez.com.ar/YOUR_USERNAME/caldavpuller.git
|
||||||
|
cd caldavpuller
|
||||||
|
|
||||||
|
# Add upstream remote
|
||||||
|
git remote add upstream ssh://git@gitea.soliverez.com.ar/alvaro/caldavpuller.git
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install Development Tools**
|
||||||
|
```bash
|
||||||
|
# Install Rust toolchain
|
||||||
|
rustup update stable
|
||||||
|
rustup component add rustfmt clippy rust-analyzer
|
||||||
|
|
||||||
|
# Verify installation
|
||||||
|
cargo --version
|
||||||
|
rustfmt --version
|
||||||
|
clippy --version
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Build and Test**
|
||||||
|
```bash
|
||||||
|
# Build the project
|
||||||
|
cargo build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cargo test
|
||||||
|
|
||||||
|
# Check formatting
|
||||||
|
cargo fmt --check
|
||||||
|
|
||||||
|
# Run linter
|
||||||
|
cargo clippy -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### 1. **Create a Branch**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Sync with upstream
|
||||||
|
git fetch upstream
|
||||||
|
git checkout main
|
||||||
|
git merge upstream/main
|
||||||
|
|
||||||
|
# Create feature branch
|
||||||
|
git checkout -b feature/your-feature-name
|
||||||
|
# or
|
||||||
|
git checkout -b fix/your-fix-name
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Make Changes**
|
||||||
|
|
||||||
|
- Follow the existing code style
|
||||||
|
- Add tests for new functionality
|
||||||
|
- Update documentation as needed
|
||||||
|
- Ensure all tests pass
|
||||||
|
|
||||||
|
### 3. **Commit Changes**
|
||||||
|
|
||||||
|
Use clear, descriptive commit messages:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Good commit message
|
||||||
|
git commit -m "feat: Add support for calendar color filtering
|
||||||
|
|
||||||
|
- Add color field to CalendarInfo struct
|
||||||
|
- Implement color-based filtering in CalendarFilter
|
||||||
|
- Add configuration option for color preferences
|
||||||
|
- Add unit tests for color filtering logic"
|
||||||
|
|
||||||
|
# Another good example
|
||||||
|
git commit -m "fix: Handle timezone parsing errors gracefully
|
||||||
|
|
||||||
|
- Add proper error handling for unknown timezone identifiers
|
||||||
|
- Return meaningful error messages to users
|
||||||
|
- Add integration tests for timezone edge cases"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. **Submit Pull Request**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Push to your fork
|
||||||
|
git push origin feature/your-feature-name
|
||||||
|
|
||||||
|
# Create pull request on Forgejo
|
||||||
|
# Provide clear description of changes and testing done
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style and Standards
|
||||||
|
|
||||||
|
### 1. **Formatting**
|
||||||
|
|
||||||
|
Use `rustfmt` with default settings:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Linting**
|
||||||
|
|
||||||
|
All code must pass `clippy` without warnings:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo clippy -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Documentation**
|
||||||
|
|
||||||
|
- Document all public APIs with `///` comments
|
||||||
|
- Include examples for complex functionality
|
||||||
|
- Update README and other documentation as needed
|
||||||
|
|
||||||
|
```rust
|
||||||
|
/// Filters calendars based on user-defined criteria.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use caldav_sync::CalendarFilter;
|
||||||
|
///
|
||||||
|
/// let filter = CalendarFilter::new()
|
||||||
|
/// .with_selected_calendars(vec!["Work".to_string()]);
|
||||||
|
///
|
||||||
|
/// assert!(filter.should_import_calendar("Work"));
|
||||||
|
/// assert!(!filter.should_import_calendar("Personal"));
|
||||||
|
/// ```
|
||||||
|
pub struct CalendarFilter {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. **Error Handling**
|
||||||
|
|
||||||
|
- Use `Result<T, CalDavError>` for fallible operations
|
||||||
|
- Provide meaningful error context
|
||||||
|
- Handle errors gracefully at the UI layer
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub async fn sync_calendars(&mut self) -> CalDavResult<SyncStats> {
|
||||||
|
let calendars = self.discover_calendars().await
|
||||||
|
.context("Failed to discover calendars")?;
|
||||||
|
|
||||||
|
// ... rest of implementation
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5. **Testing**
|
||||||
|
|
||||||
|
Write comprehensive tests:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_calendar_filtering() {
|
||||||
|
let filter = CalendarFilter::new()
|
||||||
|
.with_selected_calendars(vec!["Work".to_string()]);
|
||||||
|
|
||||||
|
assert!(filter.should_import_calendar("Work"));
|
||||||
|
assert!(!filter.should_import_calendar("Personal"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### 1. **Unit Tests**
|
||||||
|
|
||||||
|
Test individual components in isolation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test --lib
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Integration Tests**
|
||||||
|
|
||||||
|
Test component interactions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo test --test integration_tests
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Manual Testing**
|
||||||
|
|
||||||
|
Test with real CalDAV servers:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and run with debug logging
|
||||||
|
cargo build
|
||||||
|
./target/debug/caldav-sync --debug --list-events
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. **Test Coverage**
|
||||||
|
|
||||||
|
Aim for high test coverage, especially for:
|
||||||
|
- Configuration parsing
|
||||||
|
- Error handling paths
|
||||||
|
- Calendar filtering logic
|
||||||
|
- Timezone conversions
|
||||||
|
|
||||||
|
## Types of Contributions
|
||||||
|
|
||||||
|
### 1. **Bug Fixes**
|
||||||
|
|
||||||
|
- Check existing issues for bug reports
|
||||||
|
- Create minimal reproduction case
|
||||||
|
- Add tests that fail before the fix
|
||||||
|
- Fix the issue and ensure tests pass
|
||||||
|
|
||||||
|
### 2. **New Features**
|
||||||
|
|
||||||
|
- Open issue for discussion first
|
||||||
|
- Design the feature interface
|
||||||
|
- Implement with tests
|
||||||
|
- Update documentation
|
||||||
|
|
||||||
|
### 3. **Documentation**
|
||||||
|
|
||||||
|
- Improve README and guides
|
||||||
|
- Add code examples
|
||||||
|
- Fix typos and clarity issues
|
||||||
|
- Translate documentation if possible
|
||||||
|
|
||||||
|
### 4. **Performance Improvements**
|
||||||
|
|
||||||
|
- Profile existing code
|
||||||
|
- Identify bottlenecks
|
||||||
|
- Implement optimizations
|
||||||
|
- Add benchmarks for verification
|
||||||
|
|
||||||
|
## Areas Needing Help
|
||||||
|
|
||||||
|
### 1. **Enhanced CalDAV Support**
|
||||||
|
|
||||||
|
- Better support for CalDAV extensions
|
||||||
|
- Handling of recurring events
|
||||||
|
- Support for attachments and attendees
|
||||||
|
|
||||||
|
### 2. **User Experience**
|
||||||
|
|
||||||
|
- Interactive configuration wizard
|
||||||
|
- Progress indicators for long operations
|
||||||
|
- Better error messages and recovery
|
||||||
|
|
||||||
|
### 3. **Testing Infrastructure**
|
||||||
|
|
||||||
|
- Mock CalDAV server for testing
|
||||||
|
- Automated testing in CI/CD
|
||||||
|
- Performance benchmarks
|
||||||
|
|
||||||
|
### 4. **Documentation**
|
||||||
|
|
||||||
|
- User guides for different platforms
|
||||||
|
- API documentation
|
||||||
|
- Troubleshooting guides
|
||||||
|
|
||||||
|
## Code Review Process
|
||||||
|
|
||||||
|
### 1. **Self-Review**
|
||||||
|
|
||||||
|
Before submitting, review your own changes:
|
||||||
|
- Code follows project style
|
||||||
|
- Tests are comprehensive
|
||||||
|
- Documentation is updated
|
||||||
|
- No debug code or TODOs left
|
||||||
|
|
||||||
|
### 2. **Review Criteria**
|
||||||
|
|
||||||
|
Maintainers will review for:
|
||||||
|
- Correctness and safety
|
||||||
|
- Performance implications
|
||||||
|
- User experience impact
|
||||||
|
- Code maintainability
|
||||||
|
|
||||||
|
### 3. **Feedback**
|
||||||
|
|
||||||
|
Be prepared to:
|
||||||
|
- Answer questions about your changes
|
||||||
|
- Make requested modifications
|
||||||
|
- Discuss alternative approaches
|
||||||
|
- Update tests based on feedback
|
||||||
|
|
||||||
|
## Release Process
|
||||||
|
|
||||||
|
### 1. **Version Management**
|
||||||
|
|
||||||
|
- Follow semantic versioning (MAJOR.MINOR.PATCH)
|
||||||
|
- Update version in `Cargo.toml`
|
||||||
|
- Create git tag for releases
|
||||||
|
|
||||||
|
### 2. **Changelog**
|
||||||
|
|
||||||
|
Maintain `CHANGELOG.md` with:
|
||||||
|
- New features
|
||||||
|
- Bug fixes
|
||||||
|
- Breaking changes
|
||||||
|
- Migration notes
|
||||||
|
|
||||||
|
### 3. **Release Checklist**
|
||||||
|
|
||||||
|
- [ ] All tests pass
|
||||||
|
- [ ] Documentation updated
|
||||||
|
- [ ] Version numbers updated
|
||||||
|
- [ ] Changelog updated
|
||||||
|
- [ ] Release tag created
|
||||||
|
- [ ] Release artifacts built
|
||||||
|
|
||||||
|
## Support and Communication
|
||||||
|
|
||||||
|
### 1. **Issues and Questions**
|
||||||
|
|
||||||
|
- Use GitHub issues for bug reports and feature requests
|
||||||
|
- Check existing issues before creating new ones
|
||||||
|
- Provide clear, reproducible examples
|
||||||
|
|
||||||
|
### 2. **Discussions**
|
||||||
|
|
||||||
|
- Use discussions for general questions
|
||||||
|
- Share ideas and suggestions
|
||||||
|
- Ask for help with development
|
||||||
|
|
||||||
|
### 3. **Code of Conduct**
|
||||||
|
|
||||||
|
Be respectful and constructive:
|
||||||
|
- Welcome newcomers and help them learn
|
||||||
|
- Assume good faith in interactions
|
||||||
|
- Focus on what is best for the community
|
||||||
|
- Show empathy towards other community members
|
||||||
|
|
||||||
|
## Recognition
|
||||||
|
|
||||||
|
Contributors are recognized in:
|
||||||
|
- `CONTRIBUTORS.md` file
|
||||||
|
- Release notes
|
||||||
|
- Git commit history
|
||||||
|
- Project documentation
|
||||||
|
|
||||||
|
Thank you for contributing to the CalDAV Calendar Synchronizer! Your contributions help make this project better for everyone.
|
||||||
17
CONTRIBUTORS.md
Normal file
17
CONTRIBUTORS.md
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Contributors
|
||||||
|
|
||||||
|
This project exists thanks to all the people who contribute.
|
||||||
|
|
||||||
|
## Lead Developer
|
||||||
|
|
||||||
|
- **Alvaro Soliverez** - *Project creator and maintainer*
|
||||||
|
|
||||||
|
## Development Setup
|
||||||
|
|
||||||
|
For information on how to contribute to this project, please see [CONTRIBUTING.md](CONTRIBUTING.md).
|
||||||
|
|
||||||
|
## Acknowledgments
|
||||||
|
|
||||||
|
- The Rust community for excellent tools and libraries
|
||||||
|
- The CalDAV protocol developers and maintainers
|
||||||
|
- All users who provide feedback and bug reports
|
||||||
416
DEVELOPMENT.md
Normal file
416
DEVELOPMENT.md
Normal file
|
|
@ -0,0 +1,416 @@
|
||||||
|
# Development Guide
|
||||||
|
|
||||||
|
This document provides comprehensive information about the design, architecture, and development of the CalDAV Calendar Synchronizer.
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
The application is built with a modular architecture using Rust's strong type system and async capabilities.
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
#### 1. **Configuration System** (`src/config.rs`)
|
||||||
|
- **Purpose**: Manage configuration from files, environment variables, and CLI arguments
|
||||||
|
- **Features**:
|
||||||
|
- TOML-based configuration files
|
||||||
|
- Environment variable support
|
||||||
|
- Command-line argument overrides
|
||||||
|
- Configuration validation
|
||||||
|
- **Key Types**: `Config`, `ServerConfig`, `CalendarConfig`, `SyncConfig`
|
||||||
|
|
||||||
|
#### 2. **CalDAV Client** (`src/caldav_client.rs`)
|
||||||
|
- **Purpose**: Handle CalDAV protocol operations with Zoho and Nextcloud
|
||||||
|
- **Features**:
|
||||||
|
- HTTP client with authentication
|
||||||
|
- Calendar discovery via PROPFIND
|
||||||
|
- Event retrieval via REPORT requests
|
||||||
|
- Event creation via PUT requests
|
||||||
|
- **Key Types**: `CalDavClient`, `CalendarInfo`, `CalDavEventInfo`
|
||||||
|
|
||||||
|
#### 3. **Event Model** (`src/event.rs`)
|
||||||
|
- **Purpose**: Represent calendar events and handle parsing
|
||||||
|
- **Features**:
|
||||||
|
- iCalendar data parsing
|
||||||
|
- Timezone-aware datetime handling
|
||||||
|
- Event filtering and validation
|
||||||
|
- **Key Types**: `Event`, `EventBuilder`, `EventFilter`
|
||||||
|
|
||||||
|
#### 4. **Timezone Handler** (`src/timezone.rs`)
|
||||||
|
- **Purpose**: Manage timezone conversions and datetime operations
|
||||||
|
- **Features**:
|
||||||
|
- Convert between different timezones
|
||||||
|
- Parse timezone information from iCalendar data
|
||||||
|
- Handle DST transitions
|
||||||
|
- **Key Types**: `TimezoneHandler`, `TimeZoneInfo`
|
||||||
|
|
||||||
|
#### 5. **Calendar Filter** (`src/calendar_filter.rs`)
|
||||||
|
- **Purpose**: Filter calendars and events based on user criteria
|
||||||
|
- **Features**:
|
||||||
|
- Calendar name filtering
|
||||||
|
- Regex pattern matching
|
||||||
|
- Event date range filtering
|
||||||
|
- **Key Types**: `CalendarFilter`, `FilterRule`, `EventFilter`
|
||||||
|
|
||||||
|
#### 6. **Sync Engine** (`src/sync.rs`)
|
||||||
|
- **Purpose**: Coordinate the synchronization process
|
||||||
|
- **Features**:
|
||||||
|
- Pull events from Zoho
|
||||||
|
- Push events to Nextcloud
|
||||||
|
- Conflict resolution
|
||||||
|
- Progress tracking
|
||||||
|
- **Key Types**: `SyncEngine`, `SyncResult`, `SyncStats`
|
||||||
|
|
||||||
|
#### 7. **Error Handling** (`src/error.rs`)
|
||||||
|
- **Purpose**: Comprehensive error management
|
||||||
|
- **Features**:
|
||||||
|
- Custom error types
|
||||||
|
- Error context and chaining
|
||||||
|
- User-friendly error messages
|
||||||
|
- **Key Types**: `CalDavError`, `CalDavResult`
|
||||||
|
|
||||||
|
## Design Decisions
|
||||||
|
|
||||||
|
### 1. **Selective Calendar Import**
|
||||||
|
The application allows users to select specific Zoho calendars to import from, consolidating all events into a single Nextcloud calendar. This design choice:
|
||||||
|
|
||||||
|
- **Reduces complexity** compared to bidirectional sync
|
||||||
|
- **Provides clear data flow** (Zoho → Nextcloud)
|
||||||
|
- **Minimizes sync conflicts**
|
||||||
|
- **Matches user requirements** exactly
|
||||||
|
|
||||||
|
### 2. **Timezone Handling**
|
||||||
|
All events are converted to UTC internally for consistency, while preserving original timezone information:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
pub struct Event {
|
||||||
|
pub id: String,
|
||||||
|
pub summary: String,
|
||||||
|
pub start: DateTime<Utc>,
|
||||||
|
pub end: DateTime<Utc>,
|
||||||
|
pub original_timezone: Option<String>,
|
||||||
|
pub source_calendar: String,
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Configuration Hierarchy**
|
||||||
|
Configuration is loaded in priority order:
|
||||||
|
|
||||||
|
1. **Command line arguments** (highest priority)
|
||||||
|
2. **User config file** (`config/config.toml`)
|
||||||
|
3. **Default config file** (`config/default.toml`)
|
||||||
|
4. **Environment variables**
|
||||||
|
5. **Hardcoded defaults** (lowest priority)
|
||||||
|
|
||||||
|
### 4. **Error Handling Strategy**
|
||||||
|
Uses `thiserror` for custom error types and `anyhow` for error propagation:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum CalDavError {
|
||||||
|
#[error("HTTP error: {0}")]
|
||||||
|
Http(#[from] reqwest::Error),
|
||||||
|
|
||||||
|
#[error("Configuration error: {0}")]
|
||||||
|
Config(String),
|
||||||
|
|
||||||
|
#[error("Calendar not found: {0}")]
|
||||||
|
CalendarNotFound(String),
|
||||||
|
|
||||||
|
// ... more error variants
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
### 1. **Application Startup**
|
||||||
|
```
|
||||||
|
1. Load CLI arguments
|
||||||
|
2. Load configuration files
|
||||||
|
3. Apply environment variables
|
||||||
|
4. Validate configuration
|
||||||
|
5. Initialize logging
|
||||||
|
6. Create CalDAV clients
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Calendar Discovery**
|
||||||
|
```
|
||||||
|
1. Connect to Zoho CalDAV server
|
||||||
|
2. Authenticate with app password
|
||||||
|
3. Send PROPFIND request to discover calendars
|
||||||
|
4. Parse calendar list and metadata
|
||||||
|
5. Apply user filters to select calendars
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Event Synchronization**
|
||||||
|
```
|
||||||
|
1. Query selected Zoho calendars for events (next week)
|
||||||
|
2. Parse iCalendar data into Event objects
|
||||||
|
3. Convert timestamps to UTC with timezone preservation
|
||||||
|
4. Apply event filters (duration, status, patterns)
|
||||||
|
5. Connect to Nextcloud CalDAV server
|
||||||
|
6. Create target calendar if needed
|
||||||
|
7. Upload events to Nextcloud calendar
|
||||||
|
8. Report sync statistics
|
||||||
|
```
|
||||||
|
|
||||||
|
## Key Algorithms
|
||||||
|
|
||||||
|
### 1. **Calendar Filtering**
|
||||||
|
```rust
|
||||||
|
impl CalendarFilter {
|
||||||
|
pub fn should_import_calendar(&self, calendar_name: &str) -> bool {
|
||||||
|
// Check exact matches
|
||||||
|
if self.selected_names.contains(&calendar_name.to_string()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check regex patterns
|
||||||
|
for pattern in &self.regex_patterns {
|
||||||
|
if pattern.is_match(calendar_name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Timezone Conversion**
|
||||||
|
```rust
|
||||||
|
impl TimezoneHandler {
|
||||||
|
pub fn convert_to_utc(&self, dt: DateTime<FixedOffset>, timezone: &str) -> CalDavResult<DateTime<Utc>> {
|
||||||
|
let tz = self.get_timezone(timezone)?;
|
||||||
|
let local_dt = dt.with_timezone(&tz);
|
||||||
|
Ok(local_dt.with_timezone(&Utc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Event Processing**
|
||||||
|
```rust
|
||||||
|
impl SyncEngine {
|
||||||
|
pub async fn sync_calendar(&mut self, calendar: &CalendarInfo) -> CalDavResult<SyncResult> {
|
||||||
|
// 1. Fetch events from Zoho
|
||||||
|
let zoho_events = self.fetch_zoho_events(calendar).await?;
|
||||||
|
|
||||||
|
// 2. Filter and process events
|
||||||
|
let processed_events = self.process_events(zoho_events)?;
|
||||||
|
|
||||||
|
// 3. Upload to Nextcloud
|
||||||
|
let upload_results = self.upload_to_nextcloud(processed_events).await?;
|
||||||
|
|
||||||
|
// 4. Return sync statistics
|
||||||
|
Ok(SyncResult::from_upload_results(upload_results))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Schema
|
||||||
|
|
||||||
|
### Complete Configuration Structure
|
||||||
|
```toml
|
||||||
|
# Zoho Configuration (Source)
|
||||||
|
[zoho]
|
||||||
|
server_url = "https://caldav.zoho.com/caldav"
|
||||||
|
username = "your-zoho-email@domain.com"
|
||||||
|
password = "your-zoho-app-password"
|
||||||
|
selected_calendars = ["Work Calendar", "Personal Calendar"]
|
||||||
|
|
||||||
|
# Nextcloud Configuration (Target)
|
||||||
|
[nextcloud]
|
||||||
|
server_url = "https://your-nextcloud-domain.com"
|
||||||
|
username = "your-nextcloud-username"
|
||||||
|
password = "your-nextcloud-app-password"
|
||||||
|
target_calendar = "Imported-Zoho-Events"
|
||||||
|
create_if_missing = true
|
||||||
|
|
||||||
|
# General Settings
|
||||||
|
[server]
|
||||||
|
timeout = 30
|
||||||
|
|
||||||
|
[calendar]
|
||||||
|
color = "#3174ad"
|
||||||
|
timezone = "UTC"
|
||||||
|
|
||||||
|
[sync]
|
||||||
|
interval = 300
|
||||||
|
sync_on_startup = true
|
||||||
|
weeks_ahead = 1
|
||||||
|
dry_run = false
|
||||||
|
|
||||||
|
# Optional Filtering
|
||||||
|
[filters]
|
||||||
|
min_duration_minutes = 5
|
||||||
|
max_duration_hours = 24
|
||||||
|
exclude_patterns = ["Cancelled:", "BLOCKED"]
|
||||||
|
include_status = ["confirmed", "tentative"]
|
||||||
|
exclude_status = ["cancelled"]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dependencies and External Libraries
|
||||||
|
|
||||||
|
### Core Dependencies
|
||||||
|
```toml
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1.0", features = ["full"] } # Async runtime
|
||||||
|
reqwest = { version = "0.11", features = ["json", "xml"] } # HTTP client
|
||||||
|
serde = { version = "1.0", features = ["derive"] } # Serialization
|
||||||
|
chrono = { version = "0.4", features = ["serde"] } # Date/time
|
||||||
|
chrono-tz = "0.8" # Timezone support
|
||||||
|
quick-xml = "0.28" # XML parsing
|
||||||
|
thiserror = "1.0" # Error handling
|
||||||
|
anyhow = "1.0" # Error propagation
|
||||||
|
config = "0.13" # Configuration
|
||||||
|
clap = { version = "4.0", features = ["derive"] } # CLI
|
||||||
|
tracing = "0.1" # Logging
|
||||||
|
tracing-subscriber = "0.3" # Log formatting
|
||||||
|
toml = "0.8" # TOML parsing
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional Dependencies for Future Features
|
||||||
|
```toml
|
||||||
|
# For enhanced XML handling
|
||||||
|
serde_xml_rs = "0.6"
|
||||||
|
|
||||||
|
# For better HTTP client customization
|
||||||
|
http = "0.2"
|
||||||
|
|
||||||
|
# For async file operations
|
||||||
|
tokio-util = "0.7"
|
||||||
|
|
||||||
|
# For better error formatting
|
||||||
|
color-eyre = "0.6"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### 1. **Unit Tests**
|
||||||
|
- Individual module functionality
|
||||||
|
- Configuration parsing and validation
|
||||||
|
- Event parsing and timezone conversion
|
||||||
|
- Error handling paths
|
||||||
|
|
||||||
|
### 2. **Integration Tests**
|
||||||
|
- End-to-end CalDAV operations
|
||||||
|
- Configuration loading from files
|
||||||
|
- CLI argument processing
|
||||||
|
- HTTP client behavior
|
||||||
|
|
||||||
|
### 3. **Mock Testing**
|
||||||
|
- Mock CalDAV server responses
|
||||||
|
- Test error conditions without real servers
|
||||||
|
- Validate retry logic and timeout handling
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
### 1. **Async Operations**
|
||||||
|
All network operations are async to prevent blocking:
|
||||||
|
```rust
|
||||||
|
pub async fn fetch_events(&self, calendar: &CalendarInfo) -> CalDavResult<Vec<Event>> {
|
||||||
|
let response = self.client
|
||||||
|
.request(reqwest::Method::REPORT, &calendar.url)
|
||||||
|
.body(report_body)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
// Process response...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Memory Management**
|
||||||
|
- Stream processing for large calendar responses
|
||||||
|
- Efficient string handling with `Cow<str>` where appropriate
|
||||||
|
- Clear lifecycle management for HTTP connections
|
||||||
|
|
||||||
|
### 3. **Configuration Caching**
|
||||||
|
- Cache parsed timezone information
|
||||||
|
- Reuse HTTP connections where possible
|
||||||
|
- Validate configuration once at startup
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
### 1. **Authentication**
|
||||||
|
- Support for app-specific passwords only
|
||||||
|
- Never log authentication credentials
|
||||||
|
- Secure storage of sensitive configuration
|
||||||
|
|
||||||
|
### 2. **Network Security**
|
||||||
|
- Enforce HTTPS by default
|
||||||
|
- SSL certificate validation
|
||||||
|
- Custom CA certificate support
|
||||||
|
|
||||||
|
### 3. **Data Privacy**
|
||||||
|
- Minimal data collection (only required event fields)
|
||||||
|
- Optional debug logging with sensitive data filtering
|
||||||
|
- Clear data retention policies
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
### 1. **Enhanced Filtering**
|
||||||
|
- Advanced regex patterns
|
||||||
|
- Calendar color-based filtering
|
||||||
|
- Attendee-based filtering
|
||||||
|
|
||||||
|
### 2. **Bidirectional Sync**
|
||||||
|
- Two-way synchronization with conflict resolution
|
||||||
|
- Event modification tracking
|
||||||
|
- Deletion synchronization
|
||||||
|
|
||||||
|
### 3. **Performance Optimizations**
|
||||||
|
- Parallel calendar processing
|
||||||
|
- Incremental sync with change detection
|
||||||
|
- Local caching and offline mode
|
||||||
|
|
||||||
|
### 4. **User Experience**
|
||||||
|
- Interactive configuration wizard
|
||||||
|
- Web-based status dashboard
|
||||||
|
- Real-time sync notifications
|
||||||
|
|
||||||
|
## Build and Development
|
||||||
|
|
||||||
|
### 1. **Development Setup**
|
||||||
|
```bash
|
||||||
|
# Clone repository
|
||||||
|
git clone ssh://git@gitea.soliverez.com.ar/alvaro/caldavpuller.git
|
||||||
|
cd caldavpuller
|
||||||
|
|
||||||
|
# Install Rust toolchain
|
||||||
|
rustup update stable
|
||||||
|
rustup component add rustfmt clippy
|
||||||
|
|
||||||
|
# Build in development mode
|
||||||
|
cargo build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cargo test
|
||||||
|
|
||||||
|
# Check formatting
|
||||||
|
cargo fmt --check
|
||||||
|
|
||||||
|
# Run linter
|
||||||
|
cargo clippy -- -D warnings
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. **Release Build**
|
||||||
|
```bash
|
||||||
|
# Build optimized release
|
||||||
|
cargo build --release
|
||||||
|
|
||||||
|
# Create distribution archive
|
||||||
|
tar -czf caldav-sync-${VERSION}-${TARGET}.tar.gz \
|
||||||
|
-C target/release caldav-sync \
|
||||||
|
-C ../config example.toml \
|
||||||
|
-C .. README.md LICENSE
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. **Testing with Mock Servers**
|
||||||
|
For testing without real CalDAV servers, use the mock server setup:
|
||||||
|
```bash
|
||||||
|
# Start mock CalDAV server
|
||||||
|
cargo run --bin mock-server
|
||||||
|
|
||||||
|
# Run integration tests against mock server
|
||||||
|
cargo test --test integration_tests
|
||||||
|
```
|
||||||
|
|
||||||
|
This architecture provides a solid foundation for the CalDAV synchronization tool while maintaining flexibility for future enhancements.
|
||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2025 Alvaro Soliverez
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
136
README.md
136
README.md
|
|
@ -14,18 +14,18 @@ A Rust-based command-line tool that synchronizes calendar events between Zoho Ca
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
### 1. Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- Rust 1.70+ (for building from source)
|
- Rust 1.70+ (for building from source)
|
||||||
- Zoho account with CalDAV access
|
- Zoho account with CalDAV access
|
||||||
- Nextcloud instance with CalDAV enabled
|
- Nextcloud instance with CalDAV enabled
|
||||||
- App-specific passwords for both services (recommended)
|
- App-specific passwords for both services (recommended)
|
||||||
|
|
||||||
### 2. Installation
|
### Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repository
|
# Clone the repository
|
||||||
git clone <repository-url>
|
git clone ssh://git@gitea.soliverez.com.ar/alvaro/caldavpuller.git
|
||||||
cd caldavpuller
|
cd caldavpuller
|
||||||
|
|
||||||
# Build the project
|
# Build the project
|
||||||
|
|
@ -34,7 +34,7 @@ cargo build --release
|
||||||
# The binary will be at target/release/caldav-sync
|
# The binary will be at target/release/caldav-sync
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Configuration
|
### Configuration
|
||||||
|
|
||||||
Copy the example configuration file:
|
Copy the example configuration file:
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ target_calendar = "Imported-Zoho-Events"
|
||||||
create_if_missing = true
|
create_if_missing = true
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. First Run
|
### First Run
|
||||||
|
|
||||||
Test the configuration with a dry run:
|
Test the configuration with a dry run:
|
||||||
|
|
||||||
|
|
@ -77,35 +77,6 @@ Perform a one-time sync:
|
||||||
./target/release/caldav-sync --once
|
./target/release/caldav-sync --once
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration Details
|
|
||||||
|
|
||||||
### Zoho Setup
|
|
||||||
|
|
||||||
1. **Enable CalDAV in Zoho**:
|
|
||||||
- Go to Zoho Mail Settings → CalDAV
|
|
||||||
- Enable CalDAV access
|
|
||||||
- Generate an app-specific password
|
|
||||||
|
|
||||||
2. **Find Calendar Names**:
|
|
||||||
```bash
|
|
||||||
./target/release/caldav-sync --list-events --debug
|
|
||||||
```
|
|
||||||
This will show all available calendars.
|
|
||||||
|
|
||||||
### Nextcloud Setup
|
|
||||||
|
|
||||||
1. **Enable CalDAV**:
|
|
||||||
- Usually enabled by default
|
|
||||||
- Access at `https://your-domain.com/remote.php/dav/`
|
|
||||||
|
|
||||||
2. **Generate App Password**:
|
|
||||||
- Go to Settings → Security → App passwords
|
|
||||||
- Create a new app password for the sync tool
|
|
||||||
|
|
||||||
3. **Target Calendar**:
|
|
||||||
- The tool can automatically create the target calendar
|
|
||||||
- Or create it manually in Nextcloud first
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
### Command Line Options
|
### Command Line Options
|
||||||
|
|
@ -149,36 +120,7 @@ Options:
|
||||||
caldav-sync --username "user@example.com" --password "app-password" --once
|
caldav-sync --username "user@example.com" --password "app-password" --once
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration Reference
|
## Configuration
|
||||||
|
|
||||||
### Complete Configuration Example
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[server]
|
|
||||||
url = "https://caldav.zoho.com/caldav"
|
|
||||||
username = "your-email@domain.com"
|
|
||||||
password = "your-app-password"
|
|
||||||
timeout = 30
|
|
||||||
|
|
||||||
[calendar]
|
|
||||||
name = "Work Calendar"
|
|
||||||
color = "#4285F4"
|
|
||||||
|
|
||||||
[sync]
|
|
||||||
sync_interval = 300
|
|
||||||
sync_on_startup = true
|
|
||||||
weeks_ahead = 1
|
|
||||||
dry_run = false
|
|
||||||
|
|
||||||
[filters]
|
|
||||||
exclude_patterns = ["Cancelled:", "BLOCKED"]
|
|
||||||
min_duration_minutes = 5
|
|
||||||
max_duration_hours = 24
|
|
||||||
|
|
||||||
[logging]
|
|
||||||
level = "info"
|
|
||||||
file = "caldav-sync.log"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Environment Variables
|
### Environment Variables
|
||||||
|
|
||||||
|
|
@ -193,6 +135,10 @@ export CALDAV_CALENDAR="Work Calendar"
|
||||||
./target/release/caldav-sync
|
./target/release/caldav-sync
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Complete Configuration Example
|
||||||
|
|
||||||
|
See `config/example.toml` for a comprehensive configuration example with all available options.
|
||||||
|
|
||||||
## Security Considerations
|
## Security Considerations
|
||||||
|
|
||||||
1. **Use App Passwords**: Never use your main account password
|
1. **Use App Passwords**: Never use your main account password
|
||||||
|
|
@ -233,65 +179,11 @@ caldav-sync --debug --list-events
|
||||||
|
|
||||||
This will show detailed HTTP requests, responses, and processing steps.
|
This will show detailed HTTP requests, responses, and processing steps.
|
||||||
|
|
||||||
## Development
|
## More Information
|
||||||
|
|
||||||
### Building from Source
|
- **Development & Design**: See [DEVELOPMENT.md](DEVELOPMENT.md)
|
||||||
|
- **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||||
```bash
|
- **License**: See [LICENSE](LICENSE)
|
||||||
# Clone the repository
|
|
||||||
git clone <repository-url>
|
|
||||||
cd caldavpuller
|
|
||||||
|
|
||||||
# Build in debug mode
|
|
||||||
cargo build
|
|
||||||
|
|
||||||
# Build in release mode
|
|
||||||
cargo build --release
|
|
||||||
|
|
||||||
# Run tests
|
|
||||||
cargo test
|
|
||||||
|
|
||||||
# Check code formatting
|
|
||||||
cargo fmt --check
|
|
||||||
|
|
||||||
# Run linter
|
|
||||||
cargo clippy
|
|
||||||
```
|
|
||||||
|
|
||||||
### Project Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
caldavpuller/
|
|
||||||
├── src/
|
|
||||||
│ ├── main.rs # CLI interface and entry point
|
|
||||||
│ ├── lib.rs # Library interface
|
|
||||||
│ ├── config.rs # Configuration management
|
|
||||||
│ ├── caldav_client.rs # CalDAV HTTP client
|
|
||||||
│ ├── event.rs # Event data structures
|
|
||||||
│ ├── timezone.rs # Timezone handling
|
|
||||||
│ ├── calendar_filter.rs # Calendar filtering logic
|
|
||||||
│ ├── sync.rs # Synchronization engine
|
|
||||||
│ └── error.rs # Error types and handling
|
|
||||||
├── config/
|
|
||||||
│ ├── default.toml # Default configuration
|
|
||||||
│ └── example.toml # Example configuration
|
|
||||||
├── tests/
|
|
||||||
│ └── integration_tests.rs # Integration tests
|
|
||||||
├── Cargo.toml # Rust project configuration
|
|
||||||
└── README.md # This file
|
|
||||||
```
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create a feature branch
|
|
||||||
3. Make your changes
|
|
||||||
4. Add tests if applicable
|
|
||||||
5. Submit a pull request
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue