Skip to content
This repository was archived by the owner on May 16, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
env/
venv/
.env/
.venv/

.idea/
__pycache__/
*.py[cod]
*.pyo
*.pyd
*.pyc
*.pdb
*.json
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ __pycache__/
*/__pycache__/
*.py[cod]
*$py.class
env
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11
FROM python:3.11-slim
WORKDIR /app
RUN apt-get update &&\
apt-get install -y curl
Expand Down
21 changes: 17 additions & 4 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import argparse

import os
import gradio as gr
from loguru import logger

Expand All @@ -8,7 +8,7 @@
from tab.order import order_tab
from tab.problems import problems_tab
from tab.settings import setting_tab

from tab.log import log_tab
header = """
# CPP 抢票🌈

Expand All @@ -30,11 +30,17 @@

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--port", type=int, default=7860, help="server port")
parser.add_argument("--port", type=int, default=11451, help="server port")
parser.add_argument("--share", type=bool, default=False, help="create a public link")
args = parser.parse_args()

LOG_PATH = (os.environ.get("LOG_PATH", "logs/app.log"))
os.remove(LOG_PATH) if os.path.exists(LOG_PATH) else None
logger.remove()
logger.add(LOG_PATH, rotation="1 MB", retention="7 days", encoding="utf-8")
logger.add(lambda msg: print(msg, end=""), level="INFO")
logger.add("app.log")

with gr.Blocks(head=short_js, css=custom_css) as demo:
gr.Markdown(header)
with gr.Tab("配置"):
Expand All @@ -47,7 +53,14 @@
login_tab()
with gr.Tab("常见问题"):
problems_tab()
with gr.Tab("日志"):
log_tab()

print("CPP账号的登录是在此控制台,请留意提示!!")
print("点击下面的网址运行程序 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓")
demo.launch(share=args.share, inbrowser=True)
demo.launch(share=args.share,
server_name="0.0.0.0",
server_port=7860,
inbrowser=False,
allowed_paths=["/usr/local/bin"]
)
19 changes: 19 additions & 0 deletions tab/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import gradio as gr
import os

LOG_PATH = (os.environ.get("LOG_PATH", "logs/app.log"))
def read_last_logs(n=1000):
if not os.path.exists(LOG_PATH):
return "No logs found."
with open(LOG_PATH, "r", encoding="utf-8") as f:
lines = f.readlines()
return "".join(lines[-n:])

def log_tab():
log_textbox = gr.Textbox(label="最近日志", lines=20, interactive=False)
refresh_btn = gr.Button("刷新日志")
log_file_download = gr.File(label="下载完整日志", value=LOG_PATH, interactive=False)

refresh_btn.click(fn=read_last_logs, inputs=None, outputs=log_textbox)
timer = gr.Timer(5.0)
timer.tick(fn=read_last_logs, outputs=log_textbox)
38 changes: 26 additions & 12 deletions tab/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,10 @@ def login_tab():
info="此窗口为输出信息", label="输出信息", interactive=False
)
with gr.Row():
upload_ui = gr.UploadButton(label="导入")
add_btn = gr.Button("登录")
upload_ui = gr.UploadButton(label="导入配置文件")

def upload_file(filepath):
main_request.cookieManager.db.delete("cookie")
main_request.cookieManager.reset()
yield ["已经注销,请选择登录信息文件", gr.update(), gr.update()]
try:
configDB.insert("cookie_path", filepath)
Expand All @@ -52,20 +51,35 @@ def upload_file(filepath):

upload_ui.upload(upload_file, [upload_ui], [info_ui, username_ui, gr_file_ui])

def add():
main_request.cookieManager.db.delete("cookie")
yield ["已经注销,在控制台(终端)登录", gr.update(value="未登录"),
gr.update(value=configDB.get("cookie_path"))]
with gr.Row():
user_input = gr.Textbox(label="用户名")
pass_input = gr.Textbox(label="密码", type="password")
login_btn = gr.Button("使用账号密码登录")
logout_btn = gr.Button("注销登录")

def login(username, password):
main_request.cookieManager.reset()
yield ["已经注销,请重新登录", gr.update(value="未登录"), gr.update(value=configDB.get("cookie_path"))]
try:
main_request.cookieManager.get_cookies_str_force()
main_request.cookieManager.login_by_phone_passwd(username, password)
name = main_request.get_request_name()
yield [f"登录成功", gr.update(value=name), gr.update(value=configDB.get("cookie_path"))]
if name == '未登录':
yield ["登录失败,请检查账号密码", gr.update(value="未登录"), gr.update(value=configDB.get("cookie_path"))]
else:
yield [gr.update(value="登录成功"), gr.update(value=name), gr.update(value=configDB.get("cookie_path"))]
except Exception:
name = main_request.get_request_name()
yield ["登录出现错误", gr.update(value=name), gr.update(value=configDB.get("cookie_path"))]

add_btn.click(
fn=add,
def logout():
main_request.cookieManager.reset()
yield ["已经注销,重新登录", gr.update(value="未登录"), gr.update(value=configDB.get("cookie_path"))]
login_btn.click(
fn=login,
inputs=[user_input, pass_input],
outputs=[info_ui, username_ui, gr_file_ui]
)
logout_btn.click(
fn=logout,
inputs=None,
outputs=[info_ui, username_ui, gr_file_ui]
)
Expand Down
61 changes: 39 additions & 22 deletions util/CookieManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,8 @@
class CookieManager:
def __init__(self, config_file_path):
self.db = KVDatabase(config_file_path)

@logger.catch
def _login_and_save_cookies(
self, login_url="https://cp.allcpp.cn/#/login/main"
):
print("开始填写登录信息")
phone = input("输入手机号:")
password = input("输入密码:")
def login_by_phone_passwd(self, phone, password):
login_url = "https://user.allcpp.cn/api/login/normal"
headers = {
'accept': 'application/json, text/plain, */*',
Expand All @@ -31,22 +25,40 @@ def _login_and_save_cookies(
'sec-fetch-site': 'same-site',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36 Edg/127.0.0.0'
}
while True:
payload = f"account={phone}&password={password}&phoneAccountBindToken=undefined&thirdAccountBindToken=undefined"
response = requests.request("POST", login_url, headers=headers, data=payload)
payload = f"account={phone}&password={password}&phoneAccountBindToken=undefined&thirdAccountBindToken=undefined"
response = requests.request("POST", login_url, headers=headers, data=payload)
if response.status_code != 200:
raise RuntimeError(f"登录失败,状态码 {response.status_code},响应内容:{response.text[:100]}")
try:
res_json = response.json()
logger.info(f"登录响应体: {res_json}")
if "token" in res_json:
cookies_dict = response.cookies.get_dict()
logger.info(f"cookies: {cookies_dict}")
self.db.insert("cookie", cookies_dict)
self.db.insert("password", password)
self.db.insert("phone", phone)

return response.cookies
else:
phone = input("输入手机号:")
password = input("输入密码:")
except Exception as e:
raise RuntimeError(f"登录返回无法解析为 JSON:{e}\n响应内容:{response.text[:200]}")
logger.info(f"登录响应体: {res_json}")
if "token" in res_json and res_json["token"] is not None:
cookies_dict = response.cookies.get_dict()
logger.success("登录成功")
logger.info(f"cookies: {cookies_dict}")
self.db.insert("cookie", cookies_dict)
self.db.insert("password", password)
self.db.insert("phone", phone)
return response.cookies
else:
logger.error("登录失败,请检查账号密码是否正确")
return None

@logger.catch
def _login_and_save_cookies(
self, login_url="https://cp.allcpp.cn/#/login/main"
):
logger.info("开始填写登录信息")
phone = input("输入手机号:")
password = input("输入密码:")
while self.login_by_phone_passwd(phone, password) is None:
logger.error("登录失败,请检查账号密码是否正确")
phone = input("输入手机号:")
password = input("输入密码:")
logger.success("登录成功")


def refreshToken(self):
login_url = "https://user.allcpp.cn/api/login/normal"
Expand Down Expand Up @@ -114,3 +126,8 @@ def set_config_value(self, name, value):
def get_cookies_str_force(self):
self._login_and_save_cookies()
return self.get_cookies_str()

def reset(self):
self.db.delete("cookie")
self.db.delete("password")
self.db.delete("phone")