Files
cat-shark 01827224d6 fix: 修复主程序卡死与下载器集成,新增真实数据测试
- LookingWebMain: 强制 IPv4 避免 IPv6 不可达挂起;requests 加超时防卡死
- get_seed_from_element_detail: 修复限流页崩溃与 favicon 误作来源 URL,改用 canonical/传入 URL
- QbittorrentDownloader: 修复 main() 中模块/类误用导致的 download_by_seed AttributeError;请求加超时
- MySqlService: 修复数据库不可达时 query/execute/close 的 None 崩溃,close 后置空 connection
- 新增 cf_session: Cloudflare 人机认证 cookie 管理 + 限流退避重试 + 自动弹浏览器刷新验证
- 新增 refresh_cf_cookies.py: 弹出浏览器手动验证并保存 cf_clearance
- tests/: 真实网络/数据库测试(get_page、seed_is_exist、cf_session)+ run_tests.py runner
- 清理无用脚本(final_test2/verify_replace/REPLACEMENT_INFO),.idea 与 cookie 文件入 .gitignore

注: test_qbittorrent_downloader.py 11 个用例为既有失败(mock 目标 session 为实例属性,与实现错配),未在本次范围
2026-08-30 12:24:26 +08:00

128 lines
4.7 KiB
Python

import pymysql
from loguru import logger
class DatabaseConfig:
HOST = "192.168.123.199"
PORT = 3306
USER = "root"
PASSWORD = "GUOxy5157"
DB = "LookingWeb"
class MySQLDatabase:
def __init__(self, host, prot, user, password, db):
self.port = prot
self.host = host
self.user = user
self.password = password
self.db = db
self.connection = None
self.connect()
def __enter__(self):
self.connect()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if self.connection and self.connection.open:
self.connection.close()
@classmethod
def create_connection(cls):
return cls(DatabaseConfig.HOST, DatabaseConfig.PORT, DatabaseConfig.USER, DatabaseConfig.PASSWORD,
DatabaseConfig.DB)
def connect(self):
if not self.connection or not self.connection.open:
try:
self.connection = pymysql.connect(
host=self.host, port=self.port, user=self.user,
password=self.password, db=self.db, charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
logger.info("数据库连接成功:{}@{}", self.user, self.host)
except pymysql.MySQLError as e:
logger.error("数据库连接失败:{}", str(e))
def close(self):
if self.connection and self.connection.open:
self.connection.close()
self.connection = None
def query(self, sql, params=None):
self.connect()
if not self.connection:
logger.error("查询失败:{},无数据库连接", sql)
return None
with self.connection.cursor() as cursor:
try:
cursor.execute(sql, params or ())
result = cursor.fetchall()
logger.debug("查询成功:{}", sql)
return result
except pymysql.MySQLError as e:
logger.error("查询失败:{},错误:{}", sql, str(e))
return None
def execute(self, sql, params=None):
self.connect()
if not self.connection:
logger.error("执行失败:{},无数据库连接", sql)
return
with self.connection.cursor() as cursor:
cursor.execute(sql, params or ())
self.connection.commit()
def is_connected():
logger.debug("正在检查数据库连接...")
with MySQLDatabase.create_connection() as mysql:
try:
mysql.query("SELECT * FROM seeds_info where id = 1")
logger.info("数据库连接检查通过")
return True
except pymysql.MySQLError as e:
logger.error("数据库连接检查失败:{}", str(e))
return False
def seed_is_exist(seed):
with MySQLDatabase.create_connection() as mysql:
try:
sql = "SELECT * FROM seeds_info where seed_url = %s"
result = mysql.query(sql, (seed.seedUrl,))
if not result:
logger.info("种子不存在: {}", seed.seedUrl)
return False
else:
logger.info("种子已存在: {}", seed.seedUrl)
return True
except pymysql.MySQLError as e:
logger.error("检查种子存在失败: {},错误: {}", seed.seedUrl, str(e))
return False
def save_seed(seed_info):
with MySQLDatabase.create_connection() as connection:
query = """
INSERT INTO seeds_info (name, seed_url, have_download, create_time, update_time, url)
VALUES (%s, %s, %s, %s, %s, %s)
"""
values = (seed_info.name, seed_info.seedUrl, seed_info.haveDownload, seed_info.createTime, seed_info.updateTime,
seed_info.url)
try:
connection.execute(query, values)
logger.info("种子信息保存成功: {}", seed_info.seedUrl)
return True
except pymysql.MySQLError as e:
logger.error("保存种子信息失败: {},错误: {}", seed_info.seedUrl, str(e))
return False
def delete_seed(seed_info):
query = "DELETE FROM seeds_info WHERE seed_url = %s"
value = (seed_info.seedUrl,)
with MySQLDatabase.create_connection() as connection:
try:
connection.execute(query, value)
logger.info("种子删除成功: {}", seed_info.seedUrl)
return True
except pymysql.MySQLError as e:
logger.error("删除种子失败: {},错误: {}", seed_info.seedUrl, str(e))
return False