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 []