The version manager takes an optional Checkout, so the companion node pack is handled like the plugin itself: api/tts_version.py finds it among the custom_nodes folders by its node class and accepts only a git clone of the official repository; releases are fetched only on "Check for updates", an update checks out the newest stable tag and can be undone. A checkout without the release tags (cloned before it, then pulled) is matched by ls-remote. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
97 lines
3.6 KiB
Python
97 lines
3.6 KiB
Python
"""Version and updates of the companion node pack Anomalous_TTS (GPT-SoVITS Settings).
|
|
|
|
Only a git checkout of the official repository is touched, found among the
|
|
custom_nodes folders by its node class and checked by its `origin` remote. The
|
|
rules are those of the plugin's own version panel (api/version_manager.py):
|
|
published releases are fetched only when asked, a switch checks out a
|
|
published release tag, refuses over modified tracked files and can be undone.
|
|
"""
|
|
|
|
import asyncio
|
|
import os
|
|
|
|
from aiohttp import web
|
|
|
|
import folder_paths
|
|
|
|
from . import version_manager as vm
|
|
|
|
OFFICIAL = ("demongatanjieu", "anomalous_tts")
|
|
NODE_CLASS = "AnomalousTTS_CharacterSpeech"
|
|
STATE_FILE = os.path.join(vm.PLUGIN_DIR, ".anomalous_tts_version.local.json")
|
|
READ_LIMIT = 200_000
|
|
|
|
|
|
def _node_folders():
|
|
"""custom_nodes folders whose nodes.py defines the Anomalous_TTS node (disabled ones left out)."""
|
|
for base in folder_paths.get_folder_paths("custom_nodes"):
|
|
try:
|
|
names = sorted(os.listdir(base))
|
|
except OSError:
|
|
continue
|
|
for name in names:
|
|
folder = os.path.join(base, name)
|
|
if name.endswith(".disabled") or not os.path.exists(os.path.join(folder, ".git")):
|
|
continue
|
|
try:
|
|
with open(os.path.join(folder, "nodes.py"), encoding="utf-8", errors="replace") as handle:
|
|
if NODE_CLASS in handle.read(READ_LIMIT):
|
|
yield folder
|
|
except OSError:
|
|
continue
|
|
|
|
|
|
def find_checkout():
|
|
"""The installed Anomalous_TTS as a version_manager.Checkout, or None (not installed, not a git
|
|
clone, or cloned from somewhere else)."""
|
|
for folder in _node_folders():
|
|
repo = vm.Checkout(folder, STATE_FILE)
|
|
owner_repo = vm._github_repo(vm._git_out("remote", "get-url", "origin", repo=repo))
|
|
if owner_repo and tuple(part.lower() for part in owner_repo) == OFFICIAL:
|
|
return repo
|
|
return None
|
|
|
|
|
|
def _checkout():
|
|
repo = find_checkout()
|
|
if repo is None:
|
|
raise vm.VersionError("tts_missing", "Anomalous_TTS is not installed as a git clone of its GitHub repository")
|
|
return repo
|
|
|
|
|
|
def state():
|
|
repo = find_checkout()
|
|
return {"found": False} if repo is None else {"found": True, "state": vm.current_state(repo)}
|
|
|
|
|
|
async def api_get_state(request):
|
|
"""GET /anomalous/tts_version - Installed Anomalous_TTS version (local, no network)."""
|
|
try:
|
|
return web.json_response({"success": True, **(await asyncio.to_thread(state))})
|
|
except vm.VersionError as error:
|
|
return vm.error_response(error)
|
|
|
|
|
|
async def api_get_releases(request):
|
|
"""GET /anomalous/tts_version/releases?refresh=1 - Its published releases (network, only when asked)."""
|
|
refresh = request.query.get("refresh") == "1"
|
|
return await vm.run(lambda: vm.list_releases(refresh, _checkout()))
|
|
|
|
|
|
async def api_update(request):
|
|
"""POST /anomalous/tts_version/update {tag} - Check out a published release."""
|
|
tag = str((await vm.json_body(request)).get("tag", ""))
|
|
return await vm.run(lambda: vm.switch_to(tag, _checkout()))
|
|
|
|
|
|
async def api_undo(request):
|
|
"""POST /anomalous/tts_version/undo - Back to where the last update came from."""
|
|
return await vm.run(lambda: vm.undo_last_switch(_checkout()))
|
|
|
|
|
|
def register_routes(app):
|
|
app.router.add_get('/anomalous/tts_version', api_get_state)
|
|
app.router.add_get('/anomalous/tts_version/releases', api_get_releases)
|
|
app.router.add_post('/anomalous/tts_version/update', api_update)
|
|
app.router.add_post('/anomalous/tts_version/undo', api_undo)
|