Loading modules/translators/trans_sakura.py +10 −15 Original line number Diff line number Diff line # stealt & modified from https://github.com/zyddnys/manga-image-translator/blob/main/manga_translator/translators/chatgpt.py from http import client from pydoc import cli import re import time from token import OP from typing import List, Dict, Union import yaml import asyncio import traceback import time import openai from .base import BaseTranslator, register_translator from utils.error_handling import create_error_dialog OPENAPI_V1_API = int(openai.__version__.split('.')[0]) >= 1 Loading Loading @@ -235,20 +234,18 @@ class SakuraTranslator(BaseTranslator): try: response = self._request_translation(prompt) break except openai.APIError: except openai.APIError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server error. Attempt: {server_error_attempt}') time.sleep(1) except openai.APIConnectionError: except openai.APIConnectionError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server connection error.Current API baseurl is "{self.api_base}" Attempt: {server_error_attempt}') Loading @@ -264,20 +261,18 @@ class SakuraTranslator(BaseTranslator): try: response = self._request_translation(prompt) break except openai.error.APIError: except openai.error.APIError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server error. Attempt: {server_error_attempt}') time.sleep(1) except openai.error.APIConnectionError: except openai.error.APIConnectionError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server connection error.Current API baseurl is "{self.api_base}" Attempt: {server_error_attempt}') Loading ui/drawingpanel.py +1 −1 Original line number Diff line number Diff line Loading @@ -380,7 +380,7 @@ class DrawingPanel(Widget): def initDLModule(self, module_manager: ModuleManager): self.module_manager = module_manager module_manager.canvas_inpaint_finished.connect(self.on_inpaint_finished) module_manager.inpaint_thread.exception_occurred.connect(self.on_inpaint_failed) module_manager.inpaint_thread.inpaint_failed.connect(self.on_inpaint_failed) def setInpaintToolWidth(self, width): self.inpaint_pen.setWidthF(width) Loading ui/global_search_widget.py +3 −3 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ class SearchResultTree(QTreeView): class GlobalReplaceThead(ThreadBase): finished = Signal() _thread_error_msg = 'Failed to perform replacement' _thread_exception_type = 'GlobalReplaceThead' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) Loading Loading @@ -275,8 +276,7 @@ class GlobalReplaceThead(ThreadBase): def on_finished(self): self.progress_bar.hide() def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''): super().handleRunTimeException(msg, detail, verbose) def on_exec_failed(self): self.progress_bar.hide() Loading ui/io_thread.py +21 −14 Original line number Diff line number Diff line Loading @@ -8,36 +8,38 @@ from qtpy.QtWidgets import QDialog, QMessageBox, QFileDialog from utils.logger import logger as LOGGER from utils.io_utils import imread, imwrite from utils.error_handling import create_error_dialog from .config_proj import ProjImgTrans from .stylewidgets import ProgressMessageBox class ThreadBase(QThread): exception_occured = Signal(str, str, str) _thread_exception_type = None _thread_error_msg = 'Thread job failed.' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.job = None self.exception_occured.connect(self.handleRunTimeException) def on_exec_failed(self): return def run(self): if self.job is not None: try: self.job() except Exception as e: self.exception_occured.emit(self.tr('Execution error'), str(e), traceback.format_exc()) self.on_exec_failed() create_error_dialog(e, self._thread_error_msg, self._thread_exception_type) self.job = None def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''): if detail is not None: msg += ': ' + detail LOGGER.error(msg + '\n' + verbose) err = QMessageBox() err.setText(msg) err.setDetailedText(verbose) err.exec() class ImgSaveThread(ThreadBase): img_writed = Signal(str) _thread_exception_type = 'ImgSaveThread' _thread_error_msg = 'Failed to save image.' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.im_save_list = [] Loading Loading @@ -68,6 +70,8 @@ class ImgTransProjFileIOThread(ThreadBase): fin_page = Signal() fin_io = Signal() _thread_exception_type = 'ImgTransProjFileIOThread' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.proj: ProjImgTrans = None Loading @@ -83,13 +87,14 @@ class ImgTransProjFileIOThread(ThreadBase): if self.fin_counter == self.num_pages: self.progress_bar.hide() def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''): super().handleRunTimeException(msg, detail, verbose) def on_exec_failed(self): self.progress_bar.hide() class ExportDocThread(ImgTransProjFileIOThread): _thread_error_msg = 'Failed to export Doc' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.progress_bar.setTaskName(self.tr('Export as doc...')) Loading Loading @@ -124,6 +129,8 @@ class ExportDocThread(ImgTransProjFileIOThread): class ImportDocThread(ImgTransProjFileIOThread): _thread_error_msg = 'Failed to import Doc' def __init__(self, parent, *args, **kwargs): super().__init__(parent, *args, **kwargs) self.progress_bar.setTaskName(self.tr('Import doc...')) Loading ui/mainwindow.py +25 −10 Original line number Diff line number Diff line Loading @@ -4,7 +4,6 @@ from typing import List, Union from pathlib import Path import subprocess from functools import partial import time from qtpy.QtWidgets import QFileDialog, QMenu, QHBoxLayout, QVBoxLayout, QApplication, QStackedWidget, QSplitter, QListWidget, QShortcut, QListWidgetItem, QMessageBox, QTextEdit, QPlainTextEdit from qtpy.QtCore import Qt, QPoint, QSize, QEvent, Signal Loading @@ -14,6 +13,7 @@ from utils.logger import logger as LOGGER from utils.text_processing import is_cjk, full_len, half_len from utils.textblock import TextBlock from utils import shared from utils.error_handling import create_error_dialog from modules.translators.trans_chatgpt import GPTTranslator from .misc import parse_stylesheet, set_html_family from utils.config import ProgramConfig, pcfg, save_config, text_styles, save_text_styles, load_textstyle_from Loading Loading @@ -65,11 +65,14 @@ class MainWindow(mainwindow_cls): translator = None restart_signal = Signal() create_errdialog = Signal(str, str, str) def __init__(self, app: QApplication, config: ProgramConfig, open_dir='', **exec_args) -> None: super().__init__() shared.create_errdialog_in_mainthread = self.create_errdialog.emit self.create_errdialog.connect(self.on_create_errdialog) self.app = app self.setupThread() self.setupUi() Loading Loading @@ -346,9 +349,7 @@ class MainWindow(mainwindow_cls): self.opening_dir = False except Exception as e: self.opening_dir = False LOGGER.exception(e) LOGGER.warning("Failed to load project from " + directory) self.module_manager.handleRunTimeException(self.tr('Failed to load project ') + directory, '') create_error_dialog(e, self.tr('Failed to load project ') + directory) return def dropOpenDir(self, directory: str): Loading @@ -367,9 +368,7 @@ class MainWindow(mainwindow_cls): self.opening_dir = False except Exception as e: self.opening_dir = False LOGGER.exception(e) LOGGER.warning("Failed to load project from " + json_path) self.module_manager.handleRunTimeException(self.tr('Failed to load project ') + json_path, '') create_error_dialog(e, self.tr('Failed to load project from') + json_path) def updatePageList(self): if self.pageList.count() != 0: Loading Loading @@ -1041,7 +1040,7 @@ class MainWindow(mainwindow_cls): save_config() self.textPanel.formatpanel.textstyle_panel.style_area.setStyles(text_styles) except Exception as e: self.module_manager.handleRunTimeException(self.tr(f'Failed to load from {p}'), str(e)) create_error_dialog(e, self.tr(f'Failed to load from {p}')) def export_tstyles(self): ddir = osp.dirname(pcfg.text_styles_path) Loading @@ -1062,7 +1061,7 @@ class MainWindow(mainwindow_cls): save_text_styles(raise_exception=True) save_config() except Exception as e: self.module_manager.handleRunTimeException(self.tr(f'Failed save to {savep}'), str(e)) create_error_dialog(e, self.tr(f'Failed save to {savep}')) pcfg.text_styles_path = oldp def fold_textarea(self, fold: bool): Loading Loading @@ -1223,3 +1222,19 @@ class MainWindow(mainwindow_cls): if pcfg.module.enable_inpaint: shared.pbar['inpaint'] = tqdm(range(npages), desc="Inpaint") self.run_imgtrans() def on_create_errdialog(self, error_msg: str, detail_traceback: str = '', exception_type: str = ''): try: if exception_type != '': shared.showed_exception.add(exception_type) err = QMessageBox() err.setText(error_msg) err.setDetailedText(detail_traceback) err.exec() if exception_type != '': shared.showed_exception.remove(exception_type) except: if exception_type in shared.showed_exception: shared.showed_exception.remove(exception_type) LOGGER.error('Failed to create error dialog') LOGGER.error(traceback.format_exc()) No newline at end of file Loading
modules/translators/trans_sakura.py +10 −15 Original line number Diff line number Diff line # stealt & modified from https://github.com/zyddnys/manga-image-translator/blob/main/manga_translator/translators/chatgpt.py from http import client from pydoc import cli import re import time from token import OP from typing import List, Dict, Union import yaml import asyncio import traceback import time import openai from .base import BaseTranslator, register_translator from utils.error_handling import create_error_dialog OPENAPI_V1_API = int(openai.__version__.split('.')[0]) >= 1 Loading Loading @@ -235,20 +234,18 @@ class SakuraTranslator(BaseTranslator): try: response = self._request_translation(prompt) break except openai.APIError: except openai.APIError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server error. Attempt: {server_error_attempt}') time.sleep(1) except openai.APIConnectionError: except openai.APIConnectionError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server connection error.Current API baseurl is "{self.api_base}" Attempt: {server_error_attempt}') Loading @@ -264,20 +261,18 @@ class SakuraTranslator(BaseTranslator): try: response = self._request_translation(prompt) break except openai.error.APIError: except openai.error.APIError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server error. Attempt: {server_error_attempt}') time.sleep(1) except openai.error.APIConnectionError: except openai.error.APIConnectionError as e: server_error_attempt += 1 if server_error_attempt >= self.retry_attempts: self.logger.error( 'Sakura server error. Returning original text.') create_error_dialog(e, 'Sakura translation failed. Return original text.', exception_type='SakuraTranslator') return '\n'.join(prompt) self.logger.warn( f'Restarting request due to a server connection error.Current API baseurl is "{self.api_base}" Attempt: {server_error_attempt}') Loading
ui/drawingpanel.py +1 −1 Original line number Diff line number Diff line Loading @@ -380,7 +380,7 @@ class DrawingPanel(Widget): def initDLModule(self, module_manager: ModuleManager): self.module_manager = module_manager module_manager.canvas_inpaint_finished.connect(self.on_inpaint_finished) module_manager.inpaint_thread.exception_occurred.connect(self.on_inpaint_failed) module_manager.inpaint_thread.inpaint_failed.connect(self.on_inpaint_failed) def setInpaintToolWidth(self, width): self.inpaint_pen.setWidthF(width) Loading
ui/global_search_widget.py +3 −3 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ class SearchResultTree(QTreeView): class GlobalReplaceThead(ThreadBase): finished = Signal() _thread_error_msg = 'Failed to perform replacement' _thread_exception_type = 'GlobalReplaceThead' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) Loading Loading @@ -275,8 +276,7 @@ class GlobalReplaceThead(ThreadBase): def on_finished(self): self.progress_bar.hide() def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''): super().handleRunTimeException(msg, detail, verbose) def on_exec_failed(self): self.progress_bar.hide() Loading
ui/io_thread.py +21 −14 Original line number Diff line number Diff line Loading @@ -8,36 +8,38 @@ from qtpy.QtWidgets import QDialog, QMessageBox, QFileDialog from utils.logger import logger as LOGGER from utils.io_utils import imread, imwrite from utils.error_handling import create_error_dialog from .config_proj import ProjImgTrans from .stylewidgets import ProgressMessageBox class ThreadBase(QThread): exception_occured = Signal(str, str, str) _thread_exception_type = None _thread_error_msg = 'Thread job failed.' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.job = None self.exception_occured.connect(self.handleRunTimeException) def on_exec_failed(self): return def run(self): if self.job is not None: try: self.job() except Exception as e: self.exception_occured.emit(self.tr('Execution error'), str(e), traceback.format_exc()) self.on_exec_failed() create_error_dialog(e, self._thread_error_msg, self._thread_exception_type) self.job = None def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''): if detail is not None: msg += ': ' + detail LOGGER.error(msg + '\n' + verbose) err = QMessageBox() err.setText(msg) err.setDetailedText(verbose) err.exec() class ImgSaveThread(ThreadBase): img_writed = Signal(str) _thread_exception_type = 'ImgSaveThread' _thread_error_msg = 'Failed to save image.' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.im_save_list = [] Loading Loading @@ -68,6 +70,8 @@ class ImgTransProjFileIOThread(ThreadBase): fin_page = Signal() fin_io = Signal() _thread_exception_type = 'ImgTransProjFileIOThread' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.proj: ProjImgTrans = None Loading @@ -83,13 +87,14 @@ class ImgTransProjFileIOThread(ThreadBase): if self.fin_counter == self.num_pages: self.progress_bar.hide() def handleRunTimeException(self, msg: str, detail: str = None, verbose: str = ''): super().handleRunTimeException(msg, detail, verbose) def on_exec_failed(self): self.progress_bar.hide() class ExportDocThread(ImgTransProjFileIOThread): _thread_error_msg = 'Failed to export Doc' def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.progress_bar.setTaskName(self.tr('Export as doc...')) Loading Loading @@ -124,6 +129,8 @@ class ExportDocThread(ImgTransProjFileIOThread): class ImportDocThread(ImgTransProjFileIOThread): _thread_error_msg = 'Failed to import Doc' def __init__(self, parent, *args, **kwargs): super().__init__(parent, *args, **kwargs) self.progress_bar.setTaskName(self.tr('Import doc...')) Loading
ui/mainwindow.py +25 −10 Original line number Diff line number Diff line Loading @@ -4,7 +4,6 @@ from typing import List, Union from pathlib import Path import subprocess from functools import partial import time from qtpy.QtWidgets import QFileDialog, QMenu, QHBoxLayout, QVBoxLayout, QApplication, QStackedWidget, QSplitter, QListWidget, QShortcut, QListWidgetItem, QMessageBox, QTextEdit, QPlainTextEdit from qtpy.QtCore import Qt, QPoint, QSize, QEvent, Signal Loading @@ -14,6 +13,7 @@ from utils.logger import logger as LOGGER from utils.text_processing import is_cjk, full_len, half_len from utils.textblock import TextBlock from utils import shared from utils.error_handling import create_error_dialog from modules.translators.trans_chatgpt import GPTTranslator from .misc import parse_stylesheet, set_html_family from utils.config import ProgramConfig, pcfg, save_config, text_styles, save_text_styles, load_textstyle_from Loading Loading @@ -65,11 +65,14 @@ class MainWindow(mainwindow_cls): translator = None restart_signal = Signal() create_errdialog = Signal(str, str, str) def __init__(self, app: QApplication, config: ProgramConfig, open_dir='', **exec_args) -> None: super().__init__() shared.create_errdialog_in_mainthread = self.create_errdialog.emit self.create_errdialog.connect(self.on_create_errdialog) self.app = app self.setupThread() self.setupUi() Loading Loading @@ -346,9 +349,7 @@ class MainWindow(mainwindow_cls): self.opening_dir = False except Exception as e: self.opening_dir = False LOGGER.exception(e) LOGGER.warning("Failed to load project from " + directory) self.module_manager.handleRunTimeException(self.tr('Failed to load project ') + directory, '') create_error_dialog(e, self.tr('Failed to load project ') + directory) return def dropOpenDir(self, directory: str): Loading @@ -367,9 +368,7 @@ class MainWindow(mainwindow_cls): self.opening_dir = False except Exception as e: self.opening_dir = False LOGGER.exception(e) LOGGER.warning("Failed to load project from " + json_path) self.module_manager.handleRunTimeException(self.tr('Failed to load project ') + json_path, '') create_error_dialog(e, self.tr('Failed to load project from') + json_path) def updatePageList(self): if self.pageList.count() != 0: Loading Loading @@ -1041,7 +1040,7 @@ class MainWindow(mainwindow_cls): save_config() self.textPanel.formatpanel.textstyle_panel.style_area.setStyles(text_styles) except Exception as e: self.module_manager.handleRunTimeException(self.tr(f'Failed to load from {p}'), str(e)) create_error_dialog(e, self.tr(f'Failed to load from {p}')) def export_tstyles(self): ddir = osp.dirname(pcfg.text_styles_path) Loading @@ -1062,7 +1061,7 @@ class MainWindow(mainwindow_cls): save_text_styles(raise_exception=True) save_config() except Exception as e: self.module_manager.handleRunTimeException(self.tr(f'Failed save to {savep}'), str(e)) create_error_dialog(e, self.tr(f'Failed save to {savep}')) pcfg.text_styles_path = oldp def fold_textarea(self, fold: bool): Loading Loading @@ -1223,3 +1222,19 @@ class MainWindow(mainwindow_cls): if pcfg.module.enable_inpaint: shared.pbar['inpaint'] = tqdm(range(npages), desc="Inpaint") self.run_imgtrans() def on_create_errdialog(self, error_msg: str, detail_traceback: str = '', exception_type: str = ''): try: if exception_type != '': shared.showed_exception.add(exception_type) err = QMessageBox() err.setText(error_msg) err.setDetailedText(detail_traceback) err.exec() if exception_type != '': shared.showed_exception.remove(exception_type) except: if exception_type in shared.showed_exception: shared.showed_exception.remove(exception_type) LOGGER.error('Failed to create error dialog') LOGGER.error(traceback.format_exc()) No newline at end of file