meyosaj406 commited on
Commit
6da7743
·
verified ·
1 Parent(s): 1dfd0cd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -54
app.py CHANGED
@@ -12,7 +12,7 @@ USERNAME = os.getenv("APP_USERNAME", "未设置")
12
  PASSWORD = os.getenv("APP_PASSWORD", "未设置")
13
  BASE_URL = "https://free-api.rorryson.com"
14
 
15
- # 强制 Python 立即输出日志,不缓存 (解决日志不显示问题)
16
  sys.stdout.reconfigure(encoding='utf-8')
17
 
18
  # 初始化界面状态
@@ -22,13 +22,12 @@ if 'status_msg' not in st.session_state:
22
  st.session_state.status_msg = "系统就绪 (等待指令)"
23
 
24
  def log_print(msg):
25
- """日志助手:同时打印到后台控制台和记录时间"""
26
  timestamp = datetime.now().strftime("%H:%M:%S")
27
- # flush=True 确保日志立即出现在 Hugging Face 的 Logs 标签页中
28
  print(f"[{timestamp}] {msg}", flush=True)
29
  return timestamp
30
 
31
- # ================= 2. 核心签到逻辑 (高保真版) =================
32
  def perform_checkin():
33
  log_print("🚀 --- 开始执行任务 ---")
34
 
@@ -38,8 +37,7 @@ def perform_checkin():
38
 
39
  session = requests.Session()
40
 
41
- # 【关键修改】完全复刻你最新提供的 Curl Headers
42
- # 包含 Sec-Fetch 系列,这是防止 401 的关键
43
  base_headers = {
44
  "Host": "free-api.rorryson.com",
45
  "Connection": "keep-alive",
@@ -58,46 +56,35 @@ def perform_checkin():
58
  session.headers.update(base_headers)
59
 
60
  try:
61
- # ---------------- 步骤 1: 登录 ----------------
62
- # 登录时的特征头
63
- session.headers.update({
64
- "Referer": "https://free-api.rorryson.com/login",
65
- "New-API-User": "-1"
66
- })
67
-
68
  log_print("正在尝试登录...")
69
  res_login = session.post(f"{BASE_URL}/api/user/login?turnstile=", json={"username": USERNAME, "password": PASSWORD})
70
 
71
  if res_login.status_code != 200:
72
- log_print(f"登录失败: {res_login.status_code} - {res_login.text}")
73
  st.session_state.status_msg = f"❌ 登录失败 ({res_login.status_code})"
74
  return
75
 
76
  log_print("✅ 登录成功,Session Cookie 已获取")
77
 
78
- # ---------------- 步骤 2: 签到 (重点) ----------------
79
- # 切换到签到环境,特征头必须变
80
  session.headers.update({
81
  "Referer": "https://free-api.rorryson.com/console/topup",
82
- "New-API-User": "201", # 你的Curl里是201
83
- "Cache-Control": "no-store" # 你的Curl里有这个
84
  })
85
-
86
- time.sleep(1) # 模拟人类操作延迟
87
 
88
  log_print("正在尝试签到...")
89
  res_checkin = session.post(f"{BASE_URL}/api/user/checkin")
90
-
91
  ts = datetime.now().strftime("%H:%M:%S")
92
 
93
- # 处理各种签到结果
94
  if res_checkin.status_code == 200:
95
  try:
96
  data = res_checkin.json()
97
  msg = data.get("message", "OK")
98
- log_print(f"签到返回消息: {msg}")
99
-
100
- # 智能判断中文提示
101
  if "已" in msg or "duplicate" in msg.lower():
102
  st.session_state.status_msg = f"🔸 {msg} ({ts})"
103
  else:
@@ -106,27 +93,32 @@ def perform_checkin():
106
  st.session_state.status_msg = f"✅ 签到请求成功 ({ts})"
107
 
108
  elif res_checkin.status_code == 422:
109
- # 422 通常代表“无法处理”,在这里就是“今天已经过了”
110
- log_print("服务器返回 422 (重复签到)")
111
- st.session_state.status_msg = f"🔸 今天已签到过 (无需重复) ({ts})"
112
-
113
  else:
114
  log_print(f"签到异常: {res_checkin.status_code}")
115
  st.session_state.status_msg = f"⚠️ 接口返回 {res_checkin.status_code} ({ts})"
116
 
117
- # ---------------- 步骤 3: 查余额 ----------------
118
- # 保持 Headers 不变
119
  res_info = session.get(f"{BASE_URL}/api/user/self")
120
  if res_info.status_code == 200:
121
- quota = res_info.json().get("data", {}).get("quota", "Err")
122
- st.session_state.quota = quota
123
- log_print(f"当前余额: {quota}")
 
 
 
 
 
 
 
 
124
 
125
  except Exception as e:
126
  log_print(f"程序崩溃: {str(e)}")
127
- st.session_state.status_msg = "💥 系统内部错误 (查看Logs)"
128
 
129
- # ================= 3. 后台调度线程 =================
130
  def run_scheduler():
131
  while True:
132
  schedule.run_pending()
@@ -135,30 +127,21 @@ def run_scheduler():
135
  def start_background_thread():
136
  if 'scheduler_started' not in st.session_state:
137
  log_print("⚡ 系统启动初始化...")
138
-
139
- # 1. 启动时立即尝试一次 (方便你看日志确认是否成功)
140
  perform_checkin()
141
-
142
- # 2. 设定每天 UTC 00:00 (北京时间 08:00) 自动运行
143
  schedule.every().day.at("00:00").do(perform_checkin)
144
-
145
- # 3. 启动线程
146
  t = threading.Thread(target=run_scheduler, daemon=True)
147
  t.start()
148
  st.session_state.scheduler_started = True
149
  log_print("⏰ 定时任务已设定: 每天北京时间 08:00")
150
 
151
- # ================= 4. 前端界面 (Streamlit) =================
152
  st.set_page_config(page_title="R-API 哨兵", page_icon="🛡️", layout="centered")
153
 
154
- # 必须调用启动函数
155
  start_background_thread()
156
 
157
- # 赛博风格 CSS
158
  st.markdown("""
159
  <style>
160
  .stApp {background-color: #050505; color: #ccc;}
161
- /* 隐藏不需要的组件 */
162
  #MainMenu {visibility: hidden;}
163
  footer {visibility: hidden;}
164
 
@@ -168,7 +151,9 @@ st.markdown("""
168
  box-shadow: 0 4px 15px rgba(0,0,0,0.5);
169
  }
170
  .metric-label {font-size: 0.9rem; color: #666; margin-bottom: 5px;}
171
- .metric-val {font-size: 2rem; font-weight: bold; color: #fff; font-family: monospace;}
 
 
172
 
173
  .status-box {
174
  margin-top: 25px; padding: 15px; border-radius: 8px;
@@ -176,8 +161,6 @@ st.markdown("""
176
  font-family: "Microsoft YaHei", sans-serif; color: #00c6ff;
177
  text-align: center;
178
  }
179
-
180
- /* 按钮美化 */
181
  .stButton>button {
182
  width: 100%; height: 50px; background: linear-gradient(90deg, #00c6ff, #0072ff);
183
  border: none; color: white; font-weight: bold; font-size: 1rem; border-radius: 8px;
@@ -185,7 +168,6 @@ st.markdown("""
185
  </style>
186
  """, unsafe_allow_html=True)
187
 
188
- # 界面布局
189
  st.markdown("<br>", unsafe_allow_html=True)
190
 
191
  col1, col2 = st.columns(2)
@@ -197,25 +179,22 @@ with col1:
197
  </div>
198
  """, unsafe_allow_html=True)
199
  with col2:
200
- # 余额根据是否有数值变色
201
  color = "#00ffcc" if st.session_state.quota != "---" else "#444"
202
  st.markdown(f"""
203
  <div class="metric-card">
204
- <div class="metric-label">当前账户余额</div>
205
  <div class="metric-val" style="color:{color}">{st.session_state.quota}</div>
206
  </div>
207
  """, unsafe_allow_html=True)
208
 
209
  st.markdown("<br>", unsafe_allow_html=True)
210
 
211
- # 手动签到按钮
212
  if st.button("🚀 立即执行手动签到", use_container_width=True):
213
  with st.spinner("正在连接服务器..."):
214
  perform_checkin()
215
  time.sleep(0.5)
216
  st.rerun()
217
 
218
- # 状态显示区
219
  st.markdown(f"""
220
  <div class="status-box">
221
  系统状态: {st.session_state.status_msg}
@@ -226,3 +205,4 @@ st.markdown(f"""
226
 
227
 
228
 
 
 
12
  PASSWORD = os.getenv("APP_PASSWORD", "未设置")
13
  BASE_URL = "https://free-api.rorryson.com"
14
 
15
+ # 强制 Python 立即输出日志,不缓存
16
  sys.stdout.reconfigure(encoding='utf-8')
17
 
18
  # 初始化界面状态
 
22
  st.session_state.status_msg = "系统就绪 (等待指令)"
23
 
24
  def log_print(msg):
25
+ """日志助手"""
26
  timestamp = datetime.now().strftime("%H:%M:%S")
 
27
  print(f"[{timestamp}] {msg}", flush=True)
28
  return timestamp
29
 
30
+ # ================= 2. 核心签到逻辑 =================
31
  def perform_checkin():
32
  log_print("🚀 --- 开始执行任务 ---")
33
 
 
37
 
38
  session = requests.Session()
39
 
40
+ # 基础 Headers (防 401)
 
41
  base_headers = {
42
  "Host": "free-api.rorryson.com",
43
  "Connection": "keep-alive",
 
56
  session.headers.update(base_headers)
57
 
58
  try:
59
+ # --- 步骤 1: 登录 ---
60
+ session.headers.update({"Referer": "https://free-api.rorryson.com/login", "New-API-User": "-1"})
 
 
 
 
 
61
  log_print("正在尝试登录...")
62
  res_login = session.post(f"{BASE_URL}/api/user/login?turnstile=", json={"username": USERNAME, "password": PASSWORD})
63
 
64
  if res_login.status_code != 200:
65
+ log_print(f"登录失败: {res_login.status_code}")
66
  st.session_state.status_msg = f"❌ 登录失败 ({res_login.status_code})"
67
  return
68
 
69
  log_print("✅ 登录成功,Session Cookie 已获取")
70
 
71
+ # --- 步骤 2: 签到 ---
 
72
  session.headers.update({
73
  "Referer": "https://free-api.rorryson.com/console/topup",
74
+ "New-API-User": "201",
75
+ "Cache-Control": "no-store"
76
  })
77
+ time.sleep(1)
 
78
 
79
  log_print("正在尝试签到...")
80
  res_checkin = session.post(f"{BASE_URL}/api/user/checkin")
 
81
  ts = datetime.now().strftime("%H:%M:%S")
82
 
 
83
  if res_checkin.status_code == 200:
84
  try:
85
  data = res_checkin.json()
86
  msg = data.get("message", "OK")
87
+ log_print(f"签到返回: {msg}")
 
 
88
  if "已" in msg or "duplicate" in msg.lower():
89
  st.session_state.status_msg = f"🔸 {msg} ({ts})"
90
  else:
 
93
  st.session_state.status_msg = f"✅ 签到请求成功 ({ts})"
94
 
95
  elif res_checkin.status_code == 422:
96
+ log_print("签到状态 422 (重复到)")
97
+ st.session_state.status_msg = f"🔸 今天已签到过 ({ts})"
 
 
98
  else:
99
  log_print(f"签到异常: {res_checkin.status_code}")
100
  st.session_state.status_msg = f"⚠️ 接口返回 {res_checkin.status_code} ({ts})"
101
 
102
+ # --- 步骤 3: 查余额 (自动换算) ---
 
103
  res_info = session.get(f"{BASE_URL}/api/user/self")
104
  if res_info.status_code == 200:
105
+ raw_quota = res_info.json().get("data", {}).get("quota", 0)
106
+
107
+ # 【核心修改】积分换算逻辑:除以 500,000
108
+ try:
109
+ real_balance = float(raw_quota) / 500000
110
+ # 格式化显示: 加$符号,��留2位小数,加千位分隔符
111
+ st.session_state.quota = f"${real_balance:,.2f}"
112
+ except:
113
+ st.session_state.quota = str(raw_quota)
114
+
115
+ log_print(f"原始积分: {raw_quota} -> 换算显示: {st.session_state.quota}")
116
 
117
  except Exception as e:
118
  log_print(f"程序崩溃: {str(e)}")
119
+ st.session_state.status_msg = "💥 系统内部错误"
120
 
121
+ # ================= 3. 后台调度 =================
122
  def run_scheduler():
123
  while True:
124
  schedule.run_pending()
 
127
  def start_background_thread():
128
  if 'scheduler_started' not in st.session_state:
129
  log_print("⚡ 系统启动初始化...")
 
 
130
  perform_checkin()
 
 
131
  schedule.every().day.at("00:00").do(perform_checkin)
 
 
132
  t = threading.Thread(target=run_scheduler, daemon=True)
133
  t.start()
134
  st.session_state.scheduler_started = True
135
  log_print("⏰ 定时任务已设定: 每天北京时间 08:00")
136
 
137
+ # ================= 4. 前端界面 =================
138
  st.set_page_config(page_title="R-API 哨兵", page_icon="🛡️", layout="centered")
139
 
 
140
  start_background_thread()
141
 
 
142
  st.markdown("""
143
  <style>
144
  .stApp {background-color: #050505; color: #ccc;}
 
145
  #MainMenu {visibility: hidden;}
146
  footer {visibility: hidden;}
147
 
 
151
  box-shadow: 0 4px 15px rgba(0,0,0,0.5);
152
  }
153
  .metric-label {font-size: 0.9rem; color: #666; margin-bottom: 5px;}
154
+
155
+ /* 余额字体显示 */
156
+ .metric-val {font-size: 1.8rem; font-weight: bold; color: #fff; font-family: monospace;}
157
 
158
  .status-box {
159
  margin-top: 25px; padding: 15px; border-radius: 8px;
 
161
  font-family: "Microsoft YaHei", sans-serif; color: #00c6ff;
162
  text-align: center;
163
  }
 
 
164
  .stButton>button {
165
  width: 100%; height: 50px; background: linear-gradient(90deg, #00c6ff, #0072ff);
166
  border: none; color: white; font-weight: bold; font-size: 1rem; border-radius: 8px;
 
168
  </style>
169
  """, unsafe_allow_html=True)
170
 
 
171
  st.markdown("<br>", unsafe_allow_html=True)
172
 
173
  col1, col2 = st.columns(2)
 
179
  </div>
180
  """, unsafe_allow_html=True)
181
  with col2:
 
182
  color = "#00ffcc" if st.session_state.quota != "---" else "#444"
183
  st.markdown(f"""
184
  <div class="metric-card">
185
+ <div class="metric-label">当前账户余额 (USD)</div>
186
  <div class="metric-val" style="color:{color}">{st.session_state.quota}</div>
187
  </div>
188
  """, unsafe_allow_html=True)
189
 
190
  st.markdown("<br>", unsafe_allow_html=True)
191
 
 
192
  if st.button("🚀 立即执行手动签到", use_container_width=True):
193
  with st.spinner("正在连接服务器..."):
194
  perform_checkin()
195
  time.sleep(0.5)
196
  st.rerun()
197
 
 
198
  st.markdown(f"""
199
  <div class="status-box">
200
  系统状态: {st.session_state.status_msg}
 
205
 
206
 
207
 
208
+