Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import os | |
| from pathlib import Path | |
| import paramiko | |
| def _sftp_client() -> tuple[paramiko.SFTPClient, paramiko.Transport]: | |
| host = (os.environ.get("SFTP_HOST") or "").strip() | |
| user = (os.environ.get("SFTP_USER") or "").strip() | |
| port = int((os.environ.get("SFTP_PORT") or "22").strip() or "22") | |
| password = os.environ.get("SFTP_PASS") | |
| if not host or not user: | |
| raise RuntimeError("Missing SFTP_HOST or SFTP_USER") | |
| if not password: | |
| raise RuntimeError("Missing SFTP_PASS") | |
| t = paramiko.Transport((host, port)) | |
| # force password-only auth | |
| t.connect(username=user, password=password) | |
| return paramiko.SFTPClient.from_transport(t), t | |
| def _mkdir_p(sftp: paramiko.SFTPClient, remote_dir: str) -> None: | |
| parts = [p for p in remote_dir.strip("/").split("/") if p] | |
| cur = "" | |
| for part in parts: | |
| cur += "/" + part | |
| try: | |
| sftp.stat(cur) | |
| except FileNotFoundError: | |
| sftp.mkdir(cur) | |
| def store_to_sftp( | |
| pdf_id: str, | |
| template_id: str, | |
| cfg_json_bytes: bytes, | |
| pdf_bytes: bytes, | |
| pdf_name: str, | |
| ) -> str: | |
| """ | |
| Remote layout: | |
| <base>/<template_id>/<pdf_id>/ | |
| trainer_config_<pdf_id>__<template_id>.json | |
| <pdf_name or <pdf_id>.pdf> | |
| """ | |
| base = (os.environ.get("SFTP_BASE_DIR") or "/").strip() | |
| if not base.startswith("/"): | |
| base = "/" + base | |
| base = base.rstrip("/") or "/" | |
| sftp, transport = _sftp_client() | |
| try: | |
| remote_dir = f"{base}/{template_id}/{pdf_id}".replace("//", "/") | |
| _mkdir_p(sftp, remote_dir) | |
| remote_cfg = f"{remote_dir}/trainer_config_{pdf_id}__{template_id}.json" | |
| remote_pdf_name = (pdf_name or f"{pdf_id}.pdf").lstrip("/") | |
| remote_pdf = f"{remote_dir}/{remote_pdf_name}" | |
| with sftp.open(remote_cfg, "wb") as f: | |
| f.write(cfg_json_bytes) | |
| with sftp.open(remote_pdf, "wb") as f: | |
| f.write(pdf_bytes) | |
| return remote_dir | |
| finally: | |
| try: | |
| sftp.close() | |
| finally: | |
| transport.close() | |