Commit 00e4a6a2 authored by dmMaze's avatar dmMaze
Browse files

prevent writing target config/imgtrans_proj directly to avoid corruption

parent a1115722
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -534,12 +534,16 @@ class MainWindow(mainwindow_cls):
        save_config()

    def closeEvent(self, event: QCloseEvent) -> None:
        if not self.imgtrans_proj.is_empty:
            self.conditional_save(keep_exist_as_backup=True)
        while True:
            if not self.imsave_thread.isRunning():
                break
            time.sleep(0.1)
        self.st_manager.hovering_transwidget = None
        self.st_manager.blockSignals(True)
        self.canvas.prepareClose()
        self.save_config()
        if not self.imgtrans_proj.is_empty:
            self.imgtrans_proj.save()
        return super().closeEvent(event)

    def changeEvent(self, event: QEvent):
@@ -569,14 +573,14 @@ class MainWindow(mainwindow_cls):
        self.canvas.alt_pressed = False
        self.canvas.scale_tool_mode = False

    def conditional_save(self):
    def conditional_save(self, keep_exist_as_backup=False):
        if self.canvas.projstate_unsaved and not self.opening_dir:
            update_scene_text = save_proj = self.canvas.text_change_unsaved()
            save_rst_only = not self.canvas.draw_change_unsaved()
            if not save_rst_only:
                save_proj = True
            
            self.saveCurrentPage(update_scene_text, save_proj, restore_interface=True, save_rst_only=save_rst_only)
            self.saveCurrentPage(update_scene_text, save_proj, restore_interface=True, save_rst_only=save_rst_only, keep_exist_as_backup=keep_exist_as_backup)

    def pageListCurrentItemChanged(self):
        item = self.pageList.currentItem()
@@ -882,7 +886,7 @@ class MainWindow(mainwindow_cls):
            LOGGER.debug('Manually saving...')
            self.saveCurrentPage(update_scene_text=True, save_proj=True, restore_interface=True, save_rst_only=False)

    def saveCurrentPage(self, update_scene_text=True, save_proj=True, restore_interface=False, save_rst_only=False):
    def saveCurrentPage(self, update_scene_text=True, save_proj=True, restore_interface=False, save_rst_only=False, keep_exist_as_backup=False):
        
        if not self.imgtrans_proj.img_valid:
            return
@@ -916,7 +920,7 @@ class MainWindow(mainwindow_cls):

        if save_proj:
            try:
                self.imgtrans_proj.save()
                self.imgtrans_proj.save(keep_exist_as_backup=keep_exist_as_backup)
                if not save_rst_only:
                    mask_path = self.imgtrans_proj.get_mask_path()
                    mask_array = self.imgtrans_proj.mask_array
+16 −9
Original line number Diff line number Diff line
@@ -256,28 +256,35 @@ def json_dump_program_config(obj, **kwargs):
def save_config():
    global pcfg
    try:
        with open(shared.CONFIG_PATH, 'w', encoding='utf8') as f:
        tmp_save_tgt = shared.CONFIG_PATH + '.tmp'
        with open(tmp_save_tgt, 'w', encoding='utf8') as f:
            f.write(json_dump_program_config(pcfg))
        LOGGER.info('Config saved')
        return True
    except Exception as e:
        LOGGER.error(f'Failed save config to {shared.CONFIG_PATH}: {e}')
        LOGGER.error(f'Failed save config to {tmp_save_tgt}: {e}')
        LOGGER.error(traceback.format_exc())
        return False
    
    os.replace(tmp_save_tgt, shared.CONFIG_PATH)
    LOGGER.info('Config saved')
    return True

def save_text_styles(raise_exception = False):
    global pcfg, text_styles
    try:
        style_dir = osp.dirname(pcfg.text_styles_path)
        if not osp.exists(style_dir):
            os.makedirs(style_dir)
        with open(pcfg.text_styles_path, 'w', encoding='utf8') as f:
        tmp_save_tgt = pcfg.text_styles_path + '.tmp'
        with open(tmp_save_tgt, 'w', encoding='utf8') as f:
            f.write(json_dump_nested_obj(text_styles))
        LOGGER.info('Text style saved')
        return True

    except Exception as e:
        LOGGER.error(f'Failed save text style to {pcfg.text_styles_path}: {e}')
        LOGGER.error(f'Failed save text style to {tmp_save_tgt}: {e}')
        LOGGER.error(traceback.format_exc())
        if raise_exception:
            raise e
        return False

    os.replace(tmp_save_tgt, pcfg.text_styles_path)
    LOGGER.info('Text style saved')
    return True
 No newline at end of file
+13 −4
Original line number Diff line number Diff line
@@ -296,11 +296,20 @@ class ProjImgTrans:
        self.set_current_img_byidx(0)
        self.save()
        
    def save(self):
    def save(self, keep_exist_as_backup=False):
        if not osp.exists(self.directory):
            raise ProjectDirNotExistException
        with open(self.proj_path, "w", encoding="utf-8") as f:
        tmp_save_tgt = self.proj_path + '.tmp'
        try:
            with open(tmp_save_tgt, "w", encoding="utf-8") as f:
                f.write(json.dumps(self.to_dict(), ensure_ascii=False, cls=TextBlkEncoder))
        except:
            raise Exception(f'Failed to write {self.to_dict()}')
        if osp.exists(self.proj_path) and keep_exist_as_backup:
            os.replace(self.proj_path, self.proj_path + '.backup')
            os.replace(tmp_save_tgt, self.proj_path)
        else:
            os.replace(tmp_save_tgt, self.proj_path)
        LOGGER.debug(f'project saved to {self.proj_path}')

    def to_dict(self) -> Dict: