# studio einszwovier Web Application **FastAPI-based PDF print cost calculator** with automated ink coverage analysis, Matrix integration, and multi-service hub for studio einszwovier Maker Space. [![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?logo=docker)](https://www.docker.com/) [![FastAPI](https://img.shields.io/badge/FastAPI-0.104+-009688?logo=fastapi)](https://fastapi.tiangolo.com/) [![Matrix](https://img.shields.io/badge/Matrix-Integrated-000000?logo=matrix)](https://matrix.org/) --- ## ๐ŸŽฏ Features ### Core Application - **๐Ÿ“„ PDF Cost Calculator**: Automated ink coverage analysis with color/B&W detection - **๐Ÿ–ผ๏ธ Course Management**: Dynamic course list with image gallery and modal viewer - **๐Ÿ“Š Cost Estimation**: Per-page breakdown with configurable rates (โ‚ฌ/mยฒ) - **๐Ÿ’ฌ Matrix Integration**: Automatic order submission to Matrix room ### Integrated Services - **๐Ÿ“š BookStack Wiki**: Documentation and knowledge base (port 6875) - **๐Ÿค– Ollama + Open WebUI**: Local LLM chatbot interface (port 8080) - **๐Ÿ“จ Matrix Synapse**: Print order collection and payment tracking (port 8008) - **๏ฟฝ Element Web**: Browser-based Matrix chat client (port 8082) - **๏ฟฝ๐Ÿณ Portainer**: Container management dashboard (port 9000) - **๐Ÿ““ JupyterHub**: Multi-user Jupyter notebook server for drone programming (port 8001) - **๐ŸฆŠ Forgejo**: Self-hosted Git service for code collaboration (port 3003) - **๐Ÿ”„ Watchtower**: Automatic container updates every 24 hours - **๐Ÿ—‚๏ธ Autokanban**: Kollektive Toโ€‘Doโ€‘Liste / Aufgabenboard (port 8000) --- ## ๐Ÿ—๏ธ Architecture ![Architecture Diagram](images/architecture.png)
View Mermaid source code ```mermaid graph TB subgraph "studio einszwovier Web Platform" LP[๐Ÿ  Landing Page
Port 80] About[โ„น๏ธ About Page
/about] CostCalc[๐Ÿ’ฐ Cost Calculator
/cost] LP --> About LP --> CostCalc end subgraph "Services Accessible from Landing Page" BookStack[๏ฟฝ BookStack
Port 6875
Wissenssammlung] OpenWebUI[๐Ÿค– Open WebUI
Port 8080
LLM Chatbot] JupyterHub[๏ฟฝ JupyterHub
Port 8001
Python Notebooks] Forgejo[๐ŸฆŠ Forgejo
Port 3003
Git Server] ElementWeb[๏ฟฝ Element Web
Port 8082
Matrix Chat] Portainer[๏ฟฝ Portainer
Port 9000
Admin Panel] LP -.->|Link| BookStack LP -.->|Link| OpenWebUI LP -.->|Link| JupyterHub LP -.->|Link| Forgejo LP -.->|Link| ElementWeb LP -.->|Link| Portainer end subgraph "Backend Services" Synapse[๏ฟฝ Synapse
Port 8008
Matrix Server] Ollama[๐Ÿ”ฎ Ollama
Port 11434
LLM Engine] MariaDB[(๏ฟฝ MariaDB
BookStack DB)] ElementWeb --> Synapse OpenWebUI --> Ollama BookStack --> MariaDB CostCalc --> Synapse end subgraph "Educational Resources" Notebooks[๐Ÿ“’ Drone Programming
djitellopy Package] GitRepos[๐Ÿ“ฆ Code Repositories
Project Source] Knowledge[๏ฟฝ Documentation
Guides & Tutorials] JupyterHub --> Notebooks Forgejo --> GitRepos BookStack --> Knowledge end subgraph "Persistent Storage" PDFUploads[๐Ÿ“ PDF Files
data/uploads/] CoursesCSV[๐Ÿ“‹ Courses CSV
data/courses.csv] MatrixData[(๐Ÿ—„๏ธ Matrix Data
matrix/data/)] JupyterVols[(๐Ÿ’พ Jupyter Volumes
User Workspaces)] ForgejoData[(๐Ÿ“š Forgejo Data
forgejo/data/)] CostCalc --> PDFUploads About --> CoursesCSV Synapse --> MatrixData JupyterHub --> JupyterVols Forgejo --> ForgejoData end subgraph "Infrastructure" Watchtower[๐Ÿ”„ Watchtower
Auto-Updates
Every 24h] Network[๐ŸŒ einszwovier_network
Docker Network] end classDef webapp fill:#e3f2fd,stroke:#1976d2,stroke-width:2px classDef service fill:#fff3e0,stroke:#f57c00,stroke-width:2px classDef backend fill:#e8f5e9,stroke:#388e3c,stroke-width:2px classDef storage fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px classDef edu fill:#fce4ec,stroke:#c2185b,stroke-width:2px classDef infra fill:#fafafa,stroke:#616161,stroke-width:2px class LP,About,CostCalc webapp class BookStack,OpenWebUI,JupyterHub,Forgejo,ElementWeb,Portainer service class Synapse,Ollama,MariaDB backend class PDFUploads,CoursesCSV,MatrixData,JupyterVols,ForgejoData storage class Notebooks,GitRepos,Knowledge edu class Watchtower,Network infra ```
--- ## ๐Ÿš€ Quick Start ### Prerequisites **On the host system:** - **Docker** & **Docker Compose** installed - **curl** - for testing and healthchecks (install: `brew install curl` on macOS) - **Poppler** (for pdf2image - included in Docker) - **Port availability**: 80, 3003, 6875, 8001, 8008, 8080, 8082, 9000, 11434 - **Port availability**: 80, 3003, 6875, 8000, 8001, 8008, 8080, 8082, 9000, 11434 **Note:** Python dependencies are containerized and don't need to be installed on the host. ### Installation 1. **Clone the repository:** ```bash git clone https://github.com/arontaupe/124-webapp.git cd 124-webapp ``` 2. **Configure environment:** ```bash cp .env.example .env nano .env # Update SERVER_HOSTNAME and passwords ``` 3. **Start the stack:** ```bash docker compose up -d --build ``` 4. **Access services:** - Web App: (or ) - BookStack: - Open WebUI: - Portainer: - Matrix: - Element Web: - Autokanban: - JupyterHub: - Forgejo: ### First-Time Setup 1. **Get Matrix Room ID:** ```bash python get_room_id.py ``` 2. **Update .env with room ID:** ```bash MATRIX_ROOM="!YourRoomID:${SERVER_HOSTNAME}" ``` 3. **Restart web container:** ```bash docker compose restart web ``` --- ## ๐Ÿ“š Course Management Courses are managed via CSV file with optional images: ### Add a Course 1. **Edit `data/courses.csv`:** ```csv title,description,dates,offen_fuer,image My Course,Learn cool stuff,"Oct '25",Grade 10,/static/images/courses/my-course.jpg ``` 2. **Add course image (optional):** ```bash cp my-image.jpg static/images/courses/my-course.jpg ``` 3. **Changes apply immediately** (no restart needed) ### Course Image Features - **Thumbnail view**: 80x80px next to course info - **Hover zoom**: Expands to 200x200px on hover - **Click to enlarge**: Opens full-size modal viewer - **Auto-cropping**: `object-fit: cover` ensures uniform display See [data/KURSE_README.md](data/KURSE_README.md) for detailed documentation. --- ## ๐Ÿ”ง Configuration ### Environment Variables Key variables in `.env`: ```bash # Server Configuration SERVER_HOSTNAME=your-server.com # Print Rates (โ‚ฌ/mยฒ) RATE_PER_M2_BLACK=4.0 RATE_PER_M2_COLOR=5.0 # Matrix Integration MATRIX_USER="@einszwovier:${SERVER_HOSTNAME}" MATRIX_PASS="your_password" MATRIX_HOMESERVER="http://${SERVER_HOSTNAME}:8008" MATRIX_ROOM="!RoomID:${SERVER_HOSTNAME}" # Service Ports SYNAPSE_PORT=8008 OLLAMA_PORT=11434 OPENWEBUI_PORT=8080 BOOKSTACK_PORT=6875 PORTAINER_PORT=9000 JUPYTER_PORT=8001 FORGEJO_PORT=3003 # JupyterHub Authentication JUPYTER_PASSWORD=einszwo4 ``` See [.env.example](.env.example) for full configuration. --- ## ๐Ÿณ Docker Services | Service | Image | Port | Purpose | Resources | |---------|-------|------|---------|-----------| | **web** | Custom (FastAPI) | 80 | Main application | 1 CPU, 1GB RAM | | **synapse** | matrixdotorg/synapse | 8008 | Matrix homeserver | 2 CPU, 2GB RAM | | **ollama** | ollama/ollama | 11434 | LLM inference | 6 CPU, 16GB RAM | | **open-webui** | ghcr.io/open-webui/open-webui | 8080 | LLM chat UI | 2 CPU, 2GB RAM | | **bookstack** | lscr.io/linuxserver/bookstack | 6875 | Documentation wiki | Default | | **bookstack-mariadb** | lscr.io/linuxserver/mariadb | 3306 | Database for BookStack | Default | | **jupyterhub** | Custom (Python 3.13) | 8001 | Multi-user Jupyter notebooks | 2 CPU, 2GB RAM | | **forgejo** | codeberg.org/forgejo/forgejo:11 | 3003, 222 | Git service (web, SSH) | Default | | **portainer** | portainer/portainer-ce | 9000, 9443 | Container management | Default | | **watchtower** | containrrr/watchtower | - | Auto-updates (24h) | Default | ### Health Checks All services have health checks configured: - **web**: `curl http://localhost:8000/` - **synapse**: `curl http://localhost:8008/_matrix/static/` - **ollama**: `curl http://localhost:11434/` - **open-webui**: `curl http://localhost:8080/` - **bookstack**: `curl http://localhost/` - **mariadb**: MariaDB query test - **portainer**: API status check - **watchtower**: Process check --- ## ๐Ÿ“– Documentation - **[SECURITY.md](SECURITY.md)** - Security best practices and secrets management - **[PORTABILITY.md](PORTABILITY.md)** - Server migration guide - **[PRE_RELEASE_CHECKLIST.md](PRE_RELEASE_CHECKLIST.md)** - Pre-publication verification - **[data/KURSE_README.md](data/KURSE_README.md)** - Course management guide --- ## ๐Ÿ” Security **Before deploying to production:** 1. โœ… Change all passwords in `.env` 2. โœ… Generate new `BOOKSTACK_APP_KEY` 3. โœ… Update Matrix credentials 4. โœ… Configure firewall (restrict Portainer access) 5. โœ… Set up HTTPS/SSL 6. โœ… Enable automated backups See [SECURITY.md](SECURITY.md) for comprehensive security guidelines. **Security Disclosure:** If you discover a vulnerability, email `einszwovier@gvb-gymnasium.de` instead of opening a public issue. --- ## ๐Ÿ”„ Backup & Restore ### Backup All Data ```bash ./backup.sh ``` Creates timestamped backups of: - BookStack database & files - Matrix homeserver data - PDF uploads - Course data & images - Environment configuration ### Restore from Backup ```bash ./restore.sh YYYYMMDD_HHMMSS ``` --- ## ๏ฟฝ BookStack API (create pages programmatically) You can automate content creation in BookStack using the HTTP API and a Personal Access Token (User Settings โ†’ API Tokens). Example `curl` to list books: ```bash curl -H "Authorization: Token token=\"$BOOKSTACK_API_TOKEN\"" \ "$BOOKSTACK_APP_URL/api/books" ``` Create a page with `curl`: ```bash curl -X POST -H "Authorization: Token token=\"$BOOKSTACK_API_TOKEN\"" \ -H "Content-Type: application/json" \ -d '{"name":"My Page","book_id":1,"html":"

Hello

"}' \ "$BOOKSTACK_APP_URL/api/pages" ``` There's a small helper script in the repo: `bookstack_api_create_page.py` which demonstrates listing books and creating a page interactively. --- ## ๏ฟฝ๐Ÿšข Deployment & Portability This application is designed to be **fully portable**. To move to a new server: 1. **On old server:** ```bash ./backup.sh ``` 2. **On new server:** ```bash git clone cd 124-webapp cp .env.example .env # Update SERVER_HOSTNAME in .env ./restore.sh YYYYMMDD_HHMMSS docker compose up -d ``` See [PORTABILITY.md](PORTABILITY.md) for detailed migration guide. --- ## ๐Ÿ› ๏ธ Development ### Local Development ```bash # Option 1: Direct Python (with auto-reload) python run_app.py # Option 2: Docker Compose docker compose up --build ``` ### Project Structure ```zsh . โ”œโ”€โ”€ main.py # FastAPI application โ”œโ”€โ”€ cost_calculator.py # PDF analysis logic โ”œโ”€โ”€ mailer.py # Matrix integration โ”œโ”€โ”€ templates/ # Jinja2 templates โ”‚ โ”œโ”€โ”€ base.html โ”‚ โ”œโ”€โ”€ landing.html โ”‚ โ”œโ”€โ”€ about.html โ”‚ โ”œโ”€โ”€ cost-calculator.html โ”‚ โ””โ”€โ”€ result.html โ”œโ”€โ”€ static/ # CSS, images, fonts โ”‚ โ”œโ”€โ”€ css/style.css โ”‚ โ”œโ”€โ”€ images/ โ”‚ โ””โ”€โ”€ fonts/ โ”œโ”€โ”€ data/ โ”‚ โ”œโ”€โ”€ courses.csv # Course database โ”‚ โ””โ”€โ”€ uploads/ # PDF uploads โ”œโ”€โ”€ docker-compose.yml # Service orchestration โ”œโ”€โ”€ Dockerfile # Web app container โ””โ”€โ”€ requirements.txt # Python dependencies ``` ### Key Technologies - **FastAPI** - Modern Python web framework - **PyPDF2** - PDF metadata extraction - **pdf2image** - PDF to image conversion - **Pillow + NumPy** - Image processing & ink analysis - **matrix-nio** - Matrix protocol client - **Jinja2** - Template engine - **Gunicorn + Uvicorn** - Production WSGI/ASGI servers --- ## ๐Ÿค Contributing Contributions are welcome! This is part of **studio einszwovier**, a collaborative Maker Space. 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request --- ## ๐Ÿ“„ License This project is part of studio einszwovier educational initiative. --- ## ๐Ÿ“ž Contact **studio einszwovier** Gabriele-von-Bรผlow-Gymnasium Tile-Brรผgge-Weg 63, 13509 Berlin (Tegel) - **Email**: - **Team**: Aron Petau & Friedrich Weber - **Hours**: Tuesday - Thursday, 11:00 - 16:00 - **Location**: Room 124 --- ## ๐Ÿ™ Acknowledgments - Matrix.org for the communication protocol - Ollama team for local LLM support - BookStack for the documentation platform - FastAPI community - All contributors and students of studio einszwovier --- Made with โค๏ธ at studio einszwovier Maker Space