"Remove presentation files and related scripts"
This commit is contained in:
Binary file not shown.
Binary file not shown.
@ -1,50 +0,0 @@
|
||||
# MYP Platform Schulungspräsentation
|
||||
|
||||
Diese PowerPoint-Präsentation wurde erstellt, um einen umfassenden Überblick über die Backend-Komponente der MYP-Platform zu geben, einem 3D-Drucker-Reservierungssystem.
|
||||
|
||||
## Verfügbare Präsentationen
|
||||
|
||||
In diesem Verzeichnis finden Sie zwei PowerPoint-Präsentationen:
|
||||
|
||||
1. **MYP_Backend_Schulung.pptx** - Grundlegende Version mit klarem, minimalem Design
|
||||
2. **MYP_Backend_Schulung_Enhanced.pptx** - Verbesserte Version mit Bildern und farblichen Akzenten
|
||||
|
||||
## Inhalt der Präsentation
|
||||
|
||||
Die Präsentation deckt folgende Themen ab:
|
||||
|
||||
- Systemüberblick und Hauptfunktionen
|
||||
- Technologie-Stack und verwendete Bibliotheken
|
||||
- Backend-Architektur und Modulstruktur
|
||||
- Datenmodell und Datenbankdesign
|
||||
- API-Endpunkte und Funktionalität
|
||||
- Job-Scheduler und Automatisierung
|
||||
- Logging-System und Fehlerbehandlung
|
||||
- Sicherheitskonzepte und Best Practices
|
||||
|
||||
## Tipps für die Präsentation
|
||||
|
||||
1. **Vorbereitung:** Laden Sie die Präsentation vor Ihrer Schulung herunter und testen Sie sie auf Ihrem Gerät.
|
||||
2. **Bildschirmauflösung:** Die Präsentation ist für eine 16:9-Auflösung optimiert.
|
||||
3. **Notizen:** Ergänzen Sie gerne eigene Notizen zu den einzelnen Folien basierend auf Ihrer Erfahrung mit dem System.
|
||||
4. **Live-Demo:** Erwägen Sie, die Präsentation mit einer Live-Demo des Systems zu ergänzen.
|
||||
|
||||
## Anpassung der Präsentation
|
||||
|
||||
Falls Sie die Präsentation anpassen möchten:
|
||||
|
||||
1. Beide Präsentationen wurden mit den Python-Skripten `create_presentation.py` und `create_presentation_enhanced.py` erstellt.
|
||||
2. Bearbeiten Sie die entsprechenden Skripte und führen Sie sie erneut aus, um angepasste Versionen zu erstellen.
|
||||
3. Bildmaterial für die verbesserte Version wird in einem Unterordner `presentation_images` gespeichert.
|
||||
|
||||
## Voraussetzungen für die Generierung
|
||||
|
||||
Um die Präsentationsskripte selbst auszuführen, benötigen Sie:
|
||||
|
||||
```bash
|
||||
pip install python-pptx requests pillow
|
||||
```
|
||||
|
||||
## Kontakt
|
||||
|
||||
Bei Fragen zur Präsentation oder zum MYP-Platform-System wenden Sie sich bitte an das Entwicklungsteam.
|
@ -34,8 +34,8 @@ SESSION_LIFETIME = timedelta(days=7)
|
||||
|
||||
# SSL-Konfiguration
|
||||
SSL_ENABLED = True
|
||||
SSL_CERT_PATH = "app/certs/myp.crt"
|
||||
SSL_KEY_PATH = "app/certs/myp.key"
|
||||
SSL_CERT_PATH = "../certs/myp.crt"
|
||||
SSL_KEY_PATH = "../certs/myp.key"
|
||||
SSL_HOSTNAME = "raspberrypi"
|
||||
|
||||
# Scheduler-Konfiguration
|
||||
|
@ -1,344 +0,0 @@
|
||||
import os
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN
|
||||
|
||||
# Stile und Konstanten
|
||||
TITLE_FONT = 'Helvetica Neue'
|
||||
BODY_FONT = 'Helvetica Neue'
|
||||
PRIMARY_COLOR = RGBColor(0, 122, 255) # Apple Blau
|
||||
DARK_TEXT = RGBColor(50, 50, 50)
|
||||
LIGHT_TEXT = RGBColor(240, 240, 240)
|
||||
BACKGROUND_COLOR = RGBColor(250, 250, 250)
|
||||
SLIDE_WIDTH = Inches(13.333)
|
||||
SLIDE_HEIGHT = Inches(7.5)
|
||||
|
||||
# Ausgabepfad
|
||||
output_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
output_path = os.path.join(output_dir, 'MYP_Backend_Schulung.pptx')
|
||||
|
||||
# Neue Präsentation erstellen
|
||||
prs = Presentation()
|
||||
|
||||
# Foliengröße auf 16:9 setzen
|
||||
prs.slide_width = SLIDE_WIDTH
|
||||
prs.slide_height = SLIDE_HEIGHT
|
||||
|
||||
# Hilfsfunktion für einheitliche Formatierung
|
||||
def apply_text_style(paragraph, font_size, bold=False, color=DARK_TEXT, alignment=PP_ALIGN.LEFT):
|
||||
paragraph.alignment = alignment
|
||||
run = paragraph.runs[0]
|
||||
run.font.name = BODY_FONT
|
||||
run.font.size = Pt(font_size)
|
||||
run.font.bold = bold
|
||||
run.font.color.rgb = color
|
||||
|
||||
# Titelfolie
|
||||
slide_layout = prs.slide_layouts[0] # Titelfolie
|
||||
slide = prs.slides.add_slide(slide_layout)
|
||||
|
||||
# Hintergrund anpassen (einfacher weißer Hintergrund für Apple-ähnlichen Look)
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
# Titel hinzufügen
|
||||
title_shape = slide.shapes.title
|
||||
title_shape.text = "MYP Platform"
|
||||
title_paragraph = title_shape.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 54, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.CENTER)
|
||||
|
||||
# Untertitel hinzufügen
|
||||
subtitle_shape = slide.placeholders[1]
|
||||
subtitle_shape.text = "3D-Drucker Reservierungssystem\nBackend-Schulung"
|
||||
subtitle_paragraph = subtitle_shape.text_frame.paragraphs[0]
|
||||
apply_text_style(subtitle_paragraph, 32, color=DARK_TEXT, alignment=PP_ALIGN.CENTER)
|
||||
|
||||
# Folie 2: Überblick
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Systemüberblick"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Reservierungssystem für 3D-Drucker"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Automatische Steuerung von Smart Plugs"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Echtzeit-Überwachung von Druckaufträgen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Administrationsfunktionen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Statistik und Analyse"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 3: Technologie-Stack
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Technologie-Stack"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Backend: Python 3.11 mit Flask"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Frontend: HTML/CSS/JavaScript mit Tailwind CSS"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Datenbank: SQLite mit SQLAlchemy ORM"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Authentifizierung: Flask-Login"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Hardware-Integration: PyP110 für Tapo Smart Plug Steuerung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Automatisierung: Integrierter Job-Scheduler"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 4: Architektur
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Backend-Architektur"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Flask-App: Zentrale Anwendungslogik"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Blueprints: Modulare Strukturierung (auth, user, kiosk)"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Models: SQLAlchemy ORM für Datenbankkommunikation"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Utils: Job-Scheduler, Logging, Template-Helpers"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• API: RESTful-Endpunkte für Frontend-Kommunikation"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 5: Datenmodell
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Datenmodell"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• User: Benutzer mit Rollen und Authentifizierung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Printer: 3D-Drucker mit Smart-Plug-Konfigurationen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Job: Druckaufträge mit Status und Zeitplanung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Stats: Systemstatistiken und Metriken"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 6: API-Endpunkte
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "API-Endpunkte"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• /api/jobs: Druckaufträge verwalten"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/printers: Drucker verwalten"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/users: Benutzer verwalten"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/stats: Statistiken abrufen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/scheduler: Scheduler steuern"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 7: Scheduler
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Job-Scheduler"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Automatische Steuerung der Drucker"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Einschalten bei Auftragsstart"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Ausschalten bei Auftragsende"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Statusüberwachung und -aktualisierung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Sammeln von Statistiken"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 8: Logging
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Logging-System"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Separate Logs für verschiedene Bereiche:"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - App-Logs: Allgemeine Anwendungslogs"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Auth-Logs: Authentifizierungsereignisse"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Job-Logs: Druckauftragsoperationen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Printer-Logs: Druckerstatusänderungen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Scheduler-Logs: Automatisierungsaktionen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 9: Sicherheit
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Sicherheitskonzept"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Benutzerauthentifizierung mit bcrypt"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Rollenbasierte Zugriffskontrolle"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• CSRF-Schutz bei Formularen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Besitzer-Check für Druckaufträge"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Sichere HTTP-Header"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Folie 10: Zusammenfassung
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
title = slide.shapes.title
|
||||
title.text = "Zusammenfassung"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Vollständige Lösung für 3D-Drucker-Management"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Modulare Architektur für einfache Erweiterbarkeit"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Robuste Sicherheitskonzepte"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Umfassendes Logging und Überwachung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Automatisierung von Routineaufgaben"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Präsentation speichern
|
||||
prs.save(output_path)
|
||||
print(f"Präsentation wurde erstellt: {output_path}")
|
@ -1,587 +0,0 @@
|
||||
import os
|
||||
import io
|
||||
import requests
|
||||
from PIL import Image
|
||||
from pptx import Presentation
|
||||
from pptx.util import Inches, Pt
|
||||
from pptx.dml.color import RGBColor
|
||||
from pptx.enum.text import PP_ALIGN
|
||||
|
||||
# Stile und Konstanten
|
||||
TITLE_FONT = 'Helvetica Neue'
|
||||
BODY_FONT = 'Helvetica Neue'
|
||||
PRIMARY_COLOR = RGBColor(0, 122, 255) # Apple Blau
|
||||
SECONDARY_COLOR = RGBColor(88, 86, 214) # Apple Lila
|
||||
ACCENT_COLOR = RGBColor(255, 149, 0) # Apple Orange
|
||||
DARK_TEXT = RGBColor(50, 50, 50)
|
||||
LIGHT_TEXT = RGBColor(240, 240, 240)
|
||||
BACKGROUND_COLOR = RGBColor(250, 250, 250)
|
||||
SLIDE_WIDTH = Inches(13.333)
|
||||
SLIDE_HEIGHT = Inches(7.5)
|
||||
|
||||
# Ausgabepfad
|
||||
output_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
output_path = os.path.join(output_dir, 'MYP_Backend_Schulung_Enhanced.pptx')
|
||||
images_dir = os.path.join(output_dir, 'presentation_images')
|
||||
|
||||
# Verzeichnis für Bilder erstellen, falls es nicht existiert
|
||||
os.makedirs(images_dir, exist_ok=True)
|
||||
|
||||
# Funktion zum Herunterladen von Stock-Bildern (nur Beispiel, Sie können auch eigene Bilder verwenden)
|
||||
def download_stock_image(url, filename):
|
||||
try:
|
||||
image_path = os.path.join(images_dir, filename)
|
||||
# Wenn das Bild bereits existiert, nicht erneut herunterladen
|
||||
if os.path.exists(image_path):
|
||||
return image_path
|
||||
|
||||
response = requests.get(url, stream=True)
|
||||
if response.status_code == 200:
|
||||
with open(image_path, 'wb') as f:
|
||||
f.write(response.content)
|
||||
return image_path
|
||||
else:
|
||||
print(f"Fehler beim Herunterladen des Bildes: {response.status_code}")
|
||||
return None
|
||||
except Exception as e:
|
||||
print(f"Fehler: {e}")
|
||||
return None
|
||||
|
||||
# Platzhalterbilder für die Präsentation
|
||||
# Im echten Einsatz würden Sie eigene Bilder oder lizenzfreie Bilder verwenden
|
||||
image_urls = {
|
||||
"header": "https://cdn.pixabay.com/photo/2017/08/10/02/05/tiles-shapes-2617112_1280.jpg",
|
||||
"3d_printer": "https://cdn.pixabay.com/photo/2019/07/06/11/15/3d-printer-4320296_1280.jpg",
|
||||
"backend": "https://cdn.pixabay.com/photo/2016/11/27/21/42/stock-1863880_1280.jpg",
|
||||
"database": "https://cdn.pixabay.com/photo/2017/06/14/16/20/network-2402637_1280.jpg",
|
||||
"api": "https://cdn.pixabay.com/photo/2018/05/04/20/01/website-3374825_1280.jpg",
|
||||
"scheduler": "https://cdn.pixabay.com/photo/2018/01/17/07/06/laptop-3087585_1280.jpg",
|
||||
"security": "https://cdn.pixabay.com/photo/2017/11/19/23/56/cyber-security-2965030_1280.jpg",
|
||||
"summary": "https://cdn.pixabay.com/photo/2019/04/14/10/27/book-4126483_1280.jpg"
|
||||
}
|
||||
|
||||
# Bilder herunterladen
|
||||
image_paths = {}
|
||||
for key, url in image_urls.items():
|
||||
filename = f"{key}.jpg"
|
||||
image_path = download_stock_image(url, filename)
|
||||
if image_path:
|
||||
image_paths[key] = image_path
|
||||
else:
|
||||
print(f"Konnte Bild {key} nicht herunterladen")
|
||||
|
||||
# Neue Präsentation erstellen
|
||||
prs = Presentation()
|
||||
|
||||
# Foliengröße auf 16:9 setzen
|
||||
prs.slide_width = SLIDE_WIDTH
|
||||
prs.slide_height = SLIDE_HEIGHT
|
||||
|
||||
# Hilfsfunktion für einheitliche Formatierung
|
||||
def apply_text_style(paragraph, font_size, bold=False, color=DARK_TEXT, alignment=PP_ALIGN.LEFT):
|
||||
paragraph.alignment = alignment
|
||||
run = paragraph.runs[0]
|
||||
run.font.name = BODY_FONT
|
||||
run.font.size = Pt(font_size)
|
||||
run.font.bold = bold
|
||||
run.font.color.rgb = color
|
||||
|
||||
# Hilfsfunktion zum Hinzufügen eines Bildes zu einer Folie
|
||||
def add_image_to_slide(slide, image_path, left, top, width, height=None, keep_ratio=True):
|
||||
if not os.path.exists(image_path):
|
||||
print(f"Bildpfad existiert nicht: {image_path}")
|
||||
return None
|
||||
|
||||
img = Image.open(image_path)
|
||||
width_inches = width
|
||||
|
||||
if keep_ratio and height is None:
|
||||
# Seitenverhältnis beibehalten
|
||||
img_ratio = img.height / img.width
|
||||
height_inches = width_inches * img_ratio
|
||||
else:
|
||||
height_inches = height
|
||||
|
||||
return slide.shapes.add_picture(image_path, left, top, width=width_inches, height=height_inches)
|
||||
|
||||
# Hilfsfunktion zum Erstellen eines abgerundeten Farbbereichs (als Ersatz für abgerundete Rechtecke)
|
||||
def add_rectangle_to_slide(slide, left, top, width, height, color=PRIMARY_COLOR):
|
||||
shape = slide.shapes.add_shape(1, left, top, width, height) # 1 = Rechteck
|
||||
shape.fill.solid()
|
||||
shape.fill.fore_color.rgb = color
|
||||
shape.line.fill.solid()
|
||||
shape.line.fill.fore_color.rgb = color
|
||||
return shape
|
||||
|
||||
# ------------- FOLIE 1: TITELFOLIE -------------
|
||||
slide_layout = prs.slide_layouts[0] # Titelfolie
|
||||
slide = prs.slides.add_slide(slide_layout)
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
# Hintergrundbild (wenn verfügbar)
|
||||
if "header" in image_paths:
|
||||
header_img = add_image_to_slide(slide,
|
||||
image_paths["header"],
|
||||
Inches(0),
|
||||
Inches(0),
|
||||
SLIDE_WIDTH,
|
||||
SLIDE_HEIGHT,
|
||||
keep_ratio=False)
|
||||
# Bild in den Hintergrund
|
||||
if header_img:
|
||||
header_img.z_order = 0
|
||||
|
||||
# Halbtransparentes Overlay
|
||||
overlay = add_rectangle_to_slide(slide,
|
||||
Inches(0),
|
||||
Inches(0),
|
||||
SLIDE_WIDTH,
|
||||
SLIDE_HEIGHT,
|
||||
RGBColor(0, 0, 0))
|
||||
overlay.fill.transparency = 0.4 # 40% Transparenz
|
||||
overlay.z_order = 1
|
||||
|
||||
# Titel hinzufügen
|
||||
title_shape = slide.shapes.title
|
||||
title_shape.text = "MYP Platform"
|
||||
title_paragraph = title_shape.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 64, bold=True, color=LIGHT_TEXT, alignment=PP_ALIGN.CENTER)
|
||||
title_shape.z_order = 2
|
||||
|
||||
# Untertitel hinzufügen
|
||||
subtitle_shape = slide.placeholders[1]
|
||||
subtitle_shape.text = "3D-Drucker Reservierungssystem\nBackend-Schulung"
|
||||
subtitle_paragraph = subtitle_shape.text_frame.paragraphs[0]
|
||||
apply_text_style(subtitle_paragraph, 36, color=LIGHT_TEXT, alignment=PP_ALIGN.CENTER)
|
||||
subtitle_shape.z_order = 2
|
||||
|
||||
# ------------- FOLIE 2: ÜBERBLICK -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Systemüberblick"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Reservierungssystem für 3D-Drucker"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Automatische Steuerung von Smart Plugs"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Echtzeit-Überwachung von Druckaufträgen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Administrationsfunktionen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Statistik und Analyse"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Bild einfügen (wenn verfügbar)
|
||||
if "3d_printer" in image_paths:
|
||||
printer_img = add_image_to_slide(slide,
|
||||
image_paths["3d_printer"],
|
||||
Inches(7),
|
||||
Inches(2),
|
||||
Inches(5))
|
||||
|
||||
# ------------- FOLIE 3: TECHNOLOGIE-STACK -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Technologie-Stack"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Backend: Python 3.11 mit Flask"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = SECONDARY_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Frontend: HTML/CSS/JavaScript mit Tailwind CSS"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Datenbank: SQLite mit SQLAlchemy ORM"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Authentifizierung: Flask-Login"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Hardware-Integration: PyP110 für Tapo Smart Plug Steuerung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Automatisierung: Integrierter Job-Scheduler"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Bild einfügen (wenn verfügbar)
|
||||
if "backend" in image_paths:
|
||||
backend_img = add_image_to_slide(slide,
|
||||
image_paths["backend"],
|
||||
Inches(7),
|
||||
Inches(2),
|
||||
Inches(5))
|
||||
|
||||
# ------------- FOLIE 4: ARCHITEKTUR -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Backend-Architektur"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Flask-App: Zentrale Anwendungslogik"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = PRIMARY_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Blueprints: Modulare Strukturierung (auth, user, kiosk)"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Models: SQLAlchemy ORM für Datenbankkommunikation"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Utils: Job-Scheduler, Logging, Template-Helpers"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• API: RESTful-Endpunkte für Frontend-Kommunikation"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = SECONDARY_COLOR
|
||||
|
||||
# ------------- FOLIE 5: DATENMODELL -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Datenmodell"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• User: Benutzer mit Rollen und Authentifizierung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Printer: 3D-Drucker mit Smart-Plug-Konfigurationen"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Job: Druckaufträge mit Status und Zeitplanung"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = SECONDARY_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Stats: Systemstatistiken und Metriken"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Bild einfügen (wenn verfügbar)
|
||||
if "database" in image_paths:
|
||||
db_img = add_image_to_slide(slide,
|
||||
image_paths["database"],
|
||||
Inches(7),
|
||||
Inches(2),
|
||||
Inches(5))
|
||||
|
||||
# ------------- FOLIE 6: API-ENDPUNKTE -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "API-Endpunkte"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• /api/jobs: Druckaufträge verwalten"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = SECONDARY_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/printers: Drucker verwalten"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/users: Benutzer verwalten"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/stats: Statistiken abrufen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• /api/scheduler: Scheduler steuern"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = PRIMARY_COLOR
|
||||
|
||||
# Bild einfügen (wenn verfügbar)
|
||||
if "api" in image_paths:
|
||||
api_img = add_image_to_slide(slide,
|
||||
image_paths["api"],
|
||||
Inches(7),
|
||||
Inches(2),
|
||||
Inches(5))
|
||||
|
||||
# ------------- FOLIE 7: JOB-SCHEDULER -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Job-Scheduler"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Automatische Steuerung der Drucker"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Einschalten bei Auftragsstart"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Ausschalten bei Auftragsende"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Statusüberwachung und -aktualisierung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Sammeln von Statistiken"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Bild einfügen (wenn verfügbar)
|
||||
if "scheduler" in image_paths:
|
||||
scheduler_img = add_image_to_slide(slide,
|
||||
image_paths["scheduler"],
|
||||
Inches(7),
|
||||
Inches(2),
|
||||
Inches(5))
|
||||
|
||||
# ------------- FOLIE 8: LOGGING-SYSTEM -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Logging-System"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Separate Logs für verschiedene Bereiche:"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.bold = True
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - App-Logs: Allgemeine Anwendungslogs"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Auth-Logs: Authentifizierungsereignisse"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Job-Logs: Druckauftragsoperationen"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = SECONDARY_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Printer-Logs: Druckerstatusänderungen"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = " - Scheduler-Logs: Automatisierungsaktionen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# ------------- FOLIE 9: SICHERHEITSKONZEPT -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Sicherheitskonzept"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Benutzerauthentifizierung mit bcrypt"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = SECONDARY_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Rollenbasierte Zugriffskontrolle"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• CSRF-Schutz bei Formularen"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Besitzer-Check für Druckaufträge"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Sichere HTTP-Header"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
# Bild einfügen (wenn verfügbar)
|
||||
if "security" in image_paths:
|
||||
security_img = add_image_to_slide(slide,
|
||||
image_paths["security"],
|
||||
Inches(7),
|
||||
Inches(2),
|
||||
Inches(5))
|
||||
|
||||
# ------------- FOLIE 10: ZUSAMMENFASSUNG -------------
|
||||
slide = prs.slides.add_slide(prs.slide_layouts[1])
|
||||
|
||||
# Hintergrund anpassen
|
||||
background = slide.background
|
||||
fill = background.fill
|
||||
fill.solid()
|
||||
fill.fore_color.rgb = BACKGROUND_COLOR
|
||||
|
||||
title = slide.shapes.title
|
||||
title.text = "Zusammenfassung"
|
||||
title_paragraph = title.text_frame.paragraphs[0]
|
||||
apply_text_style(title_paragraph, 44, bold=True, color=PRIMARY_COLOR, alignment=PP_ALIGN.LEFT)
|
||||
|
||||
# Inhalt
|
||||
content = slide.placeholders[1]
|
||||
tf = content.text_frame
|
||||
|
||||
p = tf.paragraphs[0]
|
||||
p.text = "• Vollständige Lösung für 3D-Drucker-Management"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.bold = True
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Modulare Architektur für einfache Erweiterbarkeit"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Robuste Sicherheitskonzepte"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = SECONDARY_COLOR
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Umfassendes Logging und Überwachung"
|
||||
apply_text_style(p, 28)
|
||||
|
||||
p = tf.add_paragraph()
|
||||
p.text = "• Automatisierung von Routineaufgaben"
|
||||
apply_text_style(p, 28)
|
||||
p.runs[0].font.color.rgb = ACCENT_COLOR
|
||||
|
||||
# Bild einfügen (wenn verfügbar)
|
||||
if "summary" in image_paths:
|
||||
summary_img = add_image_to_slide(slide,
|
||||
image_paths["summary"],
|
||||
Inches(7),
|
||||
Inches(2),
|
||||
Inches(5))
|
||||
|
||||
# Präsentation speichern
|
||||
prs.save(output_path)
|
||||
print(f"Verbesserte Präsentation wurde erstellt: {output_path}")
|
Binary file not shown.
Before Width: | Height: | Size: 92 KiB |
Binary file not shown.
Before Width: | Height: | Size: 191 KiB |
Binary file not shown.
Before Width: | Height: | Size: 182 KiB |
Binary file not shown.
Before Width: | Height: | Size: 416 KiB |
Binary file not shown.
Before Width: | Height: | Size: 193 KiB |
Binary file not shown.
Before Width: | Height: | Size: 252 KiB |
Reference in New Issue
Block a user