# 📅 Turmli Bar Calendar Tool A modern, mobile-friendly web application that fetches and displays calendar events from an ICS (iCalendar) feed. Built with Python, FastAPI, and a responsive web interface. ## ✨ Features - **Automatic Daily Updates**: Fetches calendar data automatically every day and every 4 hours - **Mobile-Responsive Design**: Warm, inviting interface optimized for all devices - **Bar-Themed Colors**: Cozy atmosphere with rich browns and warm earth tones - **Custom Branding**: Integrated Turmli Bar logo - **Event Grouping**: Events organized by date for easy viewing - **Caching**: Local caching ensures calendar is available even if the source is temporarily unavailable - **API Endpoints**: JSON API for programmatic access to calendar data - **Real-time Updates**: - Manual refresh button triggers actual ICS file fetch - Auto-refresh with countdown timer (5 minutes) - Status messages showing fetch progress and results - **Container Support**: Docker and Podman compatible for easy deployment ## 🚀 Quick Start ### Option 1: Container Deployment (Docker/Podman) #### Using Docker ```bash # Clone the repository git clone cd turmli-bar-calendar-tool # Deploy with Docker ./deploy.sh start # Or deploy with Podman (rootless containers) ./deploy-podman.sh start ``` The application will be available at `http://localhost:8000` ### Option 2: Local Development ### Prerequisites - Python 3.13 or higher - [uv](https://github.com/astral-sh/uv) package manager (for local development only) ### Installation 1. Clone the repository: ```bash git clone cd turmli-bar-calendar-tool ``` 2. Install dependencies using uv: ```bash uv sync ``` 3. Run the server: ```bash ./run.sh ``` Or directly with uv: ```bash uv run uvicorn main:app --host 0.0.0.0 --port 8000 --reload ``` 4. Open your browser and navigate to: ``` http://localhost:8000 ``` ## 📱 Features & Interface ### Web Interface - **Responsive Design**: Optimized for mobile phones, tablets, and desktops - **Visual Calendar**: Warm, inviting display with time, location, and all-day indicators - **Bar Atmosphere**: Rich brown and tan colors that evoke a cozy bar environment - **Branded Experience**: Features the Turmli Bar logo with subtle sepia toning - **Smart Refresh**: - Manual refresh button that fetches new data from the ICS source - Auto-refresh countdown timer (5 minutes) - Visual feedback showing fetch progress and results - Displays whether data has changed since last update ### Event Display - Events grouped by date - Shows next 30 days of events - Clear time indicators for scheduled events - "All Day" badges for full-day events - Location information with map pin icons - Smooth animations and hover effects ## 🔧 Configuration ### Timezone By default, the application uses `Europe/Berlin` timezone. To change it, modify the timezone in `main.py`: ```python tz = pytz.timezone('Europe/Berlin') # Change to your timezone ``` ### Calendar URL The calendar ICS URL is configured in `main.py`. To use a different calendar: ```python CALENDAR_URL = "your-calendar-ics-url-here" ``` ### Update Schedule The calendar updates: - Daily at 2:00 AM - Every 4 hours throughout the day You can modify the schedule in the `startup_event` function in `main.py`. ## 🌐 API Endpoints ### `GET /` Returns the HTML interface with calendar events ### `GET /api/events` Returns calendar events in JSON format: ```json { "events": [ { "title": "Meeting", "location": "Conference Room", "start": "2024-01-15T10:00:00", "end": "2024-01-15T11:00:00", "all_day": false } ], "last_updated": "2024-01-15T08:00:00" } ``` ### `POST /api/refresh` Manually triggers a calendar refresh from the ICS source: ```json { "status": "success", "message": "Calendar refreshed successfully", "events_count": 15, "previous_count": 14, "data_changed": true, "last_updated": "2024-01-15T08:00:00" } ``` The refresh button in the UI: - Shows a loading spinner while fetching - Displays success/error status - Shows if data has changed - Automatically reloads the page after successful fetch - Resets the auto-refresh countdown timer ## 🎨 Customization ### Logo The application displays the Turmli Bar logo (`Vektor-Logo.svg`) in the header. To use a different logo: 1. Place your logo file in the project root or `static/` directory 2. Update the logo path in `main.py` if needed ### Styling The interface uses warm, bar-appropriate colors with rich browns (#2c1810, #8b4513), warm tans (#f4e4d4, #d4a574), and cream accents. The design creates a cozy, inviting atmosphere while maintaining excellent readability. Colors are easy on the eyes with subtle gradients and soft shadows. You can customize the appearance by modifying the CSS in the `HTML_TEMPLATE` variable in `main.py`. ### Event Display Period By default, shows events for the next 30 days. Change this in the `fetch_calendar` function: ```python cutoff = now + timedelta(days=30) # Modify the number of days ``` ## 🚢 Deployment ### 🐳 Container Deployment (Docker/Podman) #### Quick Start ```bash # Deploy the application ./deploy.sh start # Start on default port 8000 PORT=8080 ./deploy.sh start # Start on custom port # Manage the application ./deploy.sh status # Check container status ./deploy.sh logs # View application logs ./deploy.sh stop # Stop container ./deploy.sh restart # Restart container ./deploy.sh update # Pull updates and restart ``` #### Container Files Included - **Dockerfile/Containerfile**: Python 3.13 container (uses pip for simplicity) - **docker-compose.yml**: Docker Compose configuration - **podman-compose.yml**: Podman Compose configuration - **deploy.sh**: Docker deployment script - **deploy-podman.sh**: Podman deployment script (supports rootless) **Note**: The container uses `pip` for dependency installation to keep things simple. Local development still uses `uv` for better package management. ##### Podman Support Podman is a daemonless, rootless container engine that's a drop-in replacement for Docker: ```bash # Using Podman deployment script ./deploy-podman.sh start # Generate systemd service (Podman only) ./deploy-podman.sh systemd ``` See [PODMAN_README.md](PODMAN_README.md) for detailed Podman instructions. #### Container Features - **Simple Build**: Straightforward Python container - **Health Checks**: Built-in monitoring endpoint - **Volume Persistence**: Calendar cache persists between restarts - **Auto-restart**: Container restarts automatically on failure #### Environment Variables Set the port if needed (default is 8000): ```bash PORT=8080 ./deploy.sh start ``` Or use compose directly: ```bash # Docker Compose PORT=8080 docker-compose up -d # Podman Compose PORT=8080 podman-compose -f podman-compose.yml up -d ``` #### Simple Container Commands ```bash # Using the deployment script (recommended) ./deploy.sh start # Build and start ./deploy.sh stop # Stop container ./deploy.sh logs # View logs ./deploy.sh status # Check health (Docker) ./deploy-podman.sh status # Check health (Podman) # Or use container commands directly # Docker: docker build -t turmli-calendar . docker run -d -p 8000:8000 -v $(pwd)/calendar_cache.json:/app/calendar_cache.json turmli-calendar # Podman (rootless): podman build -t turmli-calendar . podman run -d -p 8000:8000 -v $(pwd)/calendar_cache.json:/app/calendar_cache.json:Z turmli-calendar ``` ### Traditional Deployment For non-container deployments, use systemd: ```ini [Unit] Description=Turmli Bar Calendar Tool After=network.target [Service] Type=simple User=youruser WorkingDirectory=/path/to/turmli-bar-calendar-tool ExecStart=/usr/bin/uv run uvicorn main:app --host 0.0.0.0 --port 8000 Restart=on-failure [Install] WantedBy=multi-user.target ``` ### Notes for Internal Use - The application runs on a single port (default 8000) - No SSL/HTTPS needed for internal network - Simple Python server is sufficient for ~30 users - Calendar cache persists in `calendar_cache.json` - Automatic refresh every 5 minutes ## 📝 License MIT License - feel free to use and modify as needed. ## 🤝 Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## 🐛 Troubleshooting ### Calendar not updating - Check the console logs for any error messages - Verify the ICS URL is accessible - Check the `calendar_cache.json` file for cached data ### Events not showing - Ensure the calendar has events in the next 30 days - Check timezone settings match your location - Verify the ICS file format is valid ### Port already in use - Change the port in `run.sh` or when running uvicorn directly - Check for other processes using port 8000: `lsof -i :8000`