File size: 10,377 Bytes
931e053 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
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 [] |