mirror of
https://github.com/KenanZhu/AutoLibrary.git
synced 2026-08-01 21:59:36 +08:00
refactor(bulletin): 提取 ALBulletinFetchWorker 到独立文件
This commit is contained in:
@@ -7,14 +7,11 @@ This software is provided "as is", without any warranty of any kind.
|
||||
You may use, modify, and distribute this file under the terms of the MIT License.
|
||||
See the LICENSE file for details.
|
||||
"""
|
||||
import requests
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any
|
||||
|
||||
from PySide6.QtCore import (
|
||||
Qt,
|
||||
QThread,
|
||||
Signal,
|
||||
Slot,
|
||||
QTimer
|
||||
@@ -32,53 +29,12 @@ from PySide6.QtWidgets import (
|
||||
QWidget
|
||||
)
|
||||
|
||||
from gui.ALBulletinWorker import ALBulletinFetchWorker
|
||||
from gui.ALStatusLabel import ALStatusLabel
|
||||
from gui.resources.ui.Ui_ALBulletinDialog import Ui_ALBulletinDialog
|
||||
from managers.bulletin.BulletinManager import instance as bulletinInstance
|
||||
|
||||
|
||||
class ALBulletinFetchWorker(QThread):
|
||||
"""
|
||||
Worker thread for fetching bulletins from the server.
|
||||
"""
|
||||
|
||||
fetchWorkerIsFinished = Signal(dict)
|
||||
fetchWorkerFinishedWithError = Signal(str)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent=None,
|
||||
request_url: str = "",
|
||||
params: dict = None
|
||||
):
|
||||
|
||||
super().__init__(parent)
|
||||
self.__request_url = request_url.rstrip("/") if request_url else ""
|
||||
self.__params = params or {}
|
||||
|
||||
def run(
|
||||
self
|
||||
):
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
self.__request_url, params=self.__params, timeout=5
|
||||
)
|
||||
response.raise_for_status()
|
||||
r = response.json()
|
||||
if r.get("code") == 200:
|
||||
data = r.get("data", {})
|
||||
self.fetchWorkerIsFinished.emit(data)
|
||||
else:
|
||||
raise Exception(
|
||||
f"服务器返回错误: [{r.get('code', '未知代码')}] {r.get('msg', '未知错误')}"
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
self.fetchWorkerFinishedWithError.emit(f"获取公告数据时发生网络错误: \n{e}")
|
||||
except Exception as e:
|
||||
self.fetchWorkerFinishedWithError.emit(f"获取公告数据时发生未知错误: \n{e}")
|
||||
|
||||
|
||||
class ALBulletinItemWidget(QWidget):
|
||||
"""
|
||||
Single bulletin item widget for the bulletin list.
|
||||
@@ -216,6 +172,9 @@ class ALBulletinDialog(QDialog, Ui_ALBulletinDialog):
|
||||
self,
|
||||
iso_str: str
|
||||
):
|
||||
"""
|
||||
Set last sync time to update the UI status.
|
||||
"""
|
||||
|
||||
try:
|
||||
dt = datetime.fromisoformat(iso_str)
|
||||
|
||||
@@ -16,7 +16,7 @@ from PySide6.QtCore import (
|
||||
Slot
|
||||
)
|
||||
|
||||
from gui.ALBulletinDialog import ALBulletinFetchWorker
|
||||
from gui.ALBulletinWorker import ALBulletinFetchWorker
|
||||
from managers.bulletin.BulletinManager import instance as bulletinInstance
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (c) 2026 KenanZhu.
|
||||
All rights reserved.
|
||||
|
||||
This software is provided "as is", without any warranty of any kind.
|
||||
You may use, modify, and distribute this file under the terms of the MIT License.
|
||||
See the LICENSE file for details.
|
||||
"""
|
||||
import requests
|
||||
|
||||
from PySide6.QtCore import (
|
||||
QThread,
|
||||
Signal
|
||||
)
|
||||
|
||||
|
||||
class ALBulletinFetchWorker(QThread):
|
||||
"""
|
||||
Worker thread for fetching bulletins from the server.
|
||||
"""
|
||||
|
||||
fetchWorkerIsFinished = Signal(dict)
|
||||
fetchWorkerFinishedWithError = Signal(str)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent=None,
|
||||
request_url: str = "",
|
||||
params: dict = None
|
||||
):
|
||||
|
||||
super().__init__(parent)
|
||||
self.__request_url = request_url.rstrip("/") if request_url else ""
|
||||
self.__params = params or {}
|
||||
|
||||
def run(
|
||||
self
|
||||
):
|
||||
|
||||
try:
|
||||
response = requests.get(
|
||||
self.__request_url, params=self.__params, timeout=5
|
||||
)
|
||||
response.raise_for_status()
|
||||
r = response.json()
|
||||
if r.get("code") == 200:
|
||||
data = r.get("data", {})
|
||||
self.fetchWorkerIsFinished.emit(data)
|
||||
else:
|
||||
raise Exception(
|
||||
f"服务器返回错误: [{r.get('code', '未知代码')}] {r.get('msg', '未知错误')}"
|
||||
)
|
||||
except requests.RequestException as e:
|
||||
self.fetchWorkerFinishedWithError.emit(f"获取公告数据时发生网络错误: \n{e}")
|
||||
except Exception as e:
|
||||
self.fetchWorkerFinishedWithError.emit(f"获取公告数据时发生未知错误: \n{e}")
|
||||
+72
-59
@@ -41,6 +41,7 @@ from managers.theme.ThemeManager import(
|
||||
instance as themeInstance
|
||||
)
|
||||
|
||||
from gui.ALBulletinWorker import ALBulletinFetchWorker
|
||||
from gui.ALWidgetMixin import CenterOnParentMixin
|
||||
from gui.resources.ui.Ui_ALSettingsWidget import Ui_ALSettingsWidget
|
||||
from interfaces.ConfigProvider import (
|
||||
@@ -196,6 +197,7 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
self
|
||||
):
|
||||
|
||||
# appearance settings
|
||||
theme = self.__cfg_mgr.get(CfgKey.GLOBAL.APPEARANCE.THEME, "system")
|
||||
style = self.__cfg_mgr.get(CfgKey.GLOBAL.APPEARANCE.STYLE, "Fusion")
|
||||
custom_theme = self.__cfg_mgr.get(CfgKey.GLOBAL.APPEARANCE.CUSTOM_THEME, "")
|
||||
@@ -218,7 +220,7 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
self.CustomThemeComboBox.setCurrentIndex(idx)
|
||||
self.updateCustomThemeInfo()
|
||||
self.updateCustomThemeStatus()
|
||||
|
||||
# bulletin settings
|
||||
bulletin_mgr = bulletinInstance()
|
||||
self.__original_bulletin_url = bulletin_mgr.serverUrl()
|
||||
self.__original_bulletin_auto_fetch = bulletin_mgr.autoFetch()
|
||||
@@ -274,10 +276,17 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
elif need_theme == "dark":
|
||||
self.DarkThemeRadio.setChecked(True)
|
||||
|
||||
def collectSettings(
|
||||
def clearBulletinTestStatus(
|
||||
self
|
||||
):
|
||||
|
||||
self.BulletinTestStatusLabel.setText("")
|
||||
self.BulletinTestStatusLabel.setStyleSheet("")
|
||||
|
||||
def collectAppearanceSettings(
|
||||
self
|
||||
) -> tuple[str, str, str]:
|
||||
|
||||
if self.LightThemeRadio.isChecked():
|
||||
theme = "light"
|
||||
elif self.DarkThemeRadio.isChecked():
|
||||
@@ -290,41 +299,29 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
custom_theme = ""
|
||||
return theme, style, custom_theme
|
||||
|
||||
def clearBulletinTestStatus(
|
||||
def collectBulletinSettings(
|
||||
self
|
||||
):
|
||||
|
||||
self.BulletinTestStatusLabel.setText("")
|
||||
self.BulletinTestStatusLabel.setStyleSheet("")
|
||||
|
||||
def saveBulletinSettings(
|
||||
self
|
||||
):
|
||||
) -> tuple[str, bool, int]:
|
||||
|
||||
url = self.BulletinServerUrlEdit.text().strip()
|
||||
auto_fetch = self.BulletinAutoFetchCheck.isChecked()
|
||||
sync_interval = self.BulletinSyncIntervalSpin.value()
|
||||
if sync_interval < 1:
|
||||
sync_interval = 5
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.SERVER_URL, url)
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.AUTO_FETCH, auto_fetch)
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.SYNC_INTERVAL, sync_interval)
|
||||
self.__original_bulletin_url = url
|
||||
self.__original_bulletin_auto_fetch = auto_fetch
|
||||
self.__original_bulletin_sync_interval = sync_interval
|
||||
return url, auto_fetch, sync_interval
|
||||
|
||||
def saveAndApply(
|
||||
def saveAppearanceSettings(
|
||||
self
|
||||
):
|
||||
|
||||
theme, style, custom_theme = self.collectSettings()
|
||||
theme, style, custom_theme = self.collectAppearanceSettings()
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.STYLE, style)
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.CUSTOM_THEME, custom_theme)
|
||||
setActiveStyle(style)
|
||||
if not _applyCustomTheme(custom_theme, theme):
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.CUSTOM_THEME, "")
|
||||
self.syncRadioFromNeedTheme(custom_theme)
|
||||
theme, _, _ = self.collectSettings()
|
||||
theme, _, _ = self.collectAppearanceSettings()
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.APPEARANCE.THEME, theme)
|
||||
self.setNavigationIcons()
|
||||
self.updateCustomThemeStatus()
|
||||
@@ -333,7 +330,24 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
self.__original_custom_theme = custom_theme if custom_theme else ""
|
||||
self.__original_style = getActiveStyle()
|
||||
|
||||
def saveBulletinSettings(
|
||||
self
|
||||
):
|
||||
|
||||
url, auto_fetch, sync_interval = self.collectBulletinSettings()
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.SERVER_URL, url)
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.AUTO_FETCH, auto_fetch)
|
||||
self.__cfg_mgr.set(CfgKey.GLOBAL.BULLETIN.SYNC_INTERVAL, sync_interval)
|
||||
self.__original_bulletin_url = url
|
||||
self.__original_bulletin_auto_fetch = auto_fetch
|
||||
self.__original_bulletin_sync_interval = sync_interval
|
||||
|
||||
def saveSettings(
|
||||
self
|
||||
):
|
||||
|
||||
self.saveBulletinSettings()
|
||||
self.saveAppearanceSettings()
|
||||
|
||||
def maybeRestart(
|
||||
self
|
||||
@@ -351,6 +365,34 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
return True
|
||||
return False
|
||||
|
||||
@Slot()
|
||||
def onImportCustomThemeButtonClicked(
|
||||
self
|
||||
):
|
||||
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self,
|
||||
"导入主题 - AutoLibrary",
|
||||
"",
|
||||
"主题文件 (*.altheme *.qss);;所有文件 (*)"
|
||||
)
|
||||
if not file_path:
|
||||
return
|
||||
try:
|
||||
file_id = themeInstance().importTheme(file_path)
|
||||
self.populateCustomThemes()
|
||||
idx = self.CustomThemeComboBox.findData(file_id)
|
||||
if idx >= 0:
|
||||
self.CustomThemeComboBox.setCurrentIndex(idx)
|
||||
self.updateCustomThemeStatus()
|
||||
self.updateCustomThemeInfo()
|
||||
except Exception as e:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"导入失败 - AutoLibrary",
|
||||
f"无法导入主题文件:{e}"
|
||||
)
|
||||
|
||||
@Slot()
|
||||
def onRemoveCustomThemeButtonClicked(
|
||||
self
|
||||
@@ -388,34 +430,6 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
f"无法删除主题:{e}"
|
||||
)
|
||||
|
||||
@Slot()
|
||||
def onImportCustomThemeButtonClicked(
|
||||
self
|
||||
):
|
||||
|
||||
file_path, _ = QFileDialog.getOpenFileName(
|
||||
self,
|
||||
"导入主题 - AutoLibrary",
|
||||
"",
|
||||
"主题文件 (*.altheme *.qss);;所有文件 (*)"
|
||||
)
|
||||
if not file_path:
|
||||
return
|
||||
try:
|
||||
file_id = themeInstance().importTheme(file_path)
|
||||
self.populateCustomThemes()
|
||||
idx = self.CustomThemeComboBox.findData(file_id)
|
||||
if idx >= 0:
|
||||
self.CustomThemeComboBox.setCurrentIndex(idx)
|
||||
self.updateCustomThemeStatus()
|
||||
self.updateCustomThemeInfo()
|
||||
except Exception as e:
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
"导入失败 - AutoLibrary",
|
||||
f"无法导入主题文件:{e}"
|
||||
)
|
||||
|
||||
@Slot()
|
||||
def onCustomThemeComboBoxChanged(
|
||||
self,
|
||||
@@ -464,30 +478,29 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
self.BulletinTestStatusLabel.setText("正在测试连接...")
|
||||
self.BulletinTestStatusLabel.setStyleSheet("")
|
||||
self.__bulletin_test_t0 = time.monotonic()
|
||||
from gui.ALBulletinDialog import ALBulletinFetchWorker
|
||||
api_url = url.rstrip("/") + "/bulletins"
|
||||
self.__bulletin_test_worker = ALBulletinFetchWorker(
|
||||
self, api_url, {"date": "", "time": "", "range_hour": "1"}
|
||||
)
|
||||
self.__bulletin_test_worker.fetchWorkerIsFinished.connect(
|
||||
self.__onBulletinTestFetched
|
||||
self.onBulletinTestFetched
|
||||
)
|
||||
self.__bulletin_test_worker.fetchWorkerFinishedWithError.connect(
|
||||
self.__onBulletinTestError
|
||||
self.onBulletinTestError
|
||||
)
|
||||
self.__bulletin_test_worker.start()
|
||||
|
||||
@Slot(dict)
|
||||
def __onBulletinTestFetched(
|
||||
def onBulletinTestFetched(
|
||||
self,
|
||||
data: dict
|
||||
):
|
||||
|
||||
self.__bulletin_test_worker.fetchWorkerIsFinished.disconnect(
|
||||
self.__onBulletinTestFetched
|
||||
self.onBulletinTestFetched
|
||||
)
|
||||
self.__bulletin_test_worker.fetchWorkerFinishedWithError.disconnect(
|
||||
self.__onBulletinTestError
|
||||
self.onBulletinTestError
|
||||
)
|
||||
self.__bulletin_test_worker.deleteLater()
|
||||
self.__bulletin_test_worker = None
|
||||
@@ -500,16 +513,16 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
QTimer.singleShot(3000, self, self.clearBulletinTestStatus)
|
||||
|
||||
@Slot(str)
|
||||
def __onBulletinTestError(
|
||||
def onBulletinTestError(
|
||||
self,
|
||||
error_message: str
|
||||
):
|
||||
|
||||
self.__bulletin_test_worker.fetchWorkerIsFinished.disconnect(
|
||||
self.__onBulletinTestFetched
|
||||
self.onBulletinTestFetched
|
||||
)
|
||||
self.__bulletin_test_worker.fetchWorkerFinishedWithError.disconnect(
|
||||
self.__onBulletinTestError
|
||||
self.onBulletinTestError
|
||||
)
|
||||
self.__bulletin_test_worker.deleteLater()
|
||||
self.__bulletin_test_worker = None
|
||||
@@ -529,9 +542,9 @@ class ALSettingsWidget(CenterOnParentMixin, QWidget, Ui_ALSettingsWidget):
|
||||
self
|
||||
):
|
||||
|
||||
_, style, _ = self.collectSettings()
|
||||
_, style, _ = self.collectAppearanceSettings()
|
||||
style_changed = self.__original_style != style
|
||||
self.saveAndApply()
|
||||
self.saveSettings()
|
||||
if style_changed:
|
||||
self.maybeRestart()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user