feat(export): neutrale Export-Variante ohne Firmenbranding
Beim Bericht-Export lässt sich im Modal nun zwischen "Mit AegisSight-Branding" und "Ohne Firmen-Branding" wählen. Im neutralen Modus entfallen Logo, AegisSight-Zeile auf dem Deckblatt und Branding-Footer; die Datei-Metadaten werden neutralisiert. Das Deckblatt mit Titel, Stand und Ersteller bleibt erhalten. Betrifft PDF und DOCX. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dieser Commit ist enthalten in:
@@ -462,8 +462,12 @@ def _build_export_metadata(
|
||||
organization_name: str | None,
|
||||
top_locations: list[str] | None,
|
||||
snapshot_count: int = 0,
|
||||
include_branding: bool = True,
|
||||
) -> dict:
|
||||
"""Einheitlicher Metadaten-Dict fuer PDF (HTML-Meta-Tags) und DOCX (core_properties)."""
|
||||
"""Einheitlicher Metadaten-Dict fuer PDF (HTML-Meta-Tags) und DOCX (core_properties).
|
||||
|
||||
include_branding=False neutralisiert alle AegisSight-Firmenbezeichnungen (White-Label-Export).
|
||||
"""
|
||||
is_research = incident.get("type") == "research"
|
||||
type_label = "Hintergrundrecherche" if is_research else "Live-Monitoring"
|
||||
category = "OSINT-Hintergrundrecherche" if is_research else "OSINT-Lagebericht"
|
||||
@@ -546,23 +550,37 @@ def _build_export_metadata(
|
||||
comments_lines.append("Orte: " + ", ".join(top_locations[:5]))
|
||||
comments = "\n".join(comments_lines)
|
||||
|
||||
publisher = organization_name or "AegisSight"
|
||||
identifier = f"urn:aegissight:incident:{incident.get('id', '0')}:{now.strftime('%Y%m%dT%H%M%S')}"
|
||||
rights = (
|
||||
"Vertrauliche Lageanalyse — AegisSight Monitor. "
|
||||
"Weitergabe nur an autorisierte Empfänger."
|
||||
)
|
||||
# Branding-abhaengige Felder: bei include_branding=False neutralisiert (White-Label-Export)
|
||||
if include_branding:
|
||||
publisher = organization_name or "AegisSight"
|
||||
author = creator or "AegisSight Monitor"
|
||||
creator_app = "AegisSight Monitor"
|
||||
producer = "WeasyPrint + AegisSight Monitor"
|
||||
urn_ns = "aegissight"
|
||||
rights = (
|
||||
"Vertrauliche Lageanalyse — AegisSight Monitor. "
|
||||
"Weitergabe nur an autorisierte Empfänger."
|
||||
)
|
||||
else:
|
||||
publisher = organization_name or ""
|
||||
author = creator or "Unbekannt"
|
||||
creator_app = ""
|
||||
producer = "WeasyPrint"
|
||||
urn_ns = "report"
|
||||
rights = "Vertrauliche Lageanalyse. Weitergabe nur an autorisierte Empfänger."
|
||||
identifier = f"urn:{urn_ns}:incident:{incident.get('id', '0')}:{now.strftime('%Y%m%dT%H%M%S')}"
|
||||
|
||||
return {
|
||||
"title": title,
|
||||
"author": creator or "AegisSight Monitor",
|
||||
"author": author,
|
||||
"subject": subject,
|
||||
"keywords": unique_keywords,
|
||||
"keywords_comma": ", ".join(unique_keywords),
|
||||
"keywords_semicolon": "; ".join(unique_keywords),
|
||||
"category": category,
|
||||
"comments": comments,
|
||||
"creator_app": "AegisSight Monitor",
|
||||
"creator_app": creator_app,
|
||||
"producer": producer,
|
||||
"language": "de-DE",
|
||||
"created": created,
|
||||
"modified": modified,
|
||||
@@ -634,7 +652,7 @@ def _enrich_pdf_metadata(pdf_bytes: bytes, meta: dict) -> bytes:
|
||||
|
||||
# PDF Namespace
|
||||
xmp["pdf:Keywords"] = meta.get("keywords_comma", "")
|
||||
xmp["pdf:Producer"] = "WeasyPrint + AegisSight Monitor"
|
||||
xmp["pdf:Producer"] = meta.get("producer", "WeasyPrint + AegisSight Monitor")
|
||||
|
||||
# XMP Namespace
|
||||
xmp["xmp:CreatorTool"] = meta.get("creator_app", "AegisSight Monitor")
|
||||
@@ -681,6 +699,7 @@ async def generate_pdf(
|
||||
organization_name: str | None = None,
|
||||
top_locations: list[str] | None = None,
|
||||
snapshot_count: int = 0,
|
||||
include_branding: bool = True,
|
||||
) -> bytes:
|
||||
"""PDF-Report via WeasyPrint generieren."""
|
||||
# Sections aus scope ableiten wenn nicht explizit angegeben
|
||||
@@ -713,6 +732,7 @@ async def generate_pdf(
|
||||
meta = _build_export_metadata(
|
||||
incident, articles, fact_checks, all_sources, creator, scope, sections,
|
||||
organization_name, top_locations, snapshot_count=snapshot_count,
|
||||
include_branding=include_branding,
|
||||
)
|
||||
|
||||
env = Environment(loader=FileSystemLoader(str(TEMPLATE_DIR)))
|
||||
@@ -741,6 +761,7 @@ async def generate_pdf(
|
||||
timeline=_prepare_timeline(articles) if scope == "full" else [],
|
||||
articles=articles if scope == "full" else [],
|
||||
meta=meta,
|
||||
include_branding=include_branding,
|
||||
)
|
||||
|
||||
# Artikel pub_date aufbereiten
|
||||
@@ -764,6 +785,7 @@ async def generate_docx(
|
||||
organization_name: str | None = None,
|
||||
top_locations: list[str] | None = None,
|
||||
snapshot_count: int = 0,
|
||||
include_branding: bool = True,
|
||||
) -> bytes:
|
||||
"""Word-Report via python-docx generieren."""
|
||||
doc = Document()
|
||||
@@ -795,6 +817,7 @@ async def generate_docx(
|
||||
meta = _build_export_metadata(
|
||||
incident, articles, fact_checks, all_sources, creator, scope, sections,
|
||||
organization_name, top_locations, snapshot_count=snapshot_count,
|
||||
include_branding=include_branding,
|
||||
)
|
||||
|
||||
# Dateimetadaten setzen (sichtbar in Explorer/Finder, DMS-Systemen)
|
||||
@@ -823,13 +846,15 @@ async def generate_docx(
|
||||
for _ in range(6):
|
||||
doc.add_paragraph()
|
||||
|
||||
title_para = doc.add_paragraph()
|
||||
title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
run = title_para.add_run("AegisSight Monitor")
|
||||
run.font.size = Pt(12)
|
||||
run.font.color.rgb = RGBColor(0x0a, 0x18, 0x32)
|
||||
# Firmenname-Zeile nur im gebrandeten Export
|
||||
if include_branding:
|
||||
title_para = doc.add_paragraph()
|
||||
title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
run = title_para.add_run("AegisSight Monitor")
|
||||
run.font.size = Pt(12)
|
||||
run.font.color.rgb = RGBColor(0x0a, 0x18, 0x32)
|
||||
|
||||
doc.add_paragraph()
|
||||
doc.add_paragraph()
|
||||
|
||||
type_label = "Hintergrundrecherche" if incident.get("type") == "research" else "Live-Monitoring"
|
||||
type_para = doc.add_paragraph()
|
||||
@@ -978,7 +1003,11 @@ async def generate_docx(
|
||||
doc.add_paragraph()
|
||||
footer = doc.add_paragraph()
|
||||
footer.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||||
run = footer.add_run(f"Erstellt mit AegisSight Monitor — aegis-sight.de — {now.strftime('%d.%m.%Y')}")
|
||||
if include_branding:
|
||||
footer_text = f"Erstellt mit AegisSight Monitor — aegis-sight.de — {now.strftime('%d.%m.%Y')}"
|
||||
else:
|
||||
footer_text = f"Stand: {now.strftime('%d.%m.%Y')}"
|
||||
run = footer.add_run(footer_text)
|
||||
run.font.size = Pt(8)
|
||||
run.font.color.rgb = RGBColor(0x0a, 0x18, 0x32)
|
||||
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren