| |
|
|
| import os |
| import shutil |
| import tarfile |
| import tempfile |
| import requests |
|
|
| class DownloadLoRANode: |
| @classmethod |
| def INPUT_TYPES(cls): |
| return { |
| "required": { |
| "lora_url": ("STRING", {"default": "https://example.com/flux-lora.tar"}), |
| "lora_name": ("STRING", {"default": "my_lora"}), |
| "loras_dir": ("STRING", {"default": "./ComfyUI/models/loras"}), |
| } |
| } |
|
|
| RETURN_TYPES = ("STRING",) |
| FUNCTION = "download_lora" |
| CATEGORY = "Utils/LoRA" |
| NODE_NAME = "Download LoRA (.tar URL)" |
|
|
| def download_lora(self, lora_url, lora_name, loras_dir): |
| os.makedirs(loras_dir, exist_ok=True) |
|
|
| with tempfile.TemporaryDirectory() as tmpdir: |
| tar_path = os.path.join(tmpdir, f"{lora_name}.tar") |
|
|
| |
| with requests.get(lora_url, stream=True, timeout=300) as r: |
| r.raise_for_status() |
| with open(tar_path, "wb") as f: |
| for chunk in r.iter_content(1 << 20): |
| f.write(chunk) |
|
|
| |
| with tarfile.open(tar_path, "r") as t: |
| t.extractall(tmpdir) |
|
|
| |
| safetensor_file = None |
| for root, _, files in os.walk(tmpdir): |
| for fn in files: |
| if fn.endswith(".safetensors"): |
| safetensor_file = os.path.join(root, fn) |
| break |
| if safetensor_file: |
| break |
|
|
| if not safetensor_file: |
| raise RuntimeError("❌ Не найден .safetensors в архиве") |
|
|
| dst = os.path.join(loras_dir, f"{lora_name}.safetensors") |
| shutil.move(safetensor_file, dst) |
|
|
| return (dst,) |
|
|
|
|
| NODE_CLASS_MAPPINGS = { |
| "Download LoRA (.tar URL)": DownloadLoRANode |
| } |
|
|