mirror of
https://github.com/hyb-oyqq/FRAISEMOE-Addons-Installer-NEXT.git
synced 2026-01-01 11:40:45 +00:00
feat(core): 优化隐私协议管理并添加日志功能
- 重构 PrivacyManager 类,增加隐私协议版本检查和用户同意状态管理 - 在主窗口初始化时获取云端配置,提高效率 - 添加日志功能,记录应用启动、隐私协议加载等关键事件 - 优化错误处理和用户提示信息
This commit is contained in:
@@ -41,8 +41,14 @@ class DebugManager:
|
||||
Args:
|
||||
checked: 是否启用调试模式
|
||||
"""
|
||||
print(f"Toggle debug mode: {checked}")
|
||||
self.main_window.config["debug_mode"] = checked
|
||||
self.main_window.save_config(self.main_window.config)
|
||||
|
||||
# 更新打开log文件按钮状态
|
||||
if hasattr(self, 'ui_manager') and hasattr(self.ui_manager, 'open_log_action'):
|
||||
self.ui_manager.open_log_action.setEnabled(checked)
|
||||
|
||||
if checked:
|
||||
self.start_logging()
|
||||
else:
|
||||
|
||||
@@ -6,36 +6,77 @@ import json
|
||||
from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QTextBrowser, QPushButton, QCheckBox, QLabel, QMessageBox
|
||||
from PySide6.QtCore import Qt
|
||||
|
||||
from data.privacy_policy import PRIVACY_POLICY_BRIEF
|
||||
from data.config import CACHE, APP_NAME
|
||||
from data.privacy_policy import PRIVACY_POLICY_BRIEF, get_local_privacy_policy, PRIVACY_POLICY_VERSION
|
||||
from data.config import CACHE, APP_NAME, APP_VERSION
|
||||
from utils import msgbox_frame
|
||||
from utils.logger import setup_logger
|
||||
|
||||
class PrivacyManager:
|
||||
"""隐私协议管理器,负责显示隐私协议对话框并处理用户选择"""
|
||||
|
||||
def __init__(self):
|
||||
"""初始化隐私协议管理器"""
|
||||
# 初始化日志
|
||||
self.logger = setup_logger("privacy_manager")
|
||||
self.logger.info("正在初始化隐私协议管理器")
|
||||
# 确保缓存目录存在
|
||||
os.makedirs(CACHE, exist_ok=True)
|
||||
self.config_file = os.path.join(CACHE, "privacy_config.json")
|
||||
self.privacy_accepted = self._load_privacy_config()
|
||||
self.privacy_config = self._load_privacy_config()
|
||||
|
||||
# 获取隐私协议内容和版本
|
||||
self.logger.info("读取本地隐私协议文件")
|
||||
self.privacy_content, self.current_privacy_version, error = get_local_privacy_policy()
|
||||
if error:
|
||||
self.logger.warning(f"读取本地隐私协议文件警告: {error}")
|
||||
# 使用默认版本作为备用
|
||||
self.current_privacy_version = PRIVACY_POLICY_VERSION
|
||||
self.logger.info(f"隐私协议版本: {self.current_privacy_version}")
|
||||
|
||||
# 检查隐私协议版本和用户同意状态
|
||||
self.privacy_accepted = self._check_privacy_acceptance()
|
||||
|
||||
def _load_privacy_config(self):
|
||||
"""加载隐私协议配置
|
||||
|
||||
Returns:
|
||||
bool: 用户是否已同意隐私协议
|
||||
dict: 隐私协议配置信息
|
||||
"""
|
||||
if os.path.exists(self.config_file):
|
||||
try:
|
||||
with open(self.config_file, "r", encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
return config.get("privacy_accepted", False)
|
||||
return config
|
||||
except (json.JSONDecodeError, IOError) as e:
|
||||
print(f"读取隐私配置失败: {e}")
|
||||
# 如果读取失败,返回False,强制显示隐私协议
|
||||
return False
|
||||
return False
|
||||
self.logger.error(f"读取隐私配置失败: {e}")
|
||||
# 如果读取失败,返回空配置,强制显示隐私协议
|
||||
return {"privacy_accepted": False}
|
||||
return {"privacy_accepted": False}
|
||||
|
||||
def _check_privacy_acceptance(self):
|
||||
"""检查隐私协议是否需要重新同意
|
||||
|
||||
如果隐私协议版本变更,则需要重新同意
|
||||
|
||||
Returns:
|
||||
bool: 是否已有有效的隐私协议同意
|
||||
"""
|
||||
# 获取存储的版本信息
|
||||
stored_privacy_version = self.privacy_config.get("privacy_version", "0.0.0")
|
||||
stored_app_version = self.privacy_config.get("app_version", "0.0.0")
|
||||
privacy_accepted = self.privacy_config.get("privacy_accepted", False)
|
||||
|
||||
self.logger.info(f"存储的隐私协议版本: {stored_privacy_version}, 当前版本: {self.current_privacy_version}")
|
||||
self.logger.info(f"存储的应用版本: {stored_app_version}, 当前版本: {APP_VERSION}")
|
||||
self.logger.info(f"隐私协议接受状态: {privacy_accepted}")
|
||||
|
||||
# 如果隐私协议版本变更,需要重新同意
|
||||
if stored_privacy_version != self.current_privacy_version:
|
||||
self.logger.info("隐私协议版本已变更,需要重新同意")
|
||||
return False
|
||||
|
||||
# 返回当前的同意状态
|
||||
return privacy_accepted
|
||||
|
||||
def _save_privacy_config(self, accepted):
|
||||
"""保存隐私协议配置
|
||||
@@ -50,18 +91,24 @@ class PrivacyManager:
|
||||
# 确保目录存在
|
||||
os.makedirs(os.path.dirname(self.config_file), exist_ok=True)
|
||||
|
||||
# 写入配置文件
|
||||
# 写入配置文件,包含应用版本和隐私协议版本
|
||||
with open(self.config_file, "w", encoding="utf-8") as f:
|
||||
json.dump({
|
||||
"privacy_accepted": accepted,
|
||||
"version": "1.0" # 添加版本号,便于将来升级隐私协议时使用
|
||||
"privacy_version": self.current_privacy_version, # 保存当前隐私协议版本
|
||||
"app_version": APP_VERSION # 保存当前应用版本
|
||||
}, f, indent=2)
|
||||
|
||||
# 更新实例变量
|
||||
self.privacy_accepted = accepted
|
||||
self.privacy_config = {
|
||||
"privacy_accepted": accepted,
|
||||
"privacy_version": self.current_privacy_version,
|
||||
"app_version": APP_VERSION
|
||||
}
|
||||
return True
|
||||
except IOError as e:
|
||||
print(f"保存隐私协议配置失败: {e}")
|
||||
self.logger.error(f"保存隐私协议配置失败: {e}")
|
||||
# 显示保存失败的提示
|
||||
QMessageBox.warning(
|
||||
None,
|
||||
@@ -78,10 +125,10 @@ class PrivacyManager:
|
||||
"""
|
||||
# 如果用户已经同意了隐私协议,直接返回True不显示对话框
|
||||
if self.privacy_accepted:
|
||||
print("用户已同意隐私协议,无需再次显示")
|
||||
self.logger.info("用户已同意当前版本的隐私协议,无需再次显示")
|
||||
return True
|
||||
|
||||
print("首次运行或用户未同意隐私协议,显示隐私对话框")
|
||||
self.logger.info("首次运行或隐私协议版本变更,显示隐私对话框")
|
||||
|
||||
# 创建隐私协议对话框
|
||||
dialog = QDialog()
|
||||
@@ -92,13 +139,14 @@ class PrivacyManager:
|
||||
# 创建布局
|
||||
layout = QVBoxLayout(dialog)
|
||||
|
||||
# 添加标题
|
||||
title_label = QLabel("请阅读并同意以下隐私政策")
|
||||
# 添加标题和版本信息
|
||||
title_label = QLabel(f"请阅读并同意以下隐私政策 (更新日期: {self.current_privacy_version})")
|
||||
title_label.setStyleSheet("font-size: 14px; font-weight: bold;")
|
||||
layout.addWidget(title_label)
|
||||
|
||||
# 添加隐私协议文本框
|
||||
text_browser = QTextBrowser()
|
||||
# 这里使用PRIVACY_POLICY_BRIEF而不是self.privacy_content,保持UI简洁
|
||||
text_browser.setMarkdown(PRIVACY_POLICY_BRIEF)
|
||||
text_browser.setOpenExternalLinks(True)
|
||||
layout.addWidget(text_browser)
|
||||
@@ -118,7 +166,7 @@ class PrivacyManager:
|
||||
|
||||
# 连接选择框状态变化 - 修复勾选后按钮不亮起的问题
|
||||
def on_checkbox_state_changed(state):
|
||||
print(f"复选框状态变更为: {state}")
|
||||
self.logger.debug(f"复选框状态变更为: {state}")
|
||||
agree_button.setEnabled(state == 2) # Qt.Checked 在 PySide6 中值为 2
|
||||
|
||||
checkbox.stateChanged.connect(on_checkbox_state_changed)
|
||||
|
||||
@@ -5,7 +5,7 @@ import webbrowser
|
||||
import os
|
||||
|
||||
from utils import load_base64_image, msgbox_frame, resource_path
|
||||
from data.config import APP_NAME, APP_VERSION
|
||||
from data.config import APP_NAME, APP_VERSION, LOG_FILE
|
||||
|
||||
class UIManager:
|
||||
def __init__(self, main_window):
|
||||
@@ -269,9 +269,32 @@ class UIManager:
|
||||
menu_style = self._get_menu_style(font_family)
|
||||
self.dev_menu.setStyleSheet(menu_style)
|
||||
|
||||
# 创建Debug模式选项并添加到开发者选项子菜单中
|
||||
self.debug_action = QAction("Debug模式", self.main_window, checkable=True)
|
||||
self.debug_action.setFont(menu_font) # 设置相同的字体
|
||||
# 创建Debug子菜单
|
||||
self.debug_submenu = QMenu("Debug模式", self.main_window)
|
||||
self.debug_submenu.setFont(menu_font)
|
||||
self.debug_submenu.setStyleSheet(menu_style)
|
||||
|
||||
# 创建hosts文件选项子菜单
|
||||
self.hosts_submenu = QMenu("hosts文件选项", self.main_window)
|
||||
self.hosts_submenu.setFont(menu_font)
|
||||
self.hosts_submenu.setStyleSheet(menu_style)
|
||||
|
||||
# 添加hosts子选项
|
||||
self.restore_hosts_action = QAction("还原软件备份的hosts文件", self.main_window)
|
||||
self.restore_hosts_action.setFont(menu_font)
|
||||
self.restore_hosts_action.triggered.connect(self.restore_hosts_backup)
|
||||
|
||||
self.clean_hosts_action = QAction("手动删除软件添加的hosts条目", self.main_window)
|
||||
self.clean_hosts_action.setFont(menu_font)
|
||||
self.clean_hosts_action.triggered.connect(self.clean_hosts_entries)
|
||||
|
||||
# 添加到hosts子菜单
|
||||
self.hosts_submenu.addAction(self.restore_hosts_action)
|
||||
self.hosts_submenu.addAction(self.clean_hosts_action)
|
||||
|
||||
# 创建Debug开关选项
|
||||
self.debug_action = QAction("Debug开关", self.main_window, checkable=True)
|
||||
self.debug_action.setFont(menu_font)
|
||||
|
||||
# 安全地获取config属性
|
||||
config = getattr(self.main_window, 'config', {})
|
||||
@@ -285,24 +308,33 @@ class UIManager:
|
||||
if hasattr(self.main_window, 'toggle_debug_mode'):
|
||||
self.debug_action.triggered.connect(self.main_window.toggle_debug_mode)
|
||||
|
||||
# 创建狂暴下载选项(无功能)
|
||||
self.turbo_download_action = QAction("狂暴下载", self.main_window)
|
||||
self.turbo_download_action.setFont(menu_font) # 设置自定义字体
|
||||
self.turbo_download_action.setEnabled(False) # 禁用按钮
|
||||
# 创建打开log文件选项
|
||||
self.open_log_action = QAction("打开log.txt", self.main_window)
|
||||
self.open_log_action.setFont(menu_font)
|
||||
# 初始状态根据debug模式设置启用状态
|
||||
self.open_log_action.setEnabled(debug_mode)
|
||||
|
||||
# 添加到开发者选项子菜单
|
||||
self.dev_menu.addAction(self.debug_action)
|
||||
self.dev_menu.addAction(self.turbo_download_action)
|
||||
# 连接打开log文件的事件
|
||||
self.open_log_action.triggered.connect(self.open_log_file)
|
||||
|
||||
# 为未来功能预留的"切换下载源"按钮
|
||||
self.switch_source_action = QAction("切换下载源", self.main_window)
|
||||
# 添加到Debug子菜单
|
||||
self.debug_submenu.addAction(self.debug_action)
|
||||
self.debug_submenu.addAction(self.open_log_action)
|
||||
|
||||
# 为未来功能预留的"修改下载源"按钮 - 现在点击时显示"正在开发中"
|
||||
self.switch_source_action = QAction("修改下载源", self.main_window)
|
||||
self.switch_source_action.setFont(menu_font) # 设置自定义字体
|
||||
self.switch_source_action.setEnabled(False) # 暂时禁用
|
||||
self.switch_source_action.setEnabled(True) # 启用但显示"正在开发中"
|
||||
self.switch_source_action.triggered.connect(self.show_under_development)
|
||||
|
||||
# 添加到主菜单
|
||||
self.ui.menu.addAction(self.switch_source_action)
|
||||
self.ui.menu.addSeparator()
|
||||
self.ui.menu.addMenu(self.dev_menu) # 添加开发者选项子菜单
|
||||
|
||||
# 添加Debug子菜单到开发者选项菜单
|
||||
self.dev_menu.addMenu(self.debug_submenu)
|
||||
self.dev_menu.addMenu(self.hosts_submenu) # 添加hosts文件选项子菜单
|
||||
|
||||
def show_menu(self, menu, button):
|
||||
"""显示菜单
|
||||
@@ -409,6 +441,112 @@ class UIManager:
|
||||
)
|
||||
error_msg.exec()
|
||||
|
||||
def show_under_development(self):
|
||||
"""显示功能正在开发中的提示"""
|
||||
msg_box = msgbox_frame(
|
||||
f"提示 - {APP_NAME}",
|
||||
"\n该功能正在开发中,敬请期待!\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
|
||||
def open_log_file(self):
|
||||
"""打开log.txt文件"""
|
||||
if os.path.exists(LOG_FILE):
|
||||
try:
|
||||
# 使用操作系统默认程序打开日志文件
|
||||
if os.name == 'nt': # Windows
|
||||
os.startfile(LOG_FILE)
|
||||
else: # macOS 和 Linux
|
||||
import subprocess
|
||||
subprocess.call(['xdg-open', LOG_FILE])
|
||||
except Exception as e:
|
||||
msg_box = msgbox_frame(
|
||||
f"错误 - {APP_NAME}",
|
||||
f"\n打开log.txt文件失败:\n\n{str(e)}\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
else:
|
||||
msg_box = msgbox_frame(
|
||||
f"提示 - {APP_NAME}",
|
||||
"\nlog.txt文件不存在,请确保Debug模式已开启并生成日志。\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
|
||||
def restore_hosts_backup(self):
|
||||
"""还原软件备份的hosts文件"""
|
||||
if hasattr(self.main_window, 'download_manager') and hasattr(self.main_window.download_manager, 'hosts_manager'):
|
||||
try:
|
||||
# 调用恢复hosts文件的方法
|
||||
result = self.main_window.download_manager.hosts_manager.restore()
|
||||
|
||||
if result:
|
||||
msg_box = msgbox_frame(
|
||||
f"成功 - {APP_NAME}",
|
||||
"\nhosts文件已成功还原为备份版本。\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
else:
|
||||
msg_box = msgbox_frame(
|
||||
f"警告 - {APP_NAME}",
|
||||
"\n还原hosts文件失败或没有找到备份文件。\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
|
||||
msg_box.exec()
|
||||
except Exception as e:
|
||||
msg_box = msgbox_frame(
|
||||
f"错误 - {APP_NAME}",
|
||||
f"\n还原hosts文件时发生错误:\n\n{str(e)}\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
else:
|
||||
msg_box = msgbox_frame(
|
||||
f"错误 - {APP_NAME}",
|
||||
"\n无法访问hosts管理器。\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
|
||||
def clean_hosts_entries(self):
|
||||
"""手动删除软件添加的hosts条目"""
|
||||
if hasattr(self.main_window, 'download_manager') and hasattr(self.main_window.download_manager, 'hosts_manager'):
|
||||
try:
|
||||
# 调用清理hosts条目的方法
|
||||
result = self.main_window.download_manager.hosts_manager.check_and_clean_all_entries()
|
||||
|
||||
if result:
|
||||
msg_box = msgbox_frame(
|
||||
f"成功 - {APP_NAME}",
|
||||
"\n已成功清理软件添加的hosts条目。\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
else:
|
||||
msg_box = msgbox_frame(
|
||||
f"提示 - {APP_NAME}",
|
||||
"\n未发现软件添加的hosts条目或清理操作失败。\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
|
||||
msg_box.exec()
|
||||
except Exception as e:
|
||||
msg_box = msgbox_frame(
|
||||
f"错误 - {APP_NAME}",
|
||||
f"\n清理hosts条目时发生错误:\n\n{str(e)}\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
else:
|
||||
msg_box = msgbox_frame(
|
||||
f"错误 - {APP_NAME}",
|
||||
"\n无法访问hosts管理器。\n",
|
||||
QMessageBox.StandardButton.Ok,
|
||||
)
|
||||
msg_box.exec()
|
||||
|
||||
def show_about_dialog(self):
|
||||
"""显示关于对话框"""
|
||||
about_text = f"""
|
||||
|
||||
Reference in New Issue
Block a user