Skip to content

cleytonb/myCal

Repository files navigation

myCal - Command-Line Calendar for macOS

A fast, native command-line interface for managing your macOS Calendar events. Built with EventKit integration, myCal lets you create, read, update, and delete calendar events directly from your terminal - with instant synchronization to Calendar.app.

Features

  • Native macOS Integration: Uses Apple's EventKit framework for seamless Calendar.app integration
  • Instant Sync: Events appear in Calendar.app immediately - no manual sync required
  • Flexible Date Parsing: Support for absolute dates (2025-12-25), relative dates (tomorrow, next monday), and date math (+3, -2)
  • Multiple Calendars: Work with all your calendars (iCloud, Exchange, local)
  • Simple Commands: Intuitive CLI with create, list, edit, delete operations
  • No AppleScript: Direct EventKit access for reliability and speed

Requirements

  • macOS 10.14 (Mojave) or later
  • Python 3.8 or later
  • Calendar.app access permissions

Installation

Option 1: Direct Installation (Recommended)

# Clone or download the repository
cd /Users/cleytontioyama/Code/myCal

# Install dependencies
pip3 install -r requirements.txt

# Make the script executable
chmod +x myCal

# Add to your PATH (optional - choose one method)
# Method 1: Symlink to /usr/local/bin
sudo ln -s /Users/cleytontioyama/Code/myCal/myCal /usr/local/bin/myCal

# Method 2: Add to PATH in your shell profile (~/.zshrc or ~/.bash_profile)
echo 'export PATH="/Users/cleytontioyama/Code/myCal:$PATH"' >> ~/.zshrc
source ~/.zshrc

Option 2: Install as Python Package

cd /Users/cleytontioyama/Code/myCal
pip3 install -e .

Option 3: Using pip directly

pip3 install pyobjc-core pyobjc-framework-EventKit pyobjc-framework-Cocoa

Then run with: python3 /Users/cleytontioyama/Code/myCal/myCal

First Run - Grant Calendar Access

On first run, macOS will prompt you to grant Calendar access:

  1. Run any myCal command
  2. Click "OK" when prompted to grant Calendar access
  3. If you accidentally denied access, go to System Settings > Privacy & Security > Calendar and enable access for Terminal

Usage

Create Events

# Create a basic event
myCal create "Team Meeting" --date 2025-12-25 --time 14:00

# With duration (in minutes)
myCal create "Lunch Break" --date tomorrow --time 12:30 --duration 90

# With description and location
myCal create "Client Meeting" --date "next monday" --time 10:00 \
  --duration 120 --location "Conference Room A" \
  --description "Quarterly review with stakeholders"

# Specify a calendar
myCal create "Dentist Appointment" --date tomorrow --time 15:00 \
  --calendar "Personal"

List Events

# List today's events
myCal list --date today

# List all events for a specific date
myCal list --date 2025-12-25

# List events in a date range
myCal list --date today --end +7

# List events from a specific calendar
myCal list --calendar "Work" --date today

# Verbose output with all details
myCal list --date today --verbose

Show Event Details

# Show full details for a specific event
myCal show <event-id>

Edit Events

# Change event title
myCal edit <event-id> --title "Updated Title"

# Change date and time
myCal edit <event-id> --date tomorrow --time 16:00

# Change duration
myCal edit <event-id> --duration 120

# Update multiple fields
myCal edit <event-id> --title "New Title" --date "next friday" \
  --time 14:00 --location "New Location"

Delete Events

# Delete with confirmation prompt
myCal delete <event-id>

# Delete without confirmation
myCal delete <event-id> --confirm

List Calendars

# Show all available calendars
myCal calendars

Date Formats

myCal supports flexible date input:

Absolute Dates

  • 2025-12-25 - ISO format (YYYY-MM-DD)
  • 12/25/2025 - US format (MM/DD/YYYY)
  • 2025/12/25 - Alternative format

Relative Dates

  • today - Today's date
  • tomorrow - Tomorrow's date
  • yesterday - Yesterday's date

Weekday References

  • monday, tuesday, etc. - Next occurrence of that weekday
  • next monday - Explicitly next week's Monday
  • this friday - This week's Friday

Date Math

  • +3 - 3 days from today
  • -2 - 2 days ago

Time Formats

  • 14:00 - 24-hour format
  • 2:00 PM - 12-hour format with AM/PM
  • 1400 - Compact 24-hour format
  • 2 PM - Short 12-hour format

Examples

Quick Daily Workflow

# Check today's schedule
myCal list --date today

# Add a quick meeting
myCal create "Quick Sync" --date today --time 15:00 --duration 30

# Check what's coming up this week
myCal list --date today --end +7

Working with Multiple Calendars

# List all calendars
myCal calendars

# Create work event
myCal create "Sprint Planning" --date "next monday" --time 9:00 \
  --calendar "Work" --duration 120

# Create personal event
myCal create "Gym" --date tomorrow --time 18:00 \
  --calendar "Personal" --duration 60

# View only work calendar
myCal list --calendar "Work" --date today --end +7

Event Management

# Create an event
myCal create "Doctor Appointment" --date "next tuesday" --time 10:00 \
  --location "Main Street Clinic" --duration 45

# List to find the event ID
myCal list --date "next tuesday"

# Edit the event (use the ID from list command)
myCal edit <event-id> --time 10:30 --duration 60

# Show full details
myCal show <event-id>

# Delete when no longer needed
myCal delete <event-id>

How It Works

myCal uses Apple's EventKit framework through PyObjC (Python-Objective-C bridge) to:

  1. Direct Database Access: Reads and writes directly to Calendar.app's database
  2. Immediate Sync: Changes appear instantly in Calendar.app (no polling or delays)
  3. Full Integration: Works with iCloud, Exchange, and local calendars
  4. Native Permissions: Uses macOS's standard calendar permission system

The architecture is simple:

  • eventkit_bridge.py - EventKit integration layer
  • date_parser.py - Flexible date/time parsing
  • cli.py - Command-line interface
  • myCal - Executable entry point

Troubleshooting

Permission Denied

Problem: "Calendar access denied" error

Solution:

  1. Go to System Settings > Privacy & Security > Calendar
  2. Find your terminal app (Terminal.app, iTerm, etc.)
  3. Enable the checkbox
  4. Restart your terminal and try again

Event Not Found

Problem: "Event with ID 'xxx' not found"

Solution: Event IDs can change if events are modified in Calendar.app. Use myCal list to get the current ID.

PyObjC Import Errors

Problem: ImportError: No module named 'EventKit'

Solution:

pip3 install --upgrade pyobjc-core pyobjc-framework-EventKit pyobjc-framework-Cocoa

Calendar Not Found

Problem: "Calendar 'Work' not found"

Solution: Run myCal calendars to see exact calendar names (case-sensitive).

Advanced Usage

Scripting with myCal

#!/bin/bash
# Create daily standup meeting for next week

for day in monday tuesday wednesday thursday friday; do
  myCal create "Daily Standup" --date "next $day" --time 9:00 \
    --duration 15 --calendar "Work"
done

Integration with Other Tools

# Use with jq for parsing (if you add JSON output in the future)
# Create event and capture ID
EVENT_ID=$(myCal create "Meeting" --date tomorrow --time 14:00 2>&1 | grep "Event ID:" | awk '{print $3}')

# Pipe dates from other commands
date -v+1d "+%Y-%m-%d" | xargs -I {} myCal list --date {}

Development

Project Structure

myCal/
├── src/
│   ├── __init__.py
│   ├── __main__.py
│   ├── cli.py              # Command-line interface
│   ├── eventkit_bridge.py  # EventKit integration
│   └── date_parser.py      # Date/time parsing
├── myCal                   # Executable entry point
├── setup.py               # Python package setup
├── requirements.txt       # Dependencies
└── README.md             # This file

Running Tests

# Test event creation
myCal create "Test Event" --date tomorrow --time 14:00

# Verify in Calendar.app
open -a Calendar

# Clean up
myCal list --date tomorrow
myCal delete <event-id> --confirm

Limitations

  • macOS Only: Uses EventKit which is macOS-specific
  • No Recurring Events: Current version doesn't support recurrence rules (planned for future)
  • Event ID Stability: EventKit event IDs can change if events are modified externally
  • No Reminders: Currently only supports calendar events, not reminders

Future Enhancements

  • Recurring event support
  • Reminders integration
  • JSON output mode for scripting
  • Interactive mode for event selection
  • Event templates
  • Natural language parsing ("meeting tomorrow at 2pm")
  • Calendar subscriptions
  • Bulk operations

License

MIT License - See LICENSE file for details

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Test thoroughly on macOS
  5. Submit a pull request

Support

For issues, questions, or suggestions:

  • Open an issue on GitHub
  • Check existing issues for solutions
  • Read the troubleshooting section above

Acknowledgments

  • Built with PyObjC for Objective-C bridge
  • Uses Apple's EventKit framework for calendar integration
  • Inspired by the need for a fast, scriptable calendar interface

About

Command-Line Calendar for macOS

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors