266 lines
9.7 KiB
Python
266 lines
9.7 KiB
Python
import importlib.util
|
|
import subprocess
|
|
import sys
|
|
import os
|
|
import folder_paths
|
|
import time
|
|
import shutil
|
|
import signal
|
|
import re
|
|
import requests
|
|
import dotenv
|
|
from pathlib import Path
|
|
from importlib.metadata import distribution, PackageNotFoundError
|
|
|
|
USER_DATA_DIR = os.path.join(folder_paths.get_user_directory(), "DadosNodes")
|
|
os.makedirs(USER_DATA_DIR, exist_ok=True)
|
|
|
|
def is_package_installed(package_name):
|
|
try:
|
|
distribution(package_name)
|
|
return True
|
|
except PackageNotFoundError:
|
|
return False
|
|
|
|
def install_package_if_missing(package_spec):
|
|
package_spec = package_spec.split('#')[0].strip()
|
|
match = re.match(r'^([a-zA-Z0-9\-_]+)', package_spec)
|
|
if not match:
|
|
return
|
|
base_name = match.group(1)
|
|
if is_package_installed(base_name):
|
|
print(f"✅ {base_name} already installed.")
|
|
else:
|
|
print(f"⬇️ Installing {package_spec}...")
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", package_spec])
|
|
|
|
def ensure_deepseek_api():
|
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
api_dir = os.path.join(base_dir, "deepseek_api")
|
|
if not os.path.exists(api_dir):
|
|
print("DeepSeek-API not found. Cloning from GitHub...")
|
|
try:
|
|
subprocess.check_call([
|
|
"git", "clone", "https://github.com/sums001/Deepseek-API.git", api_dir
|
|
])
|
|
print("DeepSeek-API cloned successfully.")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Failed to clone DeepSeek-API: {e}")
|
|
return
|
|
req_path = os.path.join(api_dir, "requirements.txt")
|
|
if os.path.exists(req_path):
|
|
print("Checking DeepSeek dependencies...")
|
|
with open(req_path, 'r') as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line or line.startswith('#'):
|
|
continue
|
|
install_package_if_missing(line)
|
|
else:
|
|
print("⚠️ requirements.txt not found in deepseek_api folder.")
|
|
home = Path.home()
|
|
playwright_cache = home / ".cache" / "ms-playwright"
|
|
chromium_found = False
|
|
if playwright_cache.exists():
|
|
for item in playwright_cache.iterdir():
|
|
if item.is_dir() and item.name.startswith("chromium-"):
|
|
chromium_found = True
|
|
break
|
|
if chromium_found:
|
|
print("✅ Playwright Chromium already installed.")
|
|
else:
|
|
print("⬇️ Installing Playwright Chromium browser...")
|
|
try:
|
|
subprocess.check_call([sys.executable, "-m", "playwright", "install", "chromium"])
|
|
print("Playwright Chromium installed.")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Failed to install Playwright Chromium: {e}")
|
|
|
|
def ensure_py3pin():
|
|
if importlib.util.find_spec("py3pin") is None:
|
|
print("py3pin is not installed. Installing...")
|
|
try:
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "git+https://github.com/GgAaYyAaNn/py3-pinterest.git"])
|
|
print("py3pin installed successfully.")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Failed to install py3pin: {e}")
|
|
else:
|
|
print("✅ py3pin already installed.")
|
|
|
|
def ensure_dynamicprompts():
|
|
if importlib.util.find_spec("dynamicprompts") is None:
|
|
print("dynamicprompts is not installed. Installing...")
|
|
try:
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "git+https://github.com/DadoIrie/dynamicprompts.git"])
|
|
print("dynamicprompts installed successfully.")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Failed to install dynamicprompts: {e}")
|
|
else:
|
|
print("✅ dynamicprompts already installed.")
|
|
|
|
def check_deepseek_session():
|
|
api_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "deepseek_api")
|
|
session_dir = os.path.join(api_dir, "session")
|
|
if not os.path.exists(session_dir) or not os.listdir(session_dir):
|
|
print("⚠️ DeepSeek session not found.")
|
|
print(" Please run the following command once to authenticate:")
|
|
print(f" cd {api_dir} && python -m deepseek.auth")
|
|
print(" This will open a browser for you to log into DeepSeek.")
|
|
|
|
def ensure_danyapi():
|
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
api_dir = os.path.join(base_dir, "danyapi")
|
|
if not os.path.exists(api_dir):
|
|
print("DanyAPI not found. Cloning from GitHub...")
|
|
try:
|
|
subprocess.check_call([
|
|
"git", "clone", "https://github.com/FANATFANATA/DanyAPI.git", api_dir
|
|
])
|
|
print("DanyAPI cloned successfully.")
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Failed to clone DanyAPI: {e}")
|
|
return
|
|
else:
|
|
print("DanyAPI already exists.")
|
|
req_path = os.path.join(api_dir, "requirements.txt")
|
|
if os.path.exists(req_path):
|
|
print("Checking DanyAPI dependencies...")
|
|
with open(req_path, 'r') as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line or line.startswith('#'):
|
|
continue
|
|
install_package_if_missing(line)
|
|
else:
|
|
print("⚠️ requirements.txt not found in danyapi folder.")
|
|
env_example = os.path.join(api_dir, ".env.example")
|
|
env_file = os.path.join(api_dir, ".env")
|
|
if not os.path.exists(env_file):
|
|
print("Creating .env from .env.example...")
|
|
if os.path.exists(env_example):
|
|
try:
|
|
shutil.copy(env_example, env_file)
|
|
print(".env created. Please edit it to add your credentials.")
|
|
except OSError as e:
|
|
print(f"Failed to create .env: {e}")
|
|
else:
|
|
print("⚠️ .env.example not found; skipping .env creation.")
|
|
else:
|
|
print(".env already exists.")
|
|
try:
|
|
dotenv.load_dotenv(env_file)
|
|
except Exception as e:
|
|
print(f"⚠️ Failed to load .env: {e}")
|
|
|
|
def get_danyapi_pid():
|
|
"""Return PID of running DanyAPI server, using PID file or pgrep as fallback."""
|
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
api_dir = os.path.join(base_dir, "danyapi")
|
|
pid_file = os.path.join(api_dir, "danyapi.pid")
|
|
if os.path.exists(pid_file):
|
|
try:
|
|
with open(pid_file, 'r') as f:
|
|
pid_str = f.read().strip()
|
|
if pid_str:
|
|
pid = int(pid_str)
|
|
try:
|
|
os.kill(pid, 0)
|
|
return pid
|
|
except OSError:
|
|
pass
|
|
except (ValueError, OSError):
|
|
pass
|
|
try:
|
|
result = subprocess.run(["pgrep", "-f", "python -m danyapi"], capture_output=True, text=True)
|
|
if result.returncode == 0:
|
|
pids = result.stdout.strip().split()
|
|
if pids:
|
|
return int(pids[0])
|
|
except Exception:
|
|
pass
|
|
return None
|
|
|
|
def kill_danyapi_server():
|
|
pid = get_danyapi_pid()
|
|
if pid is None:
|
|
print("No DanyAPI server found.")
|
|
return
|
|
print(f"Killing DanyAPI server (PID: {pid})...")
|
|
try:
|
|
os.kill(pid, signal.SIGTERM)
|
|
time.sleep(2)
|
|
try:
|
|
os.kill(pid, 0)
|
|
os.kill(pid, signal.SIGKILL)
|
|
print(f"✅ Forcibly killed PID {pid}.")
|
|
except OSError:
|
|
print(f"✅ Gracefully killed PID {pid}.")
|
|
except OSError as e:
|
|
print(f"⚠️ Could not kill PID {pid}: {e}")
|
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
pid_file = os.path.join(base_dir, "danyapi", "danyapi.pid")
|
|
if os.path.exists(pid_file):
|
|
os.remove(pid_file)
|
|
|
|
def start_danyapi_server():
|
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
|
api_dir = os.path.join(base_dir, "danyapi")
|
|
env_file = os.path.join(api_dir, ".env")
|
|
if not os.path.exists(env_file):
|
|
print("❌ .env not found. Cannot start DanyAPI.")
|
|
return
|
|
host = os.getenv("DANYAPI_HOST")
|
|
port = os.getenv("DANYAPI_PORT")
|
|
if host and port:
|
|
health_url = f"http://{host}:{port}/health"
|
|
elif host:
|
|
health_url = f"http://{host}:8000/health"
|
|
elif port:
|
|
health_url = f"http://127.0.0.1:{port}/health"
|
|
else:
|
|
health_url = "http://127.0.0.1:8000/health"
|
|
try:
|
|
resp = requests.get(health_url, timeout=2)
|
|
if resp.status_code == 200:
|
|
print(f"✅ DanyAPI is already running on {health_url}. Skipping start.")
|
|
return
|
|
except Exception:
|
|
pass
|
|
log_file = os.path.join(api_dir, "danyapi.log")
|
|
print(f"Starting DanyAPI server (logs: {log_file})...")
|
|
python_exe = sys.executable
|
|
env = os.environ.copy()
|
|
try:
|
|
with open(log_file, "a") as log:
|
|
proc = subprocess.Popen(
|
|
[python_exe, "-m", "danyapi"],
|
|
cwd=api_dir,
|
|
stdout=log,
|
|
stderr=subprocess.STDOUT,
|
|
stdin=subprocess.DEVNULL,
|
|
env=env,
|
|
start_new_session=True,
|
|
close_fds=True,
|
|
)
|
|
pid_file = os.path.join(api_dir, "danyapi.pid")
|
|
with open(pid_file, 'w') as f:
|
|
f.write(str(proc.pid))
|
|
time.sleep(3)
|
|
try:
|
|
resp = requests.get(health_url, timeout=2)
|
|
if resp.status_code == 200:
|
|
print(f"✅ DanyAPI started (PID: {proc.pid}) at {health_url}.")
|
|
else:
|
|
print("⚠️ DanyAPI started but health check non-200.")
|
|
except Exception:
|
|
print("⚠️ DanyAPI may not be ready. Check logs.")
|
|
except Exception as e:
|
|
print(f"❌ Failed to start DanyAPI: {e}")
|
|
|
|
ensure_py3pin()
|
|
ensure_dynamicprompts()
|
|
ensure_deepseek_api()
|
|
check_deepseek_session()
|
|
ensure_danyapi()
|
|
kill_danyapi_server()
|
|
start_danyapi_server() |