feat: SMB-Verbindung hinzugefügt und Versionsnummer auf 1.0.43 erhöht
This commit is contained in:
43
app.py
43
app.py
@@ -899,6 +899,22 @@ def _remote_name(tid):
|
|||||||
return f'picopy_{tid}'
|
return f'picopy_{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."""
|
||||||
|
host = t.get('smb_host', '')
|
||||||
|
share = t.get('smb_share', '')
|
||||||
|
if not host or not share:
|
||||||
|
return f'{_remote_name(t["id"])}:{path}'
|
||||||
|
conn = f':smb,host={host},share={share}'
|
||||||
|
if t.get('smb_user'):
|
||||||
|
conn += f',user={t["smb_user"]}'
|
||||||
|
if t.get('smb_pass'):
|
||||||
|
conn += f',pass={t["smb_pass"]}'
|
||||||
|
conn += f':{path}'
|
||||||
|
return conn
|
||||||
|
|
||||||
|
|
||||||
def configure_smb_remote(tid, host, share, user, pw):
|
def configure_smb_remote(tid, host, share, user, pw):
|
||||||
rn = _remote_name(tid)
|
rn = _remote_name(tid)
|
||||||
_rclone('config', 'delete', rn)
|
_rclone('config', 'delete', rn)
|
||||||
@@ -919,14 +935,17 @@ def delete_remote(tid):
|
|||||||
|
|
||||||
|
|
||||||
def test_remote(tid):
|
def test_remote(tid):
|
||||||
remote = _remote_name(tid)
|
cfg = load_cfg()
|
||||||
|
targets = cfg.get('upload_targets', [])
|
||||||
|
t = next((x for x in targets if x['id'] == tid), {'id': tid})
|
||||||
|
root = _smb_conn(t)
|
||||||
|
test_dir = _smb_conn(t, '.picopy_writetest')
|
||||||
# 1. Verbindung prüfen
|
# 1. Verbindung prüfen
|
||||||
r = _rclone('lsd', f'{remote}:', timeout=15)
|
r = _rclone('lsd', root, timeout=15)
|
||||||
if r.returncode != 0:
|
if r.returncode != 0:
|
||||||
err = r.stderr.strip().splitlines()[-1] if r.stderr.strip() else 'Verbindung fehlgeschlagen'
|
err = r.stderr.strip().splitlines()[-1] if r.stderr.strip() else 'Verbindung fehlgeschlagen'
|
||||||
return False, f'Verbindung: {err}'
|
return False, f'Verbindung: {err}'
|
||||||
# 2. Schreibzugriff prüfen: Testverzeichnis anlegen + sofort löschen
|
# 2. Schreibzugriff prüfen: Testverzeichnis anlegen + sofort löschen
|
||||||
test_dir = f'{remote}:.picopy_writetest'
|
|
||||||
rw = _rclone('mkdir', test_dir, timeout=15)
|
rw = _rclone('mkdir', test_dir, timeout=15)
|
||||||
if rw.returncode != 0:
|
if rw.returncode != 0:
|
||||||
err = rw.stderr.strip().splitlines()[-1] if rw.stderr.strip() else 'Schreiben fehlgeschlagen'
|
err = rw.stderr.strip().splitlines()[-1] if rw.stderr.strip() else 'Schreiben fehlgeschlagen'
|
||||||
@@ -950,20 +969,18 @@ def run_uploads(local_dir: Path, cfg: dict):
|
|||||||
upload_state['current'] = name
|
upload_state['current'] = name
|
||||||
|
|
||||||
add_log(f'Upload >> {name}...')
|
add_log(f'Upload >> {name}...')
|
||||||
remote = _remote_name(t['id'])
|
|
||||||
dest_root = t.get('dest_path', 'PiCopy').strip('/')
|
dest_root = t.get('dest_path', 'PiCopy').strip('/')
|
||||||
dest = f'{remote}:{dest_root}'
|
root = _smb_conn(t)
|
||||||
|
dest = _smb_conn(t, dest_root)
|
||||||
|
|
||||||
# 1. Verbindung prüfen
|
# 1. Verbindung prüfen
|
||||||
conn = _rclone('lsd', f'{remote}:', timeout=15)
|
conn = _rclone('lsd', root, timeout=15)
|
||||||
if conn.returncode != 0:
|
if conn.returncode != 0:
|
||||||
lines = [l for l in conn.stderr.strip().splitlines() if l.strip()]
|
lines = [l for l in conn.stderr.strip().splitlines() if l.strip()]
|
||||||
err = lines[-1] if lines else 'NAS nicht erreichbar'
|
err = lines[-1] if lines else 'NAS nicht erreichbar'
|
||||||
add_log(f'Upload {name}: ✗ NAS nicht erreichbar - {err}')
|
add_log(f'Upload {name}: ✗ {err}')
|
||||||
add_log(f'Upload {name}: Hinweis: Prüfe ob VPN aktiv ist und den NAS blockiert')
|
|
||||||
with upload_lock:
|
with upload_lock:
|
||||||
upload_state['results'].append({'name': name, 'ok': False,
|
upload_state['results'].append({'name': name, 'ok': False, 'msg': err})
|
||||||
'msg': f'NAS nicht erreichbar (VPN aktiv?): {err}'})
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 2. Zielordner anlegen
|
# 2. Zielordner anlegen
|
||||||
@@ -1192,11 +1209,17 @@ def r_upload_add():
|
|||||||
if not ok:
|
if not ok:
|
||||||
return jsonify(error=f'rclone: {err}'), 500
|
return jsonify(error=f'rclone: {err}'), 500
|
||||||
|
|
||||||
|
# Credentials direkt im Entry speichern (für Connection-String bei Upload)
|
||||||
|
obscured_pw = _rclone_obscure(data.get('pass', '')) if data.get('pass') else ''
|
||||||
entry = {
|
entry = {
|
||||||
'id': tid, 'type': ctype,
|
'id': tid, 'type': ctype,
|
||||||
'name': data.get('name', ctype),
|
'name': data.get('name', ctype),
|
||||||
'dest_path': data.get('dest_path', 'PiCopy'),
|
'dest_path': data.get('dest_path', 'PiCopy'),
|
||||||
'enabled': True,
|
'enabled': True,
|
||||||
|
'smb_host': data.get('host', ''),
|
||||||
|
'smb_share': data.get('share', ''),
|
||||||
|
'smb_user': data.get('user', ''),
|
||||||
|
'smb_pass': obscured_pw,
|
||||||
}
|
}
|
||||||
targets = [t for t in cfg.get('upload_targets', []) if t['id'] != tid]
|
targets = [t for t in cfg.get('upload_targets', []) if t['id'] != tid]
|
||||||
targets.append(entry)
|
targets.append(entry)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.0.42
|
1.0.43
|
||||||
Reference in New Issue
Block a user