Release SyncVito 1.0.16

This commit is contained in:
Davito committed 2026-10-01 14:53:08 +02:00
1 parent 6c677f0161
commit 8218cfd9d5
4 files changed
+37 -6

No files matched your search

+6
View File
@@ -1,5 +1,11 @@
# Änderungsprotokoll # Änderungsprotokoll
## 1.0.16 – 2026-10-01
### Behoben
- **Verständliche Meldung bei abgelehnter NAS-Anmeldung:** Der Zugriff auf Quell- und Zielordner fängt Windows-Fehler 1326 jetzt bereits bei der Pfadprüfung ab und erklärt, dass die gespeicherten Windows-Anmeldeinformationen für den NAS-Server geprüft werden müssen.
## 1.0.15 – 2026-09-29 ## 1.0.15 – 2026-09-29
### Neu ### Neu
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "syncvito" name = "syncvito"
version = "1.0.15" version = "1.0.16"
description = "Windows-Desktopwerkzeug für lokale und NAS-Synchronisation" description = "Windows-Desktopwerkzeug für lokale und NAS-Synchronisation"
readme = "README.md" readme = "README.md"
requires-python = ">=3.11" requires-python = ">=3.11"
+29 -4
View File
@@ -32,6 +32,18 @@ class UnavailablePathError(RuntimeError):
"""Ein für die Synchronisation benötigter Pfad ist nicht erreichbar.""" """Ein für die Synchronisation benötigter Pfad ist nicht erreichbar."""
def _unavailable_path_message(label: str, path: Path, exc: OSError) -> str:
"""Erklärt typische NAS-Anmeldefehler verständlich und erhält den Pfadkontext."""
if getattr(exc, "winerror", None) == 1326:
return (
f"{label} nicht erreichbar: Windows hat die NAS-Anmeldung abgelehnt "
"(WinError 1326: Benutzername oder Kennwort falsch). Prüfe die gespeicherten "
"Windows-Anmeldeinformationen für den NAS-Server und teste den Zugriff im Explorer. "
f"Pfad: {path}"
)
return f"{label} nicht erreichbar: {path}"
def is_relative_path_ignored(relative: str, ignored_set: set[str]) -> bool: def is_relative_path_ignored(relative: str, ignored_set: set[str]) -> bool:
"""Prüft, ob ein relativer Pfad oder eines seiner Elternverzeichnisse ignoriert wird.""" """Prüft, ob ein relativer Pfad oder eines seiner Elternverzeichnisse ignoriert wird."""
if not ignored_set or not relative.strip(): if not ignored_set or not relative.strip():
@@ -241,14 +253,27 @@ class SyncEngine:
@staticmethod @staticmethod
def _validate_roots(source_root: Path, target_root: Path) -> None: def _validate_roots(source_root: Path, target_root: Path) -> None:
if not source_root.is_dir(): try:
source_is_dir = source_root.is_dir()
except OSError as exc:
raise UnavailablePathError(_unavailable_path_message("Quellordner", source_root, exc)) from exc
if not source_is_dir:
raise UnavailablePathError(f"Quellordner nicht erreichbar: {source_root}") raise UnavailablePathError(f"Quellordner nicht erreichbar: {source_root}")
if not target_root.exists():
try:
target_exists = target_root.exists()
except OSError as exc:
raise UnavailablePathError(_unavailable_path_message("Zielordner", target_root, exc)) from exc
if not target_exists:
try: try:
target_root.mkdir(parents=True, exist_ok=True) target_root.mkdir(parents=True, exist_ok=True)
except OSError as exc: except OSError as exc:
raise UnavailablePathError(f"Zielordner nicht erreichbar: {target_root}") from exc raise UnavailablePathError(_unavailable_path_message("Zielordner", target_root, exc)) from exc
if not target_root.is_dir(): try:
target_is_dir = target_root.is_dir()
except OSError as exc:
raise UnavailablePathError(_unavailable_path_message("Zielordner", target_root, exc)) from exc
if not target_is_dir:
raise UnavailablePathError(f"Ziel ist kein Ordner: {target_root}") raise UnavailablePathError(f"Ziel ist kein Ordner: {target_root}")
@staticmethod @staticmethod
+1 -1
View File
@@ -1 +1 @@
1.0.15 1.0.16