forked from IPKM/nmreval
issue126-backup (#198)
reworked autosave, closes #126; update with restart
This commit is contained in:
@ -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):
|
||||
|
Reference in New Issue
Block a user