#!/usr/bin/env python3 """ DSR Template Import Script Importiert DOCX-Vorlagen aus dem Datenschutz-Ordner und erstellt initiale Template-Versionen in der Datenbank. Verwendung: cd backend source venv/bin/activate python scripts/import_dsr_templates.py Voraussetzungen: pip install mammoth python-docx httpx """ import os import sys import re import asyncio from pathlib import Path from typing import Optional, Dict, List, Tuple # Third-party imports try: import mammoth import httpx except ImportError: print("Bitte installieren Sie die erforderlichen Pakete:") print(" pip install mammoth httpx") sys.exit(1) # Configuration CONSENT_SERVICE_URL = os.getenv("CONSENT_SERVICE_URL", "http://localhost:8081") DOCS_PATH = Path(__file__).parent.parent.parent / "docs" / "Datenschutz" # Mapping von DOCX-Dateien zu Template-Typen DOCX_TEMPLATE_MAPPING: Dict[str, Dict] = { # Eingangsbestätigungen "Muster_1_Eingangsbestätigung": { "template_type": "dsr_receipt_access", "name": "Eingangsbestätigung (Auskunft Art. 15)", "request_types": ["access"], }, # Identitätsprüfung "Muster_2_Anfrage Kontaktdaten": { "template_type": "dsr_identity_request", "name": "Anfrage Kontaktdaten zur Identifikation", "request_types": ["access", "rectification", "erasure", "restriction", "portability"], }, "Muster_2_Anfrage Identität": { "template_type": "dsr_identity_request", "name": "Anfrage Identitätsnachweis", "request_types": ["access", "rectification", "erasure", "restriction", "portability"], }, "Muster_3_Anfrage Identität": { "template_type": "dsr_identity_request", "name": "Anfrage Identitätsnachweis (erweitert)", "request_types": ["access", "rectification", "erasure", "restriction", "portability"], }, # Bearbeitungsbestätigungen "Muster_3_Bearbeitungsbestätigung": { "template_type": "dsr_processing_started", "name": "Bearbeitungsbestätigung", "request_types": ["access", "rectification", "erasure", "restriction", "portability"], }, "Muster_4_Bearbeitungsbestätigung": { "template_type": "dsr_processing_update", "name": "Bearbeitungsupdate", "request_types": ["access", "rectification", "erasure", "restriction", "portability"], }, # Rückfragen "Muster_4_Rückfragen Begehren": { "template_type": "dsr_clarification_request", "name": "Rückfragen zum Begehren", "request_types": ["access", "rectification", "erasure", "restriction", "portability"], }, "Muster_5_Rückfragen Umfang": { "template_type": "dsr_clarification_request", "name": "Rückfragen zum Umfang", "request_types": ["access"], }, # Abschluss - Auskunft "Muster_5_ Negativauskunft": { "template_type": "dsr_completed_access", "name": "Negativauskunft (keine Daten gefunden)", "request_types": ["access"], "variant": "no_data", }, "Muster_6_ Beauskunftung Art. 15": { "template_type": "dsr_completed_access", "name": "Beauskunftung nach Art. 15", "request_types": ["access"], }, # Abschluss - Berichtigung "Muster_4_Information Berichtigung": { "template_type": "dsr_completed_rectification", "name": "Information über durchgeführte Berichtigung", "request_types": ["rectification"], }, # Abschluss - Löschung "Muster_6_Information Löschung": { "template_type": "dsr_completed_erasure", "name": "Information über durchgeführte Löschung", "request_types": ["erasure"], }, # Abschluss - Datenübertragbarkeit "Muster_5_Information Übermittlung": { "template_type": "dsr_completed_portability", "name": "Information über Datenübermittlung", "request_types": ["portability"], }, # Drittübermittlung "Muster_4_Anfrage Drittübermittlung": { "template_type": "dsr_third_party_notification", "name": "Anfrage zur Drittübermittlung", "request_types": ["rectification", "erasure", "restriction"], }, } # Standard-Platzhalter-Mappings PLACEHOLDER_REPLACEMENTS = { # Antragsteller "[Name]": "{{requester_name}}", "[Vorname Name]": "{{requester_name}}", "[Anrede]": "{{requester_salutation}}", "[E-Mail]": "{{requester_email}}", "[Adresse]": "{{requester_address}}", # Anfrage "[Vorgangsnummer]": "{{request_number}}", "[Aktenzeichen]": "{{request_number}}", "[Datum des Eingangs]": "{{request_date}}", "[Eingangsdatum]": "{{request_date}}", "[Frist]": "{{deadline_date}}", "[Fristdatum]": "{{deadline_date}}", # Unternehmen "[Firmenname]": "{{company_name}}", "[Unternehmen]": "{{company_name}}", "[Unternehmensname]": "{{company_name}}", "[Firma]": "{{company_name}}", # DSB "[DSB Name]": "{{dpo_name}}", "[Name DSB]": "{{dpo_name}}", "[Datenschutzbeauftragter]": "{{dpo_name}}", "[E-Mail DSB]": "{{dpo_email}}", "[DSB E-Mail]": "{{dpo_email}}", # Sonstiges "[Datum]": "{{current_date}}", "[Portal-URL]": "{{portal_url}}", } def convert_docx_to_html(docx_path: Path) -> Tuple[str, List[str]]: """Konvertiert DOCX zu HTML mit mammoth.""" with open(docx_path, "rb") as f: result = mammoth.convert_to_html(f) html = result.value messages = [msg.message for msg in result.messages] # Bereinige HTML html = html.replace('
', '') html = re.sub(r'\s+', ' ', html) return html, messages def replace_placeholders(html: str) -> str: """Ersetzt Word-Platzhalter durch Template-Variablen.""" for placeholder, variable in PLACEHOLDER_REPLACEMENTS.items(): html = html.replace(placeholder, variable) # Suche nach nicht ersetzten Platzhaltern remaining = re.findall(r'\[([^\]]+)\]', html) if remaining: print(f" Warnung: Nicht ersetzte Platzhalter gefunden: {remaining}") return html def html_to_text(html: str) -> str: """Konvertiert HTML zu Plain-Text.""" # Entferne HTML-Tags text = re.sub(r'