Skip to content

SystemCraftsman/calendar-monitor

Repository files navigation

πŸ“… Calendar Monitor

A real-time calendar monitoring application built with Rust that displays your current and upcoming events with live countdowns. Perfect for keeping track of your schedule on a separate monitor or display.

Rust WebSocket HTML5 CSS3 JavaScript

✨ Features

🎯 Core Functionality

  • Real-time Updates: Live countdown timers with WebSocket connections
  • Current Event: Shows active meeting/event with time remaining
  • Next Event: Displays upcoming event with start countdown
  • Time Blocks: Special support for time blocks (events with [brackets])
  • Multi-Calendar Support: Read from multiple ICS files simultaneously
  • Smart Caching: Efficient 5-minute caching to reduce load times

πŸ“… Calendar Integration

  • Google Calendar OAuth: Easy "Login with Google" integration - no complex setup needed
  • ICS File Support: Read from local .ics files or live URLs
  • Multi-Source Support: Combine Google Calendar with ICS feeds seamlessly
  • Recurring Events: Full support for weekly recurring events with RRULE and UNTIL clauses
  • Timezone Handling: Proper timezone conversion (supports Europe/Istanbul)
  • Cross-midnight Events: Handles events that span midnight correctly
  • Event Filtering: Separate handling of regular events vs time blocks

🎨 Modern UI

  • Responsive Design: Mobile and desktop friendly
  • Grid Layout: Clean CSS Grid-based layout
  • Live Animations: Heartbeat effect for active current events
  • Date Display: Smart date formatting (Tomorrow, weekday names, etc.)
  • Status Indicators: Visual connection status and event states

⚑ Performance

  • Async Architecture: Non-blocking I/O operations
  • Efficient Parsing: Fast ICS file processing with deduplication
  • Memory Safe: Built with Rust's memory safety guarantees
  • Low Resource Usage: Minimal CPU and memory footprint

πŸ–ΌοΈ Interface Overview

The application displays three main sections:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     πŸ“… Calendar Monitor  πŸ”— Connect     β”‚
β”‚           πŸ“‹ Time Block: Draft.dev      β”‚
β”‚        22:00-01:00 β€’ 45:23 remaining    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   🎯 Current Event   β”‚   ⏭️ Next Event   β”‚
β”‚                      β”‚                  β”‚
β”‚   Team Standup       β”‚   Project Review β”‚
β”‚   10:00-10:30        β”‚   Tomorrow       β”‚
β”‚   ⏰ 05:23 remaining  β”‚   14:00-15:00    β”‚
β”‚                      β”‚   Starts in 3h   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Quick Installation

One-Line Installation (Recommended)

curl -sSL https://raw.githubusercontent.com/systemcraftsman/calendar-monitor/main/install.sh | sudo bash

This automatically:

  • βœ… Detects your architecture (x86_64, ARM64, ARMv7)
  • βœ… Downloads the correct binary for your system
  • βœ… Sets up systemd service for auto-start
  • βœ… Creates configuration at /etc/calendar-monitor/config.toml
  • βœ… Works on Raspberry Pi (ARM64/ARMv7)

Supported Platforms

Platform Architecture Status
🐧 Linux x86_64 Intel/AMD 64-bit βœ… Fully Supported
πŸ“ Raspberry Pi 4 ARM64 (aarch64) βœ… Fully Supported
πŸ“ Raspberry Pi 3 ARMv7 βœ… Fully Supported
🍎 macOS Intel x86_64 βœ… Fully Supported
🍎 macOS Apple Silicon ARM64 βœ… Fully Supported
πŸͺŸ Windows 10/11 x86_64 βœ… Fully Supported

After Installation

  1. Configure your calendars:

    sudo vim /etc/calendar-monitor/config.toml
  2. Start the service:

    sudo systemctl start calendar-monitor
    sudo systemctl enable calendar-monitor  # Auto-start on boot
  3. Access the interface: http://localhost:3000

  4. Connect Google Calendar (optional): Click "Connect Google Calendar"

Alternative Installation Methods

βš™οΈ Configuration

Configuration Files (Recommended)

Calendar Monitor uses a flexible configuration system with TOML files:

Configuration locations (in order of priority):

  1. ./calendar-monitor.toml (current directory)
  2. ~/.config/calendar-monitor/config.toml (user config)
  3. /etc/calendar-monitor/config.toml (system config)

Sample configuration:

[server]
host = "0.0.0.0"         # Bind to all interfaces ("127.0.0.1" for localhost only)
port = 3000              # Web server port
cache_ttl_seconds = 300  # Cache duration

[ics]
file_paths = [
    "https://calendar.google.com/calendar/ical/your-id/public/basic.ics",
    "https://outlook.live.com/owa/calendar/your-id/calendar.ics", 
    "/path/to/local/calendar.ics",
]

[google]
# Optional: Google Calendar OAuth integration
client_id = "your-google-client-id"
client_secret = "your-google-client-secret"  
redirect_uri = "http://localhost:3000/auth/google/callback"

Environment Variables (Override config files)

For dynamic configuration or deployment:

# Server configuration  
export CALENDAR_MONITOR_HOST="127.0.0.1"
export CALENDAR_MONITOR_PORT="8080"
export CALENDAR_MONITOR_CACHE_TTL="600"

# Calendar sources (comma-separated)
export ICS_FILE_PATHS="https://cal1.ics,https://cal2.ics,/local/cal.ics"

# Google OAuth (optional)
export GOOGLE_CLIENT_ID="your-client-id"
export GOOGLE_CLIENT_SECRET="your-client-secret"
export GOOGLE_REDIRECT_URI="http://localhost:3000/auth/google/callback"

Supported Calendar Sources

πŸ”— Google Calendar (Recommended)

Easiest setup - just click "Connect Google Calendar" button:

  1. No complex configuration needed
  2. Works around company restrictions
  3. Automatic authentication flow
  4. Direct API access

See Google OAuth Setup Guide for details.

πŸ“ Local ICS Files

ICS_FILE_PATHS=./calendars/work.ics,./calendars/personal.ics

🌐 Live Calendar URLs

ICS_FILE_PATHS=https://calendar.google.com/calendar/ical/your-calendar-id/basic.ics

πŸ”— Mixed Sources

Combine Google Calendar OAuth with ICS feeds:

ICS_FILE_PATHS=./local-calendar.ics,https://remote-calendar.com/feed.ics
# Plus Google OAuth for additional events

Calendar Setup Examples

πŸ“… Google Calendar
  1. Open Google Calendar
  2. Go to Settings β†’ Your calendar β†’ Integrate calendar
  3. Copy the "Secret address in iCal format"
  4. Configure your calendar source in calendar-monitor.toml or set environment variable:
    export ICS_FILE_PATHS=https://calendar.google.com/calendar/ical/your-id/private-key/basic.ics
πŸ“… Outlook Calendar
  1. Open Outlook.com
  2. Go to Settings β†’ View all Outlook settings β†’ Calendar β†’ Shared calendars
  3. Publish your calendar and copy the ICS link
  4. Configure your calendar source in calendar-monitor.toml or set environment variable:
    export ICS_FILE_PATHS=https://outlook.live.com/owa/calendar/your-calendar-id/calendar.ics
πŸ“… Apple iCloud Calendar
  1. Open iCloud Calendar
  2. Click the share icon next to your calendar
  3. Enable "Public Calendar" and copy the link
  4. Change webcal:// to https:// in the URL
  5. Configure your calendar source in calendar-monitor.toml or set environment variable:
    ICS_FILE_PATHS=https://p01-calendarws.icloud.com/published/2/your-calendar-id

Time Block Events

Time blocks are special events with titles enclosed in brackets:

[Draft.dev]        ← Detected as time block
[Red Hat Work]     ← Detected as time block
Regular Meeting    ← Regular event

Time blocks appear in the top section and don't interfere with regular meeting scheduling.

πŸ—οΈ Project Structure

calendar-monitor/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ main.rs           # Web server, routes, WebSocket handling
β”‚   β”œβ”€β”€ calendar.rs       # ICS parsing, calendar service, caching
β”‚   └── meeting.rs        # Meeting data structure and methods
β”œβ”€β”€ static/
β”‚   β”œβ”€β”€ app.js           # Frontend JavaScript, WebSocket client
β”‚   └── style.css        # CSS styling and responsive design
β”œβ”€β”€ templates/
β”‚   └── index.html       # HTML template
β”œβ”€β”€ Cargo.toml           # Dependencies and project metadata
β”œβ”€β”€ calendar-monitor.toml # Configuration file (optional)
└── README.md

πŸ› οΈ Technologies Used

Backend (Rust)

Frontend

  • HTML5 - Semantic markup
  • CSS3 - Grid layout, animations, responsive design
  • JavaScript (ES6+) - WebSocket client, DOM manipulation
  • WebSocket - Real-time communication

πŸ”§ Development

Running in Development Mode

# Enable debug logging
RUST_LOG=debug cargo run

# Run with auto-reload (requires cargo-watch)
cargo install cargo-watch
cargo watch -x run

Building for Production

# Optimized release build
cargo build --release

# Run production binary
./target/release/calendar-monitor

Testing

# Run unit tests
cargo test

# Run with coverage (requires cargo-tarpaulin)
cargo tarpaulin --out html

πŸ“Š API Endpoints

Endpoint Method Description
/ GET Serve main HTML page
/ws GET WebSocket upgrade for real-time updates
/api/meetings GET JSON API for current meeting data
/auth/google/login GET Google OAuth login redirect
/auth/google/callback GET Google OAuth callback handler
/static/* GET Static assets (CSS, JS)

WebSocket Message Format

{
  "current_meeting": {
    "title": "Team Standup",
    "start_time": "2024-01-15T10:00:00Z",
    "end_time": "2024-01-15T10:30:00Z",
    "description": null,
    "location": "Conference Room A"
  },
  "next_meeting": {
    "title": "Project Review",
    "start_time": "2024-01-15T14:00:00Z",
    "end_time": "2024-01-15T15:00:00Z"
  },
  "countdown_seconds": 1823,
  "active_time_blocks": [
    {
      "title": "[Draft.dev]",
      "start_time": "2024-01-15T19:00:00Z",
      "end_time": "2024-01-15T22:00:00Z"
    }
  ]
}

πŸ› Troubleshooting

Common Issues

No events showing
  1. Check your configuration file or environment variables
  2. Verify ICS file/URL accessibility
  3. Check logs: RUST_LOG=debug cargo run
  4. Ensure events are for today/tomorrow
WebSocket connection failed
  1. Check if port 3000 is available
  2. Verify firewall settings
  3. Try a different browser or incognito mode
  4. Check browser console for errors
Recurring events not working
  1. Verify RRULE format in ICS file
  2. Check timezone settings
  3. Currently only supports FREQ=WEEKLY rules
  4. Enable debug logging to see parsing details
Time zones incorrect
  1. Check ICS file timezone specification
  2. Currently hardcoded for Europe/Istanbul
  3. Modify parse_ical_datetime for your timezone
  4. See technical documentation for details

Development & Production

The application is optimized for production with clean logging:

# Production mode (default)
cargo run

# Development with debug logging
RUST_LOG=debug cargo run

# Run comprehensive test suite
cargo test

Production Benefits:

  • Clean, minimal logging output
  • Optimized performance without debug overhead
  • 15 comprehensive unit tests ensure reliability
  • All debugging functionality covered by tests

πŸ“š Documentation

🀝 Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch
    git checkout -b feature/amazing-feature
  3. Make your changes
  4. Add tests if applicable
  5. Run the test suite
    cargo test
    cargo clippy
    cargo fmt
  6. Commit your changes
    git commit -m 'Add amazing feature'
  7. Push to the branch
    git push origin feature/amazing-feature
  8. Open a Pull Request

Development Guidelines

  • Follow Rust naming conventions
  • Add documentation for public functions
  • Include tests for new functionality
  • Use cargo fmt for consistent formatting
  • Run cargo clippy to catch common issues

πŸ“ License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details.

πŸ™ Acknowledgments


Built with ❀️ and πŸ¦€ Rust

Report Bug β€’ Request Feature β€’ Documentation