feat(core): 增强hosts管理功能和自动还原设置

- 添加对hosts文件优选IP记录的检查,避免重复优选。
- 添加禁用自动还原hosts的选项,允许用户自定义设置。
- 更新HostsManager以支持自动还原状态的设置和检查,优化hosts文件的管理逻辑。
This commit is contained in:
hyb-oyqq
2025-08-04 11:44:10 +08:00
parent 19da86c808
commit 98bfddeb04
6 changed files with 237 additions and 3 deletions

View File

@@ -28,6 +28,7 @@ class CloudflareOptimizer:
self.optimization_cancelled = False
self.ip_optimizer_thread = None
self.ipv6_optimizer_thread = None
self.has_optimized_in_session = False # 本次启动是否已执行过优选
def is_optimization_done(self):
"""检查是否已完成优化
@@ -67,6 +68,39 @@ class CloudflareOptimizer:
Args:
url: 用于优化的URL
"""
# 解析域名
hostname = urlparse(url).hostname
# 检查hosts文件中是否已有该域名的IP记录
existing_ips = self.hosts_manager.get_hostname_entries(hostname) if hostname else []
# 判断是否继续优选的逻辑
if existing_ips and self.has_optimized_in_session:
# 如果本次会话中已执行过优选且hosts中存在记录则跳过优选过程
print(f"发现hosts文件中已有域名 {hostname} 的优选IP记录且本次会话已优选过跳过优选过程")
# 设置标记为已优选完成
self.optimization_done = True
self.countdown_finished = True
# 尝试获取现有的IPv4和IPv6地址
ipv4_entries = [ip for ip in existing_ips if ':' not in ip] # IPv4地址不含冒号
ipv6_entries = [ip for ip in existing_ips if ':' in ip] # IPv6地址包含冒号
if ipv4_entries:
self.optimized_ip = ipv4_entries[0]
if ipv6_entries:
self.optimized_ipv6 = ipv6_entries[0]
print(f"使用已存在的优选IP - IPv4: {self.optimized_ip}, IPv6: {self.optimized_ipv6}")
return True
else:
# 如果本次会话尚未优选过或hosts中没有记录则显示优选窗口
if existing_ips:
print(f"发现hosts文件中已有域名 {hostname} 的优选IP记录但本次会话尚未优选过")
# 清理已有的hosts记录准备重新优选
self.hosts_manager.clean_hostname_entries(hostname)
# 创建取消状态标记
self.optimization_cancelled = False
self.countdown_finished = False
@@ -332,6 +366,15 @@ class CloudflareOptimizer:
if ipv6_success:
success = self.hosts_manager.apply_ip(hostname, self.optimized_ipv6, clean=False) or success
# 记录此次优选操作对hosts文件进行了更新
if hasattr(self.main_window, 'config'):
self.main_window.config['last_hosts_optimized_hostname'] = hostname
from utils import save_config
save_config(self.main_window.config)
# 记录本次会话已执行过优选
self.has_optimized_in_session = True
if success:
msg_box = QtWidgets.QMessageBox(self.main_window)
msg_box.setWindowTitle(f"成功 - {self.main_window.APP_NAME}")

View File

@@ -406,6 +406,38 @@ class DownloadManager:
def _show_cloudflare_option(self):
"""显示Cloudflare加速选择对话框"""
# 首先检查队列中第一个URL的域名是否已在hosts中有优选IP
if self.download_queue:
first_url = self.download_queue[0][0]
hostname = urlparse(first_url).hostname
# 检查hosts文件中是否已有该域名的IP记录
if hostname:
existing_ips = self.cloudflare_optimizer.hosts_manager.get_hostname_entries(hostname)
if existing_ips:
print(f"发现hosts文件中已有域名 {hostname} 的优选IP记录跳过询问直接使用")
# 设置标记为已优选完成
self.cloudflare_optimizer.optimization_done = True
self.cloudflare_optimizer.countdown_finished = True
# 尝试获取现有的IPv4和IPv6地址
ipv4_entries = [ip for ip in existing_ips if ':' not in ip]
ipv6_entries = [ip for ip in existing_ips if ':' in ip]
if ipv4_entries:
self.cloudflare_optimizer.optimized_ip = ipv4_entries[0]
if ipv6_entries:
self.cloudflare_optimizer.optimized_ipv6 = ipv6_entries[0]
# 保存当前URL供CloudflareOptimizer使用
self.main_window.current_url = first_url
# 直接开始下载,跳过询问
self.next_download_task()
return
# 临时启用窗口以显示对话框
self.main_window.setEnabled(True)

View File

@@ -341,12 +341,26 @@ class UIManager:
self.clean_hosts_action.setFont(menu_font)
self.clean_hosts_action.triggered.connect(self.clean_hosts_entries)
# 添加禁用自动还原hosts的选项
self.disable_auto_restore_action = QAction("禁用关闭/重启自动还原hosts", self.main_window, checkable=True)
self.disable_auto_restore_action.setFont(menu_font)
# 从配置中读取当前状态
config = getattr(self.main_window, 'config', {})
disable_auto_restore = False
if isinstance(config, dict):
disable_auto_restore = config.get("disable_auto_restore_hosts", False)
self.disable_auto_restore_action.setChecked(disable_auto_restore)
self.disable_auto_restore_action.triggered.connect(self.toggle_disable_auto_restore_hosts)
# 添加打开hosts文件选项
self.open_hosts_action = QAction("打开hosts文件", self.main_window)
self.open_hosts_action.setFont(menu_font)
self.open_hosts_action.triggered.connect(self.open_hosts_file)
# 添加到hosts子菜单
self.hosts_submenu.addAction(self.disable_auto_restore_action)
self.hosts_submenu.addAction(self.restore_hosts_action)
self.hosts_submenu.addAction(self.clean_hosts_action)
self.hosts_submenu.addAction(self.open_hosts_action)
@@ -645,6 +659,54 @@ class UIManager:
msg_box = self._create_message_box("错误", f"\n打开hosts文件时发生错误\n\n{str(e)}\n")
msg_box.exec()
def toggle_disable_auto_restore_hosts(self, checked):
"""切换禁用自动还原hosts的状态
Args:
checked: 是否禁用自动还原
"""
if hasattr(self.main_window, 'download_manager') and hasattr(self.main_window.download_manager, 'hosts_manager'):
try:
# 调用HostsManager的方法设置自动还原标志
result = self.main_window.download_manager.hosts_manager.set_auto_restore_disabled(checked)
if result:
# 同时更新内部配置,确保立即生效
if hasattr(self.main_window, 'config'):
self.main_window.config['disable_auto_restore_hosts'] = checked
# 显示成功提示
status = "禁用" if checked else "启用"
msg_box = self._create_message_box(
"设置已更新",
f"\n{status}关闭/重启时自动还原hosts。\n\n{'hosts将被保留' if checked else 'hosts将在关闭时自动还原'}\n"
)
msg_box.exec()
else:
# 如果设置失败,恢复复选框状态
self.disable_auto_restore_action.setChecked(not checked)
msg_box = self._create_message_box(
"设置失败",
"\n更新设置时发生错误,请稍后再试。\n"
)
msg_box.exec()
except Exception as e:
# 如果发生异常,恢复复选框状态
self.disable_auto_restore_action.setChecked(not checked)
msg_box = self._create_message_box(
"错误",
f"\n更新设置时发生异常:\n\n{str(e)}\n"
)
msg_box.exec()
else:
# 如果hosts管理器不可用恢复复选框状态
self.disable_auto_restore_action.setChecked(not checked)
msg_box = self._create_message_box(
"错误",
"\nhosts管理器不可用无法更新设置。\n"
)
msg_box.exec()
def show_about_dialog(self):
"""显示关于对话框"""
about_text = f"""