diff --git a/README.md b/README.md index 928fd1d..6f53988 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,19 @@ journalctl -u dasiwa-api -f systemctl stop dasiwa-api ``` +### 📦 Логирование + +- `journalctl -u dasiwa-api -f` — стримит лог в реальном времени и сохраняет их в системном журнале, так что падения не теряют логи. +- `journalctl -u dasiwa-api --since "10 minutes ago"` выведет историю за последний период. +- Чтобы журнал системd сохранял файлы между перезагрузками, в `/etc/systemd/journald.conf` установите `Storage=persistent` и перезапустите `systemd-journald`. +- Для дополнительного файла добавьте в `dasiwa-api.service` параметры: + ```ini + [Service] + StandardOutput=append:/var/log/dasiwa-api.log + StandardError=inherit + ``` + После `sudo systemctl daemon-reload && sudo systemctl restart dasiwa-api` лог будет доступен в `/var/log/dasiwa-api.log` и его можно собирать отдельно. + --- ## 🔥 Firewall diff --git a/server.py b/server.py index 782cc7d..60a8bfd 100644 --- a/server.py +++ b/server.py @@ -41,6 +41,7 @@ WORKFLOW_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "workfl KEYS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "keys.json") COMFY_OUTPUT_DIR = os.getenv("COMFY_OUTPUT_DIR", "/ComfyUI/output") +COMFY_INPUT_DIR = os.getenv("COMFY_INPUT_DIR", "/ComfyUI/input") # ============================================================================ # Инициализация @@ -99,10 +100,12 @@ def to_nearest_multiple_of_16(value): def save_base64_to_file(base64_data, temp_dir, filename): """Сохраняет base64 данные в файл.""" decoded = base64.b64decode(base64_data) + logger.info(f"📦 Base64 decoded: {len(base64_data)} chars → {len(decoded)} bytes") os.makedirs(temp_dir, exist_ok=True) file_path = os.path.abspath(os.path.join(temp_dir, filename)) with open(file_path, "wb") as f: f.write(decoded) + logger.info(f"💾 Saved to: {file_path} ({os.path.getsize(file_path)} bytes)") return file_path @@ -119,22 +122,41 @@ def download_file(url, temp_dir, filename): return file_path +def copy_to_comfy_input(src_path, filename): + """ + Копирует файл в ComfyUI input/ директорию. + ComfyUI LoadImage ищет файлы только в своей input/ папке. + Возвращает имя файла (не полный путь). + """ + os.makedirs(COMFY_INPUT_DIR, exist_ok=True) + dst_path = os.path.join(COMFY_INPUT_DIR, filename) + shutil.copy2(src_path, dst_path) + logger.info(f"📋 Copied to ComfyUI input: {dst_path} ({os.path.getsize(dst_path)} bytes)") + return filename + + def process_image_input(job_input, prefix, temp_dir): """ Обрабатывает входные данные изображения. prefix: "image" или "last_image" - Возвращает (file_path, True) или (None, False) + Возвращает (comfy_filename, True) или (None, False) + Файл копируется в ComfyUI input/ директорию. """ path_key = f"{prefix}_path" url_key = f"{prefix}_url" b64_key = f"{prefix}_base64" + src_path = None if path_key in job_input and job_input[path_key]: - return job_input[path_key], True + src_path = job_input[path_key] elif url_key in job_input and job_input[url_key]: - return download_file(job_input[url_key], temp_dir, f"{prefix}.png"), True + src_path = download_file(job_input[url_key], temp_dir, f"{prefix}.png") elif b64_key in job_input and job_input[b64_key]: - return save_base64_to_file(job_input[b64_key], temp_dir, f"{prefix}.png"), True + src_path = save_base64_to_file(job_input[b64_key], temp_dir, f"{prefix}.png") + + if src_path: + comfy_filename = copy_to_comfy_input(src_path, f"{prefix}.png") + return comfy_filename, True return None, False @@ -288,8 +310,9 @@ def build_prompt(job_input, image_path, last_image_path, use_flf2v): negative_prompt = job_input.get("negative_prompt", prompt["6"]["inputs"]["text"]) prompt["6"]["inputs"]["text"] = negative_prompt - # Node 7: Load first frame image + # Node 7: Load first frame image (filename in ComfyUI input/ dir) prompt["7"]["inputs"]["image"] = image_path + logger.info(f"🖼️ Node 7 image: '{image_path}' (resolved: {COMFY_INPUT_DIR}/{image_path})") # Node 15: Load last frame image (for FLF2V mode) if use_flf2v and last_image_path: @@ -331,18 +354,19 @@ def build_prompt(job_input, image_path, last_image_path, use_flf2v): return prompt, seed, width, height -def cleanup_comfy_output(): - """Очистка output директории ComfyUI.""" - try: - if os.path.exists(COMFY_OUTPUT_DIR): - for fname in os.listdir(COMFY_OUTPUT_DIR): - fpath = os.path.join(COMFY_OUTPUT_DIR, fname) - if os.path.isfile(fpath): - os.unlink(fpath) - elif os.path.isdir(fpath): - shutil.rmtree(fpath) - except Exception: - pass +def cleanup_comfy_dirs(): + """Очистка output и input директорий ComfyUI.""" + for dir_path in (COMFY_OUTPUT_DIR, COMFY_INPUT_DIR): + try: + if os.path.exists(dir_path): + for fname in os.listdir(dir_path): + fpath = os.path.join(dir_path, fname) + if os.path.isfile(fpath): + os.unlink(fpath) + elif os.path.isdir(fpath): + shutil.rmtree(fpath) + except Exception: + pass def worker_loop(): @@ -415,7 +439,7 @@ def worker_loop(): # Очистка if os.path.exists(temp_dir): shutil.rmtree(temp_dir, ignore_errors=True) - cleanup_comfy_output() + cleanup_comfy_dirs() job_queue.task_done()