feat(account-manager): add list-json API for cross-skill orchestration
This commit is contained in:
@@ -586,6 +586,48 @@ def cmd_get(account_id):
|
|||||||
print(_runtime_paths_debug_text(), file=sys.stderr)
|
print(_runtime_paths_debug_text(), file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_list_json(platform_input: str, limit: int = 200) -> None:
|
||||||
|
"""
|
||||||
|
跨技能接口:stdout 仅输出一行 JSON 数组,元素结构与 get 单条一致。
|
||||||
|
平台可为 all/全部 或各平台中文名/英文键;按 updated_at 倒序,最多 limit 条(上限 500)。
|
||||||
|
"""
|
||||||
|
get_skill_logger().info("list_json filter=%r limit=%s", platform_input, limit)
|
||||||
|
init_db()
|
||||||
|
raw = (platform_input or "all").strip()
|
||||||
|
if not raw or raw.lower() == "all" or raw == "全部":
|
||||||
|
key = "all"
|
||||||
|
else:
|
||||||
|
key = resolve_platform_key(raw)
|
||||||
|
if not key:
|
||||||
|
print("ERROR:INVALID_PLATFORM_LIST_JSON 无法识别的平台名称。")
|
||||||
|
print("支持:" + _platform_list_cn_for_help())
|
||||||
|
return
|
||||||
|
lim = max(1, min(int(limit), 500))
|
||||||
|
conn = get_conn()
|
||||||
|
try:
|
||||||
|
cur = conn.cursor()
|
||||||
|
if key == "all":
|
||||||
|
cur.execute(
|
||||||
|
"SELECT id FROM accounts ORDER BY updated_at DESC, id DESC LIMIT ?",
|
||||||
|
(lim,),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
cur.execute(
|
||||||
|
"SELECT id FROM accounts WHERE platform = ? "
|
||||||
|
"ORDER BY updated_at DESC, id DESC LIMIT ?",
|
||||||
|
(key, lim),
|
||||||
|
)
|
||||||
|
ids = [r[0] for r in cur.fetchall()]
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
out = []
|
||||||
|
for aid in ids:
|
||||||
|
acc = get_account_by_id(aid)
|
||||||
|
if acc:
|
||||||
|
out.append(acc)
|
||||||
|
print(json.dumps(out, ensure_ascii=False))
|
||||||
|
|
||||||
|
|
||||||
def cmd_pick_logged_in(platform_input: str):
|
def cmd_pick_logged_in(platform_input: str):
|
||||||
"""
|
"""
|
||||||
机器可读跨技能接口:查询指定平台下「已登录」的一条账号(login_status=1,按 last_login_at 优先)。
|
机器可读跨技能接口:查询指定平台下「已登录」的一条账号(login_status=1,按 last_login_at 优先)。
|
||||||
@@ -629,6 +671,60 @@ def cmd_pick_logged_in(platform_input: str):
|
|||||||
print(json.dumps(acc, ensure_ascii=False))
|
print(json.dumps(acc, ensure_ascii=False))
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_pick_web(platform_input: str):
|
||||||
|
"""
|
||||||
|
供 llm-manager 等:取该平台用于网页自动化的账号候选。
|
||||||
|
优先 login_status=1(与 pick-logged-in 一致);若无,则取该平台 updated_at 最新的一条,
|
||||||
|
便于「已 add 未标登录」时仍打开 profile,在浏览器内登录后继续任务。
|
||||||
|
成功:stdout 仅一行 JSON(与 get 一致);失败:首行 ERROR:。
|
||||||
|
"""
|
||||||
|
get_skill_logger().info("pick_web platform_input=%r", platform_input)
|
||||||
|
key = resolve_platform_key((platform_input or "").strip())
|
||||||
|
if not key:
|
||||||
|
print("ERROR:INVALID_PLATFORM 无法识别的平台名称。")
|
||||||
|
print("支持:" + _platform_list_cn_for_help())
|
||||||
|
return
|
||||||
|
|
||||||
|
init_db()
|
||||||
|
conn = get_conn()
|
||||||
|
try:
|
||||||
|
cur = conn.cursor()
|
||||||
|
cur.execute(
|
||||||
|
"""
|
||||||
|
SELECT id FROM accounts
|
||||||
|
WHERE platform = ? AND login_status = 1
|
||||||
|
ORDER BY (last_login_at IS NULL), last_login_at DESC
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
(key,),
|
||||||
|
)
|
||||||
|
row = cur.fetchone()
|
||||||
|
if not row:
|
||||||
|
cur.execute(
|
||||||
|
"""
|
||||||
|
SELECT id FROM accounts
|
||||||
|
WHERE platform = ?
|
||||||
|
ORDER BY updated_at DESC, id DESC
|
||||||
|
LIMIT 1
|
||||||
|
""",
|
||||||
|
(key,),
|
||||||
|
)
|
||||||
|
row = cur.fetchone()
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if not row:
|
||||||
|
print("ERROR:NO_ACCOUNT 该平台在账号库中没有任何记录,请先执行 add。")
|
||||||
|
return
|
||||||
|
|
||||||
|
acc = get_account_by_id(row[0])
|
||||||
|
if not acc:
|
||||||
|
print("ERROR:ACCOUNT_NOT_FOUND")
|
||||||
|
print(_runtime_paths_debug_text(), file=sys.stderr)
|
||||||
|
return
|
||||||
|
print(json.dumps(acc, ensure_ascii=False))
|
||||||
|
|
||||||
|
|
||||||
def cmd_add(platform_input: str, phone: str):
|
def cmd_add(platform_input: str, phone: str):
|
||||||
"""添加账号:platform 可为中文展示名或英文键;手机号必填;同平台下同手机号不可重复。"""
|
"""添加账号:platform 可为中文展示名或英文键;手机号必填;同平台下同手机号不可重复。"""
|
||||||
log = get_skill_logger()
|
log = get_skill_logger()
|
||||||
@@ -1371,13 +1467,42 @@ def _mark_login_status(account_id, success: bool):
|
|||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_set_login_status(account_id_str: str, status_str: str) -> None:
|
||||||
|
"""
|
||||||
|
跨技能机器接口:回写 accounts.login_status。
|
||||||
|
成功:stdout 首行 OK:SET_LOGIN_STATUS 或 OK:CLEARED_LOGIN_STATUS,进程退出码 0。
|
||||||
|
失败:stdout 首行 ERROR:...,退出码 1。
|
||||||
|
"""
|
||||||
|
aid_s = (account_id_str or "").strip()
|
||||||
|
st_s = (status_str or "").strip()
|
||||||
|
if not aid_s.isdigit():
|
||||||
|
print("ERROR:INVALID_ACCOUNT_ID")
|
||||||
|
sys.exit(1)
|
||||||
|
if st_s not in ("0", "1"):
|
||||||
|
print("ERROR:INVALID_STATUS 须为 0 或 1")
|
||||||
|
sys.exit(1)
|
||||||
|
aid = int(aid_s)
|
||||||
|
init_db()
|
||||||
|
if get_account_by_id(aid) is None:
|
||||||
|
get_skill_logger().warning("set_login_status_not_found account_id=%r", aid)
|
||||||
|
print("ERROR:ACCOUNT_NOT_FOUND")
|
||||||
|
sys.exit(1)
|
||||||
|
ok = st_s == "1"
|
||||||
|
_mark_login_status(aid, ok)
|
||||||
|
get_skill_logger().info("set_login_status account_id=%s success=%s", aid, ok)
|
||||||
|
print("OK:SET_LOGIN_STATUS" if ok else "OK:CLEARED_LOGIN_STATUS")
|
||||||
|
|
||||||
|
|
||||||
def _cli_print_full_usage() -> None:
|
def _cli_print_full_usage() -> None:
|
||||||
"""总览(未带子命令或需要完整说明时)。"""
|
"""总览(未带子命令或需要完整说明时)。"""
|
||||||
print("用法概览(将 main.py 换为你的路径):")
|
print("用法概览(将 main.py 换为你的路径):")
|
||||||
print(" python main.py add <平台中文名> <手机号>")
|
print(" python main.py add <平台中文名> <手机号>")
|
||||||
print(" python main.py list [平台|all|全部]")
|
print(" python main.py list [平台|all|全部]")
|
||||||
print(" python main.py pick-logged-in <平台> # 跨技能用:输出一行 JSON 或 ERROR")
|
print(" python main.py pick-logged-in <平台> # 跨技能用:仅已登录账号,一行 JSON 或 ERROR")
|
||||||
|
print(" python main.py pick-web <平台> # 跨技能用:优先已登录,否则最新一条账号")
|
||||||
|
print(" python main.py list-json <平台|all> [--limit N] # 跨技能用:一行 JSON 数组,元素同 get")
|
||||||
print(" python main.py get <id>")
|
print(" python main.py get <id>")
|
||||||
|
print(" python main.py set-login-status <id> <0|1> # 跨技能回写登录态")
|
||||||
print(" python main.py open <id>")
|
print(" python main.py open <id>")
|
||||||
print(" python main.py login <id>")
|
print(" python main.py login <id>")
|
||||||
print(" python main.py delete id <id>")
|
print(" python main.py delete id <id>")
|
||||||
@@ -1456,6 +1581,30 @@ if __name__ == "__main__":
|
|||||||
_cli_fail_need_account_id("get")
|
_cli_fail_need_account_id("get")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
cmd_get(sys.argv[2])
|
cmd_get(sys.argv[2])
|
||||||
|
elif cmd == "set-login-status":
|
||||||
|
if len(sys.argv) < 4:
|
||||||
|
print("ERROR:CLI_SET_LOGIN_STATUS_MISSING_ARGS")
|
||||||
|
print("用法:python main.py set-login-status <account_id> <0|1>")
|
||||||
|
print("说明:供 llm-manager 等脚本回写登录态;成功时 stdout 首行以 OK: 开头。")
|
||||||
|
sys.exit(1)
|
||||||
|
cmd_set_login_status(sys.argv[2], sys.argv[3])
|
||||||
|
elif cmd == "list-json":
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("ERROR:CLI_LIST_JSON_MISSING_PLATFORM")
|
||||||
|
print("用法:python main.py list-json <平台|all|全部> [--limit N]")
|
||||||
|
print("说明:跨技能编排;成功时 stdout 仅一行 JSON 数组(元素与 get 一致)。")
|
||||||
|
sys.exit(1)
|
||||||
|
av = sys.argv[2:]
|
||||||
|
platform_arg = av[0]
|
||||||
|
lim = 200
|
||||||
|
if "--limit" in av:
|
||||||
|
i = av.index("--limit")
|
||||||
|
if i + 1 < len(av):
|
||||||
|
try:
|
||||||
|
lim = int(av[i + 1])
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
cmd_list_json(platform_arg, limit=lim)
|
||||||
elif cmd == "pick-logged-in":
|
elif cmd == "pick-logged-in":
|
||||||
if len(sys.argv) < 3:
|
if len(sys.argv) < 3:
|
||||||
print("ERROR:CLI_PICK_LOGGED_IN_MISSING_ARGS")
|
print("ERROR:CLI_PICK_LOGGED_IN_MISSING_ARGS")
|
||||||
@@ -1463,6 +1612,13 @@ if __name__ == "__main__":
|
|||||||
print("说明:供 llm-manager 等技能查询该平台已登录账号;成功时 stdout 仅一行 JSON。")
|
print("说明:供 llm-manager 等技能查询该平台已登录账号;成功时 stdout 仅一行 JSON。")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
cmd_pick_logged_in(sys.argv[2])
|
cmd_pick_logged_in(sys.argv[2])
|
||||||
|
elif cmd == "pick-web":
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("ERROR:CLI_PICK_WEB_MISSING_ARGS")
|
||||||
|
print("用法:python main.py pick-web <平台中文名或英文键>")
|
||||||
|
print("说明:供 llm-manager 等;优先已登录账号,否则返回该平台最新一条账号(未登录也可用于打开浏览器登录)。")
|
||||||
|
sys.exit(1)
|
||||||
|
cmd_pick_web(sys.argv[2])
|
||||||
elif cmd == "open":
|
elif cmd == "open":
|
||||||
if len(sys.argv) < 3:
|
if len(sys.argv) < 3:
|
||||||
_cli_fail_need_account_id("open")
|
_cli_fail_need_account_id("open")
|
||||||
|
|||||||
Reference in New Issue
Block a user