125 lines
3.6 KiB
Python
Executable File
125 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import json
|
|
import os
|
|
import sys
|
|
from typing import Tuple
|
|
|
|
import requests
|
|
|
|
|
|
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
CONFIG_PATH = os.path.join(ROOT_DIR, "config.json")
|
|
|
|
|
|
def ok(msg: str) -> None:
|
|
print(f"[OK] {msg}")
|
|
|
|
|
|
def warn(msg: str) -> None:
|
|
print(f"[WARN] {msg}")
|
|
|
|
|
|
def fail(msg: str) -> None:
|
|
print(f"[FAIL] {msg}")
|
|
|
|
|
|
def check_url(url: str, timeout: int = 3) -> Tuple[bool, str]:
|
|
try:
|
|
response = requests.get(url, timeout=timeout)
|
|
return True, f"HTTP {response.status_code}"
|
|
except Exception as exc:
|
|
return False, str(exc)
|
|
|
|
|
|
def main() -> int:
|
|
if not os.path.exists(CONFIG_PATH):
|
|
fail(f"Missing config file: {CONFIG_PATH}")
|
|
return 1
|
|
|
|
with open(CONFIG_PATH, "r", encoding="utf-8") as f:
|
|
cfg = json.load(f)
|
|
|
|
failures = 0
|
|
|
|
stt_provider = str(cfg.get("stt_provider", "local_whisper")).lower()
|
|
|
|
ok(f"stt_provider={stt_provider}")
|
|
|
|
imagemagick_path = cfg.get("imagemagick_path", "")
|
|
if imagemagick_path and os.path.exists(imagemagick_path):
|
|
ok(f"imagemagick_path exists: {imagemagick_path}")
|
|
else:
|
|
warn(
|
|
"imagemagick_path is not set to a valid executable path. "
|
|
"MoviePy subtitle rendering may fail."
|
|
)
|
|
|
|
firefox_profile = cfg.get("firefox_profile", "")
|
|
if firefox_profile:
|
|
if os.path.isdir(firefox_profile):
|
|
ok(f"firefox_profile exists: {firefox_profile}")
|
|
else:
|
|
warn(f"firefox_profile does not exist: {firefox_profile}")
|
|
else:
|
|
warn("firefox_profile is empty. Twitter/YouTube automation requires this.")
|
|
|
|
# Ollama (LLM)
|
|
base = str(cfg.get("ollama_base_url", "http://127.0.0.1:11434")).rstrip("/")
|
|
reachable, detail = check_url(f"{base}/api/tags")
|
|
if not reachable:
|
|
fail(f"Ollama is not reachable at {base}: {detail}")
|
|
failures += 1
|
|
else:
|
|
ok(f"Ollama reachable at {base}")
|
|
try:
|
|
tags = requests.get(f"{base}/api/tags", timeout=5).json()
|
|
models = [m.get("name") for m in tags.get("models", [])]
|
|
if models:
|
|
ok(f"Ollama models available: {', '.join(models[:10])}")
|
|
else:
|
|
warn("No models found on Ollama. Pull a model first (e.g. 'ollama pull llama3.2:3b').")
|
|
except Exception as exc:
|
|
warn(f"Could not validate Ollama model list: {exc}")
|
|
|
|
# Nano Banana 2 (image generation)
|
|
api_key = cfg.get("nanobanana2_api_key", "") or os.environ.get("GEMINI_API_KEY", "")
|
|
nb2_base = str(
|
|
cfg.get(
|
|
"nanobanana2_api_base_url",
|
|
"https://generativelanguage.googleapis.com/v1beta",
|
|
)
|
|
).rstrip("/")
|
|
if api_key:
|
|
ok("nanobanana2_api_key is set")
|
|
else:
|
|
fail("nanobanana2_api_key is empty (and GEMINI_API_KEY is not set)")
|
|
failures += 1
|
|
|
|
reachable, detail = check_url(nb2_base, timeout=8)
|
|
if not reachable:
|
|
warn(f"Nano Banana 2 base URL could not be reached: {detail}")
|
|
else:
|
|
ok(f"Nano Banana 2 base URL reachable: {nb2_base}")
|
|
|
|
if stt_provider == "local_whisper":
|
|
try:
|
|
import faster_whisper # noqa: F401
|
|
|
|
ok("faster-whisper is installed")
|
|
except Exception as exc:
|
|
fail(f"faster-whisper is not importable: {exc}")
|
|
failures += 1
|
|
|
|
if failures:
|
|
print("")
|
|
print(f"Preflight completed with {failures} blocking issue(s).")
|
|
return 1
|
|
|
|
print("")
|
|
print("Preflight passed. Local setup looks ready.")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|