refactor: optimize structure, stability and runtime performance
This commit is contained in:
@@ -40,6 +40,48 @@ def _emit(event: str, data: object, *, room: str | None = None) -> None:
|
||||
pass
|
||||
|
||||
|
||||
def _emit_account_update(user_id: int, account) -> None:
|
||||
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
|
||||
|
||||
|
||||
def _request_json(default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
data = request.get_json(silent=True)
|
||||
return data if isinstance(data, dict) else default
|
||||
|
||||
|
||||
def _ensure_accounts_loaded(user_id: int) -> dict:
|
||||
accounts = safe_get_user_accounts_snapshot(user_id)
|
||||
if accounts:
|
||||
return accounts
|
||||
load_user_accounts(user_id)
|
||||
return safe_get_user_accounts_snapshot(user_id)
|
||||
|
||||
|
||||
def _get_user_account(user_id: int, account_id: str, *, refresh_if_missing: bool = False):
|
||||
account = safe_get_account(user_id, account_id)
|
||||
if account or (not refresh_if_missing):
|
||||
return account
|
||||
load_user_accounts(user_id)
|
||||
return safe_get_account(user_id, account_id)
|
||||
|
||||
|
||||
def _validate_browse_type_input(raw_browse_type, *, default=BROWSE_TYPE_SHOULD_READ):
|
||||
browse_type = validate_browse_type(raw_browse_type, default=default)
|
||||
if not browse_type:
|
||||
return None, (jsonify({"error": "浏览类型无效"}), 400)
|
||||
return browse_type, None
|
||||
|
||||
|
||||
def _cancel_pending_account_task(user_id: int, account_id: str) -> bool:
|
||||
try:
|
||||
scheduler = get_task_scheduler()
|
||||
return bool(scheduler.cancel_pending_task(user_id=user_id, account_id=account_id))
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
@api_accounts_bp.route("/api/accounts", methods=["GET"])
|
||||
@login_required
|
||||
def get_accounts():
|
||||
@@ -49,8 +91,7 @@ def get_accounts():
|
||||
|
||||
accounts = safe_get_user_accounts_snapshot(user_id)
|
||||
if refresh or not accounts:
|
||||
load_user_accounts(user_id)
|
||||
accounts = safe_get_user_accounts_snapshot(user_id)
|
||||
accounts = _ensure_accounts_loaded(user_id)
|
||||
|
||||
return jsonify([acc.to_dict() for acc in accounts.values()])
|
||||
|
||||
@@ -63,20 +104,18 @@ def add_account():
|
||||
|
||||
current_count = len(database.get_user_accounts(user_id))
|
||||
is_vip = database.is_user_vip(user_id)
|
||||
if not is_vip and current_count >= 3:
|
||||
if (not is_vip) and current_count >= 3:
|
||||
return jsonify({"error": "普通用户最多添加3个账号,升级VIP可无限添加"}), 403
|
||||
data = request.json
|
||||
username = data.get("username", "").strip()
|
||||
password = data.get("password", "").strip()
|
||||
remark = data.get("remark", "").strip()[:200]
|
||||
|
||||
data = _request_json()
|
||||
username = str(data.get("username", "")).strip()
|
||||
password = str(data.get("password", "")).strip()
|
||||
remark = str(data.get("remark", "")).strip()[:200]
|
||||
|
||||
if not username or not password:
|
||||
return jsonify({"error": "用户名和密码不能为空"}), 400
|
||||
|
||||
accounts = safe_get_user_accounts_snapshot(user_id)
|
||||
if not accounts:
|
||||
load_user_accounts(user_id)
|
||||
accounts = safe_get_user_accounts_snapshot(user_id)
|
||||
accounts = _ensure_accounts_loaded(user_id)
|
||||
for acc in accounts.values():
|
||||
if acc.username == username:
|
||||
return jsonify({"error": f"账号 '{username}' 已存在"}), 400
|
||||
@@ -92,7 +131,7 @@ def add_account():
|
||||
safe_set_account(user_id, account_id, account)
|
||||
|
||||
log_to_client(f"添加账号: {username}", user_id)
|
||||
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
|
||||
_emit_account_update(user_id, account)
|
||||
|
||||
return jsonify(account.to_dict())
|
||||
|
||||
@@ -103,15 +142,15 @@ def update_account(account_id):
|
||||
"""更新账号信息(密码等)"""
|
||||
user_id = current_user.id
|
||||
|
||||
account = safe_get_account(user_id, account_id)
|
||||
account = _get_user_account(user_id, account_id)
|
||||
if not account:
|
||||
return jsonify({"error": "账号不存在"}), 404
|
||||
|
||||
if account.is_running:
|
||||
return jsonify({"error": "账号正在运行中,请先停止"}), 400
|
||||
|
||||
data = request.json
|
||||
new_password = data.get("password", "").strip()
|
||||
data = _request_json()
|
||||
new_password = str(data.get("password", "")).strip()
|
||||
new_remember = data.get("remember", account.remember)
|
||||
|
||||
if not new_password:
|
||||
@@ -147,7 +186,7 @@ def delete_account(account_id):
|
||||
"""删除账号"""
|
||||
user_id = current_user.id
|
||||
|
||||
account = safe_get_account(user_id, account_id)
|
||||
account = _get_user_account(user_id, account_id)
|
||||
if not account:
|
||||
return jsonify({"error": "账号不存在"}), 404
|
||||
|
||||
@@ -159,7 +198,6 @@ def delete_account(account_id):
|
||||
username = account.username
|
||||
|
||||
database.delete_account(account_id)
|
||||
|
||||
safe_remove_account(user_id, account_id)
|
||||
|
||||
log_to_client(f"删除账号: {username}", user_id)
|
||||
@@ -196,12 +234,12 @@ def update_remark(account_id):
|
||||
"""更新备注"""
|
||||
user_id = current_user.id
|
||||
|
||||
account = safe_get_account(user_id, account_id)
|
||||
account = _get_user_account(user_id, account_id)
|
||||
if not account:
|
||||
return jsonify({"error": "账号不存在"}), 404
|
||||
|
||||
data = request.json
|
||||
remark = data.get("remark", "").strip()[:200]
|
||||
data = _request_json()
|
||||
remark = str(data.get("remark", "")).strip()[:200]
|
||||
|
||||
database.update_account_remark(account_id, remark)
|
||||
|
||||
@@ -217,17 +255,18 @@ def start_account(account_id):
|
||||
"""启动账号任务"""
|
||||
user_id = current_user.id
|
||||
|
||||
account = safe_get_account(user_id, account_id)
|
||||
account = _get_user_account(user_id, account_id)
|
||||
if not account:
|
||||
return jsonify({"error": "账号不存在"}), 404
|
||||
|
||||
if account.is_running:
|
||||
return jsonify({"error": "任务已在运行中"}), 400
|
||||
|
||||
data = request.json or {}
|
||||
browse_type = validate_browse_type(data.get("browse_type"), default=BROWSE_TYPE_SHOULD_READ)
|
||||
if not browse_type:
|
||||
return jsonify({"error": "浏览类型无效"}), 400
|
||||
data = _request_json()
|
||||
browse_type, browse_error = _validate_browse_type_input(data.get("browse_type"), default=BROWSE_TYPE_SHOULD_READ)
|
||||
if browse_error:
|
||||
return browse_error
|
||||
|
||||
enable_screenshot = data.get("enable_screenshot", True)
|
||||
ok, message = submit_account_task(
|
||||
user_id=user_id,
|
||||
@@ -249,7 +288,7 @@ def stop_account(account_id):
|
||||
"""停止账号任务"""
|
||||
user_id = current_user.id
|
||||
|
||||
account = safe_get_account(user_id, account_id)
|
||||
account = _get_user_account(user_id, account_id)
|
||||
if not account:
|
||||
return jsonify({"error": "账号不存在"}), 404
|
||||
|
||||
@@ -259,20 +298,16 @@ def stop_account(account_id):
|
||||
account.should_stop = True
|
||||
account.status = "正在停止"
|
||||
|
||||
try:
|
||||
scheduler = get_task_scheduler()
|
||||
if scheduler.cancel_pending_task(user_id=user_id, account_id=account_id):
|
||||
account.status = "已停止"
|
||||
account.is_running = False
|
||||
safe_remove_task_status(account_id)
|
||||
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
|
||||
log_to_client(f"任务已取消: {account.username}", user_id)
|
||||
return jsonify({"success": True, "canceled": True})
|
||||
except Exception:
|
||||
pass
|
||||
if _cancel_pending_account_task(user_id, account_id):
|
||||
account.status = "已停止"
|
||||
account.is_running = False
|
||||
safe_remove_task_status(account_id)
|
||||
_emit_account_update(user_id, account)
|
||||
log_to_client(f"任务已取消: {account.username}", user_id)
|
||||
return jsonify({"success": True, "canceled": True})
|
||||
|
||||
log_to_client(f"停止任务: {account.username}", user_id)
|
||||
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
|
||||
_emit_account_update(user_id, account)
|
||||
|
||||
return jsonify({"success": True})
|
||||
|
||||
@@ -283,23 +318,20 @@ def manual_screenshot(account_id):
|
||||
"""手动为指定账号截图"""
|
||||
user_id = current_user.id
|
||||
|
||||
account = safe_get_account(user_id, account_id)
|
||||
if not account:
|
||||
load_user_accounts(user_id)
|
||||
account = safe_get_account(user_id, account_id)
|
||||
account = _get_user_account(user_id, account_id, refresh_if_missing=True)
|
||||
if not account:
|
||||
return jsonify({"error": "账号不存在"}), 404
|
||||
if account.is_running:
|
||||
return jsonify({"error": "任务运行中,无法截图"}), 400
|
||||
|
||||
data = request.json or {}
|
||||
data = _request_json()
|
||||
requested_browse_type = data.get("browse_type", None)
|
||||
if requested_browse_type is None:
|
||||
browse_type = normalize_browse_type(account.last_browse_type)
|
||||
else:
|
||||
browse_type = validate_browse_type(requested_browse_type, default=BROWSE_TYPE_SHOULD_READ)
|
||||
if not browse_type:
|
||||
return jsonify({"error": "浏览类型无效"}), 400
|
||||
browse_type, browse_error = _validate_browse_type_input(requested_browse_type, default=BROWSE_TYPE_SHOULD_READ)
|
||||
if browse_error:
|
||||
return browse_error
|
||||
|
||||
account.last_browse_type = browse_type
|
||||
|
||||
@@ -317,12 +349,16 @@ def manual_screenshot(account_id):
|
||||
def batch_start_accounts():
|
||||
"""批量启动账号"""
|
||||
user_id = current_user.id
|
||||
data = request.json or {}
|
||||
data = _request_json()
|
||||
|
||||
account_ids = data.get("account_ids", [])
|
||||
browse_type = validate_browse_type(data.get("browse_type", BROWSE_TYPE_SHOULD_READ), default=BROWSE_TYPE_SHOULD_READ)
|
||||
if not browse_type:
|
||||
return jsonify({"error": "浏览类型无效"}), 400
|
||||
browse_type, browse_error = _validate_browse_type_input(
|
||||
data.get("browse_type", BROWSE_TYPE_SHOULD_READ),
|
||||
default=BROWSE_TYPE_SHOULD_READ,
|
||||
)
|
||||
if browse_error:
|
||||
return browse_error
|
||||
|
||||
enable_screenshot = data.get("enable_screenshot", True)
|
||||
|
||||
if not account_ids:
|
||||
@@ -331,11 +367,10 @@ def batch_start_accounts():
|
||||
started = []
|
||||
failed = []
|
||||
|
||||
if not safe_get_user_accounts_snapshot(user_id):
|
||||
load_user_accounts(user_id)
|
||||
_ensure_accounts_loaded(user_id)
|
||||
|
||||
for account_id in account_ids:
|
||||
account = safe_get_account(user_id, account_id)
|
||||
account = _get_user_account(user_id, account_id)
|
||||
if not account:
|
||||
failed.append({"id": account_id, "reason": "账号不存在"})
|
||||
continue
|
||||
@@ -357,7 +392,13 @@ def batch_start_accounts():
|
||||
failed.append({"id": account_id, "reason": msg})
|
||||
|
||||
return jsonify(
|
||||
{"success": True, "started_count": len(started), "failed_count": len(failed), "started": started, "failed": failed}
|
||||
{
|
||||
"success": True,
|
||||
"started_count": len(started),
|
||||
"failed_count": len(failed),
|
||||
"started": started,
|
||||
"failed": failed,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -366,39 +407,29 @@ def batch_start_accounts():
|
||||
def batch_stop_accounts():
|
||||
"""批量停止账号"""
|
||||
user_id = current_user.id
|
||||
data = request.json
|
||||
data = _request_json()
|
||||
|
||||
account_ids = data.get("account_ids", [])
|
||||
|
||||
if not account_ids:
|
||||
return jsonify({"error": "请选择要停止的账号"}), 400
|
||||
|
||||
stopped = []
|
||||
|
||||
if not safe_get_user_accounts_snapshot(user_id):
|
||||
load_user_accounts(user_id)
|
||||
_ensure_accounts_loaded(user_id)
|
||||
|
||||
for account_id in account_ids:
|
||||
account = safe_get_account(user_id, account_id)
|
||||
if not account:
|
||||
continue
|
||||
|
||||
if not account.is_running:
|
||||
account = _get_user_account(user_id, account_id)
|
||||
if (not account) or (not account.is_running):
|
||||
continue
|
||||
|
||||
account.should_stop = True
|
||||
account.status = "正在停止"
|
||||
stopped.append(account_id)
|
||||
|
||||
try:
|
||||
scheduler = get_task_scheduler()
|
||||
if scheduler.cancel_pending_task(user_id=user_id, account_id=account_id):
|
||||
account.status = "已停止"
|
||||
account.is_running = False
|
||||
safe_remove_task_status(account_id)
|
||||
except Exception:
|
||||
pass
|
||||
if _cancel_pending_account_task(user_id, account_id):
|
||||
account.status = "已停止"
|
||||
account.is_running = False
|
||||
safe_remove_task_status(account_id)
|
||||
|
||||
_emit("account_update", account.to_dict(), room=f"user_{user_id}")
|
||||
_emit_account_update(user_id, account)
|
||||
|
||||
return jsonify({"success": True, "stopped_count": len(stopped), "stopped": stopped})
|
||||
|
||||
Reference in New Issue
Block a user