mirror of
https://git.hiabuto.net/C3MA/CCMA.git
synced 2026-07-01 11:14:52 +02:00
feat: Add Windows compatibility, PyInstaller build setup, and custom icon
- Add Windows LibreOffice detection fallback for soffice path - Check standard install locations (%PROGRAMFILES%, %PROGRAMFILES(X86)%) - Graceful fallback with clear error messages - Add PyInstaller build infrastructure - build/ccma.spec: PyInstaller configuration with icon generation - build/build.ps1: Automated build script for standalone exe - main.py: Entry point for PyInstaller - Supports versioning and architecture tagging - Create custom CCMA icon - Person + Gear symbol representing member administration - Cyan/White/Orange color scheme - Auto-converts PNG to ICO during build - Update documentation - README: Windows PowerShell setup instructions - README: Linux/macOS bash setup instructions - README: Standalone executable build guide - pyproject.toml: Add 'build' extra with pyinstaller+pillow - Add regression tests - Test office executable detection and Windows fallback - Verify all tests pass (80 passed)
This commit is contained in:
@@ -474,7 +474,7 @@ def _slot_at(boundaries: list[tuple[int, int]], position: int) -> tuple[int, int
|
||||
|
||||
|
||||
def _convert_to_pdf(source: Path, output_directory: Path) -> Path:
|
||||
executable = shutil.which("soffice") or shutil.which("libreoffice")
|
||||
executable = _office_executable()
|
||||
if not executable:
|
||||
raise DocumentError("LibreOffice/OpenOffice wurde nicht gefunden; PDF-Erzeugung ist nicht möglich.")
|
||||
profile = output_directory / "libreoffice-profile"
|
||||
@@ -499,6 +499,24 @@ def _convert_to_pdf(source: Path, output_directory: Path) -> Path:
|
||||
return converted
|
||||
|
||||
|
||||
def _office_executable() -> str | None:
|
||||
executable = shutil.which("soffice") or shutil.which("libreoffice")
|
||||
if executable:
|
||||
return executable
|
||||
if os.name != "nt":
|
||||
return None
|
||||
windows_roots: list[str] = []
|
||||
for variable in ("PROGRAMFILES", "ProgramW6432", "PROGRAMFILES(X86)"):
|
||||
value = os.environ.get(variable)
|
||||
if value and value not in windows_roots:
|
||||
windows_roots.append(value)
|
||||
for root in windows_roots:
|
||||
candidate = Path(root) / "LibreOffice" / "program" / "soffice.exe"
|
||||
if candidate.is_file():
|
||||
return str(candidate)
|
||||
return None
|
||||
|
||||
|
||||
def _safe_pdf_name(value: str) -> str:
|
||||
stem = Path(value.strip()).stem
|
||||
stem = re.sub(r"[^A-Za-z0-9ÄÖÜäöüß._ -]+", "-", stem).strip(" .-")
|
||||
|
||||
Reference in New Issue
Block a user