first commit
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
# ComfyUI Zip Output Node
|
||||
|
||||
[ComfyUI](https://github.com/comfyanonymous/ComfyUI) の `output` フォルダ内にある生成物を、ボタン一つでZIPファイルに圧縮するためのカスタムノードです。
|
||||
|
||||
RunPod や Google Colab などのクラウド環境(永続化ディスクを使用しない環境)で、生成された大量の画像を一度にまとめてダウンロードしたい場合に最適化されています。
|
||||
|
||||
## 主な機能
|
||||
|
||||
- **outputフォルダの一括Zip化:** 生成された画像やファイルを1つのZipにまとめます。
|
||||
- **Zipの入れ子防止:** 生成されるZipファイルの中に、過去のZipファイルが含まれないように除外処理を行います(Zip of Zip 問題の解決)。
|
||||
- **ディスク容量の節約:** オプションで、新しいZipを作成する直前に古いZipファイルを自動削除できます(RunPodなどの容量制限がある環境で有用)。
|
||||
- **ダウンロードURL支援:** ブラウザから直接ダウンロードしやすいよう、ファイル名単体を出力します。
|
||||
|
||||
## インストール方法
|
||||
|
||||
`ComfyUI/custom_nodes/` ディレクトリに移動し、このリポジトリをクローンしてください。
|
||||
|
||||
```bash
|
||||
cd ComfyUI/custom_nodes/
|
||||
git clone https://github.com/fudosanit/ComfyUI-ZipOutput.git
|
||||
@@ -0,0 +1,3 @@
|
||||
from .zip_output_node import NODE_CLASS_MAPPINGS
|
||||
|
||||
__all__ = ["NODE_CLASS_MAPPINGS"]
|
||||
@@ -0,0 +1,75 @@
|
||||
import zipfile
|
||||
import os
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
# 標準モジュールがない場合の安全策
|
||||
try:
|
||||
import folder_paths
|
||||
except ImportError:
|
||||
folder_paths = None
|
||||
|
||||
class ZipOutputFolder:
|
||||
@classmethod
|
||||
def INPUT_TYPES(cls):
|
||||
return {
|
||||
"required": {
|
||||
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
|
||||
"clear_previous_zips": ("BOOLEAN", {"default": True}),
|
||||
}
|
||||
}
|
||||
|
||||
# 出力を2つに増やしました
|
||||
RETURN_TYPES = ("STRING", "STRING")
|
||||
RETURN_NAMES = ("full_path", "filename_only")
|
||||
FUNCTION = "zip_folder"
|
||||
CATEGORY = "Custom"
|
||||
|
||||
def zip_folder(self, seed, clear_previous_zips):
|
||||
if folder_paths:
|
||||
output_dir = Path(folder_paths.get_output_directory())
|
||||
else:
|
||||
output_dir = Path("output")
|
||||
|
||||
if not output_dir.exists():
|
||||
output_dir = Path("output")
|
||||
|
||||
# --- オプション: 古いzip削除 ---
|
||||
if clear_previous_zips:
|
||||
for existing_zip in output_dir.glob("*.zip"):
|
||||
try:
|
||||
existing_zip.unlink()
|
||||
print(f"Deleted old zip: {existing_zip}")
|
||||
except Exception as e:
|
||||
print(f"Failed to delete {existing_zip}: {e}")
|
||||
|
||||
# --- Zipファイル名作成 ---
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
zip_filename = f"output_{timestamp}.zip"
|
||||
zip_path = output_dir / zip_filename
|
||||
|
||||
# --- Zip作成 ---
|
||||
with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zipf:
|
||||
for file_path in output_dir.rglob("*"):
|
||||
if not file_path.is_file():
|
||||
continue
|
||||
if file_path.absolute() == zip_path.absolute():
|
||||
continue
|
||||
if file_path.suffix.lower() == ".zip":
|
||||
continue
|
||||
|
||||
arcname = file_path.relative_to(output_dir)
|
||||
zipf.write(file_path, arcname)
|
||||
|
||||
print(f"Zip created: {zip_path}")
|
||||
|
||||
# フルパスと、ファイル名単体を返す
|
||||
return (str(zip_path), zip_filename)
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"Zip Output Folder": ZipOutputFolder
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"Zip Output Folder": "Zip Output Folder (Batch)"
|
||||
}
|
||||
Reference in New Issue
Block a user