Spaces:
Running
on
Zero
Running
on
Zero
| # admin.py | |
| import os | |
| import json | |
| import hmac | |
| import zipfile | |
| import shutil | |
| from typing import List, Tuple | |
| ALLOWED_IMAGE_EXTS = {".jpg", ".jpeg", ".png", ".tif", ".tiff"} | |
| _ADMIN_PASSWORD = os.environ.get("ADMIN_PASSWORD", "") # Hugging Face Space Secret 권장 | |
| def _persistent_base_dir() -> str: | |
| return os.environ.get("HF_PERSISTENT_DIR", "/data") | |
| def _data_root() -> str: | |
| return _persistent_base_dir() | |
| def verify_password(input_pw: str) -> bool: | |
| return bool(_ADMIN_PASSWORD) and hmac.compare_digest(input_pw or "", _ADMIN_PASSWORD) | |
| def list_sessions() -> Tuple[List[str], str]: | |
| root = _data_root() | |
| os.makedirs(root, exist_ok=True) | |
| try: | |
| items = sorted( | |
| [d for d in os.listdir(root) if os.path.isdir(os.path.join(root, d))], | |
| reverse=True | |
| ) | |
| if not items: | |
| return [], "Info: No saved sessions found under /data." | |
| return items, f"Found {len(items)} session folder(s) under /data." | |
| except Exception as e: | |
| return [], f"Error: Failed to list sessions. {e}" | |
| def session_info(session: str) -> Tuple[str, List[str]]: | |
| root = _data_root() | |
| if not session: | |
| return "Error: No session selected.", [] | |
| path = os.path.join(root, session) | |
| if not os.path.isdir(path): | |
| return "Error: Session folder does not exist.", [] | |
| # meta.json | |
| meta_text = "" | |
| meta_path = os.path.join(path, "meta.json") | |
| if os.path.isfile(meta_path): | |
| try: | |
| with open(meta_path, "r", encoding="utf-8") as fp: | |
| meta = json.load(fp) | |
| meta_text = json.dumps(meta, ensure_ascii=False, indent=2) | |
| except Exception as e: | |
| meta_text = f"(Failed to read meta.json: {e})" | |
| originals = [] | |
| for name in os.listdir(path): | |
| p = os.path.join(path, name) | |
| if os.path.isfile(p) and os.path.splitext(name)[1].lower() in ALLOWED_IMAGE_EXTS: | |
| originals.append(p) | |
| total_imgs = len(originals) | |
| info_md = ( | |
| f"**Session:** `{session}` \n" | |
| f"**Path:** `{path}` \n" | |
| f"**Images (total):** {total_imgs} \n" | |
| ) | |
| if meta_text: | |
| info_md += "\n\n**meta.json**\n```json\n" + meta_text + "\n```" | |
| return info_md | |
| def zip_session(session: str) -> str: | |
| root = _data_root() | |
| if not session: | |
| raise ValueError("Error: No session selected.") | |
| src_dir = os.path.join(root, session) | |
| if not os.path.isdir(src_dir): | |
| raise ValueError("Error: Session folder does not exist.") | |
| zip_path = f"/tmp/{session}.zip" | |
| try: | |
| if os.path.exists(zip_path): | |
| os.remove(zip_path) | |
| with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED) as zf: | |
| for rootdir, _, files in os.walk(src_dir): | |
| for f in files: | |
| full = os.path.join(rootdir, f) | |
| arc = os.path.relpath(full, src_dir) | |
| zf.write(full, arcname=arc) | |
| except Exception as e: | |
| raise RuntimeError(f"Error: Failed to create zip. {e}") | |
| return zip_path | |
| def delete_session(session: str) -> str: | |
| """ | |
| Delete the entire session folder (and its contents). | |
| Returns a status message. | |
| """ | |
| root = _data_root() | |
| if not session: | |
| return "Error: No session selected." | |
| path = os.path.join(root, session) | |
| if not os.path.isdir(path): | |
| return "Error: Session folder does not exist." | |
| try: | |
| shutil.rmtree(path) | |
| return f"Success: Deleted session '{session}'." | |
| except Exception as e: | |
| return f"Error: Failed to delete session '{session}'. {e}" | |