From c4501b381fd2106c0f439f1504a9b6b250e42062 Mon Sep 17 00:00:00 2001 From: Tobias Leuschner Date: Sat, 9 May 2026 13:53:49 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Verbesserte=20SMB-Zielkonfiguration=20u?= =?UTF-8?q?nd=20Schreibzugriffstest;=20Versionsnummer=20auf=201.0.46=20erh?= =?UTF-8?q?=C3=B6ht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 27 ++++++++++++++++++++++----- version.txt | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/app.py b/app.py index a9953a1..8a1597e 100644 --- a/app.py +++ b/app.py @@ -900,12 +900,19 @@ def _remote_name(tid): def _smb_conn(t: dict, path: str = '') -> str: - """Baut einen rclone SMB Connection-String aus gespeicherten Credentials. - Fallback auf named remote falls keine Credentials im Entry.""" + """Baut ein rclone-Ziel fuer gespeicherte SMB-Targets. + + Gespeicherte Ziele werden als benannte rclone-Remotes angelegt. Diese + Remote-Konfiguration ist die kanonische Quelle fuer Host, Share und Login; + der Inline-String bleibt nur als Fallback fuer unvollstaendige Legacy-Eintraege. + """ + if t.get('id'): + return f'{_remote_name(t["id"])}:{path}' + host = t.get('smb_host', '') share = t.get('smb_share', '') if not host or not share: - return f'{_remote_name(t["id"])}:{path}' + return f':{path}' conn = f':smb,host={host},share={share}' if t.get('smb_user'): conn += f',user={t["smb_user"]}' @@ -938,14 +945,21 @@ def test_remote(tid): cfg = load_cfg() targets = cfg.get('upload_targets', []) t = next((x for x in targets if x['id'] == tid), {'id': tid}) + dest_root = t.get('dest_path', 'PiCopy').strip('/') root = _smb_conn(t) - test_dir = _smb_conn(t, '.picopy_writetest') + dest = _smb_conn(t, dest_root) + test_dir_name = '.picopy_writetest' + test_dir = _smb_conn(t, f'{dest_root}/{test_dir_name}' if dest_root else test_dir_name) # 1. Verbindung prüfen r = _rclone('lsd', root, timeout=15) if r.returncode != 0: err = r.stderr.strip().splitlines()[-1] if r.stderr.strip() else 'Verbindung fehlgeschlagen' return False, f'Verbindung: {err}' - # 2. Schreibzugriff prüfen: Testverzeichnis anlegen + sofort löschen + # 2. Zielordner und Schreibzugriff prüfen: Ziel anlegen, Testverzeichnis anlegen + sofort löschen + mk = _rclone('mkdir', dest, timeout=15) + if mk.returncode != 0: + err = mk.stderr.strip().splitlines()[-1] if mk.stderr.strip() else 'Zielordner konnte nicht angelegt werden' + return False, f'Zielordner: {err}' rw = _rclone('mkdir', test_dir, timeout=15) if rw.returncode != 0: err = rw.stderr.strip().splitlines()[-1] if rw.stderr.strip() else 'Schreiben fehlgeschlagen' @@ -972,6 +986,9 @@ def run_uploads(local_dir: Path, cfg: dict): dest_root = t.get('dest_path', 'PiCopy').strip('/') root = _smb_conn(t) dest = _smb_conn(t, dest_root) + share = t.get('smb_share', '') + dest_label = f'{share}/{dest_root}' if share and dest_root else (share or dest_root or '/') + add_log(f'Upload {name}: Ziel {dest_label}') # Quellverzeichnis prüfen if not local_dir.exists(): diff --git a/version.txt b/version.txt index b5d7271..9e6b608 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.0.44 \ No newline at end of file +1.0.46 \ No newline at end of file