1
0
forked from IPKM/nmreval

issue126-backup (#198)

reworked autosave, closes #126; update with restart
This commit is contained in:
2024-01-03 12:30:04 +00:00
parent 58e86f4abc
commit 73bdc71a83
7 changed files with 568 additions and 306 deletions

View File

@ -1,8 +1,8 @@
from __future__ import annotations
import datetime
import os
import re
import time
from pathlib import Path
from numpy import geomspace, linspace
@ -33,7 +33,7 @@ from ..math.smooth import QSmooth
from ..nmr.coupling_calc import QCoupCalcDialog
from ..nmr.t1_from_tau import QRelaxCalc
from .._py.basewindow import Ui_BaseWindow
from ..lib.utils import UpdateDialog, Updater
from ..lib.update import UpdateDialog
class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
@ -42,7 +42,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
save_ses_sig = QtCore.pyqtSignal(str)
rest_ses_sig = QtCore.pyqtSignal(str)
def __init__(self, parents=None, path=None):
def __init__(self, parents=None, path=None, bck_file=None):
super().__init__(parent=parents)
if path is None:
@ -75,21 +75,16 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self._init_gui()
self._init_signals()
if os.getenv('APPIMAGE') is not None:
if Updater.get_update_information(os.getenv('APPIMAGE'))[0]:
self.look_for_update()
self.check_for_backup()
self.__timer = QtCore.QTimer()
self.__backup_path = config_paths() / f'{datetime.datetime.now().strftime("%Y-%m-%d_%H%M%S")}.nmr'
self.__timer.start(3*60*1000) # every three minutes
self.__timer.timeout.connect(self._autosave)
self.fit_timer = QtCore.QTimer()
self.fit_timer.setInterval(500)
self.fit_timer.timeout.connect(
lambda: self.status.setText(f'Fit running... ({self.management.fitter.step} evaluations)'))
lambda: self.status.setText(f'Fit running... ({self.management.fitter.step} evaluations)')
)
self.__backup_path = pathlib.Path(bck_file)
if os.getenv('APPIMAGE'):
# ignore AppImages if not running from AppImage
self.look_for_update()
def _init_gui(self):
self.setupUi(self)
@ -108,8 +103,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.fitlim_button.setIcon(get_icon('fit_region'))
self.toolBar_fit.addWidget(self.fitlim_button)
# self.area.dragEnterEvent = self.dragEnterEvent
while self.tabWidget.count() > 2:
self.tabWidget.removeTab(self.tabWidget.count()-1)
@ -130,12 +123,15 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.fitregion = RegionItem()
self._fit_plot_id = None
self.setGeometry(QtWidgets.QStyle.alignedRect(QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter,
self.size(), QtWidgets.qApp.desktop().availableGeometry()))
self.setGeometry(QtWidgets.QStyle.alignedRect(
QtCore.Qt.LayoutDirection.LeftToRight,
QtCore.Qt.AlignmentFlag.AlignCenter,
self.size(),
QtWidgets.qApp.desktop().availableGeometry()),
)
self.datawidget.management = self.management
self.integralwidget.management = self.management
# self.drawingswidget.graphs = self.management.graphs
self.ac_group = QtWidgets.QActionGroup(self)
self.ac_group.addAction(self.action_lm_fit)
@ -161,6 +157,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.menuData.insertAction(self.actionRedo, self.actionUndo)
self.action_save_fit_parameter.triggered.connect(self.save_fit_parameter)
# noinspection PyUnresolvedReferences
self.ac_group2.triggered.connect(self.change_fit_limits)
self.t1action.triggered.connect(lambda: self._show_tab('t1_temp'))
@ -235,8 +232,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.actionNext_window.triggered.connect(lambda: self.area.activateNextSubWindow())
self.actionPrevious.triggered.connect(lambda: self.area.activatePreviousSubWindow())
self.closeSignal.connect(self.close)
self.action_norm_max.triggered.connect(lambda: self.management.apply('norm', ('max',)))
self.action_norm_max_abs.triggered.connect(lambda: self.management.apply('norm', ('maxabs',)))
self.action_norm_first.triggered.connect(lambda: self.management.apply('norm', ('first',)))
@ -864,10 +859,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
def item_from_graph(self, item, graph_id):
self.management.graphs[graph_id].remove_external(item)
def closeEvent(self, evt):
# self._write_settings()
self.close()
@QtCore.pyqtSlot(int)
def request_data(self, idx):
idd = self.datawidget.get_indexes(idx=idx-1)
@ -995,7 +986,7 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
self.editor = QUsermodelEditor(config_paths() / 'usermodels.py', parent=self)
self.editor.modelsChanged.connect(lambda: self.fit_dialog.read_and_load_functions())
self.editor.setWindowModality(QtCore.Qt.ApplicationModal)
self.editor.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
self.editor.show()
@QtCore.pyqtSlot(list)
@ -1029,9 +1020,10 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
@staticmethod
@QtCore.pyqtSlot(name='on_actionDocumentation_triggered')
def open_doc():
docpath = '/autohome/dominik/auswerteprogramm3/doc/_build/html/index.html'
import webbrowser
webbrowser.open(docpath)
pass
# docpath = '/autohome/dominik/auswerteprogramm3/doc/_build/html/index.html'
# import webbrowser
# webbrowser.open(docpath)
def dropEvent(self, evt):
if evt.mimeData().hasUrls():
@ -1060,13 +1052,13 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
if self.sender() == self.actionLife:
from ..lib.gol import QGameOfLife
game = QGameOfLife(parent=self)
game.setWindowModality(QtCore.Qt.NonModal)
game.setWindowModality(QtCore.Qt.WindowModality.NonModal)
game.show()
elif self.sender() == self.actionMine:
from ..lib.stuff import QMines
game = QMines(parent=self)
game.setWindowModality(QtCore.Qt.NonModal)
game.setWindowModality(QtCore.Qt.WindowModality.NonModal)
game.show()
else:
@ -1094,9 +1086,6 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
def close(self):
write_state({'History': {'recent path': str(self.path)}})
# remove backup file when closing
self.__backup_path.unlink(missing_ok=True)
super().close()
def read_state(self):
@ -1120,40 +1109,16 @@ class NMRMainWindow(QtWidgets.QMainWindow, Ui_BaseWindow):
QLog(parent=self).show()
def _autosave(self):
# TODO better separate thread may it takes some time to save
def autosave(self) -> bool:
self.status.setText('Autosave...')
success = NMRWriter(self.management.graphs, self.management.data).export(self.__backup_path.with_suffix('.nmr.0'))
if success:
self.__backup_path.with_suffix('.nmr.0').rename(self.__backup_path)
self.status.setText('')
def check_for_backup(self):
backups = []
for filename in config_paths().glob('*.nmr'):
try:
backups.append((filename, datetime.datetime.strptime(filename.stem, "%Y-%m-%d_%H%M%S")))
except ValueError:
continue
if backups:
backup_by_date = sorted(backups, key=lambda x: x[1])
msg = QtWidgets.QMessageBox.information(
self, 'Backup found',
f'{len(backups)} backup files in directory {backup_by_date[-1][0].parent} found.\n\n'
f'Latest backup date: {backup_by_date[-1][1]}\n\n'
f'Press Ok to load, Cancel to delete backup, Close to do nothing.',
QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.Close
)
if msg == QtWidgets.QMessageBox.Ok:
self.management.load_files([str(backup_by_date[-1][0])])
backup_by_date[-1][0].unlink()
elif msg == QtWidgets.QMessageBox.Cancel:
backup_by_date[-1][0].unlink()
else:
pass
return success
@QtCore.pyqtSlot(name='on_actionCreate_starter_triggered')
def create_starter(self):