cmd_site.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. """与站点和凭据状态有关的子命令:endpoint / whoami。"""
  2. import sys
  3. import time
  4. from client import fmt_ts, make_client, mask, note, token_expiry
  5. from creds import bucket_name_for, get_bucket, resolve_api_url, save_creds, load_creds, CREDS_PATH
  6. from errors import ApiError, WpError, explain_api_error
  7. from sites import SITES, expand_site_alias, normalize_api_url, site_label
  8. def cmd_endpoint(args):
  9. creds = load_creds()
  10. current_url, source = resolve_api_url(getattr(args, "api", None), creds)
  11. if not args.target:
  12. for idx, site in enumerate(SITES, 1):
  13. mark = " ← 当前" if site["url"] == current_url else ""
  14. print(f" {idx}) {site['url']:<32} {site['version']} · {site['domain']}{mark}")
  15. if source in ("cli", "env"):
  16. src = "--api" if source == "cli" else "WIKIPALI_API_URL"
  17. note(f"注意:当前地址来自 {src},是一次性覆盖,未写入凭据文件。")
  18. if current_url not in [s["url"] for s in SITES]:
  19. print(f" *) {current_url:<32} 自定义地址 ← 当前")
  20. keys = "|".join(x["key"] for x in SITES)
  21. print(f"\n切换:wikipali endpoint <序号|{keys}|完整url>")
  22. return 0
  23. url = normalize_api_url(expand_site_alias(args.target))
  24. name = bucket_name_for(url)
  25. bucket = get_bucket(creds, name, url)
  26. bucket["api_url"] = url
  27. creds["current"] = name
  28. save_creds(creds)
  29. print(f"已切换到 {url}({site_label(url)})")
  30. if name != "online":
  31. note("提示:该地址是**另一个数据库**,与线上四站不共用数据与密钥。"
  32. "凭据和本地缓存都是独立的一桶,可能需要在该站点重新登录。")
  33. return 0
  34. def cmd_whoami(args):
  35. client = make_client(args)
  36. print(f"API : {client.api_note()}")
  37. print(f"凭据文件 : {CREDS_PATH}(桶:{client.bucket_name})")
  38. user = client.bucket.get("user") or {}
  39. if user.get("token"):
  40. exp = token_expiry(user["token"])
  41. expired = exp is not None and exp < time.time()
  42. print(f"用户 : {user.get('username', '?')} uid={user.get('uid', '?')}")
  43. print(f" token {mask(user['token'])} 到期 {fmt_ts(exp)}{' ⚠ 已过期' if expired else ''}")
  44. else:
  45. print("用户 : 未登录(wikipali-login)")
  46. model = client.bucket.get("model") or {}
  47. if model.get("token"):
  48. exp = token_expiry(model["token"])
  49. expired = exp is not None and exp < time.time()
  50. print(f"模型 : {model.get('name', '?')} uid={model.get('uid', '?')}")
  51. print(f" token {mask(model['token'])} 到期 {fmt_ts(exp)}{' ⚠ 已过期' if expired else ''}")
  52. else:
  53. print("模型 : 未建立(wikipali ensure-model --name <模型名>)")
  54. tokens = client.bucket.get("access_tokens") or {}
  55. if tokens:
  56. print("access token:")
  57. for uid, item in tokens.items():
  58. exp = item.get("exp") or token_expiry(item.get("token", ""))
  59. expired = exp is not None and exp < time.time()
  60. book = item.get("book", 0)
  61. scope = "全部 book" if book == 0 else f"book {book}"
  62. name = item.get("channel_name") or ""
  63. print(f" {uid[:8]}… {name:<24} {scope:<10} 到期 {fmt_ts(exp)}{' ⚠ 已过期' if expired else ''}")
  64. else:
  65. print("access token:无(wikipali grant <channel>)")
  66. if args.check:
  67. try:
  68. data = client.call("GET", "v2/auth/current", token=client.user_token)
  69. except ApiError as exc:
  70. raise explain_api_error(exc, "校验用户 token")
  71. print(f"\n服务端确认:{data.get('nickName')} / realName={data.get('realName')}(studio_name 用它)")
  72. return 0