mirror of
https://github.com/RedDeadDepresso/KKAFIO.git
synced 2025-12-22 01:10:01 +00:00
feat: thread manager
This commit is contained in:
@@ -19,12 +19,23 @@ class Logger:
|
||||
# logger box signal is used to output log to logger box
|
||||
self.logs = ""
|
||||
self.logger_signal = signalBus.loggerSignal
|
||||
self.logger = logging.getLogger("BAAS_Logger")
|
||||
formatter = logging.Formatter("%(levelname)8s |%(asctime)20s | %(message)s ")
|
||||
self.logger = logging.getLogger("KAFFIO_Logger")
|
||||
formatter = logging.Formatter("%(levelname)8s |%(category)s | %(message)s ")
|
||||
handler1 = logging.StreamHandler(stream=sys.stdout)
|
||||
handler1.setFormatter(formatter)
|
||||
self.logger.setLevel(logging.INFO)
|
||||
self.logger.addHandler(handler1)
|
||||
self.text = ['INFO', 'SUCCESS', 'ERROR', 'SKIPPED', 'REPLACED', 'RENAMED', 'REMOVED']
|
||||
# Status Text: INFO, SUCCESS, ERROR, SKIPPED, REPLACED, RENAMED, REMOVED
|
||||
self.status = [' INFO', ' SUCCESS', ' ERROR',
|
||||
' SKIPPED', ' REPLACED', ' RENAMED', ' REMOVED']
|
||||
# Status Color: Blue, Red, Green, Orange,
|
||||
self.statusColor = ['#2d8cf0', '#ed3f14', '#f90', '#f90', '#f90', '#f90', '#00c12b']
|
||||
|
||||
# Status HTML: <b style="color:$color">status</b>
|
||||
self.statusHtml = [
|
||||
f'<b style="color:{_color};">{status}</b>'
|
||||
for _color, status in zip(self.statusColor, self.status)]
|
||||
|
||||
def __out__(self, category: str, message: str, level: int = 1, raw_print=False) -> None:
|
||||
"""
|
||||
@@ -41,30 +52,34 @@ class Logger:
|
||||
|
||||
while len(logging.root.handlers) > 0:
|
||||
logging.root.handlers.pop()
|
||||
# Status Text: INFO, SUCCESS, ERROR, SKIPPED, REPLACED, RENAMED, REMOVED
|
||||
status = [' INFO', ' SUCCESS', ' ERROR',
|
||||
' SKIPPED', ' REPLACED', ' RENAMED', ' REMOVED']
|
||||
|
||||
# Status Color: Blue, Red, Green, Orange,
|
||||
statusColor = ['#2d8cf0', '#ed3f14', '#f90', '#f90', '#f90', '#f90', '#00c12b']
|
||||
|
||||
# Status HTML: <b style="color:$color">status</b>
|
||||
statusHtml = [
|
||||
f'<b style="color:{_color};">{status}</b>'
|
||||
for _color, status in zip(statusColor, status)]
|
||||
# If logger box is not None, output log to logger box
|
||||
# else output log to console
|
||||
if self.logger_signal is not None:
|
||||
if self.logger_signal is not None:
|
||||
message = message.replace('\n', '<br>').replace(' ', ' ')
|
||||
adding = (f'''
|
||||
<div style="font-family: Consolas, monospace;color:{statusColor[level - 1]};">
|
||||
{statusHtml[level - 1]} | {category} | {message}
|
||||
<div style="font-family: Consolas, monospace;color:{self.statusColor[level - 1]};">
|
||||
{self.statusHtml[level - 1]} | {category} | {message}
|
||||
</div>
|
||||
''')
|
||||
self.logs += adding
|
||||
self.logger_signal.emit(adding)
|
||||
else:
|
||||
print(f'{statusHtml[level - 1]} | {datetime.now().strftime("%Y-%m-%d %H:%M:%S")} | {message}')
|
||||
print(f'{self.statusHtml[level - 1]} | {category} | {message}')
|
||||
|
||||
def colorize(self, line):
|
||||
adding = line
|
||||
for i, s in enumerate(self.text):
|
||||
if s in line:
|
||||
adding = (f'''
|
||||
<div style="font-family: Consolas, monospace;color:{self.statusColor[i]};">
|
||||
{line}
|
||||
</div>
|
||||
|
||||
''')
|
||||
break
|
||||
self.logs += adding
|
||||
self.logger_signal.emit(adding)
|
||||
|
||||
def info(self, category: str, message: str) -> None:
|
||||
"""
|
||||
@@ -120,7 +135,7 @@ class Logger:
|
||||
|
||||
Output warn log
|
||||
"""
|
||||
self.__out__(category, message, 6)
|
||||
self.__out__(category, message, 7)
|
||||
|
||||
def line(self) -> None:
|
||||
"""
|
||||
|
||||
41
app/common/thread_manager.py
Normal file
41
app/common/thread_manager.py
Normal file
@@ -0,0 +1,41 @@
|
||||
import os
|
||||
import subprocess
|
||||
import threading
|
||||
|
||||
from app.common.signal_bus import signalBus
|
||||
from app.common.logger import logger
|
||||
|
||||
|
||||
class ThreadManager:
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._script = None
|
||||
|
||||
def start(self):
|
||||
if self._script is not None:
|
||||
self.stop()
|
||||
else:
|
||||
args = []
|
||||
if os.path.exists("script.exe"):
|
||||
args = ["script.exe"]
|
||||
elif os.path.exists("script.py"):
|
||||
args = ["python", "script.py"]
|
||||
self._script = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
threading.Thread(target=self.readOutput).start()
|
||||
|
||||
def readOutput(self):
|
||||
while self._script is not None:
|
||||
line = self._script.stdout.readline().decode('utf-8')
|
||||
if not line:
|
||||
signalBus.stopSignal.emit()
|
||||
else:
|
||||
logger.colorize(line)
|
||||
|
||||
def stop(self):
|
||||
self._script.terminate()
|
||||
self._script = None
|
||||
|
||||
|
||||
threadManager = ThreadManager()
|
||||
signalBus.startSignal.connect(threadManager.start)
|
||||
signalBus.stopSignal.connect(threadManager.stop)
|
||||
@@ -37,6 +37,7 @@ class NavigationActionButtons(QWidget):
|
||||
def __connectSignalToSlot(self):
|
||||
self.selectAllButton.clicked.connect(self.onSelectAllClicked)
|
||||
self.clearAllButton.clicked.connect(self.onClearAllClicked)
|
||||
self.startButton.clicked.connect(self.onStartClicked)
|
||||
|
||||
signalBus.startSignal.connect(lambda: self.startButton.setText("Stop"))
|
||||
signalBus.stopSignal.connect(lambda: self.startButton.setText("Start"))
|
||||
|
||||
@@ -4,7 +4,8 @@ class Handler:
|
||||
|
||||
def loadConfig(self, config):
|
||||
self.gamePath = config.get("Core", "GamePath")
|
||||
self.config = config.get(str(self))
|
||||
key = str(self).replace(" ", "")
|
||||
self.config = config.get(key)
|
||||
|
||||
def handle(self, request):
|
||||
pass
|
||||
|
||||
@@ -19,6 +19,9 @@ class Request:
|
||||
logger.info("SCRIPT", "Validating config")
|
||||
self.validateGamepath()
|
||||
self._handlers = [x for x in self.handlers if self.isTaskEnabled(x)]
|
||||
|
||||
if not self._handlers:
|
||||
logger.error("SCRIPT", "No task enabled")
|
||||
if not self._isValid:
|
||||
raise Exception()
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ class LoggerInterface(QFrame):
|
||||
self.autoscrollButton = PushButton('Autoscroll Off')
|
||||
self.loggerBox = TextEdit()
|
||||
self.loggerBox.setReadOnly(True)
|
||||
signalBus.guiMode = True
|
||||
|
||||
self.__initWidget()
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ from .logger_interface import LoggerInterface
|
||||
from .setting_interface import SettingInterface
|
||||
from ..common.config import ZH_SUPPORT_URL, EN_SUPPORT_URL, cfg
|
||||
from ..common.signal_bus import signalBus
|
||||
from ..common.thread_manager import threadManager
|
||||
from ..common import resource
|
||||
from ..components.navigation_checkbox import NavigationCheckBox
|
||||
from ..components.navigation_action_buttons import NavigationActionButtons
|
||||
|
||||
67
script.py
67
script.py
@@ -1,66 +1,5 @@
|
||||
import sys
|
||||
import traceback
|
||||
try:
|
||||
with open('traceback.log', 'w') as f:
|
||||
pass
|
||||
from app.modules.request import Request
|
||||
|
||||
from app.common.logger import logger
|
||||
from app.modules.install_chara import InstallChara
|
||||
from app.modules.remove_chara import RemoveChara
|
||||
from app.modules.fc_kks import FilterConvertKKS
|
||||
from app.modules.create_backup import CreateBackup
|
||||
|
||||
|
||||
class Script:
|
||||
def __init__(self, config, file_manager):
|
||||
"""Initializes the primary azurlane-auto instance with the passed in
|
||||
Config instance;
|
||||
|
||||
Args:
|
||||
config (Config): BAAuto Config instance
|
||||
"""
|
||||
self.config = config
|
||||
fileManager = file_manager
|
||||
self.modules = {
|
||||
'InstallChara': None,
|
||||
'RemoveChara': None,
|
||||
'CreateBackup': None,
|
||||
'FCKKS': None,
|
||||
}
|
||||
if self.config.install_chara['Enable']:
|
||||
self.modules['InstallChara'] = InstallChara(self.config, fileManager)
|
||||
if self.config.remove_chara['Enable']:
|
||||
self.modules['RemoveChara'] = RemoveChara(self.config, fileManager)
|
||||
if self.config.create_backup['Enable']:
|
||||
self.modules['CreateBackup'] = CreateBackup(self.config, fileManager)
|
||||
if self.config.fc_kks["Enable"]:
|
||||
self.modules['FCKKS'] = FilterConvertKKS(self.config, fileManager)
|
||||
|
||||
def run(self):
|
||||
for task in self.config.tasks:
|
||||
if self.modules[task]:
|
||||
logger.info("SCRIPT", f'Start Task: {task}')
|
||||
try:
|
||||
self.modules[task].logic_wrapper()
|
||||
except:
|
||||
logger.error("SCRIPT", f'Task error: {task}. For more info, check the traceback.log file.')
|
||||
with open('traceback.log', 'a') as f:
|
||||
f.write(f'[{task}]\n')
|
||||
traceback.print_exc(None, f, True)
|
||||
f.write('\n')
|
||||
sys.exit(1)
|
||||
sys.exit(0)
|
||||
|
||||
except:
|
||||
print(f'[ERROR] Script Initialisation Error. For more info, check the traceback.log file.')
|
||||
with open('traceback.log', 'w') as f:
|
||||
f.write(f'Script Initialisation Error\n')
|
||||
traceback.print_exc(None, f, True)
|
||||
f.write('\n')
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
config = Config('config.json')
|
||||
file_manager = FileManager(config)
|
||||
script = Script(config, file_manager)
|
||||
script.run()
|
||||
request = Request()
|
||||
request.process()
|
||||
Reference in New Issue
Block a user