Infini / data_manager.py
yangtb24's picture
Upload 7 files
931e053 verified
import json
import threading
from datetime import datetime
import pytz
import config
import api_client
accounts_data = {}
data_lock = threading.Lock()
shanghai_tz = pytz.timezone(config.SHANGHAI_TZ_STR)
def parse_accounts():
global accounts_data
if not config.ACCOUNTS_JSON:
print("错误: ACCOUNTS 环境变量未设置。")
return False
try:
accounts_list = json.loads(config.ACCOUNTS_JSON)
if not isinstance(accounts_list, list):
print("错误: ACCOUNTS 环境变量必须是一个 JSON 数组。")
return False
temp_accounts_data = {}
for acc in accounts_list:
if isinstance(acc, dict) and "email" in acc and "password" in acc:
temp_accounts_data[acc["email"]] = {
"password": acc["password"],
"token": None,
"profile": None,
"last_login_success": None,
"last_profile_success": None,
"last_login_attempt": None,
"last_profile_attempt": None,
"login_error": None,
"profile_error": None,
"cards_info": None,
"last_card_info_success": None,
"last_card_info_attempt": None,
"card_info_error": None,
}
else:
print(f"警告: ACCOUNTS 中的条目格式不正确: {acc}")
with data_lock:
accounts_data = temp_accounts_data
print(f"成功加载 {len(accounts_data)} 个账户。")
return True
except json.JSONDecodeError:
print("错误: ACCOUNTS 环境变量不是有效的 JSON 格式。")
return False
def login_and_store_token(email):
global accounts_data
with data_lock:
account_info = accounts_data.get(email)
if not account_info:
print(f"错误: 账户 {email} 未找到。")
return
password = account_info["password"]
print(f"[{datetime.now(shanghai_tz)}] 尝试为账户 {email} 登录...")
token, error = api_client.api_login(email, password)
with data_lock:
accounts_data[email]["last_login_attempt"] = datetime.now(shanghai_tz)
if token:
accounts_data[email]["token"] = token
accounts_data[email]["last_login_success"] = True
accounts_data[email]["login_error"] = None
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 登录成功。")
else:
accounts_data[email]["token"] = None
accounts_data[email]["last_login_success"] = False
accounts_data[email]["login_error"] = error
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 登录失败: {error}")
def fetch_and_store_profile(email):
global accounts_data
with data_lock:
account_info = accounts_data.get(email)
if not account_info:
print(f"错误: 账户 {email} 未找到 (fetch_and_store_profile)。")
return
token = account_info.get("token")
if not token:
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 没有有效的 token,跳过获取 Profile。")
with data_lock:
accounts_data[email]["last_profile_attempt"] = datetime.now(shanghai_tz)
accounts_data[email]["last_profile_success"] = False
accounts_data[email]["profile_error"] = "无有效 Token"
accounts_data[email]["profile"] = None
accounts_data[email]["last_card_info_attempt"] = datetime.now(shanghai_tz)
accounts_data[email]["cards_info"] = None
accounts_data[email]["last_card_info_success"] = False
accounts_data[email]["card_info_error"] = "因 Token 为空未尝试"
return
print(f"[{datetime.now(shanghai_tz)}] 尝试为账户 {email} 获取 Profile...")
profile, error = api_client.get_api_profile(email, token)
profile_fetch_successful_this_attempt = False
with data_lock:
accounts_data[email]["last_profile_attempt"] = datetime.now(shanghai_tz)
if profile:
accounts_data[email]["profile"] = profile
accounts_data[email]["last_profile_success"] = True
accounts_data[email]["profile_error"] = None
profile_fetch_successful_this_attempt = True
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 获取 Profile 成功。")
else:
accounts_data[email]["profile"] = None
accounts_data[email]["last_profile_success"] = False
accounts_data[email]["profile_error"] = error
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 获取 Profile 失败: {error}")
if error and ("token" in error.lower() or "auth" in error.lower() or "登录" in error.lower()):
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 获取 Profile 失败,疑似 Token 失效,将尝试重新登录。")
accounts_data[email]["token"] = None
accounts_data[email]["last_card_info_attempt"] = datetime.now(shanghai_tz)
accounts_data[email]["cards_info"] = None
accounts_data[email]["last_card_info_success"] = False
accounts_data[email]["card_info_error"] = "因 Profile 获取失败未尝试"
return
if profile_fetch_successful_this_attempt:
current_token_for_cards = None
with data_lock:
if email in accounts_data:
current_token_for_cards = accounts_data[email].get("token")
else:
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 在获取卡片信息前数据结构异常,跳过。")
return
if not current_token_for_cards:
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 在获取卡片信息前发现 Token 已失效或被清除,跳过。")
with data_lock:
if email in accounts_data:
accounts_data[email]["last_card_info_attempt"] = datetime.now(shanghai_tz)
accounts_data[email]["cards_info"] = None
accounts_data[email]["last_card_info_success"] = False
accounts_data[email]["card_info_error"] = "因 Token 失效未尝试"
return
print(f"[{datetime.now(shanghai_tz)}] Profile 获取成功,继续为账户 {email} 获取卡片信息...")
cards_info, card_error = api_client.get_api_card_info(email, current_token_for_cards)
with data_lock:
if email in accounts_data:
accounts_data[email]["last_card_info_attempt"] = datetime.now(shanghai_tz)
if cards_info:
accounts_data[email]["cards_info"] = cards_info
accounts_data[email]["last_card_info_success"] = True
accounts_data[email]["card_info_error"] = None
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 获取卡片信息成功。")
elif card_error:
accounts_data[email]["cards_info"] = None
accounts_data[email]["last_card_info_success"] = False
accounts_data[email]["card_info_error"] = card_error
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 获取卡片信息失败: {card_error}")
else: # No error, but no card_info (e.g. no cards for the account)
accounts_data[email]["cards_info"] = None
accounts_data[email]["last_card_info_success"] = True # Success in fetching, just no data
accounts_data[email]["card_info_error"] = None
print(f"[{datetime.now(shanghai_tz)}] 账户 {email} 获取卡片信息成功,但无卡片数据。")
def get_accounts_data_for_display():
with data_lock:
display_data = {}
for email, data in accounts_data.items():
display_data[email] = {
"profile": data.get("profile"),
"last_login_success": data.get("last_login_success"),
"last_profile_success": data.get("last_profile_success"),
"last_login_attempt": data.get("last_login_attempt").isoformat() if data.get("last_login_attempt") else None,
"last_profile_attempt": data.get("last_profile_attempt").isoformat() if data.get("last_profile_attempt") else None,
"login_error": data.get("login_error"),
"profile_error": data.get("profile_error"),
"token_present": bool(data.get("token")),
"cards_info": data.get("cards_info"),
"last_card_info_success": data.get("last_card_info_success"),
"last_card_info_attempt": data.get("last_card_info_attempt").isoformat() if data.get("last_card_info_attempt") else None,
"card_info_error": data.get("card_info_error")
}
return display_data
def get_all_account_emails():
with data_lock:
return list(accounts_data.keys())
def get_accounts_from_config():
if not config.ACCOUNTS_JSON:
print("错误: ACCOUNTS 环境变量未设置 (get_accounts_from_config)。")
return []
try:
accounts_list = json.loads(config.ACCOUNTS_JSON)
if not isinstance(accounts_list, list):
print("错误: ACCOUNTS 环境变量必须是一个 JSON 数组 (get_accounts_from_config)。")
return []
valid_accounts = []
for acc in accounts_list:
if isinstance(acc, dict) and "email" in acc and "password" in acc:
valid_accounts.append({"email": acc["email"], "password": acc["password"]})
else:
print(f"警告: ACCOUNTS 中的条目格式不正确,已跳过: {acc} (get_accounts_from_config)")
return valid_accounts
except json.JSONDecodeError:
print("错误: ACCOUNTS 环境变量不是有效的 JSON 格式 (get_accounts_from_config)。")
return []