Add FTP/SFTP support and tree-view folder picker with lazy loading
FTP/SFTP processor: - New ftp_processor.py with adapter pattern for FTP (passive) and SFTP - Same design as smb_processor: read PDFs, forward via SMTP, move to processed - Eingangs-/Ausgangsbelege with separate paths, modes (forward/separator) - paramiko==3.5.0 for SFTP support - Schema v9 with new ftp_* settings - Integrated in scheduler Tree-view folder picker (SMB + FTP): - Reusable tree rendering from flat path lists - Expandable/collapsible nodes with toggle arrows - Lazy loading: only top-level folders on open, sub-folders on-demand - Auto-expand ancestors of currently selected value (with preload) - Reload button stays for manual refresh - Always fresh load when opening picker - New endpoints: /api/list-smb-subfolders, /api/list-ftp-subfolders FTP-specific fixes: - list_pdfs uses LIST instead of NLST (more reliable across servers) - Stateful CWD bug fixed in ensure_dir/stat_exists/rename (previously created /Buch/Buch/X instead of /Buch/X due to CWD drift) - All operations reset CWD via _reset_cwd() before stateful calls - _resolve() helper for SFTP to handle empty path / chroot users Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
-2
@@ -4,13 +4,13 @@ import aiosqlite
|
||||
from cryptography.fernet import Fernet
|
||||
|
||||
DB_PATH = os.environ.get("DB_PATH", "/data/belegimport.db")
|
||||
SCHEMA_VERSION = 8
|
||||
SCHEMA_VERSION = 9
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
_fernet = None
|
||||
|
||||
ENCRYPTED_KEYS = {"imap_password", "smtp_password", "smb_password", "amazon_password", "amazon_client_secret", "amazon_refresh_token"}
|
||||
ENCRYPTED_KEYS = {"imap_password", "smtp_password", "smb_password", "amazon_password", "amazon_client_secret", "amazon_refresh_token", "ftp_password"}
|
||||
|
||||
DEFAULT_SETTINGS = {
|
||||
"imap_server": "",
|
||||
@@ -46,6 +46,18 @@ DEFAULT_SETTINGS = {
|
||||
"smb_source_path_ausgang": "",
|
||||
"smb_processed_path_ausgang": "",
|
||||
"smb_mode": "forward",
|
||||
# FTP / SFTP
|
||||
"ftp_enabled": "false",
|
||||
"ftp_protocol": "sftp", # "sftp" or "ftp"
|
||||
"ftp_server": "",
|
||||
"ftp_port": "22",
|
||||
"ftp_username": "",
|
||||
"ftp_password": "",
|
||||
"ftp_source_path": "",
|
||||
"ftp_processed_path": "Verarbeitet",
|
||||
"ftp_source_path_ausgang": "",
|
||||
"ftp_processed_path_ausgang": "",
|
||||
"ftp_mode": "forward",
|
||||
# Amazon
|
||||
"amazon_enabled": "false",
|
||||
"amazon_email": "",
|
||||
@@ -241,6 +253,12 @@ async def _run_migrations(db: aiosqlite.Connection, current_version: int):
|
||||
await db.commit()
|
||||
await _set_schema_version(db, 8)
|
||||
|
||||
if current_version < 9:
|
||||
logger.info("Migration v9: FTP/SFTP-Settings hinzugefuegt (defaults werden eingefuegt)")
|
||||
# No table changes needed - new settings are added via DEFAULT_SETTINGS loop in init_db
|
||||
await db.commit()
|
||||
await _set_schema_version(db, 9)
|
||||
|
||||
await db.commit()
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user