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:
@@ -6,5 +6,14 @@ dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# PyInstaller
|
||||
*.spec.bak
|
||||
*.manifest
|
||||
*.log
|
||||
version_info.txt
|
||||
|
||||
# Generierte Icons (optional - entfernen falls Icons versioniert werden sollen)
|
||||
# resources/icon.ico
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
# DocuMentor Build-Anleitung
|
||||
|
||||
## Schnellstart: Windows-Distribution erstellen
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
```bash
|
||||
# Dependencies installieren (inkl. Pillow für Icon-Generierung)
|
||||
uv sync --all-groups
|
||||
```
|
||||
|
||||
### Build ausführen
|
||||
|
||||
```bash
|
||||
# Automatischer Build (empfohlen)
|
||||
uv run python build_windows.py
|
||||
```
|
||||
|
||||
Dies erstellt automatisch:
|
||||
1. **Icon** (falls nicht vorhanden): `resources/icon.ico`
|
||||
2. **Versionsinformationen**: `version_info.txt`
|
||||
3. **Executable**: `dist/DocuMentor/DocuMentor.exe` (mit Icon und Versionsinformationen)
|
||||
4. **ZIP-Archiv**: `dist/DocuMentor-YYYYMMDD-Windows.zip`
|
||||
|
||||
### Icon anpassen (optional)
|
||||
|
||||
```bash
|
||||
# Standard-Icon generieren
|
||||
uv run python create_icon.py
|
||||
|
||||
# Oder eigenes PNG-Icon konvertieren
|
||||
uv run python create_icon.py mein-logo.png
|
||||
```
|
||||
|
||||
### Manuelle Build-Schritte
|
||||
|
||||
```bash
|
||||
# 1. Cleanup
|
||||
rm -rf build/ dist/
|
||||
|
||||
# 2. PyInstaller ausführen
|
||||
uv run pyinstaller --clean DocuMentor.spec
|
||||
|
||||
# 3. Testen
|
||||
# Auf Windows: dist/DocuMentor/DocuMentor.exe
|
||||
# Mit Wine: wine dist/DocuMentor/DocuMentor.exe
|
||||
```
|
||||
|
||||
## Setup.exe erstellen (optional)
|
||||
|
||||
### Mit Inno Setup
|
||||
|
||||
1. **Inno Setup installieren**: https://jrsoftware.org/isdl.php
|
||||
|
||||
2. **GUID generieren** für `installer.iss` (nur beim ersten Mal!):
|
||||
```bash
|
||||
uv run python generate_guid.py
|
||||
```
|
||||
|
||||
Kopiere die generierte GUID und füge sie in `installer.iss` bei `AppId` ein (Zeile ~22).
|
||||
|
||||
**WICHTIG**: Die GUID nur EINMAL generieren! Bei Updates dieselbe GUID verwenden.
|
||||
|
||||
3. **Windows-Build erstellen**:
|
||||
```bash
|
||||
uv run python build_windows.py
|
||||
```
|
||||
|
||||
Dies erstellt automatisch das Icon und kopiert es nach `dist/DocuMentor/`.
|
||||
|
||||
4. **Installer kompilieren**:
|
||||
```bash
|
||||
iscc installer.iss
|
||||
```
|
||||
|
||||
5. **Ergebnis**:
|
||||
- `dist/installer/DocuMentor-Setup-0.1.0.exe` (mit Icon und Versionsinformationen)
|
||||
|
||||
## MSI erstellen (optional)
|
||||
|
||||
Mit WiX Toolset - noch zu implementieren.
|
||||
|
||||
## Konfiguration anpassen
|
||||
|
||||
### Icon anpassen
|
||||
|
||||
**Option 1: Standard-Icon generieren**
|
||||
```bash
|
||||
uv run python create_icon.py
|
||||
```
|
||||
|
||||
**Option 2: Eigenes Icon aus PNG erstellen**
|
||||
```bash
|
||||
uv run python create_icon.py ihr-logo.png
|
||||
```
|
||||
|
||||
**Option 3: Manuell ICO-Datei platzieren**
|
||||
1. Icon erstellen oder downloaden (`.ico` Format mit mehreren Größen)
|
||||
2. Als `resources/icon.ico` speichern
|
||||
3. Beim nächsten Build wird es automatisch verwendet
|
||||
|
||||
Das Icon wird automatisch verwendet für:
|
||||
- Windows-Executable (DocuMentor.exe)
|
||||
- Inno Setup Installer
|
||||
- Desktop-Verknüpfungen
|
||||
|
||||
**Anforderungen:**
|
||||
- Multi-Size ICO (16x16 bis 256x256 Pixel)
|
||||
- Das `create_icon.py` Skript erstellt alle Größen automatisch
|
||||
|
||||
### Versionsinformationen
|
||||
|
||||
**Automatische Generierung:**
|
||||
|
||||
Versionsinformationen werden automatisch aus `pyproject.toml` generiert:
|
||||
|
||||
```bash
|
||||
uv run python create_version_info.py
|
||||
```
|
||||
|
||||
Dies liest die Version aus `pyproject.toml` und erstellt `version_info.txt`.
|
||||
|
||||
**Version ändern:**
|
||||
|
||||
In `pyproject.toml`:
|
||||
```toml
|
||||
version = "0.2.0"
|
||||
```
|
||||
|
||||
Auch aktualisieren in:
|
||||
- `installer.iss` (Zeile 13: `#define MyAppVersion`)
|
||||
|
||||
Dann Versionsinformationen neu generieren:
|
||||
```bash
|
||||
uv run python create_version_info.py
|
||||
```
|
||||
|
||||
**Was enthalten die Versionsinformationen:**
|
||||
- Dateiversion und Produktversion
|
||||
- Beschreibung und Copyright
|
||||
- Anwendungsname
|
||||
- Wird in Windows Explorer angezeigt (Rechtsklick → Eigenschaften → Details)
|
||||
|
||||
### Build-Größe reduzieren
|
||||
|
||||
In `DocuMentor.spec` Module ausschließen:
|
||||
```python
|
||||
excludes=[
|
||||
'tkinter',
|
||||
'matplotlib',
|
||||
'test',
|
||||
'unittest',
|
||||
],
|
||||
```
|
||||
|
||||
### One-File Build (alles in einer .exe)
|
||||
|
||||
In `DocuMentor.spec` ändern:
|
||||
```python
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries, # Uncomment
|
||||
a.zipfiles, # Uncomment
|
||||
a.datas, # Uncomment
|
||||
[], # Comment out
|
||||
exclude_binaries=False, # Ändern
|
||||
# ...
|
||||
name='DocuMentor',
|
||||
onefile=True, # Hinzufügen
|
||||
)
|
||||
|
||||
# COLLECT auskommentieren oder entfernen
|
||||
```
|
||||
|
||||
**Achtung**: One-File ist langsamer beim Start (3-5 Sekunden).
|
||||
|
||||
## Testing
|
||||
|
||||
### Lokales Testing
|
||||
|
||||
```bash
|
||||
# Build erstellen
|
||||
uv run python build_windows.py
|
||||
|
||||
# Mit Wine testen (Linux/WSL)
|
||||
wine dist/DocuMentor/DocuMentor.exe
|
||||
```
|
||||
|
||||
### Testing auf Windows
|
||||
|
||||
1. ZIP-Datei auf Windows-System kopieren
|
||||
2. Entpacken
|
||||
3. `DocuMentor.exe` starten
|
||||
4. Features testen:
|
||||
- [ ] Programmstart
|
||||
- [ ] Einstellungsdialog öffnet beim ersten Start
|
||||
- [ ] Projekt öffnen/erstellen
|
||||
- [ ] Tree-Navigation
|
||||
- [ ] XSL/XML-Dateien hinzufügen
|
||||
- [ ] PDF-Generierung (mit konfigurierten Tools)
|
||||
- [ ] PDF-Vergleich
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Module not found" beim Start
|
||||
|
||||
**Lösung**: Hidden imports in `DocuMentor.spec` ergänzen:
|
||||
```python
|
||||
hiddenimports=[
|
||||
'missing.module',
|
||||
]
|
||||
```
|
||||
|
||||
### Antivirus blockiert die .exe
|
||||
|
||||
**Ursache**: Unsigned executables werden oft als verdächtig eingestuft.
|
||||
|
||||
**Lösungen**:
|
||||
1. Code-Signing-Zertifikat kaufen und verwenden
|
||||
2. Bei Microsoft SmartScreen einreichen
|
||||
3. Exception in Antivirus eintragen (für Tests)
|
||||
|
||||
### Executable ist zu groß (>200 MB)
|
||||
|
||||
**Lösungen**:
|
||||
1. UPX-Kompression ist bereits aktiv
|
||||
2. Ungenutzte Module excluden (siehe oben)
|
||||
3. Virtual Environment aufräumen: `uv sync --no-dev`
|
||||
|
||||
### UI-Dateien nicht gefunden
|
||||
|
||||
**Problem**: `.ui` Dateien werden nicht gefunden.
|
||||
|
||||
**Lösung**: In `DocuMentor.spec` prüfen:
|
||||
```python
|
||||
datas=ui_files, # Muss gesetzt sein
|
||||
```
|
||||
|
||||
## Automatisierung
|
||||
|
||||
### GitHub Actions (CI/CD)
|
||||
|
||||
Siehe `docs/windows_distribution.md` für vollständiges Beispiel.
|
||||
|
||||
### Lokales Release-Skript
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# release.sh - Erstellt vollständiges Release
|
||||
|
||||
VERSION="0.1.0"
|
||||
|
||||
echo "Building DocuMentor v$VERSION..."
|
||||
|
||||
# 1. Build
|
||||
uv run python build_windows.py
|
||||
|
||||
# 2. Installer (falls Inno Setup installiert)
|
||||
if command -v iscc &> /dev/null; then
|
||||
iscc installer.iss
|
||||
echo "✓ Installer erstellt"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Release v$VERSION fertig!"
|
||||
echo " • ZIP: dist/DocuMentor-*-Windows.zip"
|
||||
echo " • Setup: dist/installer/DocuMentor-Setup-$VERSION.exe"
|
||||
```
|
||||
|
||||
## Distribution
|
||||
|
||||
### ZIP-Archiv
|
||||
|
||||
**Vorteile:**
|
||||
- Einfach, portable
|
||||
- Keine Installation nötig
|
||||
- USB-Stick-fähig
|
||||
|
||||
**Verwendung:**
|
||||
- Auf GitHub Releases hochladen
|
||||
- Per E-Mail versenden
|
||||
- Auf Webserver bereitstellen
|
||||
|
||||
### Setup.exe
|
||||
|
||||
**Vorteile:**
|
||||
- Professionell
|
||||
- Start-Menü-Integration
|
||||
- Deinstallation
|
||||
|
||||
**Verwendung:**
|
||||
- Primäre Distributions-Methode
|
||||
- Auf Website zum Download anbieten
|
||||
|
||||
## Dokumentation für Endbenutzer
|
||||
|
||||
Die `dist/DocuMentor/README.txt` wird automatisch erstellt und enthält:
|
||||
- Installationsanweisungen
|
||||
- Liste der externen Abhängigkeiten
|
||||
- Konfigurationshinweise
|
||||
|
||||
## Weitere Informationen
|
||||
|
||||
Siehe `docs/windows_distribution.md` für detaillierte Dokumentation.
|
||||
@@ -0,0 +1,79 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
"""
|
||||
PyInstaller Konfiguration für DocuMentor
|
||||
Erstellt eine eigenständige Windows-Executable ohne Python-Installation
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
block_cipher = None
|
||||
|
||||
# Projektpfad
|
||||
project_root = Path(SPECPATH)
|
||||
src_path = project_root / 'src'
|
||||
|
||||
# Alle UI-Dateien sammeln
|
||||
ui_files = []
|
||||
for ui_file in (src_path / 'ui').glob('*.ui'):
|
||||
ui_files.append((str(ui_file), 'ui'))
|
||||
|
||||
a = Analysis(
|
||||
[str(src_path / 'main.py')],
|
||||
pathex=[str(src_path)],
|
||||
binaries=[],
|
||||
datas=ui_files, # UI-Dateien einbinden
|
||||
hiddenimports=[
|
||||
'PySide6.QtCore',
|
||||
'PySide6.QtGui',
|
||||
'PySide6.QtWidgets',
|
||||
'pydantic',
|
||||
'pydantic_settings',
|
||||
'pydantic_yaml',
|
||||
'polars',
|
||||
'pyarrow',
|
||||
'connectorx',
|
||||
'pyqtdarktheme',
|
||||
],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
[],
|
||||
exclude_binaries=True,
|
||||
name='DocuMentor',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
console=False, # Keine Konsole anzeigen (GUI-Anwendung)
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
icon=str(project_root / 'resources' / 'icon.ico') if (project_root / 'resources' / 'icon.ico').exists() else None,
|
||||
version=str(project_root / 'version_info.txt') if (project_root / 'version_info.txt').exists() else None,
|
||||
)
|
||||
|
||||
coll = COLLECT(
|
||||
exe,
|
||||
a.binaries,
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
name='DocuMentor',
|
||||
)
|
||||
@@ -0,0 +1,141 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Build-Skript für Windows-Distribution von DocuMentor
|
||||
|
||||
Erstellt:
|
||||
1. Eigenständige Executable mit PyInstaller
|
||||
2. Optional: ZIP-Archiv für portable Distribution
|
||||
"""
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
def main():
|
||||
project_root = Path(__file__).parent
|
||||
dist_dir = project_root / "dist"
|
||||
build_dir = project_root / "build"
|
||||
resources_dir = project_root / "resources"
|
||||
icon_path = resources_dir / "icon.ico"
|
||||
version_info_path = project_root / "version_info.txt"
|
||||
|
||||
print("=" * 60)
|
||||
print("DocuMentor Windows Build")
|
||||
print("=" * 60)
|
||||
|
||||
# 1. Icon und Versionsinformationen generieren
|
||||
print("\n[1/6] Icon und Versionsinformationen generieren...")
|
||||
|
||||
# Icon erstellen falls nicht vorhanden
|
||||
if not icon_path.exists():
|
||||
print(" Erstelle Standard-Icon...")
|
||||
try:
|
||||
subprocess.run([sys.executable, "create_icon.py"], check=True, cwd=project_root)
|
||||
print(" ✓ Icon erstellt")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f" ✗ Icon-Erstellung fehlgeschlagen: {e}")
|
||||
print(" ⚠ Fahre ohne Icon fort...")
|
||||
else:
|
||||
print(f" ✓ Icon vorhanden: {icon_path.name}")
|
||||
|
||||
# Versionsinformationen erstellen
|
||||
print(" Erstelle Versionsinformationen...")
|
||||
try:
|
||||
subprocess.run([sys.executable, "create_version_info.py"], check=True, cwd=project_root)
|
||||
print(" ✓ Versionsinformationen erstellt")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f" ✗ Versionsinformationen-Erstellung fehlgeschlagen: {e}")
|
||||
print(" ⚠ Fahre ohne Versionsinformationen fort...")
|
||||
|
||||
# 2. Cleanup alter Builds
|
||||
print("\n[2/6] Cleanup alter Builds...")
|
||||
if dist_dir.exists():
|
||||
shutil.rmtree(dist_dir)
|
||||
print(" ✓ dist/ gelöscht")
|
||||
if build_dir.exists():
|
||||
shutil.rmtree(build_dir)
|
||||
print(" ✓ build/ gelöscht")
|
||||
|
||||
# 3. PyInstaller ausführen
|
||||
print("\n[3/6] PyInstaller Build starten...")
|
||||
try:
|
||||
subprocess.run(
|
||||
["pyinstaller", "--clean", "DocuMentor.spec"],
|
||||
check=True,
|
||||
cwd=project_root
|
||||
)
|
||||
print(" ✓ Build erfolgreich")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f" ✗ Build fehlgeschlagen: {e}")
|
||||
return 1
|
||||
|
||||
# 4. README für Distribution erstellen
|
||||
print("\n[4/6] README erstellen...")
|
||||
readme_content = """DocuMentor - XSL-Transformations-Verwaltung
|
||||
============================================
|
||||
|
||||
Installation:
|
||||
1. Entpacken Sie dieses Archiv in ein Verzeichnis Ihrer Wahl
|
||||
2. Führen Sie DocuMentor.exe aus
|
||||
|
||||
Externe Abhängigkeiten (separat zu installieren):
|
||||
- Java Runtime Environment (JRE) oder JDK
|
||||
- Apache FOP (für PDF-Generierung)
|
||||
- Saxon XSLT-Prozessor (JAR-Datei)
|
||||
- diff-pdf (für PDF-Vergleiche)
|
||||
|
||||
Beim ersten Start werden Sie aufgefordert, die Pfade zu diesen
|
||||
Tools in den Programmeinstellungen zu konfigurieren.
|
||||
|
||||
Konfiguration und Logs:
|
||||
- Windows: %APPDATA%\\DocuMentor\\
|
||||
- Konfiguration: config.json
|
||||
- Logs: logs\\
|
||||
|
||||
Support:
|
||||
Bei Fragen oder Problemen erstellen Sie bitte ein Issue auf GitHub.
|
||||
"""
|
||||
|
||||
readme_path = dist_dir / "DocuMentor" / "README.txt"
|
||||
readme_path.write_text(readme_content, encoding='utf-8')
|
||||
print(" ✓ README.txt erstellt")
|
||||
|
||||
# 5. Icon ins dist-Verzeichnis kopieren (für Installer)
|
||||
print("\n[5/6] Icon für Installer vorbereiten...")
|
||||
if icon_path.exists():
|
||||
dist_icon = dist_dir / "DocuMentor" / "icon.ico"
|
||||
shutil.copy2(icon_path, dist_icon)
|
||||
print(" ✓ Icon kopiert")
|
||||
else:
|
||||
print(" ⚠ Kein Icon vorhanden")
|
||||
|
||||
# 6. ZIP-Archiv erstellen
|
||||
print("\n[6/6] ZIP-Archiv erstellen...")
|
||||
timestamp = datetime.now().strftime("%Y%m%d")
|
||||
zip_name = f"DocuMentor-{timestamp}-Windows"
|
||||
zip_path = dist_dir / zip_name
|
||||
|
||||
shutil.make_archive(
|
||||
str(zip_path),
|
||||
'zip',
|
||||
dist_dir,
|
||||
'DocuMentor'
|
||||
)
|
||||
print(f" ✓ {zip_name}.zip erstellt")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Build abgeschlossen!")
|
||||
print("=" * 60)
|
||||
print(f"\nErgebnisse:")
|
||||
print(f" • Executable: dist/DocuMentor/DocuMentor.exe")
|
||||
print(f" • ZIP-Archiv: dist/{zip_name}.zip")
|
||||
print("\nNächste Schritte:")
|
||||
print(" 1. Testen Sie DocuMentor.exe auf einem Windows-System")
|
||||
print(" 2. Optional: Erstellen Sie einen Installer mit Inno Setup")
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
+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()
|
||||
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Generiert Windows-Versionsinformationen für PyInstaller
|
||||
|
||||
Liest Version aus pyproject.toml und erstellt version_info.txt
|
||||
"""
|
||||
|
||||
import tomllib
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def parse_version(version_str: str) -> tuple[int, int, int, int]:
|
||||
"""Parst Version-String (z.B. '0.1.0') zu Tuple (0, 1, 0, 0)."""
|
||||
parts = version_str.split('.')
|
||||
major = int(parts[0]) if len(parts) > 0 else 0
|
||||
minor = int(parts[1]) if len(parts) > 1 else 0
|
||||
patch = int(parts[2]) if len(parts) > 2 else 0
|
||||
build = 0 # Könnte aus Git-Commit-Count generiert werden
|
||||
return (major, minor, patch, build)
|
||||
|
||||
|
||||
def create_version_info(project_root: Path):
|
||||
"""Erstellt version_info.txt für PyInstaller."""
|
||||
|
||||
# pyproject.toml lesen
|
||||
pyproject_path = project_root / "pyproject.toml"
|
||||
with open(pyproject_path, 'rb') as f:
|
||||
pyproject = tomllib.load(f)
|
||||
|
||||
project = pyproject['project']
|
||||
version = project['version']
|
||||
name = project['name']
|
||||
description = project['description']
|
||||
|
||||
# Version parsen
|
||||
file_version = parse_version(version)
|
||||
product_version = file_version
|
||||
|
||||
# Jahr für Copyright
|
||||
year = datetime.now().year
|
||||
|
||||
# version_info.txt Content
|
||||
version_info_content = f"""# UTF-8
|
||||
#
|
||||
# Generiert automatisch von create_version_info.py
|
||||
# NICHT manuell bearbeiten!
|
||||
#
|
||||
|
||||
VSVersionInfo(
|
||||
ffi=FixedFileInfo(
|
||||
# filevers und prodvers als Tuple: (1, 0, 0, 0)
|
||||
filevers={file_version},
|
||||
prodvers={product_version},
|
||||
# Maske für gültige Bits in filevers und prodvers
|
||||
mask=0x3f,
|
||||
# Flags - kann VS_FF_DEBUG, VS_FF_PRERELEASE, etc. enthalten
|
||||
flags=0x0,
|
||||
# Betriebssystem - VOS_NT_WINDOWS32
|
||||
OS=0x40004,
|
||||
# Dateityp - VFT_APP (Anwendung)
|
||||
fileType=0x1,
|
||||
# Subtyp (nicht verwendet für VFT_APP)
|
||||
subtype=0x0,
|
||||
# Datumsstempel
|
||||
date=(0, 0)
|
||||
),
|
||||
kids=[
|
||||
StringFileInfo(
|
||||
[
|
||||
StringTable(
|
||||
'040904B0', # Deutsch (0x0409 = Englisch, 0x0407 = Deutsch), Unicode
|
||||
[StringStruct('CompanyName', 'Ihr Name/Organisation'),
|
||||
StringStruct('FileDescription', '{description}'),
|
||||
StringStruct('FileVersion', '{version}'),
|
||||
StringStruct('InternalName', '{name}'),
|
||||
StringStruct('LegalCopyright', '© {year} Ihr Name. Alle Rechte vorbehalten.'),
|
||||
StringStruct('OriginalFilename', '{name}.exe'),
|
||||
StringStruct('ProductName', '{name}'),
|
||||
StringStruct('ProductVersion', '{version}')])
|
||||
]),
|
||||
VarFileInfo([VarStruct('Translation', [1033, 1200])]) # Englisch, Unicode
|
||||
]
|
||||
)
|
||||
"""
|
||||
|
||||
# version_info.txt schreiben
|
||||
version_info_path = project_root / "version_info.txt"
|
||||
version_info_path.write_text(version_info_content, encoding='utf-8')
|
||||
|
||||
print(f"✓ version_info.txt erstellt")
|
||||
print(f" Version: {version}")
|
||||
print(f" Datei: {version_info_path}")
|
||||
|
||||
|
||||
def main():
|
||||
project_root = Path(__file__).parent
|
||||
create_version_info(project_root)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,274 @@
|
||||
# Icon und Versionsinformationen für Windows-Build
|
||||
|
||||
## Übersicht
|
||||
|
||||
DocuMentor unterstützt professionelle Windows-Builds mit:
|
||||
- **Anwendungs-Icon** in allen benötigten Größen
|
||||
- **Windows-Versionsinformationen** (Datei-Eigenschaften)
|
||||
- Automatische Integration in Build-Prozess
|
||||
|
||||
## Icon-System
|
||||
|
||||
### Automatische Icon-Generierung
|
||||
|
||||
Das Build-Skript generiert automatisch ein Standard-Icon, falls keins vorhanden ist:
|
||||
|
||||
```bash
|
||||
uv run python build_windows.py
|
||||
```
|
||||
|
||||
Falls `resources/icon.ico` nicht existiert, wird automatisch ein Standard-Icon mit DocuMentor-Branding erstellt.
|
||||
|
||||
### Manuelles Icon erstellen
|
||||
|
||||
#### Option 1: Standard-Icon
|
||||
|
||||
```bash
|
||||
uv run python create_icon.py
|
||||
```
|
||||
|
||||
Erstellt ein einfaches Icon mit:
|
||||
- Blauem Hintergrund (professionelles Blau: #2980B9)
|
||||
- Weißem Dokument-Symbol
|
||||
- "M" für Mentor (bei großen Icons)
|
||||
- Umgeknickter Ecke
|
||||
- Mehreren Größen (16×16 bis 256×256)
|
||||
|
||||
#### Option 2: Aus eigenem PNG
|
||||
|
||||
```bash
|
||||
uv run python create_icon.py mein-logo.png
|
||||
```
|
||||
|
||||
Konvertiert ein PNG-Bild zu einem Multi-Size Windows-Icon:
|
||||
- Unterstützt Transparenz
|
||||
- Erstellt alle benötigten Größen
|
||||
- Optimiert für verschiedene Bildschirmauflösungen
|
||||
|
||||
**PNG-Anforderungen:**
|
||||
- Idealerweise 256×256 Pixel oder größer
|
||||
- Quadratisches Format
|
||||
- PNG oder JPEG Format
|
||||
- Transparenter Hintergrund empfohlen
|
||||
|
||||
### Icon-Größen
|
||||
|
||||
Das ICO-Format enthält folgende Auflösungen:
|
||||
|
||||
| Größe | Verwendung |
|
||||
|---------|--------------------------------------|
|
||||
| 256×256 | Windows 7+, Taskleiste, große Icons |
|
||||
| 128×128 | Windows 7+, große Icons |
|
||||
| 64×64 | Hohe DPI-Displays |
|
||||
| 48×48 | Standard Desktop-Icon |
|
||||
| 32×32 | Explorer Details-Ansicht |
|
||||
| 16×16 | Kleinstes Icon, Titelleiste |
|
||||
|
||||
### Wo wird das Icon verwendet?
|
||||
|
||||
- **DocuMentor.exe** - Anwendungs-Icon
|
||||
- **Setup.exe** - Installer-Icon (Inno Setup)
|
||||
- **Desktop-Verknüpfung** - Erstellt beim Installieren
|
||||
- **Start-Menü** - Windows-Programmgruppe
|
||||
- **Taskleiste** - Beim Ausführen
|
||||
- **Deinstallations-Programm** - System-Einstellungen
|
||||
|
||||
## Versionsinformationen
|
||||
|
||||
### Automatische Generierung
|
||||
|
||||
Versionsinformationen werden automatisch vom Build-Skript generiert:
|
||||
|
||||
```bash
|
||||
uv run python build_windows.py
|
||||
```
|
||||
|
||||
### Manuelle Generierung
|
||||
|
||||
```bash
|
||||
uv run python create_version_info.py
|
||||
```
|
||||
|
||||
### Inhalt der Versionsinformationen
|
||||
|
||||
Die `version_info.txt` enthält:
|
||||
|
||||
```
|
||||
FileVersion: 0.1.0.0
|
||||
ProductVersion: 0.1.0.0
|
||||
CompanyName: Ihr Name/Organisation
|
||||
FileDescription: Professionelle XSL-Transformations-Verwaltung und PDF-Generierung
|
||||
InternalName: DocuMentor
|
||||
LegalCopyright: © 2026 Ihr Name. Alle Rechte vorbehalten.
|
||||
OriginalFilename: DocuMentor.exe
|
||||
ProductName: DocuMentor
|
||||
```
|
||||
|
||||
### Version aus pyproject.toml
|
||||
|
||||
Die Version wird automatisch aus `pyproject.toml` gelesen:
|
||||
|
||||
```toml
|
||||
[project]
|
||||
name = "DocuMentor"
|
||||
version = "0.1.0"
|
||||
description = "Professionelle XSL-Transformations-Verwaltung und PDF-Generierung"
|
||||
```
|
||||
|
||||
### Version ändern
|
||||
|
||||
**Schritt 1:** Version in `pyproject.toml` ändern:
|
||||
|
||||
```toml
|
||||
version = "0.2.0"
|
||||
```
|
||||
|
||||
**Schritt 2:** Version in `installer.iss` ändern (Zeile 13):
|
||||
|
||||
```iss
|
||||
#define MyAppVersion "0.2.0"
|
||||
```
|
||||
|
||||
**Schritt 3:** Build neu ausführen:
|
||||
|
||||
```bash
|
||||
uv run python build_windows.py
|
||||
```
|
||||
|
||||
Die Versionsinformationen werden automatisch neu generiert.
|
||||
|
||||
### Versionsnummern-Schema
|
||||
|
||||
DocuMentor verwendet [Semantic Versioning](https://semver.org/lang/de/):
|
||||
|
||||
```
|
||||
MAJOR.MINOR.PATCH
|
||||
|
||||
0.1.0 → Erste Beta-Version
|
||||
1.0.0 → Erste stabile Version
|
||||
1.1.0 → Neue Features
|
||||
1.1.1 → Bugfixes
|
||||
2.0.0 → Breaking Changes
|
||||
```
|
||||
|
||||
### Windows-Eigenschaften anzeigen
|
||||
|
||||
Nach dem Build können Sie die Versionsinformationen in Windows anzeigen:
|
||||
|
||||
1. Rechtsklick auf `DocuMentor.exe`
|
||||
2. **Eigenschaften** auswählen
|
||||
3. Tab **Details** öffnen
|
||||
|
||||
Dort sehen Sie:
|
||||
- Dateiversion
|
||||
- Produktversion
|
||||
- Beschreibung
|
||||
- Copyright
|
||||
- Produktname
|
||||
- Original-Dateiname
|
||||
|
||||
## Integration in Build-Prozess
|
||||
|
||||
### DocuMentor.spec
|
||||
|
||||
```python
|
||||
exe = EXE(
|
||||
# ...
|
||||
icon=str(project_root / 'resources' / 'icon.ico') if (project_root / 'resources' / 'icon.ico').exists() else None,
|
||||
version=str(project_root / 'version_info.txt') if (project_root / 'version_info.txt').exists() else None,
|
||||
)
|
||||
```
|
||||
|
||||
**Automatische Erkennung:**
|
||||
- Icon wird verwendet, falls vorhanden
|
||||
- Versionsinformationen werden verwendet, falls vorhanden
|
||||
- Build funktioniert auch ohne Icon/Version (mit Warnung)
|
||||
|
||||
### installer.iss
|
||||
|
||||
```iss
|
||||
SetupIconFile=dist\DocuMentor\icon.ico
|
||||
UninstallDisplayIcon={app}\DocuMentor.exe
|
||||
```
|
||||
|
||||
Das Icon wird automatisch vom `build_windows.py` nach `dist/DocuMentor/` kopiert.
|
||||
|
||||
## Anpassungen
|
||||
|
||||
### Company Name / Copyright
|
||||
|
||||
In `create_version_info.py` (Zeile ~65):
|
||||
|
||||
```python
|
||||
StringStruct('CompanyName', 'Ihr Name/Organisation'),
|
||||
StringStruct('LegalCopyright', '© {year} Ihr Name. Alle Rechte vorbehalten.'),
|
||||
```
|
||||
|
||||
Ändern Sie "Ihr Name/Organisation" auf Ihren tatsächlichen Namen oder Firmennamen.
|
||||
|
||||
### Icon-Design
|
||||
|
||||
Falls Sie das Standard-Icon anpassen möchten, bearbeiten Sie `create_icon.py`:
|
||||
|
||||
**Farben ändern** (Zeile ~31):
|
||||
```python
|
||||
bg_color = (41, 128, 185) # Blau - ändern Sie RGB-Werte
|
||||
```
|
||||
|
||||
**Symbol ändern:**
|
||||
- Bearbeiten Sie die `create_default_icon()` Funktion
|
||||
- Oder erstellen Sie Ihr eigenes Icon in einem Grafikprogramm
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Icon-Design
|
||||
|
||||
1. **Einfach und klar**: Funktioniert auch bei 16×16 Pixel
|
||||
2. **Hoher Kontrast**: Gut lesbar auf hellem und dunklem Hintergrund
|
||||
3. **Professionell**: Passend zum Business-Kontext
|
||||
4. **Wiedererkennbar**: Symbolisiert die Anwendung
|
||||
|
||||
### Versionierung
|
||||
|
||||
1. **Semantische Versionierung**: MAJOR.MINOR.PATCH
|
||||
2. **Vor jedem Release aktualisieren**
|
||||
3. **Git-Tags verwenden**: `git tag v0.1.0`
|
||||
4. **GUID beibehalten**: Nie die Inno Setup GUID ändern bei Updates!
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Icon wird nicht angezeigt
|
||||
|
||||
**Problem**: DocuMentor.exe zeigt kein Icon
|
||||
|
||||
**Lösungen:**
|
||||
1. Prüfen ob `resources/icon.ico` existiert
|
||||
2. Build neu ausführen: `uv run python build_windows.py`
|
||||
3. Windows Icon-Cache löschen und neu starten
|
||||
|
||||
### Versionsinformationen fehlen
|
||||
|
||||
**Problem**: Eigenschaften → Details zeigt keine Informationen
|
||||
|
||||
**Lösungen:**
|
||||
1. Prüfen ob `version_info.txt` existiert
|
||||
2. `uv run python create_version_info.py` ausführen
|
||||
3. Build neu ausführen
|
||||
|
||||
### Pillow-Fehler beim Icon-Erstellen
|
||||
|
||||
**Problem**: `ImportError: No module named 'PIL'`
|
||||
|
||||
**Lösung:**
|
||||
```bash
|
||||
uv sync --all-groups
|
||||
```
|
||||
|
||||
Dies installiert Pillow automatisch.
|
||||
|
||||
## Weiterführende Informationen
|
||||
|
||||
- **PyInstaller Icon-Dokumentation**: https://pyinstaller.org/en/stable/usage.html#icons
|
||||
- **Windows ICO Format**: https://en.wikipedia.org/wiki/ICO_(file_format)
|
||||
- **Semantic Versioning**: https://semver.org/lang/de/
|
||||
- **Pillow Dokumentation**: https://pillow.readthedocs.io/
|
||||
@@ -0,0 +1,291 @@
|
||||
# Windows Distribution Guide für DocuMentor
|
||||
|
||||
## Überblick
|
||||
|
||||
Dieses Dokument beschreibt, wie DocuMentor für Windows-Benutzer ohne Python-Installation verpackt wird.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
### Auf dem Entwicklungssystem
|
||||
|
||||
```bash
|
||||
# Dependencies installieren (inkl. PyInstaller)
|
||||
uv sync --all-groups
|
||||
```
|
||||
|
||||
### Für Setup.exe (optional)
|
||||
|
||||
- **Inno Setup**: Download von https://jrsoftware.org/isdl.php
|
||||
- Oder **WiX Toolset** für MSI: https://wixtoolset.org/
|
||||
|
||||
## Build-Prozess
|
||||
|
||||
### Option 1: Einfacher Build (ZIP-Distribution)
|
||||
|
||||
```bash
|
||||
# 1. PyInstaller installieren
|
||||
uv sync --all-groups
|
||||
|
||||
# 2. Build ausführen
|
||||
uv run python build_windows.py
|
||||
```
|
||||
|
||||
Dies erstellt:
|
||||
- `dist/DocuMentor/DocuMentor.exe` - Eigenständige Executable
|
||||
- `dist/DocuMentor-YYYYMMDD-Windows.zip` - Portable ZIP-Archiv
|
||||
|
||||
### Option 2: Professionelle Setup.exe mit Inno Setup
|
||||
|
||||
```bash
|
||||
# 1. PyInstaller Build
|
||||
uv run python build_windows.py
|
||||
|
||||
# 2. Inno Setup Compiler ausführen
|
||||
iscc installer.iss
|
||||
```
|
||||
|
||||
Dies erstellt:
|
||||
- `dist/installer/DocuMentor-Setup-0.1.0.exe` - Professioneller Installer
|
||||
|
||||
### Option 3: MSI-Installer mit WiX
|
||||
|
||||
```bash
|
||||
# TODO: WiX-Konfiguration noch zu erstellen
|
||||
```
|
||||
|
||||
## Manuelle Schritte
|
||||
|
||||
### 1. PyInstaller direkt verwenden
|
||||
|
||||
```bash
|
||||
# Cleanup
|
||||
rm -rf build/ dist/
|
||||
|
||||
# Build
|
||||
uv run pyinstaller --clean DocuMentor.spec
|
||||
|
||||
# Testen
|
||||
dist/DocuMentor/DocuMentor.exe
|
||||
```
|
||||
|
||||
### 2. Anpassungen vornehmen
|
||||
|
||||
**Icon hinzufügen:**
|
||||
1. Icon-Datei (`.ico`) im Projekt speichern, z.B. `resources/icon.ico`
|
||||
2. In `DocuMentor.spec` anpassen:
|
||||
```python
|
||||
icon='resources/icon.ico'
|
||||
```
|
||||
|
||||
**Versionsinformationen:**
|
||||
In `DocuMentor.spec` erweitern:
|
||||
```python
|
||||
exe = EXE(
|
||||
# ...
|
||||
version='version_info.txt', # Windows-Versionsinformationen
|
||||
)
|
||||
```
|
||||
|
||||
## PyInstaller .spec Konfiguration
|
||||
|
||||
Die Datei `DocuMentor.spec` enthält:
|
||||
|
||||
- **datas**: UI-Dateien (.ui) werden mitgepackt
|
||||
- **hiddenimports**: Alle notwendigen PySide6/Polars-Module
|
||||
- **console=False**: GUI-Anwendung ohne Konsole
|
||||
- **upx=True**: Kompression der Binaries
|
||||
|
||||
### Wichtige Einstellungen
|
||||
|
||||
```python
|
||||
# Ein-Datei-Build (alles in einer .exe)
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries, # Diese Zeilen
|
||||
a.zipfiles, # auskommentieren
|
||||
a.datas, # für One-File
|
||||
# ...
|
||||
onefile=True, # Hinzufügen
|
||||
)
|
||||
```
|
||||
|
||||
**Achtung**: One-File-Build ist langsamer beim Start, da alles temporär entpackt werden muss.
|
||||
|
||||
## Distribution
|
||||
|
||||
### ZIP-Archive
|
||||
|
||||
```bash
|
||||
# Automatisch durch build_windows.py erstellt
|
||||
dist/DocuMentor-YYYYMMDD-Windows.zip
|
||||
```
|
||||
|
||||
**Vorteile:**
|
||||
- Einfach, portable
|
||||
- Keine Installation nötig
|
||||
- Kann auf USB-Stick verwendet werden
|
||||
|
||||
**Nachteile:**
|
||||
- Keine Deinstallationsroutine
|
||||
- Keine Verknüpfungen
|
||||
- Keine Registry-Einträge
|
||||
|
||||
### Setup.exe mit Inno Setup
|
||||
|
||||
**Vorteile:**
|
||||
- Professionell
|
||||
- Deinstallation integriert
|
||||
- Start-Menü und Desktop-Icons
|
||||
- Update-Mechanismus möglich
|
||||
|
||||
**Nachteile:**
|
||||
- Benötigt Administrator-Rechte (optional)
|
||||
- Komplexere Konfiguration
|
||||
|
||||
### MSI-Installer
|
||||
|
||||
**Vorteile:**
|
||||
- Windows-Standard
|
||||
- Gruppen-Richtlinien-fähig
|
||||
- Silent Installation möglich
|
||||
|
||||
**Nachteile:**
|
||||
- Komplexe Erstellung
|
||||
- Benötigt WiX Toolset
|
||||
|
||||
## Externe Abhängigkeiten
|
||||
|
||||
DocuMentor benötigt diese Tools (NICHT im Installer enthalten):
|
||||
|
||||
1. **Java Runtime Environment (JRE) 11+**
|
||||
- Für Saxon und Apache FOP
|
||||
- Download: https://adoptium.net/
|
||||
|
||||
2. **Apache FOP**
|
||||
- XSL-FO zu PDF Konvertierung
|
||||
- Download: https://xmlgraphics.apache.org/fop/
|
||||
|
||||
3. **Saxon XSLT Prozessor**
|
||||
- XSLT 2.0/3.0 Transformationen
|
||||
- Download: https://www.saxonica.com/
|
||||
|
||||
4. **diff-pdf**
|
||||
- PDF-Vergleich
|
||||
- Download: https://vslavik.github.io/diff-pdf/
|
||||
|
||||
### Benutzer-Anleitung
|
||||
|
||||
Nach der Installation:
|
||||
|
||||
1. DocuMentor starten
|
||||
2. Beim ersten Start öffnet sich automatisch die Einstellungen
|
||||
3. Pfade zu Java, Saxon, FOP und diff-pdf konfigurieren
|
||||
4. Projekt-Verzeichnis wählen oder neues Projekt erstellen
|
||||
|
||||
## Testing
|
||||
|
||||
### Lokales Testing (Linux/WSL)
|
||||
|
||||
```bash
|
||||
# Build für Windows erstellen
|
||||
uv run python build_windows.py
|
||||
|
||||
# Executable mit Wine testen (falls verfügbar)
|
||||
wine dist/DocuMentor/DocuMentor.exe
|
||||
```
|
||||
|
||||
### Testing auf Windows
|
||||
|
||||
1. ZIP auf Windows-System kopieren
|
||||
2. Entpacken
|
||||
3. `DocuMentor.exe` ausführen
|
||||
4. Alle Features testen:
|
||||
- Projekt öffnen/erstellen
|
||||
- Tree-Navigation
|
||||
- PDF-Generierung
|
||||
- Einstellungen
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Problem: "Module not found" Fehler
|
||||
|
||||
**Lösung**: Hidden imports in `DocuMentor.spec` ergänzen:
|
||||
```python
|
||||
hiddenimports=[
|
||||
# ... existing
|
||||
'missing_module',
|
||||
]
|
||||
```
|
||||
|
||||
### Problem: UI-Dateien nicht gefunden
|
||||
|
||||
**Lösung**: Prüfen ob datas korrekt konfiguriert:
|
||||
```python
|
||||
datas=[
|
||||
('src/ui/*.ui', 'ui'),
|
||||
]
|
||||
```
|
||||
|
||||
### Problem: Executable zu groß
|
||||
|
||||
**Lösungen**:
|
||||
1. UPX-Kompression aktivieren (bereits aktiv)
|
||||
2. Excludes hinzufügen für ungenutzte Module:
|
||||
```python
|
||||
excludes=['tkinter', 'matplotlib', 'test', 'unittest']
|
||||
```
|
||||
3. One-File-Build verwenden (langsamer Start)
|
||||
|
||||
### Problem: Antivirus blockiert
|
||||
|
||||
**Lösung**:
|
||||
- Code-Signing-Zertifikat verwenden
|
||||
- Bei Microsoft einreichen für SmartScreen
|
||||
- README mit Hinweis erweitern
|
||||
|
||||
## Automatisierung mit CI/CD
|
||||
|
||||
### GitHub Actions Beispiel
|
||||
|
||||
```yaml
|
||||
name: Build Windows Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v1
|
||||
|
||||
- name: Build
|
||||
run: uv run python build_windows.py
|
||||
|
||||
- name: Create Release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: dist/*.zip
|
||||
```
|
||||
|
||||
## Versionierung
|
||||
|
||||
Version in folgenden Dateien aktualisieren:
|
||||
1. `pyproject.toml` - `version = "X.Y.Z"`
|
||||
2. `installer.iss` - `#define MyAppVersion "X.Y.Z"`
|
||||
3. Optional: `src/version.py` erstellen
|
||||
|
||||
## Lizenz und Rechtliches
|
||||
|
||||
- Alle Python-Dependencies sind in der Distribution enthalten
|
||||
- PySide6 (LGPL): Dynamische Verlinkung ist OK
|
||||
- Polars (MIT): Unproblematisch
|
||||
- Pydantic (MIT): Unproblematisch
|
||||
|
||||
Externe Tools (Saxon, FOP) haben eigene Lizenzen und müssen separat installiert werden.
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
GUID-Generator für Inno Setup
|
||||
|
||||
Generiert eine eindeutige GUID für die AppId in installer.iss
|
||||
"""
|
||||
|
||||
import uuid
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
# GUID generieren
|
||||
guid = uuid.uuid4()
|
||||
guid_str = f"{{{{{str(guid).upper()}}}}}"
|
||||
|
||||
print("=" * 60)
|
||||
print("GUID für Inno Setup AppId")
|
||||
print("=" * 60)
|
||||
print()
|
||||
print("Generierte GUID:")
|
||||
print(f" {guid_str}")
|
||||
print()
|
||||
print("Anleitung:")
|
||||
print("1. Kopieren Sie die GUID oben")
|
||||
print("2. Öffnen Sie installer.iss")
|
||||
print("3. Suchen Sie nach 'AppId={{' (Zeile ~22)")
|
||||
print("4. Ersetzen Sie die Beispiel-GUID mit Ihrer neuen GUID")
|
||||
print()
|
||||
print("Beispiel:")
|
||||
print(f" AppId={guid_str}")
|
||||
print()
|
||||
print("WICHTIG:")
|
||||
print("- Die GUID sollte nur EINMAL beim ersten Setup generiert werden")
|
||||
print("- Ändern Sie die GUID NICHT bei Updates, sonst wird die App")
|
||||
print(" als separate Anwendung installiert!")
|
||||
print("=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,73 @@
|
||||
; Inno Setup Konfiguration für DocuMentor
|
||||
; Erstellt eine professionelle Setup.exe für Windows
|
||||
;
|
||||
; Installation von Inno Setup: https://jrsoftware.org/isdl.php
|
||||
;
|
||||
; WICHTIG: Vor dem ersten Build GUID generieren!
|
||||
; python -c "import uuid; print(f'{{{{' + str(uuid.uuid4()).upper() + '}}}}')"
|
||||
; Ergebnis in AppId unten einfügen
|
||||
;
|
||||
; Build-Befehl: iscc installer.iss
|
||||
|
||||
#define MyAppName "DocuMentor"
|
||||
#define MyAppVersion "0.1.0"
|
||||
#define MyAppPublisher "Ihr Name/Organisation"
|
||||
#define MyAppURL "https://github.com/yourusername/xsl-validator"
|
||||
#define MyAppExeName "DocuMentor.exe"
|
||||
|
||||
[Setup]
|
||||
; Basis-Informationen
|
||||
; WICHTIG: Ersetzen Sie die GUID mit einer eigenen generierten GUID!
|
||||
; AppId={{BEISPIEL-GUID-HIER-EINFÜGEN}}
|
||||
AppId={{A1B2C3D4-E5F6-4789-ABCD-EF0123456789}}
|
||||
AppName={#MyAppName}
|
||||
AppVersion={#MyAppVersion}
|
||||
AppPublisher={#MyAppPublisher}
|
||||
AppPublisherURL={#MyAppURL}
|
||||
AppSupportURL={#MyAppURL}
|
||||
AppUpdatesURL={#MyAppURL}
|
||||
|
||||
; Installation
|
||||
DefaultDirName={autopf}\{#MyAppName}
|
||||
DefaultGroupName={#MyAppName}
|
||||
AllowNoIcons=yes
|
||||
|
||||
; Output
|
||||
OutputDir=dist\installer
|
||||
OutputBaseFilename=DocuMentor-Setup-{#MyAppVersion}
|
||||
SetupIconFile=dist\DocuMentor\icon.ico
|
||||
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||
|
||||
; Kompression
|
||||
Compression=lzma
|
||||
SolidCompression=yes
|
||||
|
||||
; Moderne UI
|
||||
WizardStyle=modern
|
||||
|
||||
; Rechte (normal für User-Installation, admin für System-weite Installation)
|
||||
PrivilegesRequired=lowest
|
||||
PrivilegesRequiredOverridesAllowed=dialog
|
||||
|
||||
[Languages]
|
||||
Name: "german"; MessagesFile: "compiler:Languages\German.isl"
|
||||
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||
|
||||
[Tasks]
|
||||
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||
|
||||
[Files]
|
||||
; Alle Dateien aus dem PyInstaller-Build
|
||||
Source: "dist\DocuMentor\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||
|
||||
[Icons]
|
||||
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||
Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}"
|
||||
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||
|
||||
[Run]
|
||||
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||
|
||||
[Messages]
|
||||
; Deutsche Anpassungen
|
||||
german.WelcomeLabel2=Dies wird [name/ver] auf Ihrem Computer installieren.%n%nBitte stellen Sie sicher, dass folgende externe Tools installiert sind:%n• Java Runtime Environment (JRE)%n• Apache FOP%n• Saxon XSLT-Prozessor%n• diff-pdf
|
||||
@@ -26,4 +26,6 @@ extend-exclude = ["*_ui.py"]
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"ruff>=0.14.8",
|
||||
"pyinstaller>=6.0.0",
|
||||
"pillow>=10.0.0",
|
||||
]
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 678 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 819 KiB |
@@ -0,0 +1,64 @@
|
||||
# Resources für DocuMentor
|
||||
|
||||
Dieses Verzeichnis enthält Ressourcen für den Windows-Build.
|
||||
|
||||
## Icon (icon.ico)
|
||||
|
||||
Das Icon wird verwendet für:
|
||||
- Windows-Executable (DocuMentor.exe)
|
||||
- Inno Setup Installer
|
||||
- Desktop-Verknüpfungen
|
||||
- Start-Menü-Einträge
|
||||
|
||||
### Icon erstellen
|
||||
|
||||
#### Automatisch (Standard-Icon):
|
||||
```bash
|
||||
python create_icon.py
|
||||
```
|
||||
|
||||
Dies erstellt ein einfaches Standard-Icon mit DocuMentor-Branding.
|
||||
|
||||
#### Aus eigenem PNG-Bild:
|
||||
```bash
|
||||
python create_icon.py mein-icon.png
|
||||
```
|
||||
|
||||
Ihr PNG sollte idealerweise:
|
||||
- Mindestens 256x256 Pixel groß sein
|
||||
- Quadratisch sein
|
||||
- Transparenten Hintergrund haben (optional)
|
||||
|
||||
### Icon-Anforderungen
|
||||
|
||||
Das `.ico`-Dateiformat enthält mehrere Auflösungen:
|
||||
- 256x256 (Windows 7+, Taskleiste)
|
||||
- 128x128
|
||||
- 64x64
|
||||
- 48x48 (Standard Desktop-Icon)
|
||||
- 32x32 (Explorer Details)
|
||||
- 16x16 (kleines Icon)
|
||||
|
||||
Das `create_icon.py` Skript erstellt automatisch alle diese Größen.
|
||||
|
||||
## Icon manuell ersetzen
|
||||
|
||||
1. Eigenes Icon als `resources/icon.ico` speichern
|
||||
2. Oder mit einem Online-Tool PNG→ICO konvertieren
|
||||
3. Build-Skript verwendet automatisch die vorhandene Datei
|
||||
|
||||
## Design-Richtlinien
|
||||
|
||||
Falls Sie ein eigenes Icon erstellen:
|
||||
- **Einfach und klar**: Funktioniert auch in kleinen Größen (16x16)
|
||||
- **Professionell**: Passend zum Business-Kontext
|
||||
- **Wiedererkennbar**: DocuMentor steht für Dokumenten-Management
|
||||
- **Kontrast**: Gut sichtbar auf hellem und dunklem Hintergrund
|
||||
|
||||
## Weitere Ressourcen
|
||||
|
||||
In diesem Verzeichnis können später weitere Ressourcen abgelegt werden:
|
||||
- Splash-Screen-Bilder
|
||||
- Toolbar-Icons
|
||||
- Dokumentations-Bilder
|
||||
- etc.
|
||||
@@ -0,0 +1,45 @@
|
||||
Erstelle ein professionelles Icon für eine Desktop-Anwendung namens "DocuMentor".
|
||||
|
||||
Die Anwendung wird verwendet für:
|
||||
- Verwaltung von XSL-Transformationen
|
||||
- Umwandlung von XML-Dokumenten zu PDF-Dateien
|
||||
- Vergleich und Validierung von PDF-Dokumenten
|
||||
|
||||
Design-Anforderungen:
|
||||
|
||||
1. Stil: Minimalistisch, modern, professionell, business-orientiert
|
||||
|
||||
2. Farben:
|
||||
- Hauptfarbe: Blau (#2980B9 oder ähnlich)
|
||||
- Akzentfarbe: Weiß oder helles Grau
|
||||
- Maximal 2-3 Farben insgesamt
|
||||
|
||||
3. Elemente (wähle eine Kombination):
|
||||
- Dokument-Symbol (Papier/Seite)
|
||||
- Transformation/Workflow-Element (Pfeil, Zahnrad)
|
||||
- Optional: Stilisierter Buchstabe "M" oder "D"
|
||||
|
||||
4. Technische Anforderungen:
|
||||
- Quadratisches Format
|
||||
- Einfache, klare Linien
|
||||
- Hoher Kontrast
|
||||
- Muss auch bei 16x16 Pixel noch erkennbar sein
|
||||
- Flat Design (keine 3D-Effekte)
|
||||
- Keine Farbverläufe
|
||||
|
||||
5. Hintergrund:
|
||||
- Transparent ODER
|
||||
- Einfarbig (blau oder weiß)
|
||||
|
||||
6. Referenz-Stil:
|
||||
- Ähnlich wie Microsoft Office Icons
|
||||
- Ähnlich wie Visual Studio Code Icons
|
||||
- Moderne SaaS-Anwendungs-Icons
|
||||
|
||||
Bitte erstelle ein Icon, das:
|
||||
- Professionell und vertrauenswürdig wirkt
|
||||
- Für technische Anwender geeignet ist
|
||||
- Gut in einer Windows-Taskleiste aussieht
|
||||
- Auch als Desktop-Verknüpfung funktioniert
|
||||
|
||||
Format: PNG oder SVG, mindestens 512x512 Pixel
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1,150 @@
|
||||
# Icon-Prompt für Bild-Generierungs-KI
|
||||
|
||||
## DocuMentor Logo/Icon
|
||||
|
||||
### Deutsche Version (für deutsche KI-Tools)
|
||||
|
||||
```
|
||||
Erstelle ein professionelles, minimalistisches SVG-Icon für eine Business-Software namens "DocuMentor".
|
||||
|
||||
Anwendungsbeschreibung:
|
||||
DocuMentor ist eine Desktop-Anwendung zur Verwaltung und Validierung von XSL-Transformationen. Die Software wird von technischen Redakteuren und Entwicklern verwendet, um XML-Dokumente in PDF-Dateien zu transformieren und diese zu vergleichen.
|
||||
|
||||
Design-Anforderungen:
|
||||
- Stil: Professionell, modern, technisch, business-orientiert
|
||||
- Farben: Blaue Töne (z.B. #2980B9, #3498DB) kombiniert mit neutralen Grautönen oder Weiß
|
||||
- Elemente: Kombination aus Dokumenten-Symbol und Transformations-/Workflow-Elementen
|
||||
- Einfachheit: Muss auch in sehr kleinen Größen (16x16 Pixel) erkennbar sein
|
||||
- Klare Linien und hoher Kontrast
|
||||
|
||||
Symbolik-Vorschläge:
|
||||
- Ein Dokument mit Transformations-Pfeilen
|
||||
- Gestapelte/verschachtelte Dokumente (XML → XSLT → PDF)
|
||||
- Stilisiertes "D" oder "M" für DocuMentor
|
||||
- Workflow-Diagramm mit Dokumenten-Symbolen
|
||||
- Dokument mit Zahnrad (Verarbeitung/Transformation)
|
||||
|
||||
Format: Vektorgrafik (SVG), quadratisch (1:1 Verhältnis), 512x512 Pixel oder größer
|
||||
Hintergrund: Transparent oder einfarbig (blau/weiß)
|
||||
|
||||
Stil-Referenzen: Microsoft Office Icons, Adobe Creative Cloud Icons, moderne SaaS-Anwendungen
|
||||
```
|
||||
|
||||
### Englische Version (für internationale KI-Tools wie DALL-E, Midjourney, Stable Diffusion)
|
||||
|
||||
```
|
||||
Create a professional, minimalist SVG icon for business software called "DocuMentor".
|
||||
|
||||
Application Description:
|
||||
DocuMentor is a desktop application for managing and validating XSL transformations. The software is used by technical writers and developers to transform XML documents into PDF files and compare them.
|
||||
|
||||
Design Requirements:
|
||||
- Style: Professional, modern, technical, business-oriented
|
||||
- Colors: Blue tones (e.g., #2980B9, #3498DB) combined with neutral grays or white
|
||||
- Elements: Combination of document symbol and transformation/workflow elements
|
||||
- Simplicity: Must be recognizable even at very small sizes (16x16 pixels)
|
||||
- Clean lines and high contrast
|
||||
|
||||
Symbolism Suggestions:
|
||||
- A document with transformation arrows
|
||||
- Stacked/nested documents (XML → XSLT → PDF)
|
||||
- Stylized "D" or "M" for DocuMentor
|
||||
- Workflow diagram with document symbols
|
||||
- Document with gear icon (processing/transformation)
|
||||
|
||||
Format: Vector graphic (SVG), square (1:1 ratio), 512x512 pixels or larger
|
||||
Background: Transparent or solid color (blue/white)
|
||||
|
||||
Style References: Microsoft Office icons, Adobe Creative Cloud icons, modern SaaS applications
|
||||
|
||||
Additional Instructions:
|
||||
- Flat design, not 3D
|
||||
- No gradients or complex shadows
|
||||
- Maximum 3 colors
|
||||
- Geometric shapes preferred
|
||||
- Professional and trustworthy appearance
|
||||
```
|
||||
|
||||
### Alternativer Prompt (detaillierter für KIs wie ChatGPT mit DALL-E)
|
||||
|
||||
```
|
||||
Design a minimalist icon for "DocuMentor" - a professional XML/XSL transformation management software.
|
||||
|
||||
Concept: A clean, modern icon that combines:
|
||||
1. A document/page symbol (representing XML/PDF files)
|
||||
2. An element suggesting transformation or workflow (arrows, gears, or connecting lines)
|
||||
3. Professional color scheme: Primary blue (#2980B9) with white/gray accents
|
||||
|
||||
Requirements:
|
||||
- Vector style, flat design
|
||||
- Must work well at 16x16, 48x48, and 256x256 pixels
|
||||
- High contrast for visibility
|
||||
- No text, icon only
|
||||
- Square format (512x512px minimum)
|
||||
- Transparent background preferred
|
||||
|
||||
Style inspiration: Think Microsoft Office 365 icons, VS Code icons, or modern productivity app icons - clean, professional, instantly recognizable.
|
||||
|
||||
Technical constraints:
|
||||
- Simple enough to work as a favicon
|
||||
- Clear silhouette when shown in monochrome
|
||||
- Distinctive enough to stand out in a taskbar or dock
|
||||
```
|
||||
|
||||
## Prompt für spezifische Konzepte
|
||||
|
||||
### Konzept 1: Dokument mit Transformation
|
||||
|
||||
```
|
||||
A minimalist icon showing a document page with a curved arrow pointing to another document, symbolizing transformation. Blue (#2980B9) and white color scheme. Flat design, professional, suitable for business software. SVG style, 512x512px, transparent background.
|
||||
```
|
||||
|
||||
### Konzept 2: Gestapelte Dokumente
|
||||
|
||||
```
|
||||
An icon with three overlapping document sheets in a cascading arrangement, representing XML to XSL to PDF transformation workflow. Modern flat design, blue gradient (#3498DB to #2980B9), white accents. Professional business software icon. 512x512px SVG format.
|
||||
```
|
||||
|
||||
### Konzept 3: Dokument + Zahnrad
|
||||
|
||||
```
|
||||
A clean icon combining a document page with a small gear/cog symbol in the corner, representing document processing. Minimalist design, blue (#2980B9) on white background. Professional style like Microsoft Office icons. 512x512px, vector art, high contrast.
|
||||
```
|
||||
|
||||
### Konzept 4: Stilisiertes "M"
|
||||
|
||||
```
|
||||
A stylized letter "M" for "Mentor" integrated with document/page elements. Modern, geometric, professional. Blue (#2980B9) color scheme. Suitable for small sizes. Flat design, vector style, 512x512px, transparent background.
|
||||
```
|
||||
|
||||
## Verwendung
|
||||
|
||||
1. Wähle einen der Prompts oben
|
||||
2. Füge ihn in eine Bild-Generierungs-KI ein:
|
||||
- **DALL-E 3** (ChatGPT Plus): Englischer Prompt empfohlen
|
||||
- **Midjourney**: Englischer Prompt, evtl. kürzer
|
||||
- **Adobe Firefly**: Deutscher oder englischer Prompt
|
||||
- **Stable Diffusion**: Englischer Prompt mit detaillierten Tags
|
||||
- **Leonardo.ai**: Englischer Prompt
|
||||
|
||||
3. Lade das generierte Bild herunter (idealerweise als PNG)
|
||||
|
||||
4. Konvertiere zu ICO:
|
||||
```bash
|
||||
uv run python create_icon.py generiertes-icon.png
|
||||
```
|
||||
|
||||
## Tipps für beste Ergebnisse
|
||||
|
||||
- **Iteriere**: Generiere mehrere Varianten
|
||||
- **Einfachheit**: Betone "minimalist", "simple", "clean"
|
||||
- **Größe**: Teste das Icon in verschiedenen Größen
|
||||
- **Kontrast**: Achte auf gute Sichtbarkeit auf hellem und dunklem Hintergrund
|
||||
- **Professionalität**: Vermeide zu verspielte oder kindliche Designs
|
||||
|
||||
## Nachbearbeitung
|
||||
|
||||
Falls die KI kein perfektes SVG erstellt:
|
||||
1. PNG exportieren (hohe Auflösung, mind. 512x512px)
|
||||
2. Mit Inkscape oder Adobe Illustrator zu SVG konvertieren
|
||||
3. Oder direkt als PNG verwenden und mit `create_icon.py` konvertieren
|
||||
@@ -2,6 +2,15 @@ version = 1
|
||||
revision = 3
|
||||
requires-python = ">=3.13"
|
||||
|
||||
[[package]]
|
||||
name = "altgraph"
|
||||
version = "0.17.5"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7e/f8/97fdf103f38fed6792a1601dbc16cc8aac56e7459a9fff08c812d8ae177a/altgraph-0.17.5.tar.gz", hash = "sha256:c87b395dd12fabde9c99573a9749d67da8d29ef9de0125c7f536699b4a9bc9e7", size = 48428, upload-time = "2025-11-21T20:35:50.583Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/ba/000a1996d4308bc65120167c21241a3b205464a2e0b58deda26ae8ac21d1/altgraph-0.17.5-py2.py3-none-any.whl", hash = "sha256:f3a22400bce1b0c701683820ac4f3b159cd301acab067c51c653e06961600597", size = 21228, upload-time = "2025-11-21T20:35:49.444Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "annotated-types"
|
||||
version = "0.7.0"
|
||||
@@ -46,6 +55,8 @@ dependencies = [
|
||||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "pillow" },
|
||||
{ name = "pyinstaller" },
|
||||
{ name = "ruff" },
|
||||
]
|
||||
|
||||
@@ -59,7 +70,99 @@ requires-dist = [
|
||||
]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [{ name = "ruff", specifier = ">=0.14.8" }]
|
||||
dev = [
|
||||
{ name = "pillow", specifier = ">=10.0.0" },
|
||||
{ name = "pyinstaller", specifier = ">=6.0.0" },
|
||||
{ name = "ruff", specifier = ">=0.14.8" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "macholib"
|
||||
version = "1.16.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "altgraph" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/10/2f/97589876ea967487978071c9042518d28b958d87b17dceb7cdc1d881f963/macholib-1.16.4.tar.gz", hash = "sha256:f408c93ab2e995cd2c46e34fe328b130404be143469e41bc366c807448979362", size = 59427, upload-time = "2025-11-22T08:28:38.373Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/d1/a9f36f8ecdf0fb7c9b1e78c8d7af12b8c8754e74851ac7b94a8305540fc7/macholib-1.16.4-py2.py3-none-any.whl", hash = "sha256:da1a3fa8266e30f0ce7e97c6a54eefaae8edd1e5f86f3eb8b95457cae90265ea", size = 38117, upload-time = "2025-11-22T08:28:36.939Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "25.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pefile"
|
||||
version = "2024.8.26"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/03/4f/2750f7f6f025a1507cd3b7218691671eecfd0bbebebe8b39aa0fe1d360b8/pefile-2024.8.26.tar.gz", hash = "sha256:3ff6c5d8b43e8c37bb6e6dd5085658d658a7a0bdcd20b6a07b1fcfc1c4e9d632", size = 76008, upload-time = "2024-08-26T20:58:38.155Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/16/12b82f791c7f50ddec566873d5bdd245baa1491bac11d15ffb98aecc8f8b/pefile-2024.8.26-py3-none-any.whl", hash = "sha256:76f8b485dcd3b1bb8166f1128d395fa3d87af26360c2358fb75b80019b957c6f", size = 74766, upload-time = "2024-08-26T21:01:02.632Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "12.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d0/02/d52c733a2452ef1ffcc123b68e6606d07276b0e358db70eabad7e40042b7/pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9", size = 46977283, upload-time = "2026-01-02T09:13:29.892Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/c7/2530a4aa28248623e9d7f27316b42e27c32ec410f695929696f2e0e4a778/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1", size = 4062543, upload-time = "2026-01-02T09:11:31.566Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/1f/40b8eae823dc1519b87d53c30ed9ef085506b05281d313031755c1705f73/pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179", size = 4138373, upload-time = "2026-01-02T09:11:33.367Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/77/6fa60634cf06e52139fd0e89e5bbf055e8166c691c42fb162818b7fda31d/pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0", size = 3601241, upload-time = "2026-01-02T09:11:35.011Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/bf/28ab865de622e14b747f0cd7877510848252d950e43002e224fb1c9ababf/pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587", size = 5262410, upload-time = "2026-01-02T09:11:36.682Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/34/583420a1b55e715937a85bd48c5c0991598247a1fd2eb5423188e765ea02/pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac", size = 4657312, upload-time = "2026-01-02T09:11:38.535Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1d/fd/f5a0896839762885b3376ff04878f86ab2b097c2f9a9cdccf4eda8ba8dc0/pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b", size = 6232605, upload-time = "2026-01-02T09:11:40.602Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/aa/938a09d127ac1e70e6ed467bd03834350b33ef646b31edb7452d5de43792/pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea", size = 8041617, upload-time = "2026-01-02T09:11:42.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/e8/538b24cb426ac0186e03f80f78bc8dc7246c667f58b540bdd57c71c9f79d/pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c", size = 6346509, upload-time = "2026-01-02T09:11:44.955Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/9a/632e58ec89a32738cabfd9ec418f0e9898a2b4719afc581f07c04a05e3c9/pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc", size = 7038117, upload-time = "2026-01-02T09:11:46.736Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/a2/d40308cf86eada842ca1f3ffa45d0ca0df7e4ab33c83f81e73f5eaed136d/pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644", size = 6460151, upload-time = "2026-01-02T09:11:48.625Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/88/f5b058ad6453a085c5266660a1417bdad590199da1b32fb4efcff9d33b05/pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c", size = 7164534, upload-time = "2026-01-02T09:11:50.445Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/ce/c17334caea1db789163b5d855a5735e47995b0b5dc8745e9a3605d5f24c0/pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171", size = 6332551, upload-time = "2026-01-02T09:11:52.234Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e5/07/74a9d941fa45c90a0d9465098fe1ec85de3e2afbdc15cc4766622d516056/pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a", size = 7040087, upload-time = "2026-01-02T09:11:54.822Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/09/c99950c075a0e9053d8e880595926302575bc742b1b47fe1bbcc8d388d50/pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45", size = 2452470, upload-time = "2026-01-02T09:11:56.522Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/ba/970b7d85ba01f348dee4d65412476321d40ee04dcb51cd3735b9dc94eb58/pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d", size = 5264816, upload-time = "2026-01-02T09:11:58.227Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/60/650f2fb55fdba7a510d836202aa52f0baac633e50ab1cf18415d332188fb/pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0", size = 4660472, upload-time = "2026-01-02T09:12:00.798Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/c0/5273a99478956a099d533c4f46cbaa19fd69d606624f4334b85e50987a08/pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554", size = 6268974, upload-time = "2026-01-02T09:12:02.572Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/26/0bf714bc2e73d5267887d47931d53c4ceeceea6978148ed2ab2a4e6463c4/pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e", size = 8073070, upload-time = "2026-01-02T09:12:04.75Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/cf/1ea826200de111a9d65724c54f927f3111dc5ae297f294b370a670c17786/pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82", size = 6380176, upload-time = "2026-01-02T09:12:06.626Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/e0/7938dd2b2013373fd85d96e0f38d62b7a5a262af21ac274250c7ca7847c9/pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4", size = 7067061, upload-time = "2026-01-02T09:12:08.624Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/ad/a2aa97d37272a929a98437a8c0ac37b3cf012f4f8721e1bd5154699b2518/pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0", size = 6491824, upload-time = "2026-01-02T09:12:10.488Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/44/80e46611b288d51b115826f136fb3465653c28f491068a72d3da49b54cd4/pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b", size = 7190911, upload-time = "2026-01-02T09:12:12.772Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/77/eacc62356b4cf81abe99ff9dbc7402750044aed02cfd6a503f7c6fc11f3e/pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65", size = 6336445, upload-time = "2026-01-02T09:12:14.775Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/3c/57d81d0b74d218706dafccb87a87ea44262c43eef98eb3b164fd000e0491/pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0", size = 7045354, upload-time = "2026-01-02T09:12:16.599Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/82/8b9b97bba2e3576a340f93b044a3a3a09841170ab4c1eb0d5c93469fd32f/pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8", size = 2454547, upload-time = "2026-01-02T09:12:18.704Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/87/bdf971d8bbcf80a348cc3bacfcb239f5882100fe80534b0ce67a784181d8/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91", size = 4062533, upload-time = "2026-01-02T09:12:20.791Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/4f/5eb37a681c68d605eb7034c004875c81f86ec9ef51f5be4a63eadd58859a/pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796", size = 4138546, upload-time = "2026-01-02T09:12:23.664Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/6d/19a95acb2edbace40dcd582d077b991646b7083c41b98da4ed7555b59733/pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd", size = 3601163, upload-time = "2026-01-02T09:12:26.338Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/36/2b8138e51cb42e4cc39c3297713455548be855a50558c3ac2beebdc251dd/pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13", size = 5266086, upload-time = "2026-01-02T09:12:28.782Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/4b/649056e4d22e1caa90816bf99cef0884aed607ed38075bd75f091a607a38/pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e", size = 4657344, upload-time = "2026-01-02T09:12:31.117Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/6b/c5742cea0f1ade0cd61485dc3d81f05261fc2276f537fbdc00802de56779/pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643", size = 6232114, upload-time = "2026-01-02T09:12:32.936Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/8f/9f521268ce22d63991601aafd3d48d5ff7280a246a1ef62d626d67b44064/pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5", size = 8042708, upload-time = "2026-01-02T09:12:34.78Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/eb/257f38542893f021502a1bbe0c2e883c90b5cff26cc33b1584a841a06d30/pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de", size = 6347762, upload-time = "2026-01-02T09:12:36.748Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/5a/8ba375025701c09b309e8d5163c5a4ce0102fa86bbf8800eb0d7ac87bc51/pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9", size = 7039265, upload-time = "2026-01-02T09:12:39.082Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/dc/cf5e4cdb3db533f539e88a7bbf9f190c64ab8a08a9bc7a4ccf55067872e4/pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a", size = 6462341, upload-time = "2026-01-02T09:12:40.946Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/47/0291a25ac9550677e22eda48510cfc4fa4b2ef0396448b7fbdc0a6946309/pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a", size = 7165395, upload-time = "2026-01-02T09:12:42.706Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/4c/e005a59393ec4d9416be06e6b45820403bb946a778e39ecec62f5b2b991e/pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030", size = 6431413, upload-time = "2026-01-02T09:12:44.944Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/af/f23697f587ac5f9095d67e31b81c95c0249cd461a9798a061ed6709b09b5/pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94", size = 7176779, upload-time = "2026-01-02T09:12:46.727Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/36/6a51abf8599232f3e9afbd16d52829376a68909fe14efe29084445db4b73/pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4", size = 2543105, upload-time = "2026-01-02T09:12:49.243Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/54/2e1dd20c8749ff225080d6ba465a0cab4387f5db0d1c5fb1439e2d99923f/pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2", size = 5268571, upload-time = "2026-01-02T09:12:51.11Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/61/571163a5ef86ec0cf30d265ac2a70ae6fc9e28413d1dc94fa37fae6bda89/pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61", size = 4660426, upload-time = "2026-01-02T09:12:52.865Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/e1/53ee5163f794aef1bf84243f755ee6897a92c708505350dd1923f4afec48/pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51", size = 6269908, upload-time = "2026-01-02T09:12:54.884Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/0b/b4b4106ff0ee1afa1dc599fde6ab230417f800279745124f6c50bcffed8e/pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc", size = 8074733, upload-time = "2026-01-02T09:12:56.802Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/9f/80b411cbac4a732439e629a26ad3ef11907a8c7fc5377b7602f04f6fe4e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14", size = 6381431, upload-time = "2026-01-02T09:12:58.823Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/b7/d65c45db463b66ecb6abc17c6ba6917a911202a07662247e1355ce1789e7/pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8", size = 7068529, upload-time = "2026-01-02T09:13:00.885Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/96/dfd4cd726b4a45ae6e3c669fc9e49deb2241312605d33aba50499e9d9bd1/pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924", size = 6492981, upload-time = "2026-01-02T09:13:03.314Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4d/1c/b5dc52cf713ae46033359c5ca920444f18a6359ce1020dd3e9c553ea5bc6/pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef", size = 7191878, upload-time = "2026-01-02T09:13:05.276Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/26/c4188248bd5edaf543864fe4834aebe9c9cb4968b6f573ce014cc42d0720/pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988", size = 6438703, upload-time = "2026-01-02T09:13:07.491Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/0e/69ed296de8ea05cb03ee139cee600f424ca166e632567b2d66727f08c7ed/pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6", size = 7182927, upload-time = "2026-01-02T09:13:09.841Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/f5/68334c015eed9b5cff77814258717dec591ded209ab5b6fb70e2ae873d1d/pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831", size = 2545104, upload-time = "2026-01-02T09:13:12.068Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polars"
|
||||
@@ -176,6 +279,47 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/39/8d263fbcb409a8f5dd78ac8f89f1e6af1d4e4d9fbb7f856ca3245b354809/pydantic_yaml-1.6.0-py3-none-any.whl", hash = "sha256:02cb800b455b68daeeb74ad736c252a94a0b203da5fbbeef02539d468e1d98f8", size = 22511, upload-time = "2025-08-08T21:01:11.425Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyinstaller"
|
||||
version = "6.17.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "altgraph" },
|
||||
{ name = "macholib", marker = "sys_platform == 'darwin'" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pefile", marker = "sys_platform == 'win32'" },
|
||||
{ name = "pyinstaller-hooks-contrib" },
|
||||
{ name = "pywin32-ctypes", marker = "sys_platform == 'win32'" },
|
||||
{ name = "setuptools" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/01/80/9e0dad9c69a7cfd4b5aaede8c6225d762bab7247a2a6b7651e1995522001/pyinstaller-6.17.0.tar.gz", hash = "sha256:be372bd911392b88277e510940ac32a5c2a6ce4b8d00a311c78fa443f4f27313", size = 4014147, upload-time = "2025-11-24T19:43:32.109Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/35/f5/37e419d84d5284ecab11ef8b61306a3b978fe6f0fd69a9541e16bfd72e65/pyinstaller-6.17.0-py3-none-macosx_10_13_universal2.whl", hash = "sha256:4e446b8030c6e5a2f712e3f82011ecf6c7ead86008357b0d23a0ec4bcde31dac", size = 1031880, upload-time = "2025-11-24T19:42:30.862Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/b6/2e184879ab9cf90a1d2867fdd34d507c4d246b3cc52ca05aad00bfc70ee7/pyinstaller-6.17.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:aa9fd87aaa28239c6f0d0210114029bd03f8cac316a90bab071a5092d7c85ad7", size = 731968, upload-time = "2025-11-24T19:42:35.421Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/76/f529de98f7e5cce7904c19b224990003fc2267eda2ee5fdd8452acb420a9/pyinstaller-6.17.0-py3-none-manylinux2014_i686.whl", hash = "sha256:060b122e43e7c0b23e759a4153be34bd70914135ab955bb18a67181e0dca85a2", size = 743217, upload-time = "2025-11-24T19:42:39.286Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/10/c02bfbb050cafc4c353cf69baf95407e211e1372bd286ab5ce5cbc13a30a/pyinstaller-6.17.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:cd213d1a545c97dfe4a3c40e8213ff7c5127fc115c49229f27a3fa541503444b", size = 741119, upload-time = "2025-11-24T19:42:43.12Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/9d/69fdacfd9335695f5900a376cfe3e4aed28f0720ffc15fee81fdb9d920bc/pyinstaller-6.17.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:89c0d18ba8b62c6607abd8cf2299ae5ffa5c36d8c47f39608ce8c3f357f6099f", size = 738111, upload-time = "2025-11-24T19:42:46.97Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/1e/e8e36e1568f6865ac706c6e1f875c1a346ddaa9f9a8f923d66545d2240ed/pyinstaller-6.17.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2a147b83cdebb07855bd5a663600891550062373a2ca375c58eacead33741a27", size = 737795, upload-time = "2025-11-24T19:42:50.675Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/15/9dc0f81ccb746c27bfa6ee53164422fe47ee079c7a717d9c4791aba78797/pyinstaller-6.17.0-py3-none-musllinux_1_1_aarch64.whl", hash = "sha256:f8cfbbfa6708e54fb936df6dd6eafaf133e84efb0d2fe25b91cfeefa793c4ca4", size = 736891, upload-time = "2025-11-24T19:42:54.458Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/e6/bed54821c1ebe1275c559661d3e7bfa23c406673b515252dfbf89db56c65/pyinstaller-6.17.0-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:97f4c1942f7b4cd73f9e38b49cc8f5f8a6fbb44922cb60dd3073a189b77ee1ae", size = 736752, upload-time = "2025-11-24T19:42:58.144Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/84/897d759198676b910d69d42640b6d25d50b449f2209e18127a974cf59dbe/pyinstaller-6.17.0-py3-none-win32.whl", hash = "sha256:ce0be227a037fd4be672226db709088565484f597d6b230bceec19850fdd4c85", size = 1317851, upload-time = "2025-11-24T19:43:04.361Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/f5/6a122efe024433ecc34aab6f499e0bd2bbe059c639b77b0045aa2421b0bf/pyinstaller-6.17.0-py3-none-win_amd64.whl", hash = "sha256:b019940dbf7a01489d6b26f9fb97db74b504e0a757010f7ad078675befc85a82", size = 1378685, upload-time = "2025-11-24T19:43:10.395Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/96/14991773c9e599707a53594429ccf372f9ee638df3b7d26b65fd1a7433f0/pyinstaller-6.17.0-py3-none-win_arm64.whl", hash = "sha256:3c92a335e338170df7e615f75279cfeea97ade89e6dd7694943c8c185460f7b7", size = 1320032, upload-time = "2025-11-24T19:43:16.388Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyinstaller-hooks-contrib"
|
||||
version = "2025.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "setuptools" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/45/2f/2c68b6722d233dae3e5243751aafc932940b836919cfaca22dd0c60d417c/pyinstaller_hooks_contrib-2025.11.tar.gz", hash = "sha256:dfe18632e06655fa88d218e0d768fd753e1886465c12a6d4bce04f1aaeec917d", size = 169183, upload-time = "2025-12-23T12:59:37.361Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/c4/3a096c6e701832443b957b9dac18a163103360d0c7f5842ca41695371148/pyinstaller_hooks_contrib-2025.11-py3-none-any.whl", hash = "sha256:777e163e2942474aa41a8e6d31ac1635292d63422c3646c176d584d04d971c34", size = 449478, upload-time = "2025-12-23T12:59:35.987Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyqtdarktheme"
|
||||
version = "2.1.0"
|
||||
@@ -245,6 +389,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pywin32-ctypes"
|
||||
version = "0.2.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471, upload-time = "2024-08-14T10:15:34.626Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756, upload-time = "2024-08-14T10:15:33.187Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruamel-yaml"
|
||||
version = "0.18.15"
|
||||
@@ -300,6 +453,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/63/8b41cea3afd7f58eb64ac9251668ee0073789a3bc9ac6f816c8c6fef986d/ruff-0.14.8-py3-none-win_arm64.whl", hash = "sha256:965a582c93c63fe715fd3e3f8aa37c4b776777203d8e1d8aa3cc0c14424a4b99", size = 13634522, upload-time = "2025-12-04T15:06:43.212Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "80.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shiboken6"
|
||||
version = "6.9.2"
|
||||
|
||||
Reference in New Issue
Block a user