Build: Vollständige Windows-Distribution-Infrastruktur
Implementiert ein professionelles Build-System für Windows-Benutzer ohne Python-Installation: PyInstaller-Integration: - DocuMentor.spec mit automatischer Icon/Version-Einbindung - Unterstützung für alle PySide6-UI-Dateien und Dependencies - UPX-Kompression für kleinere Executable-Größe Icon-System: - create_icon.py generiert Standard-Icon oder konvertiert PNG zu ICO - Multi-Size ICO (16x16 bis 256x256) für alle Windows-Kontexte - Automatische Integration in Build-Prozess - Prompts für Bild-KIs (Gemini, DALL-E, etc.) Versionsinformationen: - create_version_info.py liest Version aus pyproject.toml - Windows-Datei-Eigenschaften (Rechtsklick → Details) - Automatische Generierung bei jedem Build Build-Automatisierung: - build_windows.py orchestriert gesamten Build-Prozess - Erstellt Icon und Versionsinformationen automatisch - Generiert ZIP-Archiv für Distribution - Cleanup alter Builds Inno Setup-Integration: - installer.iss für professionelle Setup.exe - GUID-Generator (generate_guid.py) - Desktop-Verknüpfungen und Start-Menü-Integration Dokumentation: - BUILD.md - Schnellstart-Anleitung - docs/windows_distribution.md - Detaillierte Distribution-Dokumentation - docs/icon_and_version_info.md - Icon- und Versions-System - resources/icon_prompt.md - KI-Prompts für Icon-Generierung Dependencies: - pyinstaller>=6.0.0 für Executable-Erstellung - pillow>=10.0.0 für Icon-Generierung Externe Abhängigkeiten (Java, FOP, Saxon, diff-pdf) bleiben separat installierbar. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
+164
@@ -0,0 +1,164 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Icon-Generator für DocuMentor
|
||||
|
||||
Erstellt ein Icon aus einem PNG oder generiert ein Standard-Icon.
|
||||
Unterstützt Windows (.ico) und verschiedene Größen.
|
||||
|
||||
Verwendung:
|
||||
python create_icon.py # Generiert Standard-Icon
|
||||
python create_icon.py source.png # Konvertiert PNG zu ICO
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
except ImportError:
|
||||
print("Fehler: Pillow ist nicht installiert.")
|
||||
print("Installation: uv pip install pillow")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def create_default_icon(output_path: Path):
|
||||
"""Erstellt ein Standard-Icon mit DocuMentor-Branding."""
|
||||
sizes = [256, 128, 64, 48, 32, 16]
|
||||
images = []
|
||||
|
||||
for size in sizes:
|
||||
# Neues Bild erstellen mit Farbverlauf
|
||||
img = Image.new('RGB', (size, size), color='white')
|
||||
draw = ImageDraw.Draw(img)
|
||||
|
||||
# Hintergrund: Blau-Verlauf (vereinfacht als solides Blau)
|
||||
bg_color = (41, 128, 185) # Professionelles Blau
|
||||
draw.rectangle([0, 0, size, size], fill=bg_color)
|
||||
|
||||
# Dokument-Symbol (vereinfachte Darstellung)
|
||||
margin = size // 8
|
||||
doc_left = margin
|
||||
doc_top = margin
|
||||
doc_right = size - margin
|
||||
doc_bottom = size - margin
|
||||
|
||||
# Weißes Dokument
|
||||
draw.rectangle(
|
||||
[doc_left, doc_top, doc_right, doc_bottom],
|
||||
fill='white',
|
||||
outline=(52, 73, 94),
|
||||
width=max(1, size // 64)
|
||||
)
|
||||
|
||||
# Ecke umgeknickt (rechts oben)
|
||||
fold_size = size // 6
|
||||
points = [
|
||||
(doc_right - fold_size, doc_top),
|
||||
(doc_right, doc_top + fold_size),
|
||||
(doc_right - fold_size, doc_top + fold_size),
|
||||
]
|
||||
draw.polygon(points, fill=(220, 220, 220), outline=(52, 73, 94))
|
||||
|
||||
# Text-Linien im Dokument (nur bei größeren Icons)
|
||||
if size >= 32:
|
||||
line_margin = doc_left + size // 12
|
||||
line_width = doc_right - doc_left - size // 6
|
||||
line_count = min(3, size // 32)
|
||||
line_spacing = (doc_bottom - doc_top - fold_size) // (line_count + 2)
|
||||
|
||||
for i in range(line_count):
|
||||
y = doc_top + fold_size + line_spacing * (i + 1)
|
||||
draw.rectangle(
|
||||
[line_margin, y, line_margin + line_width, y + max(1, size // 128)],
|
||||
fill=(52, 73, 94)
|
||||
)
|
||||
|
||||
# "M" für Mentor (nur bei großen Icons)
|
||||
if size >= 64:
|
||||
try:
|
||||
# Versuche System-Font zu verwenden
|
||||
font_size = size // 4
|
||||
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", font_size)
|
||||
except:
|
||||
# Fallback auf Default-Font
|
||||
font = ImageFont.load_default()
|
||||
|
||||
text = "M"
|
||||
# Zentrieren (grobe Schätzung)
|
||||
bbox = draw.textbbox((0, 0), text, font=font)
|
||||
text_width = bbox[2] - bbox[0]
|
||||
text_height = bbox[3] - bbox[1]
|
||||
text_x = (size - text_width) // 2
|
||||
text_y = doc_bottom - text_height - margin // 2
|
||||
|
||||
draw.text((text_x, text_y), text, fill=bg_color, font=font)
|
||||
|
||||
images.append(img)
|
||||
|
||||
# Als ICO speichern
|
||||
images[0].save(
|
||||
output_path,
|
||||
format='ICO',
|
||||
sizes=[(img.width, img.height) for img in images],
|
||||
append_images=images[1:]
|
||||
)
|
||||
print(f"✓ Standard-Icon erstellt: {output_path}")
|
||||
|
||||
|
||||
def convert_png_to_ico(source_path: Path, output_path: Path):
|
||||
"""Konvertiert ein PNG-Bild zu einem Multi-Size ICO."""
|
||||
try:
|
||||
img = Image.open(source_path)
|
||||
|
||||
# Zu RGBA konvertieren falls nötig
|
||||
if img.mode != 'RGBA':
|
||||
img = img.convert('RGBA')
|
||||
|
||||
# Verschiedene Größen erstellen
|
||||
sizes = [256, 128, 64, 48, 32, 16]
|
||||
images = []
|
||||
|
||||
for size in sizes:
|
||||
resized = img.resize((size, size), Image.Resampling.LANCZOS)
|
||||
images.append(resized)
|
||||
|
||||
# Als ICO speichern
|
||||
images[0].save(
|
||||
output_path,
|
||||
format='ICO',
|
||||
sizes=[(img.width, img.height) for img in images],
|
||||
append_images=images[1:]
|
||||
)
|
||||
print(f"✓ Icon erstellt aus {source_path.name}: {output_path}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"✗ Fehler beim Konvertieren: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
project_root = Path(__file__).parent
|
||||
resources_dir = project_root / "resources"
|
||||
resources_dir.mkdir(exist_ok=True)
|
||||
|
||||
output_ico = resources_dir / "icon.ico"
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
# PNG zu ICO konvertieren
|
||||
source_path = Path(sys.argv[1])
|
||||
if not source_path.exists():
|
||||
print(f"Fehler: Datei nicht gefunden: {source_path}")
|
||||
sys.exit(1)
|
||||
|
||||
convert_png_to_ico(source_path, output_ico)
|
||||
else:
|
||||
# Standard-Icon generieren
|
||||
print("Erstelle Standard-Icon...")
|
||||
create_default_icon(output_ico)
|
||||
|
||||
print(f"\nIcon gespeichert: {output_ico}")
|
||||
print("Das Icon wird automatisch von PyInstaller und Inno Setup verwendet.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user