HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //workspace/rebuild_montessori.py
#!/usr/bin/env python3
"""Montessori-Dateien Rebuild Script"""

import os, glob, zipfile
from xml.etree import ElementTree as ET
from docx import Document
from docx.shared import Inches
from docx.enum.text import WD_ALIGN_PARAGRAPH
from pptx import Presentation
from pptx.util import Inches as PptxInches

IMG_DIR = "/mnt/onedrive_write/FOS_Deutsch_Lehrplanvergleich_2026/06_Bilder/"

IMAGE_MAP = {
    'AB2_Digitale-Texte_multiple-Dokumente_Montessori.docx': 'VK_Digitale-Texte_Illustration.png',
    'AB3_Konstruktives-Feedback_Montessori.docx': 'VK_Funktion1_Einstieg.png',
    'AB1_Social-Media-Phänomene_Montessori.docx': 'JG11_Social-Media_Illustration.png',
    'AB2_KI-gestütztes-Schreiben_Montessori.docx': 'JG11_Funktion1_Einstieg.png',
    'AB3_Podcasts-moderne-Medienformate_Montessori.docx': 'JG11_Podcast-Medien_Illustration.png',
    'AB1_Desinformation_erkennen_Montessori.docx': 'JG12_Medienmanipulation_Analyse.png',
    'AB2_Framing_Storytelling_Montessori.docx': 'JG12_Framing_Perspektiven.png',
    'AB3_KI_gestütztes_Schreiben_Montessori.docx': 'JG12_Funktion1_Einstieg.png',
    'AB1_Data_Bias_Montessori.docx': 'JG13_Data_Bias_Algorithmen.png',
    'AB2_Wissenschaftliches_Arbeiten_KI_Montessori.docx': 'JG13_Funktion1_Einstieg.png',
    'AB3_Mensch_vs_KI_Kreativitaet_Montessori.docx': 'JG13_Mensch_vs_KI_Kreativitaet.png',
}

PPTX_IMAGE_MAP = {
    'Arbeitsphasen_Vorklasse_KI-Schreiben_Montessori.pptx': 'VK_KI-Schreiben_Illustration.png',
    'Einführung_Vorklasse_Deutsch_2026_Montessori.pptx': 'VK_Digitale-Texte_Illustration.png',
    'Arbeitsphasen_Jahrgang11_Social-Media_Montessori.pptx': 'JG11_Social-Media_Illustration.png',
    'Einführung_Jahrgang11_Deutsch_2026_Montessori.pptx': 'JG11_Social-Media_Illustration.png',
    'Arbeitsphasen_Medienkompetenz_JG12_Montessori.pptx': 'JG12_Medienmanipulation_Analyse.png',
    'Einführung_Medienkompetenz_JG12_Montessori.pptx': 'JG12_Framing_Perspektiven.png',
    'Arbeitsphasen_KI_Kritik_Kreativitaet_JG13_Montessori.pptx': 'JG13_Mensch_vs_KI_Kreativitaet.png',
    'Einführung_KI_Medienkultur_JG13_Montessori.pptx': 'JG13_Data_Bias_Algorithmen.png',
}

def fix_umlauts(text):
    r = text
    for o,n in [('erschliessen','erschließen'),('Ergaenze','Ergänze'),('ergaenze','ergänze'),
                ('aendern','ändern'),('Aendern','Ändern'),('ueberarbeiten','überarbeiten'),
                ('Ueberarbeitung','Überarbeitung'),('fuer','für'),('Fuer','Für'),
                ('koennen','können'),('koennte','könnte'),('Koennte','Könnte'),
                ('koenntest','könntest'),('moechtest','möchtest'),('Moechtest','Möchtest'),
                ('fuenfmal','fünfmal'),('Schueler','Schüler'),('schueler','schüler'),
                ('Loesung','Lösung'),('loesung','lösung'),('Loesungen','Lösungen'),
                ('Vorschlaege','Vorschläge'),('Staerken','Stärken'),('Schwaechen','Schwächen'),
                ('verstaerken','verstärken'),('Verstaerkung','Verstärkung'),
                ('serios','seriös'),('Seriositaet','Seriosität'),('pruefe','prüfe'),
                ('Pruefe','Prüfe'),('pruefen','prüfen'),('Pruefung','Prüfung'),
                ('haeufigsten','häufigsten'),('Haeufigsten','Häufigsten'),('Saetze','Sätze'),
                ('saetze','sätze'),('regelmaessig','regelmäßig'),('Regelmaessigkeit','Regelmäßigkeit'),
                ('ueben','üben'),('Uebung','Übung'),('ueber','über'),('Ueber','Über'),
                ('Ueberblick','Überblick'),('Begriffsklaerung','Begriffsklärung'),
                ('Praesentation','Präsentation'),('Praesentieren','Präsentieren'),
                ('Aktivitaet','Aktivität'),('Qualitaet','Qualität'),('Kreativitaet','Kreativität'),
                ('Authentizitaet','Authentizität'),('Originalitaet','Originalität'),
                ('Aesthetisch','Ästhetisch'),('aesthetisch','ästhetisch'),
                ('Gefaehrlich','Gefährlich'),('gefaehrlich','gefährlich'),
                ('Leistungsschwaechere','Leistungsschwächere'),('Leistungsstaerkere','Leistungsstärkere'),
                ('Feedbackqualitaet','Feedbackqualität'),('Zusaetzliche','Zusätzliche'),
                ('zusaetzliche','zusätzliche'),('Faelle','Fälle'),('Unzulaessig','Unzulässig'),
                ('unzulaessig','unzulässig'),('Zulaessig','Zulässig'),('zulaessig','zulässig'),
                ('Begruendung','Begründung'),('begruenden','begründen'),('Begruende','Begründe'),
                ('begruende','begründe'),('Erorterung','Erörterung'),('Woertlich','Wörtlich'),
                ('woertlich','wörtlich'),('Unverandert','Unverändert'),('Uberarbeitung','Überarbeitung'),
                ('Ueberarbeitung','Überarbeitung'),('Wahle','Wähle'),('waehle','wähle'),
                ('Waehle','Wähle'),('Aehnliche','Ähnliche'),('aehnliche','ähnliche'),
                ('Strasse','Straße'),('strasse','straße'),('Strassen','Straßen'),
                ('strassen','straßen'),('Gross','Groß'),('gross','groß'),('Mass','Maß'),
                ('Massstab','Maßstab'),('Ausmass','Ausmaß'),('Gruessen','Grüßen'),
                ('Zeitunabhaengig','Zeitunabhängig'),('Durchfuehrung','Durchführung'),
                ('Fussnote','Fußnote'),('Angehoerige','Angehörige'),('Erklaerung','Erklärung'),
                ('erklaeren','erklären'),('erklaert','erklärt'),('Flaeche','Fläche'),
                ('flaeche','fläche'),('Baeume','Bäume'),('Baecker','Bäcker'),
                ('Naechste','Nächste'),('naechste','nächste'),('naechsten','nächsten'),
                ('Fruehling','Frühling'),('frueh','früh'),('Tuer','Tür'),
                ('Praegnanz','Prägnanz'),('Uebereinstimmung','Übereinstimmung'),
                ('Geraete','Geräte')]:
        r = r.replace(o,n)
    return r

def extract_docx_paragraphs(fp):
    ps = []
    try:
        with zipfile.ZipFile(fp,'r') as z:
            xml = z.read('word/document.xml')
            tree = ET.fromstring(xml)
            for p in tree.iter('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}p'):
                ts = [t.text for t in p.iter('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}t') if t.text]
                if ts: ps.append(''.join(ts))
    except Exception as e: print(f"  Fehler: {e}")
    return ps

def rebuild_docx(fp, img=None):
    ps = extract_docx_paragraphs(fp)
    doc = Document()
    embedded = False
    if ps:
        doc.add_heading(fix_umlauts(ps[0][:80]), level=1)
    if img and os.path.exists(img):
        try:
            p = doc.add_paragraph()
            r = p.add_run()
            r.add_picture(img, width=Inches(5.5))
            p.alignment = WD_ALIGN_PARAGRAPH.CENTER
            doc.add_paragraph()
            embedded = True
            print(f"  ✓ Bild: {os.path.basename(img)}")
        except Exception as e: print(f"  ✗ Bild-Fehler: {e}")
    skip = ['VK_Digitale-Texte_Illustration','VK_Funktion1_Einstieg','JG11_Social-Media_Illustration',
            'JG11_Funktion1_Einstieg','JG11_Podcast-Medien_Illustration','JG12_Medienmanipulation_Analyse',
            'JG12_Framing_Perspektiven','JG12_Funktion1_Einstieg','JG13_Data_Bias_Algorithmen',
            'JG13_Funktion1_Einstieg','JG13_Mensch_vs_KI_Kreativitaet']
    for i,para in enumerate(ps):
        if i==0 or '[Bild:' in para or para.strip() in skip or 'Illustration]' in para: continue
        f = fix_umlauts(para)
        if f.strip(): doc.add_paragraph(f)
    doc.save(fp)
    return embedded

def rebuild_pptx(fp, img=None):
    embedded = False
    try:
        prs = Presentation(fp)
        for s in prs.slides:
            for sh in s.shapes:
                if sh.has_text_frame:
                    for p in sh.text_frame.paragraphs:
                        for r in p.runs:
                            if r.text: r.text = fix_umlauts(r.text)
        if img and os.path.exists(img) and len(prs.slides)>0:
            try:
                sl = prs.slides[0]
                sl.shapes.add_picture(img, PptxInches(5.5), PptxInches(1.5), width=PptxInches(4.0))
                embedded = True
                print(f"  ✓ Bild: {os.path.basename(img)}")
            except Exception as e: print(f"  ✗ Bild-Fehler: {e}")
        prs.save(fp)
    except Exception as e: print(f"  ✗ Fehler: {e}")
    return embedded

if __name__ == "__main__":
    base = "/mnt/onedrive_write/FOS_Deutsch_Lehrplanvergleich_2026"
    print("="*60 + "\nMONTESORI REBUILD - DOCX\n" + "="*60)
    for fp in sorted(glob.glob(f"{base}/**/*_Montessori.docx", recursive=True)):
        fn = os.path.basename(fp)
        print(f"\n{fn}")
        img = IMAGE_MAP.get(fn)
        rebuild_docx(fp, os.path.join(IMG_DIR, img) if img else None)
        print("  ✓ Gespeichert")
    print("\n" + "="*60 + "\nMONTESORI REBUILD - PPTX\n" + "="*60)
    for fp in sorted(glob.glob(f"{base}/**/*_Montessori.pptx", recursive=True)):
        fn = os.path.basename(fp)
        print(f"\n{fn}")
        img = PPTX_IMAGE_MAP.get(fn)
        rebuild_pptx(fp, os.path.join(IMG_DIR, img) if img else None)
        print("  ✓ Gespeichert")
    print("\nFERTIG!")