diff --git a/src/Model/Study.py b/src/Model/Study.py index 6c6141f2f162f0bb2444da8800614a8604a8c200..d0ba7747ef19c7b71e68c73dc7ff2db09e8ceb22 100644 --- a/src/Model/Study.py +++ b/src/Model/Study.py @@ -104,9 +104,13 @@ class Study(SQLModel): logger.error(e) fname = fname + "." + str(self._old_save_id) - filename = os.path.join(fdir, "_PAMHYR_", "__old__", fname) - shutil.copy(self.filename, filename) - self._old_save_id += 1 + if os.path.exists(self.filename) and ".backup" not in self.filename: + filename = os.path.join(fdir, "_PAMHYR_", "__old__", fname) + logger.debug(f"Backup previous version copy: {filename}") + shutil.copy(self.filename, filename) + self._old_save_id += 1 + else: + self._init_db_file(self.filename, is_new=True) # Save self.last_save_date = datetime.now() @@ -128,6 +132,16 @@ class Study(SQLModel): @filename.setter def filename(self, filename): + if filename is None: + self._filename = None + self.status.modified() + return + + if self._filename is not None and self._filename != "": + self._filename = str(filename) + self.status.modified() + return + self._filename = str(filename) self._init_db_file(filename, is_new=True) self.status.modified() diff --git a/src/View/Configure/Window.py b/src/View/Configure/Window.py index 255c6011f0370649936ca3abb7372b019b735eba..4a9788bf11b21d38a03b3a1ae17f55e112c1c520 100644 --- a/src/View/Configure/Window.py +++ b/src/View/Configure/Window.py @@ -123,11 +123,11 @@ class ConfigureWindow(PamhyrDialog): def setup_data(self): # Backup self.set_check_box("checkBox_backup", self._config.backup_enable) - self.set_line_edit_text("lineEdit_backup_path", - self._config.backup_path) + # self.set_line_edit_text("lineEdit_backup_path", + # self._config.backup_path) self.set_time_edit("timeEdit_backup_frequence", self._config.backup_frequence) - self.set_spin_box("spinBox_backup_max", self._config.backup_max) + # self.set_spin_box("spinBox_backup_max", self._config.backup_max) # Editor self.set_line_edit_text("lineEdit_editor_cmd", @@ -155,12 +155,12 @@ class ConfigureWindow(PamhyrDialog): "pushButton_stricklers_del": self.del_stricklers, "pushButton_stricklers_sort": self.sort_stricklers, # Others - "pushButton_backup_path": lambda: self.file_dialog( - select_file=False, - callback=lambda f: self.set_line_edit_text( - "lineEdit_backup_path", f[0] - ) - ), + # "pushButton_backup_path": lambda: self.file_dialog( + # select_file=False, + # callback=lambda f: self.set_line_edit_text( + # "lineEdit_backup_path", f[0] + # ) + # ), } for button in buttons: @@ -172,11 +172,12 @@ class ConfigureWindow(PamhyrDialog): # Backup self._config.backup_enable = self.get_check_box("checkBox_backup") - self._config.backup_path = self.get_line_edit_text( - "lineEdit_backup_path") + # self._config.backup_path = self.get_line_edit_text( + # "lineEdit_backup_path") self._config.backup_frequence = self.get_time_edit( - "timeEdit_backup_frequence") - self._config.backup_max = self.get_spin_box("spinBox_backup_max") + "timeEdit_backup_frequence" + ) + # self._config.backup_max = self.get_spin_box("spinBox_backup_max") # Stricklers self._config.stricklers = deepcopy(self._stricklers) diff --git a/src/View/MainWindow.py b/src/View/MainWindow.py index 3fa718e2c1ee68fa65cb1f6d4faf66e145f50020..bf0a36512ae26e0d712330d58d4ac26819388f8e 100644 --- a/src/View/MainWindow.py +++ b/src/View/MainWindow.py @@ -21,6 +21,9 @@ import sys import logging import subprocess from queue import Queue +from functools import reduce +from platformdirs import user_cache_dir +from tools import logger_exception from PyQt5 import QtGui from PyQt5.QtGui import ( @@ -365,6 +368,10 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): self.set_debug_lvl(debug=False) def setup_timer(self): + self.setup_timer_propagation() + self.setup_timer_backup() + + def setup_timer_propagation(self): self._init_propagation_keys() self._propagation_timer = QTimer(self) @@ -374,6 +381,32 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): self._do_propagate_update ) + def get_config_backup_freq_to_sec(self): + v = self.conf.backup_frequence.split(":") + m = [ + (60 * 60), # Hour to sec + 60, # Minute to sec + 1 # Sec + ] + + ts = reduce( + lambda acc, x: acc + x, + map( + lambda v, m: int(v) * int(m), + v, m + ) + ) + + return ts + + def setup_timer_backup(self): + self._backup_timer = QTimer(self) + + ts = self.get_config_backup_freq_to_sec() + self._backup_timer.start(ts * 1000) + + self._backup_timer.timeout.connect(self._backup) + def _init_propagation_keys(self): self._propagation_keys = Modules(0) @@ -523,11 +556,12 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): progress.setWindowModality(Qt.WindowModal) progress.setValue(0) - logger.info("Save...") + logger.info(f"Save ({self._study.filename})...") self._study.save( progress=lambda: progress.setValue(progress.value() + 1) ) logger.info("Done") + self.conf.set_last_study(self._study.filename) def save_as_study(self): """Save current study as new file @@ -569,11 +603,53 @@ class ApplicationWindow(QMainWindow, ListedSubWindow, WindowToolKit): progress.setWindowModality(Qt.WindowModal) progress.setValue(0) - logger.info("Save...") + logger.info(f"Save ({self._study.filename})...") self._study.save( progress=lambda: progress.setValue(progress.value() + 1) ) logger.info("Done") + self.conf.set_last_study(self._study.filename) + + def _backup(self): + if not self.conf.backup_enable: + return + + if self._study is None: + return + + old = self._study.filename + file_name = "" + if old == "" or old is None: + file_name = os.path.join( + user_cache_dir("pamhyr"), + "unsaved.pamhyr.backup" + ) + # Set backup at last study open + self.conf.set_last_study(file_name) + else: + file_name = self._study.filename + ".backup" + + self._study.filename = file_name + + try: + sql_request_count = self._study.sql_save_request_count() + progress = QProgressDialog( + "Saving...", None, + 0, sql_request_count, + parent=self + ) + progress.setWindowModality(Qt.WindowModal) + progress.setValue(0) + + logger.info(f"Backup ({self._study.filename})...") + self._study.save( + progress=lambda: progress.setValue(progress.value() + 1) + ) + logger.info("Done") + except Exception as e: + logger_exception(e) + + self._study.filename = old ################## # MSG AND DIALOG # diff --git a/src/View/ui/ConfigureDialog.ui b/src/View/ui/ConfigureDialog.ui index 3caaab7f1cbe18093cf1e205ce5bd9945046a5d8..5ff289d08a86c8d1e1a40e726df4dddfcb2e5664 100644 --- a/src/View/ui/ConfigureDialog.ui +++ b/src/View/ui/ConfigureDialog.ui @@ -115,7 +115,7 @@ </widget> <widget class="QWidget" name="tab_backup"> <property name="enabled"> - <bool>false</bool> + <bool>true</bool> </property> <attribute name="title"> <string>Backup</string> @@ -134,13 +134,6 @@ </property> </widget> </item> - <item> - <widget class="QLabel" name="label_8"> - <property name="text"> - <string>Path</string> - </property> - </widget> - </item> <item> <widget class="QLabel" name="label_9"> <property name="text"> @@ -148,13 +141,6 @@ </property> </widget> </item> - <item> - <widget class="QLabel" name="label_10"> - <property name="text"> - <string>Max. archives</string> - </property> - </widget> - </item> </layout> </item> <item> @@ -164,28 +150,16 @@ <property name="text"> <string>Enable</string> </property> + <property name="checked"> + <bool>true</bool> + </property> <property name="tristate"> <bool>false</bool> </property> </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <widget class="QLineEdit" name="lineEdit_backup_path"/> - </item> - <item> - <widget class="QPushButton" name="pushButton_backup_path"> - <property name="text"> - <string/> - </property> - <property name="icon"> - <iconset> - <normaloff>ressources/open.png</normaloff>ressources/open.png</iconset> - </property> - </widget> - </item> - </layout> + <layout class="QHBoxLayout" name="horizontalLayout_3"/> </item> <item> <widget class="QTimeEdit" name="timeEdit_backup_frequence"> @@ -196,6 +170,9 @@ <second>0</second> </time> </property> + <property name="currentSection"> + <enum>QDateTimeEdit::MinuteSection</enum> + </property> <property name="displayFormat"> <string>HH:mm:ss</string> </property> @@ -211,16 +188,6 @@ </property> </widget> </item> - <item> - <widget class="QSpinBox" name="spinBox_backup_max"> - <property name="minimum"> - <number>1</number> - </property> - <property name="value"> - <number>10</number> - </property> - </widget> - </item> </layout> </item> </layout> diff --git a/src/config.py b/src/config.py index f15ae6776118d41a89f51f8102d12a34e4a31173..6c7eccfb7216258f0dfba2fddd8aad672435b440 100644 --- a/src/config.py +++ b/src/config.py @@ -20,6 +20,8 @@ import os import pickle import logging +from platformdirs import user_cache_dir + from SQL import SQL from Model.Stricklers.Stricklers import Stricklers @@ -27,7 +29,7 @@ from Model.Stricklers.StricklersList import StricklersList from Solver.Solvers import solver_type_list -config_dir = "/.cache/pamhyr/" +config_dir = user_cache_dir("pamhyr") config_file = "config.sqlite3" logger = logging.getLogger() @@ -181,12 +183,12 @@ class Config(SQL): # Backup v = self.execute("SELECT value FROM data WHERE key='backup_enable'") self.backup_enable = v[0] == "True" - v = self.execute("SELECT value FROM data WHERE key='backup_path'") - self.backup_path = v[0] + # v = self.execute("SELECT value FROM data WHERE key='backup_path'") + # self.backup_path = v[0] v = self.execute("SELECT value FROM data WHERE key='backup_frequence'") self.backup_frequence = v[0] - v = self.execute("SELECT value FROM data WHERE key='backup_max'") - self.backup_max = int(v[0]) + # v = self.execute("SELECT value FROM data WHERE key='backup_max'") + # self.backup_max = int(v[0]) # Editor v = self.execute("SELECT value FROM data WHERE key='editor'") @@ -250,9 +252,9 @@ class Config(SQL): def _save(self): data = { "backup_enable": self.backup_enable, - "backup_path": self.backup_path, + # "backup_path": self.backup_path, "backup_frequence": self.backup_frequence, - "backup_max": self.backup_max, + # "backup_max": self.backup_max, "editor": self.editor, "lang": self.lang, "last_study": self.last_study, @@ -291,9 +293,9 @@ class Config(SQL): # Backup self.backup_enable = True - self.backup_path = "" + # self.backup_path = "" self.backup_frequence = "00:05:00" - self.backup_max = 10 + # self.backup_max = 10 # Editor self.editor = "editor @file" @@ -350,13 +352,13 @@ class Config(SQL): file = "" if os.name == 'posix': - ndir = os.path.expanduser('~') + config_dir + ndir = config_dir else: - ndir = os.path.expanduser('~') + config_dir + ndir = config_dir ndir = ndir.replace("/", "\\") os.makedirs(ndir, exist_ok=True) - file = ndir + config_file + file = os.path.join(ndir, config_file) return file