add element web
This commit is contained in:
parent
98417edd8b
commit
000ec5d25f
9 changed files with 209 additions and 236 deletions
150
README.md
150
README.md
|
|
@ -1,6 +1,6 @@
|
||||||
# Studio EinsZwoVier Web Application
|
# 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.
|
**FastAPI-based PDF print cost calculator** with automated ink coverage analysis, Matrix integration, and multi-service hub for studio einszwovier Maker Space.
|
||||||
|
|
||||||
[](https://www.docker.com/)
|
[](https://www.docker.com/)
|
||||||
[](https://fastapi.tiangolo.com/)
|
[](https://fastapi.tiangolo.com/)
|
||||||
|
|
@ -33,100 +33,84 @@
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TB
|
graph TB
|
||||||
subgraph "Studio EinsZwoVier Web App (Port 80)"
|
subgraph "studio einszwovier Web Platform"
|
||||||
LP[🏠 Landing Page<br/>studio-einszwovier.local]
|
LP[🏠 Landing Page<br/>Port 80]
|
||||||
About[ℹ️ About Page<br/>/about<br/>Courses + Team Info]
|
About[ℹ️ About Page<br/>/about]
|
||||||
Cost[💰 Cost Calculator<br/>/cost<br/>PDF Analysis]
|
CostCalc[💰 Cost Calculator<br/>/cost]
|
||||||
|
|
||||||
LP --> About
|
LP --> About
|
||||||
LP --> Cost
|
LP --> CostCalc
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "Course Management"
|
subgraph "Services Accessible from Landing Page"
|
||||||
CSV[📝 courses.csv<br/>Title, Description, Dates, Image]
|
BookStack[<5B> BookStack<br/>Port 6875<br/>Wissenssammlung]
|
||||||
Images[🖼️ Course Images<br/>static/images/courses/]
|
OpenWebUI[🤖 Open WebUI<br/>Port 8080<br/>LLM Chatbot]
|
||||||
Modal[🔍 Image Modal<br/>Click to Enlarge]
|
JupyterHub[<5B> JupyterHub<br/>Port 8001<br/>Python Notebooks]
|
||||||
|
Forgejo[🦊 Forgejo<br/>Port 3003<br/>Git Server]
|
||||||
About --> CSV
|
ElementWeb[<5B> Element Web<br/>Port 8082<br/>Matrix Chat]
|
||||||
CSV --> Images
|
Portainer[<5B> Portainer<br/>Port 9000<br/>Admin Panel]
|
||||||
Images --> Modal
|
|
||||||
|
LP -.->|Link| BookStack
|
||||||
|
LP -.->|Link| OpenWebUI
|
||||||
|
LP -.->|Link| JupyterHub
|
||||||
|
LP -.->|Link| Forgejo
|
||||||
|
LP -.->|Link| ElementWeb
|
||||||
|
LP -.->|Link| Portainer
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "PDF Processing Pipeline"
|
subgraph "Backend Services"
|
||||||
Upload[📤 Upload PDF]
|
Synapse[<5B> Synapse<br/>Port 8008<br/>Matrix Server]
|
||||||
Analysis[🔬 Analyze<br/>- Dimensions<br/>- Ink Coverage<br/>- Color Detection]
|
Ollama[🔮 Ollama<br/>Port 11434<br/>LLM Engine]
|
||||||
Quote[📋 Quote Generation<br/>Per-page Breakdown]
|
MariaDB[(<28> MariaDB<br/>BookStack DB)]
|
||||||
|
|
||||||
Cost --> Upload
|
ElementWeb --> Synapse
|
||||||
Upload --> Analysis
|
|
||||||
Analysis --> Quote
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Matrix Integration"
|
|
||||||
MatrixRoom[💬 Matrix Room<br/>Print Orders]
|
|
||||||
PDF_Upload[📎 PDF Attachment]
|
|
||||||
Summary[📊 Order Summary<br/>German Language]
|
|
||||||
|
|
||||||
Quote --> MatrixRoom
|
|
||||||
Quote --> PDF_Upload
|
|
||||||
Quote --> Summary
|
|
||||||
end
|
|
||||||
|
|
||||||
subgraph "Integrated Services"
|
|
||||||
BookStack[📚 BookStack Wiki<br/>:6875]
|
|
||||||
Ollama[🤖 Ollama LLM<br/>:11434]
|
|
||||||
OpenWebUI[💭 Open WebUI<br/>:8080]
|
|
||||||
Portainer[🐳 Portainer<br/>:9000]
|
|
||||||
Synapse[📨 Matrix Synapse<br/>:8008]
|
|
||||||
JupyterHub[📓 JupyterHub<br/>:8001<br/>Drone Programming]
|
|
||||||
Forgejo[🦊 Forgejo Git<br/>:3003<br/>Code Collaboration]
|
|
||||||
|
|
||||||
LP -.-> BookStack
|
|
||||||
LP -.-> OpenWebUI
|
|
||||||
LP -.-> Portainer
|
|
||||||
LP -.-> JupyterHub
|
|
||||||
LP -.-> Forgejo
|
|
||||||
OpenWebUI --> Ollama
|
OpenWebUI --> Ollama
|
||||||
MatrixRoom --> Synapse
|
BookStack --> MariaDB
|
||||||
|
CostCalc --> Synapse
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "Educational Stack"
|
subgraph "Educational Resources"
|
||||||
Notebooks[📒 Jupyter Notebooks<br/>Python Drone Code]
|
Notebooks[📒 Drone Programming<br/>djitellopy Package]
|
||||||
GitRepos[📦 Git Repositories<br/>Project Source Code]
|
GitRepos[📦 Code Repositories<br/>Project Source]
|
||||||
DronePackages[🚁 djitellopy<br/>Tello SDK]
|
Knowledge[<5B> Documentation<br/>Guides & Tutorials]
|
||||||
|
|
||||||
JupyterHub --> Notebooks
|
JupyterHub --> Notebooks
|
||||||
Forgejo --> GitRepos
|
Forgejo --> GitRepos
|
||||||
Notebooks -.-> DronePackages
|
BookStack --> Knowledge
|
||||||
end
|
end
|
||||||
|
|
||||||
subgraph "Data Persistence"
|
subgraph "Persistent Storage"
|
||||||
Uploads[📁 data/uploads/<br/>PDF Files]
|
PDFUploads[📁 PDF Files<br/>data/uploads/]
|
||||||
Courses[📋 data/courses.csv<br/>Course List]
|
CoursesCSV[📋 Courses CSV<br/>data/courses.csv]
|
||||||
MatrixDB[(🗄️ Matrix DB<br/>homeserver.db)]
|
MatrixData[(🗄️ Matrix Data<br/>matrix/data/)]
|
||||||
BookDB[(🗄️ BookStack DB<br/>MariaDB)]
|
JupyterVols[(💾 Jupyter Volumes<br/>User Workspaces)]
|
||||||
JupyterVolumes[(💾 Jupyter Volumes<br/>User Workspaces)]
|
ForgejoData[(📚 Forgejo Data<br/>forgejo/data/)]
|
||||||
ForgejoData[(📚 Forgejo Data<br/>Git Repos)]
|
|
||||||
|
CostCalc --> PDFUploads
|
||||||
Upload --> Uploads
|
About --> CoursesCSV
|
||||||
CSV --> Courses
|
Synapse --> MatrixData
|
||||||
Synapse --> MatrixDB
|
JupyterHub --> JupyterVols
|
||||||
BookStack --> BookDB
|
|
||||||
JupyterHub --> JupyterVolumes
|
|
||||||
Forgejo --> ForgejoData
|
Forgejo --> ForgejoData
|
||||||
end
|
end
|
||||||
|
|
||||||
|
subgraph "Infrastructure"
|
||||||
|
Watchtower[🔄 Watchtower<br/>Auto-Updates<br/>Every 24h]
|
||||||
|
Network[🌐 einszwovier_network<br/>Docker Network]
|
||||||
|
end
|
||||||
|
|
||||||
classDef webapp fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
|
classDef webapp fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
|
||||||
classDef service fill:#fff3e0,stroke:#f57c00,stroke-width:2px
|
classDef service fill:#fff3e0,stroke:#f57c00,stroke-width:2px
|
||||||
classDef data fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
|
classDef backend fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
|
||||||
classDef matrix 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 edu fill:#fce4ec,stroke:#c2185b,stroke-width:2px
|
||||||
|
classDef infra fill:#fafafa,stroke:#616161,stroke-width:2px
|
||||||
|
|
||||||
class LP,About,Cost,Upload,Analysis,Quote webapp
|
class LP,About,CostCalc webapp
|
||||||
class BookStack,Ollama,OpenWebUI,Portainer,Synapse,JupyterHub,Forgejo service
|
class BookStack,OpenWebUI,JupyterHub,Forgejo,ElementWeb,Portainer service
|
||||||
class Uploads,Courses,MatrixDB,BookDB,JupyterVolumes,ForgejoData data
|
class Synapse,Ollama,MariaDB backend
|
||||||
class MatrixRoom,PDF_Upload,Summary,CSV,Images,Modal matrix
|
class PDFUploads,CoursesCSV,MatrixData,JupyterVols,ForgejoData storage
|
||||||
class Notebooks,GitRepos,DronePackages edu
|
class Notebooks,GitRepos,Knowledge edu
|
||||||
|
class Watchtower,Network infra
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -380,7 +364,7 @@ docker compose up --build
|
||||||
|
|
||||||
### Project Structure
|
### Project Structure
|
||||||
|
|
||||||
```
|
```zsh
|
||||||
.
|
.
|
||||||
├── main.py # FastAPI application
|
├── main.py # FastAPI application
|
||||||
├── cost_calculator.py # PDF analysis logic
|
├── cost_calculator.py # PDF analysis logic
|
||||||
|
|
@ -417,7 +401,7 @@ docker compose up --build
|
||||||
|
|
||||||
## 🤝 Contributing
|
## 🤝 Contributing
|
||||||
|
|
||||||
Contributions are welcome! This is part of **Studio EinsZwoVier**, a collaborative Maker Space.
|
Contributions are welcome! This is part of **studio einszwovier**, a collaborative Maker Space.
|
||||||
|
|
||||||
1. Fork the repository
|
1. Fork the repository
|
||||||
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||||||
|
|
@ -429,13 +413,13 @@ Contributions are welcome! This is part of **Studio EinsZwoVier**, a collaborati
|
||||||
|
|
||||||
## 📄 License
|
## 📄 License
|
||||||
|
|
||||||
This project is part of Studio EinsZwoVier educational initiative.
|
This project is part of studio einszwovier educational initiative.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 📞 Contact
|
## 📞 Contact
|
||||||
|
|
||||||
**Studio EinsZwoVier**
|
**studio einszwovier**
|
||||||
Gabriele-von-Bülow-Gymnasium
|
Gabriele-von-Bülow-Gymnasium
|
||||||
Tile-Brügge-Weg 63, 13509 Berlin (Tegel)
|
Tile-Brügge-Weg 63, 13509 Berlin (Tegel)
|
||||||
|
|
||||||
|
|
@ -452,8 +436,8 @@ Tile-Brügge-Weg 63, 13509 Berlin (Tegel)
|
||||||
- Ollama team for local LLM support
|
- Ollama team for local LLM support
|
||||||
- BookStack for the documentation platform
|
- BookStack for the documentation platform
|
||||||
- FastAPI community
|
- FastAPI community
|
||||||
- All contributors and students of Studio EinsZwoVier
|
- All contributors and students of studio einszwovier
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Made with ❤️ at Studio EinsZwoVier Maker Space**
|
Made with ❤️ at studio einszwovier Maker Space
|
||||||
|
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
# Kurse verwalten
|
|
||||||
|
|
||||||
## Kurse bearbeiten
|
|
||||||
|
|
||||||
Die aktuellen Kurse werden aus der Datei `courses.csv` geladen und automatisch auf der "Über uns" Seite angezeigt.
|
|
||||||
|
|
||||||
### CSV-Format
|
|
||||||
|
|
||||||
Die Datei hat fünf Spalten (alle außer `title` sind optional):
|
|
||||||
- `title` - Der Titel des Kurses (erforderlich)
|
|
||||||
- `description` - Eine kurze Beschreibung (optional)
|
|
||||||
- `dates` - Termine und Zeiten (optional)
|
|
||||||
- `offen_fuer` - Zielgruppe/Altersgruppe (optional)
|
|
||||||
- `image` - Pfad zum Kursbild (optional)
|
|
||||||
|
|
||||||
**Beispiel:**
|
|
||||||
```csv
|
|
||||||
title,description,dates,offen_fuer,image
|
|
||||||
Löten und Leuchten,Herstellung von Nachttischleuchten mit 3D-Design und Löttechnik,"Di 15.10. 14:00-16:00",Klasse 7-9,/static/images/courses/loeten.jpg
|
|
||||||
Die Vogelvilla,Bau von Vogelhäusern mit Lasercutter und Holzbearbeitung,"Mi 23.10. 13:00-15:00",alle Schüler:innen,
|
|
||||||
Robotik Intro,,,ab Klasse 5,/static/images/courses/robotik.jpg
|
|
||||||
```
|
|
||||||
|
|
||||||
### Kursbilder hinzufügen
|
|
||||||
|
|
||||||
1. Speichere das Bild in `/static/images/courses/`
|
|
||||||
2. Verwende den Pfad `/static/images/courses/dein-bild.jpg` in der CSV
|
|
||||||
3. Empfohlene Bildgröße: mindestens 640x400 Pixel
|
|
||||||
4. Unterstützte Formate: JPG, PNG, WebP
|
|
||||||
|
|
||||||
**Tipp:** Wenn kein Bild angegeben ist, wird der Kurs ohne Bild angezeigt (nur Text).### Felder im Detail
|
|
||||||
|
|
||||||
#### `title` (erforderlich)
|
|
||||||
Der Kursname - wird immer angezeigt.
|
|
||||||
|
|
||||||
#### `description` (optional)
|
|
||||||
Kurzbeschreibung des Kurses. Wird nur angezeigt, wenn vorhanden.
|
|
||||||
|
|
||||||
#### `dates` (optional)
|
|
||||||
Termine und Uhrzeiten. Kann mehrere Termine enthalten:
|
|
||||||
- Einzelner Termin: `Mi 23.10. 13:00-15:00`
|
|
||||||
- Mehrere Termine: `Di 15.10. 14:00-16:00, Do 17.10. 14:00-16:00`
|
|
||||||
- Bei Terminen mit Kommas: In Anführungszeichen setzen
|
|
||||||
|
|
||||||
#### `offen_fuer` (optional)
|
|
||||||
Freitextfeld für die Zielgruppe:
|
|
||||||
- `Klasse 7-9`
|
|
||||||
- `alle Schüler:innen`
|
|
||||||
- `ab 14 Jahren`
|
|
||||||
- `Oberstufe`
|
|
||||||
|
|
||||||
### Kurs hinzufügen
|
|
||||||
|
|
||||||
Einfach eine neue Zeile am Ende der Datei hinzufügen:
|
|
||||||
```csv
|
|
||||||
title,description,dates,offen_fuer
|
|
||||||
Löten und Leuchten,Herstellung von Nachttischleuchten mit 3D-Design und Löttechnik,"Di 15.10. 14:00-16:00, Do 17.10. 14:00-16:00",Klasse 7-9
|
|
||||||
Neuer Kurs,Beschreibung des neuen Kurses,"Mo 20.10. 15:00-17:00",Klasse 8-10
|
|
||||||
```
|
|
||||||
|
|
||||||
### Fehlende Informationen
|
|
||||||
|
|
||||||
Alle Felder außer `title` sind optional. Beispiele:
|
|
||||||
|
|
||||||
**Nur Titel und Beschreibung:**
|
|
||||||
```csv
|
|
||||||
title,description,dates,offen_fuer
|
|
||||||
Workshop XYZ,Toller Workshop über Making,,
|
|
||||||
```
|
|
||||||
|
|
||||||
**Nur Titel und Termine:**
|
|
||||||
```csv
|
|
||||||
title,description,dates,offen_fuer
|
|
||||||
Workshop ABC,,"Fr 25.10. 14:00",
|
|
||||||
```
|
|
||||||
|
|
||||||
**Nur Titel und Zielgruppe:**
|
|
||||||
```csv
|
|
||||||
title,description,dates,offen_fuer
|
|
||||||
Workshop 123,,,Klasse 9-10
|
|
||||||
```
|
|
||||||
|
|
||||||
### Kurs entfernen
|
|
||||||
|
|
||||||
Einfach die entsprechende Zeile löschen.
|
|
||||||
|
|
||||||
### Wichtig
|
|
||||||
|
|
||||||
- **Keine Anführungszeichen** verwenden, außer der Text enthält ein Komma
|
|
||||||
- **Keine Zeilenumbrüche** innerhalb der Beschreibung
|
|
||||||
- Die erste Zeile (`title,description,dates,offen_fuer,image`) muss erhalten bleiben
|
|
||||||
- Nach dem Speichern wird die Änderung sofort auf der Website sichtbar
|
|
||||||
|
|
||||||
### Darstellung auf der Website
|
|
||||||
|
|
||||||
Die Kurse werden in einem **Grid-Layout** mit **Karten-Design** angezeigt:
|
|
||||||
|
|
||||||
- **Große, fette Titel** (1.5em) mit pinker Unterstreichung
|
|
||||||
- **Hover-Effekt**: Karten heben sich beim Überfahren an
|
|
||||||
- **Responsive**: Auf Mobilgeräten eine Spalte, auf Desktop mehrere Spalten
|
|
||||||
- **Kursbilder** (optional): 200px hoch, oben auf der Karte
|
|
||||||
- **Metadata** am unteren Rand: Datum und Zielgruppe mit Icons
|
|
||||||
|
|
||||||
**Beispiel mit Bild:**
|
|
||||||
```
|
|
||||||
┌─────────────────────────────┐
|
|
||||||
│ [Kursbild 640x400] │
|
|
||||||
├─────────────────────────────┤
|
|
||||||
│ Löten und Leuchten │ ← 1.5em, fett, pink unterstrichen
|
|
||||||
│ ───────────────────── │
|
|
||||||
│ │
|
|
||||||
│ Herstellung von Nachtisch- │ ← Beschreibung
|
|
||||||
│ leuchten mit 3D-Design │
|
|
||||||
│ │
|
|
||||||
├─────────────────────────────┤
|
|
||||||
│ 📅 Dez. '24 │ ← Metadata mit Icons
|
|
||||||
│ 👥 Klasse 5-6 │
|
|
||||||
└─────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
**Beispiel ohne Bild:**
|
|
||||||
```
|
|
||||||
┌─────────────────────────────┐
|
|
||||||
│ Textiles Plotten │ ← Direkt der Titel
|
|
||||||
│ ───────────────── │
|
|
||||||
│ │
|
|
||||||
│ Erschaffe deine eigenen │
|
|
||||||
│ Klamottendesigns │
|
|
||||||
│ │
|
|
||||||
├─────────────────────────────┤
|
|
||||||
│ 📅 Mai '25 │
|
|
||||||
│ 👥 Jhg. 9 │
|
|
||||||
└─────────────────────────────┘
|
|
||||||
```
|
|
||||||
|
|
||||||
### Live-Update
|
|
||||||
|
|
||||||
Die Kurse werden bei jedem Seitenaufruf neu geladen. Es ist **kein Neustart** des Servers erforderlich!
|
|
||||||
|
|
||||||
### Keine Kurse anzeigen
|
|
||||||
|
|
||||||
Wenn keine Kurse stattfinden, einfach alle Zeilen außer der Kopfzeile löschen:
|
|
||||||
```csv
|
|
||||||
title,description
|
|
||||||
```
|
|
||||||
|
|
||||||
Die Seite zeigt dann: "Aktuell sind keine Kurse geplant. Schaut bald wieder vorbei!"
|
|
||||||
|
|
@ -264,6 +264,31 @@ services:
|
||||||
- "description=Forgejo Git Server"
|
- "description=Forgejo Git Server"
|
||||||
- "maintainer=Studio EinsZwoVier"
|
- "maintainer=Studio EinsZwoVier"
|
||||||
|
|
||||||
|
element-web:
|
||||||
|
image: vectorim/element-web:latest
|
||||||
|
container_name: element-web
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${ELEMENT_PORT:-8082}:80"
|
||||||
|
volumes:
|
||||||
|
- ./element-web/config.json:/app/config.json:ro
|
||||||
|
mem_limit: 512m
|
||||||
|
cpus: 0.5
|
||||||
|
mem_reservation: 128m
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:80 || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 20s
|
||||||
|
depends_on:
|
||||||
|
synapse:
|
||||||
|
condition: service_started
|
||||||
|
labels:
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
- "description=Element Web Matrix Client"
|
||||||
|
- "maintainer=studio einszwovier"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
portainer_data:
|
portainer_data:
|
||||||
driver: local
|
driver: local
|
||||||
|
|
|
||||||
74
element-web/README.md
Normal file
74
element-web/README.md
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
# Element Web - Matrix Client
|
||||||
|
|
||||||
|
Element Web is a browser-based Matrix client that connects to the studio einszwovier Matrix (Synapse) server.
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The `config.json` file configures Element Web to connect to the local Synapse homeserver at `http://einszwovier.local:8008`.
|
||||||
|
|
||||||
|
### Key Settings
|
||||||
|
|
||||||
|
- **Homeserver**: Points to local Synapse instance
|
||||||
|
- **Server name**: `einszwovier.local`
|
||||||
|
- **Brand**: "studio einszwovier Chat"
|
||||||
|
- **Default language**: German (DE)
|
||||||
|
- **Default theme**: Light mode
|
||||||
|
- **Guest access**: Enabled (users can preview without account)
|
||||||
|
|
||||||
|
## Access
|
||||||
|
|
||||||
|
- **URL**: `http://einszwovier.local:8082`
|
||||||
|
- **No app required**: Works in any modern web browser
|
||||||
|
- **Mobile friendly**: Responsive design works on phones and tablets
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
1. Navigate to `http://einszwovier.local:8082`
|
||||||
|
2. Click "Sign In" or "Create Account"
|
||||||
|
3. Use existing Matrix credentials or create a new account
|
||||||
|
4. Join rooms (e.g., the print order room)
|
||||||
|
5. Chat, share files, and collaborate!
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- ✅ End-to-end encryption
|
||||||
|
- ✅ File sharing and media uploads
|
||||||
|
- ✅ Read receipts and typing indicators
|
||||||
|
- ✅ Markdown formatting
|
||||||
|
- ✅ Voice and video calls (browser-to-browser)
|
||||||
|
- ✅ Room directory browsing
|
||||||
|
- ✅ Cross-device message sync
|
||||||
|
|
||||||
|
## Updates
|
||||||
|
|
||||||
|
Element Web is managed by Watchtower and updates automatically with the rest of the stack.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**Can't connect to homeserver:**
|
||||||
|
|
||||||
|
- Ensure Synapse is running: `docker-compose ps synapse`
|
||||||
|
- Check Synapse logs: `docker-compose logs synapse`
|
||||||
|
- Verify hostname resolution: `ping einszwovier.local`
|
||||||
|
|
||||||
|
**Login fails:**
|
||||||
|
|
||||||
|
- Verify credentials with Matrix admin
|
||||||
|
- Check Synapse registration settings in `matrix/data/homeserver.yaml`
|
||||||
|
|
||||||
|
**Performance issues:**
|
||||||
|
|
||||||
|
- Element Web is resource-intensive for large rooms
|
||||||
|
- Consider using Hydrogen (lighter client) for low-end devices
|
||||||
|
- Clear browser cache and reload
|
||||||
|
|
||||||
|
## Security Notes
|
||||||
|
|
||||||
|
- Element Web runs on HTTP in the local network
|
||||||
|
- For production/internet exposure, configure HTTPS via reverse proxy
|
||||||
|
- User sessions are stored in browser local storage
|
||||||
|
- Encryption keys are managed client-side
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Maintained by studio einszwovier**
|
||||||
27
element-web/config.json
Normal file
27
element-web/config.json
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
"default_server_config": {
|
||||||
|
"m.homeserver": {
|
||||||
|
"base_url": "http://einszwovier.local:8008",
|
||||||
|
"server_name": "einszwovier.local"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"brand": "studio einszwovier Chat",
|
||||||
|
"disable_guests": false,
|
||||||
|
"disable_login_language_selector": false,
|
||||||
|
"default_country_code": "DE",
|
||||||
|
"show_labs_settings": false,
|
||||||
|
"default_theme": "light",
|
||||||
|
"settingDefaults": {
|
||||||
|
"language": "de"
|
||||||
|
},
|
||||||
|
"room_directory": {
|
||||||
|
"servers": [
|
||||||
|
"einszwovier.local"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"enable_presence_by_hs_url": {
|
||||||
|
"http://einszwovier.local:8008": true
|
||||||
|
},
|
||||||
|
"terms_and_conditions_links": [],
|
||||||
|
"privacy_policy_url": null
|
||||||
|
}
|
||||||
5
main.py
5
main.py
|
|
@ -19,6 +19,7 @@ BOOKSTACK_PORT = os.environ.get("BOOKSTACK_PORT", "6875")
|
||||||
OPENWEBUI_PORT = os.environ.get("OPENWEBUI_PORT", "8080")
|
OPENWEBUI_PORT = os.environ.get("OPENWEBUI_PORT", "8080")
|
||||||
PORTAINER_PORT = os.environ.get("PORTAINER_PORT", "9000")
|
PORTAINER_PORT = os.environ.get("PORTAINER_PORT", "9000")
|
||||||
FORGEJO_PORT = os.environ.get("FORGEJO_PORT", "3003")
|
FORGEJO_PORT = os.environ.get("FORGEJO_PORT", "3003")
|
||||||
|
ELEMENT_PORT = os.environ.get("ELEMENT_PORT", "8082")
|
||||||
|
|
||||||
# Courses CSV path
|
# Courses CSV path
|
||||||
COURSES_CSV = Path("data/courses.csv")
|
COURSES_CSV = Path("data/courses.csv")
|
||||||
|
|
@ -86,6 +87,7 @@ async def welcome(request: Request):
|
||||||
"openwebui_port": OPENWEBUI_PORT,
|
"openwebui_port": OPENWEBUI_PORT,
|
||||||
"portainer_port": PORTAINER_PORT,
|
"portainer_port": PORTAINER_PORT,
|
||||||
"forgejo_port": FORGEJO_PORT,
|
"forgejo_port": FORGEJO_PORT,
|
||||||
|
"element_port": ELEMENT_PORT,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -120,7 +122,8 @@ async def cost_dashboard(request: Request):
|
||||||
|
|
||||||
@app.post("/upload")
|
@app.post("/upload")
|
||||||
async def upload_file(request: Request, file: UploadFile = File(...)):
|
async def upload_file(request: Request, file: UploadFile = File(...)):
|
||||||
if not allowed_file(file.filename):
|
# Ensure filename is present (UploadFile.filename can be None) before validation
|
||||||
|
if not file.filename or not allowed_file(file.filename):
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
"cost-calculator.html",
|
"cost-calculator.html",
|
||||||
{"request": request, "error": "Unsupported file type. Only PDF allowed."},
|
{"request": request, "error": "Unsupported file type. Only PDF allowed."},
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,14 @@
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>{% block title %}Studio Einszwovier{% endblock %}</title>
|
<title>{% block title %}studio einszwovier{% endblock %}</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<a href="/" class="logo-link">
|
<a href="/" class="logo-link">
|
||||||
<img src="/static/images/logo.png" alt="Studio Einszwovier Logo" class="logo">
|
<img src="/static/images/logo.png" alt="studio einszwovier Logo" class="logo">
|
||||||
</a>
|
</a>
|
||||||
<nav>
|
<nav>
|
||||||
<a href="/">Startseite</a> |
|
<a href="/">Startseite</a> |
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,12 @@
|
||||||
Entwicklung und Projektmanagement.</div>
|
Entwicklung und Projektmanagement.</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a class="link-card" href="http://{{ server_hostname }}:{{ element_port }}" target="_blank">
|
||||||
|
<div class="title">Matrix Chat</div>
|
||||||
|
<div class="tagline">Browser-basierter Chat für die studio einszwovier Community. Nutzt den bestehenden
|
||||||
|
Matrix-Server – keine App-Installation nötig.</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
<a class="link-card" href="mailto:einszwovier@gvb-gymnasium.de" target="_blank">
|
<a class="link-card" href="mailto:einszwovier@gvb-gymnasium.de" target="_blank">
|
||||||
<div class="title">Kontakt</div>
|
<div class="title">Kontakt</div>
|
||||||
<div class="tagline">Schreibe uns direkt an: einszwovier@gvb-gymnasium.de</div>
|
<div class="tagline">Schreibe uns direkt an: einszwovier@gvb-gymnasium.de</div>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<!-- templates/result.html -->
|
<!-- templates/result.html -->
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block title %}Druckkosten Ergebnis – Studio EinsZwoVier{% endblock %}
|
{% block title %}Druckkosten Ergebnis – studio einszwovier{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
@ -70,7 +70,8 @@
|
||||||
<input type="text" id="name" name="name" required placeholder="Dein Name">
|
<input type="text" id="name" name="name" required placeholder="Dein Name">
|
||||||
|
|
||||||
<label for="comment"><strong>Zusätzliche Hinweise:</strong></label>
|
<label for="comment"><strong>Zusätzliche Hinweise:</strong></label>
|
||||||
<textarea id="comment" name="comment" rows="4" placeholder="z. B. doppelseitig oder spezielles Papier"></textarea>
|
<textarea id="comment" name="comment" rows="4"
|
||||||
|
placeholder="z. B. doppelseitig oder spezielles Papier"></textarea>
|
||||||
|
|
||||||
<button type="submit">Auftrag senden</button>
|
<button type="submit">Auftrag senden</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -79,4 +80,4 @@
|
||||||
<a href="/">Neues PDF hochladen</a>
|
<a href="/">Neues PDF hochladen</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue