| from pathlib import Path |
| import os |
| from urllib.parse import quote |
|
|
| from fastapi import FastAPI |
| from fastapi.responses import FileResponse |
| from fastapi.staticfiles import StaticFiles |
|
|
|
|
| BASE_DIR = Path(__file__).resolve().parent |
| STATIC_DIR = BASE_DIR / "static" |
| APP_DIR = BASE_DIR.parent |
| ANIME_RIG_DIR = Path( |
| os.getenv("ANIME_RIG_DIR", str(APP_DIR / "data" / "Anime2.5DRig")) |
| ).resolve() |
| AVATAR_DATA_DIR = Path( |
| os.getenv("AVATAR_DATA_DIR", "/buckets/Anime2.5DRig/avatar_data") |
| ).resolve() |
|
|
| app = FastAPI(title="ChatGPT Live Avatar Test") |
| app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") |
|
|
| if ANIME_RIG_DIR.is_dir(): |
| app.mount( |
| "/Anime2.5DRig", |
| StaticFiles(directory=ANIME_RIG_DIR, html=True), |
| name="anime2.5drig", |
| ) |
|
|
| if AVATAR_DATA_DIR.is_dir(): |
| app.mount( |
| "/AvatarData", |
| StaticFiles(directory=AVATAR_DATA_DIR), |
| name="avatar-data", |
| ) |
|
|
|
|
| @app.get("/api/status") |
| def status() -> dict[str, object]: |
| index_path = ANIME_RIG_DIR / "index.html" |
| return { |
| "ok": True, |
| "animeRigAvailable": index_path.is_file(), |
| "animeRigUrl": "/Anime2.5DRig/" if index_path.is_file() else None, |
| "samplePsdUrl": "/Anime2.5DRig/sample.psd" if index_path.is_file() else None, |
| "expectedPath": str(ANIME_RIG_DIR), |
| "repositoryPath": "data/Anime2.5DRig", |
| } |
|
|
|
|
| @app.get("/api/avatars") |
| def avatars() -> dict[str, object]: |
| items: list[dict[str, object]] = [] |
|
|
| sample_path = ANIME_RIG_DIR / "sample.psd" |
| if sample_path.is_file(): |
| items.append({ |
| "name": "sample.psd", |
| "label": "sample", |
| "url": "/Anime2.5DRig/sample.psd", |
| "builtin": True, |
| }) |
|
|
| if AVATAR_DATA_DIR.is_dir(): |
| for path in sorted(AVATAR_DATA_DIR.glob("*.psd"), key=lambda item: item.name.casefold()): |
| items.append({ |
| "name": path.name, |
| "label": path.stem, |
| "url": f"/AvatarData/{quote(path.name)}", |
| "builtin": False, |
| }) |
|
|
| return { |
| "ok": True, |
| "directory": str(AVATAR_DATA_DIR), |
| "bucketPath": "/buckets/Anime2.5DRig/avatar_data", |
| "avatars": items, |
| } |
|
|
|
|
| @app.get("/healthz") |
| def healthz() -> dict[str, bool]: |
| return {"ok": True} |
|
|
|
|
| @app.get("/") |
| def index() -> FileResponse: |
| return FileResponse(STATIC_DIR / "index.html") |
|
|