diff --git a/.DS_Store b/.DS_Store index f57e8a7..0503454 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/DEV_SETUP.md b/DEV_SETUP.md deleted file mode 100644 index 138bb0f..0000000 --- a/DEV_SETUP.md +++ /dev/null @@ -1,78 +0,0 @@ -# Development Setup Guide - -## Quick Start for Local Development - -The `run_app.py` script mimics Docker production conditions while enabling fast iteration. - -### Standard Development Mode (Recommended) -```bash -python run_app.py -``` - -**Features:** -- ✓ Loads environment variables from `.env` file -- ✓ Single Uvicorn worker with **fast auto-reload** -- ✓ Mimics Docker environment (`PYTHONUNBUFFERED=1`) -- ✓ Creates upload directory automatically -- ✓ Binds to `0.0.0.0:8000` (same as Docker) - -**Best for:** Quick code iterations, template changes, debugging - -### Production-Like Mode -```bash -python run_app.py --gunicorn -``` - -**Features:** -- ✓ Gunicorn with 4 Uvicorn workers (exactly like Docker) -- ✓ 120s timeout (same as Docker) -- ✓ Gunicorn's reload (slower but tests production server) -- ✓ Tests multi-worker behavior - -**Best for:** Testing before deploying to Docker, load testing - -## Environment Variables - -The script automatically loads `.env` file variables: -- `RATE_PER_M2_BLACK` - Black & white print rate (default: 4.0) -- `RATE_PER_M2_COLOR` - Color print rate (default: 5.0) -- `SERVER_HOSTNAME` - Server hostname (default: einszwovier.local) -- `BOOKSTACK_PORT`, `OPENWEBUI_PORT`, `PORTAINER_PORT` - Service ports -- `MATRIX_USER`, `MATRIX_PASS`, `MATRIX_HOMESERVER` - Matrix integration - -## Comparison: Dev vs Docker - -| Feature | `python run_app.py` | `docker-compose up` | -|---------|---------------------|---------------------| -| Server | Uvicorn (single worker) | Gunicorn + Uvicorn (4 workers) | -| Auto-reload | ✓ Fast (watches all files) | ✓ Slow (Docker rebuild) | -| Env loading | `.env` file | `.env` file | -| Port | 8000 | 80→8000 | -| Memory limit | None | 1GB limit | -| Health checks | No | Yes | -| Dependencies | All services | Isolated | - -## Troubleshooting - -### `.env` file not found -Create `.env` file from template: -```bash -cp .env.example .env -``` - -### Port 8000 already in use -```bash -# Find and kill process -lsof -ti:8000 | xargs kill -9 -``` - -### Environment variables not loading -Ensure `python-dotenv` is installed: -```bash -pip install python-dotenv -``` - -### Testing Matrix integration locally -1. Start Matrix server: `docker-compose up synapse -d` -2. Run app: `python run_app.py` -3. Submit test order via `/cost` endpoint diff --git a/bookstack.yml b/bookstack.yml deleted file mode 100644 index 8664125..0000000 --- a/bookstack.yml +++ /dev/null @@ -1,37 +0,0 @@ -services: - bookstack: - image: lscr.io/linuxserver/bookstack:v25.07.2-ls220 - container_name: bookstack - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/Berlin - - APP_URL=http://einszwovier.local:6875 - - APP_KEY=base64:3qjlIoUX4Tw6fUQgZcxMbz6lb8+dAzqpvItqHvahW1c= - - DB_HOST=bookstack-mariadb - - DB_PORT=3306 - - DB_DATABASE=bookstack - - DB_USERNAME=bookstack - - DB_PASSWORD=bookstack8432 - volumes: - - ./bookstack_app_data:/config - ports: - - 6875:80 - restart: unless-stopped - depends_on: - - bookstack-mariadb - - bookstack-mariadb: - image: lscr.io/linuxserver/mariadb:11.4.4 - container_name: bookstack-mariadb - environment: - - PUID=1000 - - PGID=1000 - - TZ=Europe/Berlin - - MYSQL_ROOT_PASSWORD=mysupersecretrootpassword - - MYSQL_DATABASE=bookstack - - MYSQL_USER=bookstack - - MYSQL_PASSWORD=bookstack8432 - volumes: - - ./bookstack_db_data:/config - restart: unless-stopped diff --git a/main.py b/main.py index 94ccde6..fa3327c 100644 --- a/main.py +++ b/main.py @@ -101,7 +101,8 @@ async def about(request: Request): return templates.TemplateResponse("about.html", { "request": request, - "courses": courses + "courses": courses, + "bookstack_url": f"http://{SERVER_HOSTNAME}:{BOOKSTACK_PORT}" }) @app.get("/cost", response_class=HTMLResponse) diff --git a/matrix/docker-compose.yml b/matrix/docker-compose.yml deleted file mode 100644 index 6406494..0000000 --- a/matrix/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -services: - synapse: - image: matrixdotorg/synapse:latest - container_name: synapse - restart: always - ports: - - "8008:8008" # client-server API (internal) - volumes: - - ./matrix/data:/data - environment: - - SYNAPSE_SERVER_NAME=localhost - - SYNAPSE_REPORT_STATS=no \ No newline at end of file diff --git a/static/css/style.css b/static/css/style.css index 385587b..d5fe76a 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -616,6 +616,109 @@ th { color: #FFFFFF; } +.info-box { + background-color: #e3f2fd; + border-left: 4px solid #1976d2; + border-radius: 8px; + padding: 1.5em; + margin: 1.5em 0; + line-height: 1.6; +} + +.info-box p { + margin: 0.5em 0; + text-align: left; +} + +.info-box p:first-child { + margin-top: 0; +} + +.info-box p:last-child { + margin-bottom: 0; +} + +.info-box a { + color: #1976d2; + font-weight: 600; + text-decoration: none; +} + +.info-box a:hover { + text-decoration: underline; +} + +/* Pricing Card - Prominent pricing display */ +.pricing-card { + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + border: 2px solid #28a745; + border-radius: 12px; + padding: 2em; + margin: 2em 0; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +.pricing-card h2 { + color: #28a745; + font-size: 1.8rem; + margin-bottom: 1.5em; + text-align: center; +} + +.price-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1.5em; + margin-bottom: 1.5em; +} + +.price-item { + background-color: white; + border-radius: 8px; + padding: 1.5em; + text-align: center; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); + transition: transform 0.2s ease, box-shadow 0.2s ease; +} + +.price-item:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12); +} + +.price-item.bw { + border-top: 4px solid #6c757d; +} + +.price-item.color { + border-top: 4px solid #fd7e14; +} + +.price-label { + display: block; + font-size: 1.1rem; + color: #6c757d; + margin-bottom: 0.5em; + font-weight: 600; +} + +.price-value { + display: block; + font-size: 2rem; + color: #1C1C1E; + font-weight: bold; + font-family: 'HealTheWebB', sans-serif; +} + +.pricing-note { + text-align: center; + color: #6c757d; + font-size: 0.95rem; + margin: 0; + padding-top: 1em; + border-top: 1px solid #dee2e6; +} + .disclaimer-alert { margin-top: 10px; padding: 10px 15px; diff --git a/templates/about.html b/templates/about.html index b30fd80..ee9acd5 100644 --- a/templates/about.html +++ b/templates/about.html @@ -11,7 +11,9 @@

Seit Dezember 2024 trägt unser Maker Space den Namen studio einszwovier. Er ist ein innovativer, digitaler Lernraum, der Kreativität, Technik und Bildungsgerechtigkeit verbindet. Hier wird „Making“ erlebbar: Lernende gestalten ihren Lernprozess aktiv, entdecken individuelle Stärken und erleben - durch Selbstwirksamkeit besondere Motivation.

+ durch Selbstwirksamkeit besondere Motivation. + Betreut wird der Maker Space von Aron Petau und Friedrich Weber. Einfach vorbeischauen, Ideen vorstellen und loslegen! +

@@ -27,25 +29,24 @@
  • Drohnen: Flugexperimente und Luftbildfotografie.
  • LEGO SPIKE Roboter: Spielerisches Erlernen von Robotik und Programmierung.
  • + + Wenn du mehr über unsere Ausstattung erfahren möchtest oder spezielle Geräte suchst, schau in unsere + Wissenssammlung oder frag uns direkt im Studio!
    -

    Betreuungsteam

    -

    Betreut wird der Maker Space von Aron Petau und Friedrich Weber. Sie sind - von Dienstag bis Donnerstag von 11:00 bis 16:00 Uhr vor Ort. Einfach vorbeischauen, Ideen vorstellen und loslegen! -

    -
    - -
    -

    Öffnungszeiten

    +

    Öffnungszeiten + Kontakt

    Dienstag bis Donnerstag: 11:00 – 16:00 Uhr
    Raum 124, Gabriele-von-Bülow-Gymnasium

    +

    E-Mail: einszwovier@gvb-gymnasium.de

    +

    Standort

    +

    Gabriele-von-Bülow-Gymnasium
    + Tile-Brügge-Weg 63, 13509 Berlin (Tegel)
    + Telefon: 030 21 00 52 460
    + E-Mail: info@gvb-gymnasium.de

    +
    -
    -

    Kontakt

    -

    E-Mail: einszwovier@gvb-gymnasium.de

    -

    Aktuelle Kurse

    @@ -114,13 +115,5 @@ } }); - -
    -

    Standort

    -

    Gabriele-von-Bülow-Gymnasium
    - Tile-Brügge-Weg 63, 13509 Berlin (Tegel)
    - Telefon: 030 21 00 52 460
    - E-Mail: info@gvb-gymnasium.de

    -
    {% endblock %} \ No newline at end of file diff --git a/templates/cost-calculator.html b/templates/cost-calculator.html index 470fac4..a4ddc6c 100644 --- a/templates/cost-calculator.html +++ b/templates/cost-calculator.html @@ -8,6 +8,36 @@

    Kostenrechner für Drucke

    +
    +

    + So funktioniert's: Lade dein PDF hoch, um eine Kostenschätzung zu erhalten. + Du kannst beliebige PDFs hochladen, um die Kosten zu berechnen. +

    +

    + Wichtig: Schicke den Auftrag nur ab, wenn du die Datei wirklich drucken lassen möchtest! + Für reine Kostenschätzung reicht es, die Berechnung anzusehen, ohne den Auftrag zu senden. +

    +

    + Alternative: Du kannst uns deine Datei und Infos auch per E-Mail schicken: + einszwovier@gvb-gymnasium.de +

    +
    + +
    +

    📊 Aktuelle Preise

    +
    +
    + Schwarz/Weiß + {{ rate_black if rate_black else 'RATE_PER_M2_BLACK' }} €/m² +
    +
    + Farbe + {{ rate_color if rate_color else 'RATE_PER_M2_COLOR' }} €/m² +
    +
    +

    💡 Die Preise decken nur Materialkosten(Tinte & Papier) – kein Gewinn!

    +
    + {% if error %}

    {{ error }}

    {% endif %} @@ -17,12 +47,6 @@ -

    - Preise werden über Umgebungsvariablen festgelegt:
    - S/W: {{ rate_black if rate_black else 'RATE_PER_M2_BLACK' }} € / m², - Farbe: {{ rate_color if rate_color else 'RATE_PER_M2_COLOR' }} € / m² -

    - {% if result %}

    Ergebnisse für {{ result.filename }}

    diff --git a/test_send_pdf.py b/test_send_pdf.py deleted file mode 100644 index 67a7c61..0000000 --- a/test_send_pdf.py +++ /dev/null @@ -1,72 +0,0 @@ -import os -import asyncio -from io import BytesIO -from nio import AsyncClient, UploadResponse, RoomSendResponse -from dotenv import load_dotenv - -load_dotenv() - -async def main(): - # Get credentials from environment (adjust if needed) - matrix_user = os.environ.get("MATRIX_USER", "@einszwovier_bot:localhost") - matrix_pass = os.environ.get("MATRIX_PASS") - homeserver = os.environ.get("MATRIX_HOMESERVER", "http://localhost:8008") - room_id = os.environ.get("MATRIX_ROOM") # e.g. "!abc123:localhost" - - if not all([matrix_user, matrix_pass, room_id]): - raise RuntimeError("Missing MATRIX_USER, MATRIX_PASS or MATRIX_ROOM") - - client = AsyncClient(homeserver, matrix_user) - login_resp = await client.login(matrix_pass) - if getattr(login_resp, "access_token", None) is None: - print("❌ Login failed:", login_resp) - return - - print("✅ Logged in as", matrix_user) - - pdf_path = "data/uploads/einszwovier infographics 2.pdf" # <-- put any small PDF here - with open(pdf_path, "rb") as f: - pdf_bytes = f.read() - - # ✅ Upload PDF (nio returns (resp, err)) - upload_resp, upload_err = await client.upload( - data_provider=BytesIO(pdf_bytes), - content_type="application/pdf", - filename=os.path.basename(pdf_path), - filesize=len(pdf_bytes), - ) - - if upload_err: - print("❌ Upload error:", upload_err) - await client.close() - return - - if isinstance(upload_resp, UploadResponse) and upload_resp.content_uri: - print("✅ Upload succeeded:", upload_resp.content_uri) - else: - print("❌ Upload failed:", upload_resp) - await client.close() - return - - # Send file message to room - file_resp = await client.room_send( - room_id=room_id, - message_type="m.room.message", - content={ - "msgtype": "m.file", - "body": os.path.basename(pdf_path), - "url": upload_resp.content_uri, - }, - ) - - if isinstance(file_resp, RoomSendResponse) and file_resp.event_id: - print("✅ PDF sent to room", room_id) - else: - print("❌ Failed to send PDF:", file_resp) - - await client.logout() - await client.close() - - -if __name__ == "__main__": - asyncio.run(main())