Refactor code structure for improved readability and maintainability
This commit is contained in:
123
routes/upload_routes.py
Normal file
123
routes/upload_routes.py
Normal file
@@ -0,0 +1,123 @@
|
||||
"""PiCopy – Blueprint: /api/upload/*."""
|
||||
|
||||
import subprocess
|
||||
import uuid as _uuid_mod
|
||||
|
||||
from flask import Blueprint, jsonify, request
|
||||
|
||||
from picopy.config import load_cfg, save_cfg
|
||||
from picopy.upload import (
|
||||
upload_state, upload_lock,
|
||||
configure_smb_remote, delete_remote, test_remote,
|
||||
_rclone_obscure, RCLONE_CONF as _RCLONE_CONF,
|
||||
)
|
||||
|
||||
upload_bp = Blueprint('upload', __name__)
|
||||
|
||||
|
||||
@upload_bp.route('/api/upload/targets', methods=['GET'])
|
||||
def r_upload_list():
|
||||
return jsonify(load_cfg().get('upload_targets', []))
|
||||
|
||||
|
||||
@upload_bp.route('/api/upload/targets', methods=['POST'])
|
||||
def r_upload_add():
|
||||
data = request.get_json(force=True)
|
||||
cfg = load_cfg()
|
||||
tid = data.get('id') or _uuid_mod.uuid4().hex[:8]
|
||||
ctype = data.get('type', 'smb')
|
||||
|
||||
if ctype != 'smb':
|
||||
return jsonify(error='Nur SMB/NAS wird unterstützt'), 400
|
||||
ok, err = configure_smb_remote(
|
||||
tid, data.get('host', ''), data.get('share', ''),
|
||||
data.get('user', ''), data.get('pass', ''))
|
||||
|
||||
if not ok:
|
||||
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 = {
|
||||
'id': tid, 'type': ctype,
|
||||
'name': data.get('name', ctype),
|
||||
'dest_path': data.get('dest_path', 'PiCopy'),
|
||||
'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.append(entry)
|
||||
cfg['upload_targets'] = targets
|
||||
save_cfg(cfg)
|
||||
return jsonify(ok=True, id=tid)
|
||||
|
||||
|
||||
@upload_bp.route('/api/upload/targets/<tid>', methods=['DELETE'])
|
||||
def r_upload_del(tid):
|
||||
cfg = load_cfg()
|
||||
cfg['upload_targets'] = [t for t in cfg.get('upload_targets', []) if t['id'] != tid]
|
||||
save_cfg(cfg)
|
||||
delete_remote(tid)
|
||||
return jsonify(ok=True)
|
||||
|
||||
|
||||
@upload_bp.route('/api/upload/browse', methods=['POST'])
|
||||
def r_upload_browse():
|
||||
"""Listet SMB-Freigaben eines Servers ohne gespeicherte Config (rclone connection string)."""
|
||||
data = request.get_json(force=True)
|
||||
host = data.get('host', '').strip()
|
||||
user = data.get('user', '').strip()
|
||||
pw = data.get('pass', '')
|
||||
if not host:
|
||||
return jsonify(error='Server-Adresse fehlt'), 400
|
||||
conn = f':smb,host={host}'
|
||||
if user:
|
||||
conn += f',user={user}'
|
||||
if pw:
|
||||
try:
|
||||
obscured = _rclone_obscure(pw)
|
||||
conn += f',pass={obscured}'
|
||||
except Exception:
|
||||
pass
|
||||
conn += ':'
|
||||
r = subprocess.run(
|
||||
['rclone', '--config', str(_RCLONE_CONF), 'lsd', conn],
|
||||
capture_output=True, text=True, timeout=15
|
||||
)
|
||||
if r.returncode != 0:
|
||||
lines = r.stderr.strip().splitlines()
|
||||
err = lines[-1] if lines else 'Verbindung fehlgeschlagen'
|
||||
return jsonify(error=err), 400
|
||||
shares = [line.strip().split()[-1] for line in r.stdout.splitlines() if line.strip()]
|
||||
return jsonify(shares=shares)
|
||||
|
||||
|
||||
@upload_bp.route('/api/upload/targets/<tid>/toggle', methods=['POST'])
|
||||
def r_upload_toggle(tid):
|
||||
cfg = load_cfg()
|
||||
for t in cfg.get('upload_targets', []):
|
||||
if t['id'] == tid:
|
||||
t['enabled'] = not t.get('enabled', True)
|
||||
break
|
||||
save_cfg(cfg)
|
||||
return jsonify(ok=True)
|
||||
|
||||
|
||||
@upload_bp.route('/api/upload/targets/<tid>/test', methods=['POST'])
|
||||
def r_upload_test(tid):
|
||||
from picopy.config import log
|
||||
try:
|
||||
ok, err = test_remote(tid)
|
||||
except Exception as e:
|
||||
log.exception('upload test failed')
|
||||
ok, err = False, str(e)
|
||||
return jsonify(ok=ok, error=err)
|
||||
|
||||
|
||||
@upload_bp.route('/api/upload/status')
|
||||
def r_upload_status():
|
||||
with upload_lock:
|
||||
return jsonify(dict(upload_state))
|
||||
Reference in New Issue
Block a user