From 9fcf0aaf7871ff86ad955d6c297f755e6f72c335 Mon Sep 17 00:00:00 2001 From: chendelian <116870791@qq.com> Date: Tue, 31 Mar 2026 14:18:51 +0800 Subject: [PATCH] chore: auto release commit (2026-03-31 14:18:51) --- accounts.json | 81 -------------------- scripts/account.py | 182 +++++++++++++++++++++++++-------------------- 2 files changed, 101 insertions(+), 162 deletions(-) delete mode 100644 accounts.json diff --git a/accounts.json b/accounts.json deleted file mode 100644 index dde789e..0000000 --- a/accounts.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "sohu": [ - { - "id": "sohu_account1", - "name": "搜狐账号1", - "phone": "13800000000", - "platform": "sohu", - "profile_dir": "D:/OpenClaw/chrome-profiles/sohu_account1" - }, - { - "id": "sohu_account2", - "name": "搜狐账号2", - "phone": "13900000000", - "platform": "sohu", - "profile_dir": "D:/OpenClaw/chrome-profiles/sohu_account2" - } - ], - "zhihu": [ - { - "id": "zhihu_account1", - "name": "知乎账号1", - "phone": "", - "platform": "zhihu", - "profile_dir": "D:/OpenClaw/chrome-profiles/zhihu_account1" - } - ], - "kimi": [ - { - "id": "kimi_account1", - "name": "Kimi账号1", - "phone": "13800000000", - "platform": "kimi", - "profile_dir": "D:/OpenClaw/chrome-profiles/kimi_account1" - } - ], - "deepseek": [ - { - "id": "deepseek_account1", - "name": "DeepSeek账号1", - "phone": "", - "platform": "deepseek", - "profile_dir": "D:/OpenClaw/chrome-profiles/deepseek_account1" - } - ], - "doubao": [ - { - "id": "doubao_account1", - "name": "豆包账号1", - "phone": "", - "platform": "doubao", - "profile_dir": "D:/OpenClaw/chrome-profiles/doubao_account1" - } - ], - "qianwen": [ - { - "id": "qianwen_account1", - "name": "千问账号1", - "phone": "", - "platform": "qianwen", - "profile_dir": "D:/OpenClaw/chrome-profiles/qianwen_account1" - } - ], - "yiyan": [ - { - "id": "yiyan_account1", - "name": "一言账号1", - "phone": "", - "platform": "yiyan", - "profile_dir": "D:/OpenClaw/chrome-profiles/yiyan_account1" - } - ], - "yuanbao": [ - { - "id": "yuanbao_account1", - "name": "元宝账号1", - "phone": "", - "platform": "yuanbao", - "profile_dir": "D:/OpenClaw/chrome-profiles/yuanbao_account1" - } - ] -} \ No newline at end of file diff --git a/scripts/account.py b/scripts/account.py index 4b68772..e5c91e1 100644 --- a/scripts/account.py +++ b/scripts/account.py @@ -2,7 +2,6 @@ import sys import json import os import sqlite3 -import subprocess from datetime import datetime # Windows GBK 编码兼容修复 @@ -12,7 +11,6 @@ if sys.platform == "win32": sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace') BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) SKILL_SLUG = "account-manager" -LEGACY_ACCOUNTS_FILE = os.path.join(BASE_DIR, "accounts.json") PLATFORM_URLS = { # 自媒体/图文平台 @@ -71,92 +69,35 @@ def init_db(): platform TEXT NOT NULL, phone TEXT, profile_dir TEXT, + login_status INTEGER DEFAULT 0, + last_login_at TEXT, extra_json TEXT, created_at TEXT NOT NULL, updated_at TEXT NOT NULL ) """ ) + _ensure_column(cur, "accounts", "login_status", "INTEGER DEFAULT 0") + _ensure_column(cur, "accounts", "last_login_at", "TEXT") conn.commit() finally: conn.close() -def migrate_legacy_json_if_needed(): +def _ensure_column(cur, table_name, col_name, ddl): + cur.execute(f"PRAGMA table_info({table_name})") + cols = [row[1] for row in cur.fetchall()] + if col_name not in cols: + cur.execute(f"ALTER TABLE {table_name} ADD COLUMN {col_name} {ddl}") + + +def get_account_by_id(account_id): init_db() conn = get_conn() - try: - cur = conn.cursor() - cur.execute("SELECT COUNT(1) FROM accounts") - count = cur.fetchone()[0] - if count > 0: - return - finally: - conn.close() - - if not os.path.exists(LEGACY_ACCOUNTS_FILE): - return - - try: - with open(LEGACY_ACCOUNTS_FILE, "r", encoding="utf-8") as f: - raw = json.load(f) - except Exception: - return - - now = datetime.now().isoformat(timespec="seconds") - rows = [] - for platform, accounts in (raw or {}).items(): - for acc in accounts: - acc_id = str(acc.get("id") or "").strip() - if not acc_id: - continue - profile_dir = (acc.get("profile_dir") or "").strip() or get_default_profile_dir(acc_id) - base = { - "id": acc_id, - "name": str(acc.get("name") or acc_id), - "platform": str(acc.get("platform") or platform), - "phone": str(acc.get("phone") or ""), - "profile_dir": profile_dir, - } - extra = {k: v for k, v in acc.items() if k not in base} - rows.append( - ( - base["id"], - base["name"], - base["platform"], - base["phone"], - base["profile_dir"], - json.dumps(extra, ensure_ascii=False) if extra else None, - now, - now, - ) - ) - - if not rows: - return - - conn = get_conn() - try: - cur = conn.cursor() - cur.executemany( - """ - INSERT OR REPLACE INTO accounts - (id, name, platform, phone, profile_dir, extra_json, created_at, updated_at) - VALUES (?, ?, ?, ?, ?, ?, ?, ?) - """, - rows, - ) - conn.commit() - finally: - conn.close() - -def get_account_by_id(account_id): - migrate_legacy_json_if_needed() - conn = get_conn() try: cur = conn.cursor() cur.execute( - "SELECT id, name, platform, phone, profile_dir, extra_json FROM accounts WHERE id = ?", + "SELECT id, name, platform, phone, profile_dir, login_status, last_login_at, extra_json FROM accounts WHERE id = ?", (account_id,), ) row = cur.fetchone() @@ -168,10 +109,12 @@ def get_account_by_id(account_id): "platform": row[2], "phone": row[3] or "", "profile_dir": row[4] or get_default_profile_dir(row[0]), + "login_status": int(row[5] or 0), + "last_login_at": row[6], } - if row[5]: + if row[7]: try: - extra = json.loads(row[5]) + extra = json.loads(row[7]) if isinstance(extra, dict): acc.update(extra) except Exception: @@ -185,16 +128,18 @@ def cmd_list(platform="all"): 修改后的 list 功能,能直观打出带着【手机号】的详细台账供AI查询匹配! 支持查全部(all),或指定(sohu) """ - migrate_legacy_json_if_needed() + init_db() conn = get_conn() found = False try: cur = conn.cursor() if platform == "all": - cur.execute("SELECT id, name, phone, platform FROM accounts ORDER BY platform, id") + cur.execute( + "SELECT id, name, phone, platform, login_status FROM accounts ORDER BY platform, id" + ) else: cur.execute( - "SELECT id, name, phone, platform FROM accounts WHERE platform = ? ORDER BY id", + "SELECT id, name, phone, platform, login_status FROM accounts WHERE platform = ? ORDER BY id", (platform,), ) rows = cur.fetchall() @@ -204,7 +149,8 @@ def cmd_list(platform="all"): found = False for row in rows: phone = row[2] or "未绑定手机" - print(f"账号ID:{row[0]} | 名称:{row[1]} | 手机号:{phone} | 平台:{row[3]}") + login_text = "已登录" if int(row[4] or 0) == 1 else "未登录" + print(f"账号ID:{row[0]} | 名称:{row[1]} | 手机号:{phone} | 平台:{row[3]} | 状态:{login_text}") found = True if not found: @@ -217,6 +163,48 @@ def cmd_get(account_id): return print("ERROR:ACCOUNT_NOT_FOUND") + +def cmd_add(account_id, name, platform, phone="", profile_dir=""): + init_db() + platform = (platform or "").strip().lower() + if platform not in PLATFORM_URLS: + print(f"ERROR:INVALID_PLATFORM (支持: {', '.join(sorted(PLATFORM_URLS.keys()))})") + return + + account_id = (account_id or "").strip() + name = (name or "").strip() or account_id + if not account_id: + print("ERROR:INVALID_ACCOUNT_ID") + return + + profile_dir = (profile_dir or "").strip() or get_default_profile_dir(account_id) + os.makedirs(profile_dir, exist_ok=True) + now = datetime.now().isoformat(timespec="seconds") + + conn = get_conn() + try: + cur = conn.cursor() + cur.execute( + """ + INSERT INTO accounts (id, name, platform, phone, profile_dir, login_status, last_login_at, extra_json, created_at, updated_at) + VALUES (?, ?, ?, ?, ?, 0, NULL, NULL, ?, ?) + ON CONFLICT(id) DO UPDATE SET + name = excluded.name, + platform = excluded.platform, + phone = excluded.phone, + profile_dir = excluded.profile_dir, + updated_at = excluded.updated_at + """, + (account_id, name, platform, phone, profile_dir, now, now), + ) + conn.commit() + finally: + conn.close() + + print(f"✅ 已保存账号:{account_id}({platform})") + print("ℹ️ 请继续执行登录:python account.py login <账号ID>") + + def cmd_login(account_id): """首次登录:打开浏览器,用户手动登录,登录态自动保存到Profile目录""" target = get_account_by_id(account_id) @@ -260,16 +248,48 @@ asyncio.run(main()) f.write(login_script) tmp_path = f.name - os.system(f'python "{tmp_path}"') + exit_code = os.system(f'python "{tmp_path}"') os.unlink(tmp_path) + if exit_code == 0: + _mark_login_success(account_id) + print("✅ 登录状态已标记为已登录") + else: + print("⚠️ 浏览器登录流程异常退出,登录状态未更新") + + +def _mark_login_success(account_id): + now = datetime.now().isoformat(timespec="seconds") + conn = get_conn() + try: + cur = conn.cursor() + cur.execute( + "UPDATE accounts SET login_status = 1, last_login_at = ?, updated_at = ? WHERE id = ?", + (now, now, account_id), + ) + conn.commit() + finally: + conn.close() if __name__ == "__main__": if len(sys.argv) < 2: - print("用法:python account.py list [platform] | get | login ") + print("用法:python account.py add [phone] [profile_dir] | list [platform] | get | login ") sys.exit(1) cmd = sys.argv[1] - if cmd == "list": + # 兼容写反顺序:python account.py sohu list + if len(sys.argv) >= 3 and sys.argv[2] == "list" and cmd in PLATFORM_URLS: + cmd_list(cmd) + elif cmd in PLATFORM_URLS and len(sys.argv) == 2: + cmd_list(cmd) + elif cmd == "add" and len(sys.argv) >= 5: + cmd_add( + sys.argv[2], + sys.argv[3], + sys.argv[4], + sys.argv[5] if len(sys.argv) >= 6 else "", + sys.argv[6] if len(sys.argv) >= 7 else "", + ) + elif cmd == "list": # 默认不传 platform 时打出 all cmd_list(sys.argv[2] if len(sys.argv) >= 3 else "all") elif cmd == "get" and len(sys.argv) >= 3: