| """ |
| VTX Studio beta key administration utility. |
| |
| Keys are stored in the private ManChildTechnologies/VTX-BetaKeys dataset. |
| """ |
| from __future__ import annotations |
|
|
| import argparse |
| import json |
| from pathlib import Path |
| from typing import Any |
|
|
| from beta_keys_schema import generate_unique_key, new_record, normalize_record |
| from beta_keys_store import keys_path, load_keys, save_keys |
|
|
| APP_DIR = Path(__file__).resolve().parent |
| DEFAULT_KEYS_PATH = APP_DIR / "keys.json" |
|
|
|
|
| def generate_key( |
| *, |
| name: str, |
| notes: str = "", |
| path: str | Path | None = None, |
| push: bool = True, |
| ) -> str: |
| """Generate a new ACTIVE beta key and persist it to the dataset.""" |
| if not str(name or "").strip(): |
| raise ValueError("Tester name is required.") |
|
|
| keys = load_keys(force=True) |
| beta_key = generate_unique_key(keys) |
| record = new_record(name=name, notes=notes) |
| record["key"] = beta_key |
| keys[beta_key] = normalize_record(beta_key, record) |
| if push: |
| save_keys(keys, commit_message=f"Generate beta key for {name.strip()}") |
| elif path: |
| from beta_keys_store import _write_json_file |
|
|
| _write_json_file(Path(path), keys) |
| return beta_key |
|
|
|
|
| def revoke_key(beta_key: str, path: str | Path | None = None, push: bool = True) -> dict[str, Any]: |
| key = str(beta_key or "").strip() |
| if not key: |
| raise ValueError("Beta key is required.") |
|
|
| keys = load_keys(force=True) |
| if key not in keys: |
| raise KeyError(f"Beta key not found: {key}") |
|
|
| record = normalize_record(key, keys[key]) |
| record["active"] = False |
| record["status"] = "REVOKED" |
| keys[key] = record |
| if push: |
| save_keys(keys, commit_message=f"Revoke beta key {key}") |
| return record |
|
|
|
|
| def reactivate_key(beta_key: str, path: str | Path | None = None, push: bool = True) -> dict[str, Any]: |
| key = str(beta_key or "").strip() |
| if not key: |
| raise ValueError("Beta key is required.") |
|
|
| keys = load_keys(force=True) |
| if key not in keys: |
| raise KeyError(f"Beta key not found: {key}") |
|
|
| record = normalize_record(key, keys[key]) |
| record["active"] = True |
| record["status"] = "ACTIVE" |
| keys[key] = record |
| if push: |
| save_keys(keys, commit_message=f"Reactivate beta key {key}") |
| return record |
|
|
|
|
| def delete_key(beta_key: str, push: bool = True) -> None: |
| key = str(beta_key or "").strip() |
| if not key: |
| raise ValueError("Beta key is required.") |
|
|
| keys = load_keys(force=True) |
| if key not in keys: |
| raise KeyError(f"Beta key not found: {key}") |
| del keys[key] |
| if push: |
| save_keys(keys, commit_message=f"Delete beta key {key}") |
|
|
|
|
| def export_json(output: str | Path | None = None) -> Path: |
| keys = load_keys(force=True) |
| out = Path(output) if output else keys_path() |
| out.parent.mkdir(parents=True, exist_ok=True) |
| ordered = {key: normalize_record(key, record) for key, record in sorted(keys.items())} |
| out.write_text(json.dumps(ordered, indent=2) + "\n", encoding="utf-8") |
| return out |
|
|
|
|
| def main() -> int: |
| parser = argparse.ArgumentParser(description="VTX Studio beta key manager") |
| parser.add_argument("--keys", default="", help="Optional local export path") |
| sub = parser.add_subparsers(dest="command", required=True) |
|
|
| generate = sub.add_parser("generate", help="Generate a new ACTIVE beta key") |
| generate.add_argument("--name", required=True, help="Tester name") |
| generate.add_argument("--notes", default="", help="Optional notes") |
|
|
| revoke = sub.add_parser("revoke", help="Revoke an existing beta key") |
| revoke.add_argument("beta_key", help="Beta key to revoke") |
|
|
| reactivate = sub.add_parser("reactivate", help="Reactivate a revoked beta key") |
| reactivate.add_argument("beta_key", help="Beta key to reactivate") |
|
|
| delete = sub.add_parser("delete", help="Delete an existing beta key") |
| delete.add_argument("beta_key", help="Beta key to delete") |
|
|
| export = sub.add_parser("export", help="Export keys.json snapshot") |
| export.add_argument("-o", "--output", default="", help="Optional output path") |
|
|
| args = parser.parse_args() |
|
|
| if args.command == "generate": |
| beta_key = generate_key(name=args.name, notes=args.notes) |
| print(beta_key) |
| return 0 |
|
|
| if args.command == "revoke": |
| record = revoke_key(args.beta_key) |
| print(json.dumps(record, indent=2)) |
| return 0 |
|
|
| if args.command == "reactivate": |
| record = reactivate_key(args.beta_key) |
| print(json.dumps(record, indent=2)) |
| return 0 |
|
|
| if args.command == "delete": |
| delete_key(args.beta_key) |
| print("deleted") |
| return 0 |
|
|
| if args.command == "export": |
| out = export_json(args.output or None) |
| print(str(out)) |
| return 0 |
|
|
| parser.error("Unknown command") |
| return 1 |
|
|
|
|
| if __name__ == "__main__": |
| raise SystemExit(main()) |