webtools-cli 1.3.2__tar.gz → 1.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- webtools_cli-1.3.4/ComfyUI/comfyUI.py +126 -0
- webtools_cli-1.3.4/ComfyUI/comfyu.py +120 -0
- webtools_cli-1.3.4/ComfyUI/ui.py +98 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/PKG-INFO +8 -1
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/README.md +7 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/pyproject.toml +3 -2
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/core.py +133 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools_cli.egg-info/PKG-INFO +8 -1
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools_cli.egg-info/SOURCES.txt +3 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools_cli.egg-info/top_level.txt +1 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/LICENSE +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/setup.cfg +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/__init__.py +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/__main__.py +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/cli.py +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/install.py +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/mega_client.py +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/web/index.html +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/web/script.js +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools/web/style.css +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools_cli.egg-info/dependency_links.txt +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools_cli.egg-info/entry_points.txt +0 -0
- {webtools_cli-1.3.2 → webtools_cli-1.3.4}/webtools_cli.egg-info/requires.txt +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#@title 1. System Initialization
|
|
2
|
+
#@markdown **Run this cell first.** <br>
|
|
3
|
+
#@markdown Mounts Drive, sets up ComfyUI, and extracts your high-speed Tarball cache to the local SSD for instant booting.
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
# --- Input Resources (Environment Variable Overrides) ---
|
|
11
|
+
try:
|
|
12
|
+
from google.colab import drive
|
|
13
|
+
COLAB_AVAILABLE = True
|
|
14
|
+
except ImportError:
|
|
15
|
+
COLAB_AVAILABLE = False
|
|
16
|
+
|
|
17
|
+
# Configuration from environment or defaults
|
|
18
|
+
WORKSPACE_ROOT = os.environ.get("COMFYUI_WORKSPACE")
|
|
19
|
+
if not WORKSPACE_ROOT:
|
|
20
|
+
WORKSPACE_ROOT = "/content/ComfyUI" if COLAB_AVAILABLE else os.path.join(os.getcwd(), "ComfyUI_repo")
|
|
21
|
+
|
|
22
|
+
MOUNT_DRIVE = os.environ.get("MOUNT_DRIVE", "true").lower() == "true" if COLAB_AVAILABLE else False
|
|
23
|
+
UPDATE_COMFY_UI = os.environ.get("UPDATE_COMFY_UI", "false").lower() == "true"
|
|
24
|
+
INSTALL_COMFYUI_MANAGER = os.environ.get("INSTALL_COMFYUI_MANAGER", "true").lower() == "true"
|
|
25
|
+
|
|
26
|
+
LOCAL_WORKSPACE = WORKSPACE_ROOT
|
|
27
|
+
DRIVE_WORKSPACE = "/content/drive/MyDrive/ComfyUI" if COLAB_AVAILABLE else os.path.join(os.getcwd(), "ComfyUI_drive_sim")
|
|
28
|
+
CACHE_TAR = os.path.join(DRIVE_WORKSPACE, "comfy_ui_cache.tar")
|
|
29
|
+
|
|
30
|
+
def stream_cmd(cmd, cwd=None):
|
|
31
|
+
"""Streams shell commands directly to the output"""
|
|
32
|
+
try:
|
|
33
|
+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=cwd, bufsize=1)
|
|
34
|
+
for line in iter(process.stdout.readline, ''):
|
|
35
|
+
sys.stdout.write(line)
|
|
36
|
+
sys.stdout.flush()
|
|
37
|
+
process.wait()
|
|
38
|
+
return process.returncode
|
|
39
|
+
except Exception as e:
|
|
40
|
+
print(f"Error executing command {cmd}: {e}")
|
|
41
|
+
return 1
|
|
42
|
+
|
|
43
|
+
def setup_comfyui():
|
|
44
|
+
print("[SYSTEM] Initialization Protocol Started...\n")
|
|
45
|
+
|
|
46
|
+
# 1. Mount Google Drive
|
|
47
|
+
if MOUNT_DRIVE and COLAB_AVAILABLE:
|
|
48
|
+
print("💾 Requesting Google Drive Access...")
|
|
49
|
+
try:
|
|
50
|
+
drive.mount('/content/drive')
|
|
51
|
+
except Exception as e:
|
|
52
|
+
print(f"⚠️ Drive mount failed: {e}")
|
|
53
|
+
|
|
54
|
+
# 2. Setup ComfyUI Core
|
|
55
|
+
if not os.path.exists(LOCAL_WORKSPACE):
|
|
56
|
+
print(f"\n📦 Cloning ComfyUI repository to {LOCAL_WORKSPACE}...")
|
|
57
|
+
subprocess.run(["git", "clone", "https://github.com/comfyanonymous/ComfyUI", LOCAL_WORKSPACE])
|
|
58
|
+
else:
|
|
59
|
+
if UPDATE_COMFY_UI:
|
|
60
|
+
print("\n🔄 Checking for ComfyUI updates...")
|
|
61
|
+
subprocess.run(["git", "pull"], cwd=LOCAL_WORKSPACE)
|
|
62
|
+
|
|
63
|
+
# 3. Configure Hybrid Storage & Tarball Cache
|
|
64
|
+
heavy_dirs = ["models", "output", "input"]
|
|
65
|
+
print("\n🔗 Routing heavy model directories...")
|
|
66
|
+
for d in heavy_dirs:
|
|
67
|
+
local_path = os.path.join(LOCAL_WORKSPACE, d)
|
|
68
|
+
drive_path = os.path.join(DRIVE_WORKSPACE, d)
|
|
69
|
+
if not os.path.exists(drive_path): os.makedirs(drive_path, exist_ok=True)
|
|
70
|
+
|
|
71
|
+
if os.path.exists(local_path) and not os.path.islink(local_path):
|
|
72
|
+
try:
|
|
73
|
+
if os.path.isdir(local_path): shutil.rmtree(local_path)
|
|
74
|
+
else: os.remove(local_path)
|
|
75
|
+
except: pass
|
|
76
|
+
|
|
77
|
+
if not os.path.exists(local_path):
|
|
78
|
+
try:
|
|
79
|
+
# Use absolute paths for symlinks to be safe
|
|
80
|
+
os.symlink(os.path.abspath(drive_path), os.path.abspath(local_path))
|
|
81
|
+
except Exception as e:
|
|
82
|
+
print(f" ⚠️ Could not create symlink for {d}: {e}")
|
|
83
|
+
|
|
84
|
+
print("\n⚡ Deploying High-Speed Tarball Cache for UI Elements...")
|
|
85
|
+
if os.path.exists(CACHE_TAR):
|
|
86
|
+
print(" 📦 Extracting cached UI nodes to local SSD...")
|
|
87
|
+
os.system(f"tar -xf '{CACHE_TAR}' -C '{LOCAL_WORKSPACE}' > /dev/null 2>&1")
|
|
88
|
+
else:
|
|
89
|
+
print(" ⚠️ No cache found. Creating fresh local directories...")
|
|
90
|
+
os.makedirs(os.path.join(LOCAL_WORKSPACE, "custom_nodes"), exist_ok=True)
|
|
91
|
+
os.makedirs(os.path.join(LOCAL_WORKSPACE, "user"), exist_ok=True)
|
|
92
|
+
|
|
93
|
+
# 4. Install ComfyUI Manager
|
|
94
|
+
if INSTALL_COMFYUI_MANAGER:
|
|
95
|
+
manager_path = os.path.join(LOCAL_WORKSPACE, "custom_nodes", "ComfyUI-Manager")
|
|
96
|
+
if not os.path.exists(manager_path):
|
|
97
|
+
print("\n📦 Installing ComfyUI Manager...")
|
|
98
|
+
subprocess.run(["git", "clone", "https://github.com/ltdrdata/ComfyUI-Manager.git", manager_path])
|
|
99
|
+
else:
|
|
100
|
+
print("\n✅ ComfyUI Manager verified.")
|
|
101
|
+
subprocess.run(["git", "pull"], cwd=manager_path)
|
|
102
|
+
|
|
103
|
+
# 5. Core Python Dependencies
|
|
104
|
+
print("\n🛠️ Installing base Python requirements...")
|
|
105
|
+
# Check if requirements.txt exists in LOCAL_WORKSPACE
|
|
106
|
+
req_file = os.path.join(LOCAL_WORKSPACE, "requirements.txt")
|
|
107
|
+
if os.path.exists(req_file):
|
|
108
|
+
stream_cmd([sys.executable, "-m", "pip", "install", "xformers!=0.0.18", "-r", "requirements.txt", "--extra-index-url", "https://download.pytorch.org/whl/cu121"], cwd=LOCAL_WORKSPACE)
|
|
109
|
+
|
|
110
|
+
stream_cmd([sys.executable, "-m", "pip", "install", "insightface", "onnxruntime-gpu"])
|
|
111
|
+
|
|
112
|
+
# 6. AUTO-HEAL: Custom Node Dependencies
|
|
113
|
+
print("\n🔍 [AUTO-HEAL] Scanning local custom nodes for missing dependencies...")
|
|
114
|
+
custom_nodes_dir = os.path.join(LOCAL_WORKSPACE, "custom_nodes")
|
|
115
|
+
if os.path.exists(custom_nodes_dir):
|
|
116
|
+
for item in os.listdir(custom_nodes_dir):
|
|
117
|
+
node_path = os.path.join(custom_nodes_dir, item)
|
|
118
|
+
node_req = os.path.join(node_path, "requirements.txt")
|
|
119
|
+
if os.path.isdir(node_path) and os.path.exists(node_req):
|
|
120
|
+
print(f"\n ⚙️ Restoring dependencies for: {item}")
|
|
121
|
+
stream_cmd([sys.executable, "-m", "pip", "install", "-r", "requirements.txt"], cwd=node_path)
|
|
122
|
+
|
|
123
|
+
print("\n✅ [SYSTEM READY] Initialization complete.")
|
|
124
|
+
|
|
125
|
+
if __name__ == "__main__":
|
|
126
|
+
setup_comfyui()
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import requests
|
|
3
|
+
import subprocess
|
|
4
|
+
import sys
|
|
5
|
+
from urllib.parse import urlparse, unquote
|
|
6
|
+
from tqdm.auto import tqdm
|
|
7
|
+
|
|
8
|
+
# --- Input Resources (Environment Variable Overrides) ---
|
|
9
|
+
WORKSPACE = os.environ.get("COMFYUI_WORKSPACE", "/content/ComfyUI")
|
|
10
|
+
CHECKPOINT_URLS = os.environ.get("CHECKPOINT_URLS", "")
|
|
11
|
+
UNET_DIFFUSION_URLS = os.environ.get("UNET_DIFFUSION_URLS", "")
|
|
12
|
+
TEXT_ENCODER_URLS = os.environ.get("TEXT_ENCODER_URLS", "")
|
|
13
|
+
CLIP_VISION_URLS = os.environ.get("CLIP_VISION_URLS", "")
|
|
14
|
+
VAE_URLS = os.environ.get("VAE_URLS", "")
|
|
15
|
+
LORA_URLS = os.environ.get("LORA_URLS", "")
|
|
16
|
+
CONTROLNET_URLS = os.environ.get("CONTROLNET_URLS", "")
|
|
17
|
+
UPSCALE_MODELS_URLS = os.environ.get("UPSCALE_MODELS_URLS", "")
|
|
18
|
+
EMBEDDING_URLS = os.environ.get("EMBEDDING_URLS", "")
|
|
19
|
+
CUSTOM_NODE_URLS = os.environ.get("CUSTOM_NODE_URLS", "")
|
|
20
|
+
|
|
21
|
+
# --- Downloader Logic ---
|
|
22
|
+
DIRS = {
|
|
23
|
+
"checkpoints": os.path.join(WORKSPACE, "models/checkpoints"),
|
|
24
|
+
"unet": os.path.join(WORKSPACE, "models/unet"),
|
|
25
|
+
"clip": os.path.join(WORKSPACE, "models/clip"),
|
|
26
|
+
"clip_vision": os.path.join(WORKSPACE, "models/clip_vision"),
|
|
27
|
+
"vae": os.path.join(WORKSPACE, "models/vae"),
|
|
28
|
+
"loras": os.path.join(WORKSPACE, "models/loras"),
|
|
29
|
+
"controlnet": os.path.join(WORKSPACE, "models/controlnet"),
|
|
30
|
+
"upscale_models": os.path.join(WORKSPACE, "models/upscale_models"),
|
|
31
|
+
"embeddings": os.path.join(WORKSPACE, "models/embeddings"),
|
|
32
|
+
"custom_nodes": os.path.join(WORKSPACE, "custom_nodes")
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
def get_filename(url, response):
|
|
36
|
+
"""Smartly determines filename from Content-Disposition or URL."""
|
|
37
|
+
if "Content-Disposition" in response.headers:
|
|
38
|
+
import re
|
|
39
|
+
fname = re.findall('filename="?([^"]+)"?', response.headers["Content-Disposition"])
|
|
40
|
+
if fname: return fname[0]
|
|
41
|
+
return unquote(os.path.basename(urlparse(url).path))
|
|
42
|
+
|
|
43
|
+
def download_file(url, target_dir):
|
|
44
|
+
try:
|
|
45
|
+
# Stream the download to get headers first
|
|
46
|
+
response = requests.get(url, stream=True, allow_redirects=True)
|
|
47
|
+
response.raise_for_status()
|
|
48
|
+
|
|
49
|
+
filename = get_filename(url, response)
|
|
50
|
+
file_path = os.path.join(target_dir, filename)
|
|
51
|
+
total_size = int(response.headers.get('content-length', 0))
|
|
52
|
+
|
|
53
|
+
if os.path.exists(file_path):
|
|
54
|
+
print(f" ⏩ Skipping (Exists): {filename}")
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
# Modern Progress Bar Log
|
|
58
|
+
print(f" 📥 Downloading: {filename}")
|
|
59
|
+
|
|
60
|
+
# The Progress Bar (Auto-Stretching)
|
|
61
|
+
with tqdm(
|
|
62
|
+
total=total_size,
|
|
63
|
+
unit='B',
|
|
64
|
+
unit_scale=True,
|
|
65
|
+
unit_divisor=1024,
|
|
66
|
+
desc=" 🚀 Progress",
|
|
67
|
+
dynamic_ncols=True
|
|
68
|
+
) as bar:
|
|
69
|
+
with open(file_path, 'wb') as f:
|
|
70
|
+
for chunk in response.iter_content(chunk_size=1024*1024): # 1MB chunks
|
|
71
|
+
if chunk:
|
|
72
|
+
f.write(chunk)
|
|
73
|
+
bar.update(len(chunk))
|
|
74
|
+
|
|
75
|
+
print(" ✅ Download Complete\n")
|
|
76
|
+
|
|
77
|
+
except Exception as e:
|
|
78
|
+
print(f" ❌ Failed to download: {url}")
|
|
79
|
+
print(f" Error: {e}\n")
|
|
80
|
+
|
|
81
|
+
def process_downloads(urls_str, target_dir, is_node=False):
|
|
82
|
+
if not urls_str.strip(): return
|
|
83
|
+
|
|
84
|
+
url_list = [u.strip() for u in urls_str.replace(',', '\n').split('\n') if u.strip()]
|
|
85
|
+
if not os.path.exists(target_dir): os.makedirs(target_dir, exist_ok=True)
|
|
86
|
+
|
|
87
|
+
print(f"📂 Category: {os.path.basename(target_dir)}")
|
|
88
|
+
|
|
89
|
+
for url in url_list:
|
|
90
|
+
if is_node:
|
|
91
|
+
node_name = url.split('/')[-1].replace('.git', '')
|
|
92
|
+
node_path = os.path.join(target_dir, node_name)
|
|
93
|
+
if not os.path.exists(node_path):
|
|
94
|
+
print(f" ⬇️ Cloning Node: {node_name}...")
|
|
95
|
+
subprocess.run(["git", "clone", url, node_path])
|
|
96
|
+
# Auto-install requirements
|
|
97
|
+
req = os.path.join(node_path, "requirements.txt")
|
|
98
|
+
if os.path.exists(req):
|
|
99
|
+
print(f" 📦 Installing requirements...")
|
|
100
|
+
subprocess.run([sys.executable, "-m", "pip", "install", "-r", req])
|
|
101
|
+
print(" ✅ Installed\n")
|
|
102
|
+
else:
|
|
103
|
+
print(f" ⏩ Node exists: {node_name}\n")
|
|
104
|
+
else:
|
|
105
|
+
download_file(url, target_dir)
|
|
106
|
+
|
|
107
|
+
if __name__ == "__main__":
|
|
108
|
+
# --- Execution ---
|
|
109
|
+
process_downloads(CHECKPOINT_URLS, DIRS["checkpoints"])
|
|
110
|
+
process_downloads(UNET_DIFFUSION_URLS, DIRS["unet"])
|
|
111
|
+
process_downloads(TEXT_ENCODER_URLS, DIRS["clip"])
|
|
112
|
+
process_downloads(CLIP_VISION_URLS, DIRS["clip_vision"])
|
|
113
|
+
process_downloads(VAE_URLS, DIRS["vae"])
|
|
114
|
+
process_downloads(LORA_URLS, DIRS["loras"])
|
|
115
|
+
process_downloads(CONTROLNET_URLS, DIRS["controlnet"])
|
|
116
|
+
process_downloads(UPSCALE_MODELS_URLS, DIRS["upscale_models"])
|
|
117
|
+
process_downloads(EMBEDDING_URLS, DIRS["embeddings"])
|
|
118
|
+
process_downloads(CUSTOM_NODE_URLS, DIRS["custom_nodes"], is_node=True)
|
|
119
|
+
|
|
120
|
+
print("🎉 All tasks finished.")
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#@title 4. Start ComfyUI Session
|
|
2
|
+
#@markdown Installs missing runtime dependencies, establishes an optimized IPv4 Cloudflare tunnel, and launches the ComfyUI web interface with live standard logs.
|
|
3
|
+
|
|
4
|
+
import subprocess
|
|
5
|
+
import threading
|
|
6
|
+
import time
|
|
7
|
+
import socket
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
# --- Session Configuration ---
|
|
12
|
+
#@markdown **Performance Profile:**
|
|
13
|
+
MEMORY_PROFILE = "Standard (Auto-Detect)" #@param ["Standard (Auto-Detect)", "Low VRAM (T4 GPU / Heavy Models)", "High VRAM (A100 GPU Only)"]
|
|
14
|
+
#@markdown **Visual Settings:**
|
|
15
|
+
LIVE_GENERATION_PREVIEWS = True #@param {type:"boolean"}
|
|
16
|
+
|
|
17
|
+
# Dynamic Workspace detection
|
|
18
|
+
WORKSPACE = os.environ.get("COMFYUI_WORKSPACE")
|
|
19
|
+
if not WORKSPACE:
|
|
20
|
+
if os.path.exists("/content/ComfyUI"):
|
|
21
|
+
WORKSPACE = "/content/ComfyUI"
|
|
22
|
+
else:
|
|
23
|
+
# Try to find it relative to this script
|
|
24
|
+
# Check if current directory has main.py (indicating we are inside ComfyUI)
|
|
25
|
+
if os.path.exists("main.py"):
|
|
26
|
+
WORKSPACE = os.getcwd()
|
|
27
|
+
else:
|
|
28
|
+
WORKSPACE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ComfyUI_repo")
|
|
29
|
+
|
|
30
|
+
ARGS = []
|
|
31
|
+
|
|
32
|
+
if "Low VRAM" in MEMORY_PROFILE:
|
|
33
|
+
ARGS.append("--lowvram")
|
|
34
|
+
elif "High VRAM" in MEMORY_PROFILE:
|
|
35
|
+
ARGS.append("--highvram")
|
|
36
|
+
|
|
37
|
+
if LIVE_GENERATION_PREVIEWS:
|
|
38
|
+
ARGS.extend(["--preview-method", "auto"])
|
|
39
|
+
|
|
40
|
+
# 0. Auto-Heal Missing Custom Node Dependencies
|
|
41
|
+
print("[SYSTEM] Auto-healing runtime dependencies...")
|
|
42
|
+
os.system("pip install -q gguf piexif > /dev/null 2>&1")
|
|
43
|
+
|
|
44
|
+
# 1. Initialize Network Tunnel
|
|
45
|
+
print("[SYSTEM] Verifying Cloudflare Daemon...")
|
|
46
|
+
if not os.path.exists("/usr/bin/cloudflared"):
|
|
47
|
+
print("[SYSTEM] Fetching Cloudflared via aria2c...")
|
|
48
|
+
os.system("apt-get install -y aria2 > /dev/null 2>&1")
|
|
49
|
+
os.system("aria2c -x 16 -s 16 -k 1M https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -d /content -o cloudflared.deb > /dev/null 2>&1")
|
|
50
|
+
os.system("dpkg -i /content/cloudflared.deb > /dev/null 2>&1")
|
|
51
|
+
|
|
52
|
+
def start_tunnel(port):
|
|
53
|
+
while True:
|
|
54
|
+
time.sleep(1)
|
|
55
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
56
|
+
result = sock.connect_ex(('127.0.0.1', port))
|
|
57
|
+
sock.close()
|
|
58
|
+
if result == 0:
|
|
59
|
+
break
|
|
60
|
+
|
|
61
|
+
print("\n[SYSTEM] ComfyUI Local Server Detected. Establishing Secure Tunnel...")
|
|
62
|
+
|
|
63
|
+
p = subprocess.Popen(
|
|
64
|
+
["cloudflared", "tunnel", "--url", f"http://127.0.0.1:{port}", "--edge-ip-version", "4", "--protocol", "http2"],
|
|
65
|
+
stdout=subprocess.PIPE,
|
|
66
|
+
stderr=subprocess.PIPE,
|
|
67
|
+
text=True
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
tunnel_established = False
|
|
71
|
+
for line in p.stderr:
|
|
72
|
+
if "trycloudflare.com" in line and not tunnel_established:
|
|
73
|
+
parts = line.split()
|
|
74
|
+
for part in parts:
|
|
75
|
+
if "trycloudflare.com" in part and part.startswith("http"):
|
|
76
|
+
url = part.strip()
|
|
77
|
+
print("\n" + "="*60)
|
|
78
|
+
print(f"🚀 ACTIVE TUNNEL: {url}")
|
|
79
|
+
print("="*60 + "\n")
|
|
80
|
+
tunnel_established = True
|
|
81
|
+
break
|
|
82
|
+
|
|
83
|
+
threading.Thread(target=start_tunnel, daemon=True, args=(8188,)).start()
|
|
84
|
+
|
|
85
|
+
# 2. Launch Application
|
|
86
|
+
if os.path.exists(os.path.join(WORKSPACE, "main.py")):
|
|
87
|
+
os.chdir(WORKSPACE)
|
|
88
|
+
print(f"[SYSTEM] Booting ComfyUI [Profile: {MEMORY_PROFILE}]")
|
|
89
|
+
print("[SYSTEM] Streaming Logs...\n" + "-"*60)
|
|
90
|
+
|
|
91
|
+
cmd = ["python", "main.py", "--listen", "127.0.0.1", "--port", "8188"] + ARGS
|
|
92
|
+
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1)
|
|
93
|
+
|
|
94
|
+
for line in iter(process.stdout.readline, ''):
|
|
95
|
+
sys.stdout.write(line)
|
|
96
|
+
sys.stdout.flush()
|
|
97
|
+
else:
|
|
98
|
+
print("[FATAL ERROR] ComfyUI directory missing. Please re-run the initialization cell.")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: webtools-cli
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: Advanced Web Intelligence & Scraping Toolkit with CLI and Web UI
|
|
5
5
|
Author: Abhinav Adarsh
|
|
6
6
|
License-Expression: MIT
|
|
@@ -98,6 +98,12 @@ pip install webtools-cli --upgrade
|
|
|
98
98
|
- **Image Forensics**: CLI-based Error Level Analysis (ELA) and AI-likelihood detection.
|
|
99
99
|
- **Honeypot Detector**: Identifies hidden traps and anti-bot measures (Cloudflare/CAPTCHAs).
|
|
100
100
|
|
|
101
|
+
### AI Generation & Creative Tools
|
|
102
|
+
- **ComfyUI Integration**: Seamlessly launch a full Stable Diffusion interface directly from the CLI.
|
|
103
|
+
- **Anime Studio (Anima)**: Specialized "Make Anime" mode with automated Anima model downloads (UNET, Text Encoder, VAE) from Hugging Face.
|
|
104
|
+
- **Colab Optimized**: Pre-configured for Google Colab with T4 GPU support and automated environment setup.
|
|
105
|
+
- **Secure Tunnels**: Instant Cloudflare tunnel generation for remote UI access with live logging.
|
|
106
|
+
|
|
101
107
|
### Modern Experience
|
|
102
108
|
- **Premium Visual Engine**: Sleek glassmorphism, fluid gradients, and premium Motion One animations.
|
|
103
109
|
- **Responsive Preview**: Live rendering scaling for desktop and mobile viewpoints.
|
|
@@ -128,6 +134,7 @@ Navigate the suite using quick terminal commands:
|
|
|
128
134
|
| `/web` | `/w` | Launch **Web UI** (Cloudflare Tunnel + QR) |
|
|
129
135
|
| `/cli` | `/c` | Launch **CLI Intelligence** scan |
|
|
130
136
|
| `/image` | `/i` | **Image Forensics** & AI Likelihood |
|
|
137
|
+
| `/cui` | - | **ComfyUI** AI Generation (GPU Required) |
|
|
131
138
|
| `/history`| `/hi`| View and manage scan history |
|
|
132
139
|
| `/help` | `/h` | Show full command documentation |
|
|
133
140
|
| `/clear` | - | Purge all locally scraped data |
|
|
@@ -60,6 +60,12 @@ pip install webtools-cli --upgrade
|
|
|
60
60
|
- **Image Forensics**: CLI-based Error Level Analysis (ELA) and AI-likelihood detection.
|
|
61
61
|
- **Honeypot Detector**: Identifies hidden traps and anti-bot measures (Cloudflare/CAPTCHAs).
|
|
62
62
|
|
|
63
|
+
### AI Generation & Creative Tools
|
|
64
|
+
- **ComfyUI Integration**: Seamlessly launch a full Stable Diffusion interface directly from the CLI.
|
|
65
|
+
- **Anime Studio (Anima)**: Specialized "Make Anime" mode with automated Anima model downloads (UNET, Text Encoder, VAE) from Hugging Face.
|
|
66
|
+
- **Colab Optimized**: Pre-configured for Google Colab with T4 GPU support and automated environment setup.
|
|
67
|
+
- **Secure Tunnels**: Instant Cloudflare tunnel generation for remote UI access with live logging.
|
|
68
|
+
|
|
63
69
|
### Modern Experience
|
|
64
70
|
- **Premium Visual Engine**: Sleek glassmorphism, fluid gradients, and premium Motion One animations.
|
|
65
71
|
- **Responsive Preview**: Live rendering scaling for desktop and mobile viewpoints.
|
|
@@ -90,6 +96,7 @@ Navigate the suite using quick terminal commands:
|
|
|
90
96
|
| `/web` | `/w` | Launch **Web UI** (Cloudflare Tunnel + QR) |
|
|
91
97
|
| `/cli` | `/c` | Launch **CLI Intelligence** scan |
|
|
92
98
|
| `/image` | `/i` | **Image Forensics** & AI Likelihood |
|
|
99
|
+
| `/cui` | - | **ComfyUI** AI Generation (GPU Required) |
|
|
93
100
|
| `/history`| `/hi`| View and manage scan history |
|
|
94
101
|
| `/help` | `/h` | Show full command documentation |
|
|
95
102
|
| `/clear` | - | Purge all locally scraped data |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "webtools-cli"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.4"
|
|
8
8
|
description = "Advanced Web Intelligence & Scraping Toolkit with CLI and Web UI"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -52,7 +52,8 @@ webtools-install = "webtools.install:install_playwright_browsers"
|
|
|
52
52
|
Homepage = "https://webtoolscli.pages.dev"
|
|
53
53
|
|
|
54
54
|
[tool.setuptools.packages.find]
|
|
55
|
-
include = ["webtools*"]
|
|
55
|
+
include = ["webtools*", "ComfyUI*"]
|
|
56
56
|
|
|
57
57
|
[tool.setuptools.package-data]
|
|
58
58
|
webtools = ["web/*"]
|
|
59
|
+
ComfyUI = ["*.py"]
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import sys,os,re,requests,random,subprocess,time,socket,shutil,json,zipfile,atexit,concurrent.futures,threading,qrcode,logging,queue,urllib3,base64,traceback,csv,io,mtranslate,hashlib,uuid
|
|
2
2
|
sys.dont_write_bytecode = True
|
|
3
3
|
|
|
4
|
+
def is_colab():
|
|
5
|
+
"""Detects if we are running in a Google Colab environment."""
|
|
6
|
+
return 'COLAB_GPU' in os.environ or os.path.exists('/content')
|
|
7
|
+
|
|
8
|
+
def check_gpu():
|
|
9
|
+
"""Checks if a GPU is available on the system."""
|
|
10
|
+
try:
|
|
11
|
+
import torch
|
|
12
|
+
return torch.cuda.is_available()
|
|
13
|
+
except ImportError:
|
|
14
|
+
try:
|
|
15
|
+
# Fallback to nvidia-smi check
|
|
16
|
+
subprocess.check_output(['nvidia-smi'], stderr=subprocess.STDOUT)
|
|
17
|
+
return True
|
|
18
|
+
except:
|
|
19
|
+
return False
|
|
20
|
+
|
|
4
21
|
# Enforce UTF-8 encoding for standard output to avoid UnicodeEncodeError on Windows (Emojis)
|
|
5
22
|
if sys.stdout.encoding and sys.stdout.encoding.lower() != 'utf-8':
|
|
6
23
|
try:
|
|
@@ -3480,9 +3497,117 @@ def print_image_forensics_report(data):
|
|
|
3480
3497
|
|
|
3481
3498
|
print(f"{c_b}╚{'═'*(total_w-2)}╝{R}\n")
|
|
3482
3499
|
|
|
3500
|
+
def find_comfy_dir():
|
|
3501
|
+
"""Robustly find the ComfyUI directory"""
|
|
3502
|
+
on_colab = is_colab()
|
|
3503
|
+
possible_paths = [
|
|
3504
|
+
os.path.join(os.getcwd(), "ComfyUI"), # Current directory (clone)
|
|
3505
|
+
os.path.join(os.path.dirname(PACKAGE_DIR), "ComfyUI"), # Sibling of webtools
|
|
3506
|
+
os.path.join(PACKAGE_DIR, "ComfyUI"), # Inside webtools
|
|
3507
|
+
"/content/webtools-cli/ComfyUI" if on_colab else None, # Colab default
|
|
3508
|
+
"/content/ComfyUI" if on_colab else None # Direct colab
|
|
3509
|
+
]
|
|
3510
|
+
for p in possible_paths:
|
|
3511
|
+
if p and os.path.exists(os.path.join(p, "ui.py")):
|
|
3512
|
+
return p
|
|
3513
|
+
# Recursive search as last resort
|
|
3514
|
+
for root, dirs, files in os.walk(os.getcwd()):
|
|
3515
|
+
if "ComfyUI" in dirs:
|
|
3516
|
+
p = os.path.join(root, "ComfyUI")
|
|
3517
|
+
if os.path.exists(os.path.join(p, "ui.py")):
|
|
3518
|
+
return p
|
|
3519
|
+
return None
|
|
3520
|
+
|
|
3521
|
+
def run_comfyui_mode():
|
|
3522
|
+
"""Start ComfyUI session with GPU and Colab detection"""
|
|
3523
|
+
on_colab = is_colab()
|
|
3524
|
+
has_gpu = check_gpu()
|
|
3525
|
+
|
|
3526
|
+
if not on_colab and not has_gpu:
|
|
3527
|
+
print(f"\n{Fore.RED}❌ ERROR: GPU not detected! ComfyUI requires a GPU to run.{Style.RESET_ALL}")
|
|
3528
|
+
input("\nPress Enter to return to main menu...")
|
|
3529
|
+
return
|
|
3530
|
+
|
|
3531
|
+
comfy_dir = find_comfy_dir()
|
|
3532
|
+
if not comfy_dir:
|
|
3533
|
+
print(f"\n{Fore.RED}❌ ERROR: ComfyUI folder not found!{Style.RESET_ALL}")
|
|
3534
|
+
input("\nPress Enter to return to main menu...")
|
|
3535
|
+
return
|
|
3536
|
+
|
|
3537
|
+
while True:
|
|
3538
|
+
os.system('cls' if os.name == 'nt' else 'clear')
|
|
3539
|
+
print(f"\n{Fore.CYAN}--- ComfyUI Launcher ---{Style.RESET_ALL}")
|
|
3540
|
+
print(f" {Fore.CYAN}[1]{Style.RESET_ALL} Launch Standard ComfyUI")
|
|
3541
|
+
print(f" {Fore.CYAN}[2]{Style.RESET_ALL} Launch Anime ComfyUI (Anima Model)")
|
|
3542
|
+
print(f" {Fore.RED}[b]{Style.RESET_ALL} Back to main menu")
|
|
3543
|
+
|
|
3544
|
+
cui_choice = input(f"\n{Fore.LIGHTGREEN_EX}> {Style.RESET_ALL}").strip().lower()
|
|
3545
|
+
|
|
3546
|
+
if cui_choice == 'b':
|
|
3547
|
+
return
|
|
3548
|
+
|
|
3549
|
+
if cui_choice not in ['1', '2']:
|
|
3550
|
+
continue
|
|
3551
|
+
|
|
3552
|
+
if on_colab:
|
|
3553
|
+
print(f"\n{Fore.YELLOW}⚠️ Google Colab Detected!{Style.RESET_ALL}")
|
|
3554
|
+
print(f"{Fore.CYAN}👉 IMPORTANT: Switch to T4 GPU (Edit -> Notebook settings -> T4 GPU).{Style.RESET_ALL}")
|
|
3555
|
+
time.sleep(2)
|
|
3556
|
+
|
|
3557
|
+
print(f"\n{Fore.GREEN}🚀 Starting ComfyUI Setup & Session...{Style.RESET_ALL}")
|
|
3558
|
+
|
|
3559
|
+
# 0. Run System Initialization (comfyUI.py)
|
|
3560
|
+
# This ensures the ComfyUI repo is cloned and dependencies are installed
|
|
3561
|
+
init_script = os.path.join(comfy_dir, "comfyUI.py")
|
|
3562
|
+
if os.path.exists(init_script):
|
|
3563
|
+
print(f"\n{Fore.CYAN}--- Running System Initialization ---{Style.RESET_ALL}")
|
|
3564
|
+
init_env = os.environ.copy()
|
|
3565
|
+
init_env["COMFYUI_WORKSPACE"] = comfy_dir
|
|
3566
|
+
subprocess.run([sys.executable, init_script], env=init_env)
|
|
3567
|
+
else:
|
|
3568
|
+
print(f"{Fore.YELLOW}Warning: {init_script} not found. Skipping initialization.{Style.RESET_ALL}")
|
|
3569
|
+
|
|
3570
|
+
# 1. Handle Model Downloads if Anime chosen
|
|
3571
|
+
if cui_choice == '2':
|
|
3572
|
+
print(f"\n{Fore.MAGENTA}✨ Configuring Anime Model (Anima)...{Style.RESET_ALL}")
|
|
3573
|
+
download_env = os.environ.copy()
|
|
3574
|
+
download_env["UNET_DIFFUSION_URLS"] = "https://huggingface.co/circlestone-labs/Anima/resolve/main/split_files/diffusion_models/anima-preview3-base.safetensors"
|
|
3575
|
+
download_env["TEXT_ENCODER_URLS"] = "https://huggingface.co/circlestone-labs/Anima/resolve/main/split_files/text_encoders/qwen_3_06b_base.safetensors"
|
|
3576
|
+
download_env["VAE_URLS"] = "https://huggingface.co/circlestone-labs/Anima/resolve/main/split_files/vae/qwen_image_vae.safetensors"
|
|
3577
|
+
download_env["COMFYUI_WORKSPACE"] = comfy_dir
|
|
3578
|
+
|
|
3579
|
+
# Run comfyu.py with these env vars
|
|
3580
|
+
downloader_script = os.path.join(comfy_dir, "comfyu.py")
|
|
3581
|
+
if os.path.exists(downloader_script):
|
|
3582
|
+
subprocess.run([sys.executable, downloader_script], env=download_env)
|
|
3583
|
+
else:
|
|
3584
|
+
print(f"{Fore.RED}Error: {downloader_script} not found.{Style.RESET_ALL}")
|
|
3585
|
+
|
|
3586
|
+
# 2. Launch UI
|
|
3587
|
+
ui_script = os.path.join(comfy_dir, "ui.py")
|
|
3588
|
+
if os.path.exists(ui_script):
|
|
3589
|
+
print(f"\n{Fore.CYAN}--- Initializing ComfyUI Interface ---{Style.RESET_ALL}")
|
|
3590
|
+
try:
|
|
3591
|
+
ui_env = os.environ.copy()
|
|
3592
|
+
ui_env["COMFYUI_WORKSPACE"] = comfy_dir
|
|
3593
|
+
subprocess.run([sys.executable, ui_script], env=ui_env)
|
|
3594
|
+
except Exception as e:
|
|
3595
|
+
print(f"{Fore.RED}Error running ComfyUI: {e}{Style.RESET_ALL}")
|
|
3596
|
+
else:
|
|
3597
|
+
print(f"{Fore.RED}Error: {ui_script} not found.{Style.RESET_ALL}")
|
|
3598
|
+
|
|
3599
|
+
input("\nPress Enter to return to ComfyUI menu...")
|
|
3600
|
+
|
|
3483
3601
|
def main_launcher():
|
|
3484
3602
|
"""Mode selection menu on startup"""
|
|
3485
3603
|
menu_commands = ['/web', '/cli', '/image', '/adb', '/help', '/clear', '/quit', '/history', '/w', '/c', '/i', '/a', '/h', '/q', '/hi', '--help']
|
|
3604
|
+
|
|
3605
|
+
# Conditional ComfyUI visibility
|
|
3606
|
+
has_gpu = check_gpu()
|
|
3607
|
+
on_colab = is_colab()
|
|
3608
|
+
if has_gpu or on_colab:
|
|
3609
|
+
menu_commands.extend(['/cui'])
|
|
3610
|
+
|
|
3486
3611
|
setup_autocomplete(menu_commands)
|
|
3487
3612
|
|
|
3488
3613
|
while True:
|
|
@@ -3509,11 +3634,19 @@ def main_launcher():
|
|
|
3509
3634
|
run_cli_mode()
|
|
3510
3635
|
elif choice in ['/image', '/i']:
|
|
3511
3636
|
run_image_forensics_mode()
|
|
3637
|
+
elif choice in ['/cui']:
|
|
3638
|
+
if has_gpu or on_colab:
|
|
3639
|
+
run_comfyui_mode()
|
|
3640
|
+
else:
|
|
3641
|
+
print(f"\n{Fore.RED}⚠️ Unknown Command: {choice}")
|
|
3642
|
+
time.sleep(1.5)
|
|
3512
3643
|
elif choice in ['/help', '/h', '--help']:
|
|
3513
3644
|
print(f"\n{Fore.CYAN if COLOR_SUPPORT else ''}Available Commands:")
|
|
3514
3645
|
print(f" {Fore.CYAN}/web{Style.RESET_ALL} - Launches the web engine for browser-based auditing. (Alias: /w)")
|
|
3515
3646
|
print(f" {Fore.CYAN}/cli{Style.RESET_ALL} - Runs a deep-scan intelligence report in the terminal. (Alias: /c)")
|
|
3516
3647
|
print(f" {Fore.CYAN}/image{Style.RESET_ALL} - Local/Remote Image Forensics & AI detection. (Alias: /i)")
|
|
3648
|
+
if has_gpu or on_colab:
|
|
3649
|
+
print(f" {Fore.CYAN}/cui{Style.RESET_ALL} - Start ComfyUI session for AI generation.")
|
|
3517
3650
|
print(f" {Fore.CYAN}/adb{Style.RESET_ALL} - ADB Bloatware Remover for Android devices. (Alias: /a)")
|
|
3518
3651
|
print(f" {Fore.CYAN}/clear{Style.RESET_ALL} - Purges the 'webfiles/scraped' directory and clears screen.")
|
|
3519
3652
|
print(f" {Fore.CYAN}/history{Style.RESET_ALL} - Shows command history. (Alias: /hi)")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: webtools-cli
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: Advanced Web Intelligence & Scraping Toolkit with CLI and Web UI
|
|
5
5
|
Author: Abhinav Adarsh
|
|
6
6
|
License-Expression: MIT
|
|
@@ -98,6 +98,12 @@ pip install webtools-cli --upgrade
|
|
|
98
98
|
- **Image Forensics**: CLI-based Error Level Analysis (ELA) and AI-likelihood detection.
|
|
99
99
|
- **Honeypot Detector**: Identifies hidden traps and anti-bot measures (Cloudflare/CAPTCHAs).
|
|
100
100
|
|
|
101
|
+
### AI Generation & Creative Tools
|
|
102
|
+
- **ComfyUI Integration**: Seamlessly launch a full Stable Diffusion interface directly from the CLI.
|
|
103
|
+
- **Anime Studio (Anima)**: Specialized "Make Anime" mode with automated Anima model downloads (UNET, Text Encoder, VAE) from Hugging Face.
|
|
104
|
+
- **Colab Optimized**: Pre-configured for Google Colab with T4 GPU support and automated environment setup.
|
|
105
|
+
- **Secure Tunnels**: Instant Cloudflare tunnel generation for remote UI access with live logging.
|
|
106
|
+
|
|
101
107
|
### Modern Experience
|
|
102
108
|
- **Premium Visual Engine**: Sleek glassmorphism, fluid gradients, and premium Motion One animations.
|
|
103
109
|
- **Responsive Preview**: Live rendering scaling for desktop and mobile viewpoints.
|
|
@@ -128,6 +134,7 @@ Navigate the suite using quick terminal commands:
|
|
|
128
134
|
| `/web` | `/w` | Launch **Web UI** (Cloudflare Tunnel + QR) |
|
|
129
135
|
| `/cli` | `/c` | Launch **CLI Intelligence** scan |
|
|
130
136
|
| `/image` | `/i` | **Image Forensics** & AI Likelihood |
|
|
137
|
+
| `/cui` | - | **ComfyUI** AI Generation (GPU Required) |
|
|
131
138
|
| `/history`| `/hi`| View and manage scan history |
|
|
132
139
|
| `/help` | `/h` | Show full command documentation |
|
|
133
140
|
| `/clear` | - | Purge all locally scraped data |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|