Make backup path always set
This commit is contained in:
@@ -121,8 +121,7 @@ def checkUuid(value: Any, default: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
def checkPath(value: Any, default: Path) -> Path:
|
def checkPath(value: Any, default: Path) -> Path:
|
||||||
"""Check if a value is a valid path. Non-empty strings are accepted.
|
"""Check if a value is a valid path."""
|
||||||
"""
|
|
||||||
if isinstance(value, Path):
|
if isinstance(value, Path):
|
||||||
return value
|
return value
|
||||||
elif isinstance(value, str):
|
elif isinstance(value, str):
|
||||||
|
|||||||
+16
-17
@@ -94,8 +94,8 @@ class Config:
|
|||||||
# User Settings
|
# User Settings
|
||||||
# =============
|
# =============
|
||||||
|
|
||||||
self._theme = None
|
self._themeObj = None
|
||||||
self._recent = RecentProjects(self)
|
self._recentObj = RecentProjects(self)
|
||||||
|
|
||||||
# General GUI Settings
|
# General GUI Settings
|
||||||
self.guiLocale = self._qLocale.name()
|
self.guiLocale = self._qLocale.name()
|
||||||
@@ -107,7 +107,6 @@ class Config:
|
|||||||
self.hideVScroll = False # Hide vertical scroll bars on main widgets
|
self.hideVScroll = False # Hide vertical scroll bars on main widgets
|
||||||
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
|
self.hideHScroll = False # Hide horizontal scroll bars on main widgets
|
||||||
self.lastNotes = "0x0" # The latest release notes that have been shown
|
self.lastNotes = "0x0" # The latest release notes that have been shown
|
||||||
self._lastPath = self._homePath # The user's last used path
|
|
||||||
|
|
||||||
# Size Settings
|
# Size Settings
|
||||||
self._mainWinSize = [1200, 650] # Last size of the main GUI window
|
self._mainWinSize = [1200, 650] # Last size of the main GUI window
|
||||||
@@ -121,7 +120,6 @@ class Config:
|
|||||||
self.autoSaveProj = 60 # Interval for auto-saving project, in seconds
|
self.autoSaveProj = 60 # Interval for auto-saving project, in seconds
|
||||||
self.autoSaveDoc = 30 # Interval for auto-saving document, in seconds
|
self.autoSaveDoc = 30 # Interval for auto-saving document, in seconds
|
||||||
self.emphLabels = True # Add emphasis to H1 and H2 item labels
|
self.emphLabels = True # Add emphasis to H1 and H2 item labels
|
||||||
self._backupPath = None # Backup path to use, can be none
|
|
||||||
self.backupOnClose = False # Flag for running automatic backups
|
self.backupOnClose = False # Flag for running automatic backups
|
||||||
self.askBeforeBackup = True # Flag for asking before running automatic backup
|
self.askBeforeBackup = True # Flag for asking before running automatic backup
|
||||||
|
|
||||||
@@ -174,6 +172,10 @@ class Config:
|
|||||||
self.fmtPadAfter = ""
|
self.fmtPadAfter = ""
|
||||||
self.fmtPadThin = False
|
self.fmtPadThin = False
|
||||||
|
|
||||||
|
# User Paths
|
||||||
|
self._lastPath = self._homePath # The user's last used path
|
||||||
|
self._backupPath = self._homePath # Backup path to use, can be none
|
||||||
|
|
||||||
# Spell Checking Settings
|
# Spell Checking Settings
|
||||||
self.spellLanguage = "en"
|
self.spellLanguage = "en"
|
||||||
|
|
||||||
@@ -238,13 +240,13 @@ class Config:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def recentProjects(self):
|
def recentProjects(self):
|
||||||
return self._recent
|
return self._recentObj
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def theme(self) -> GuiTheme:
|
def theme(self) -> GuiTheme:
|
||||||
if self._theme is None:
|
if self._themeObj is None:
|
||||||
raise Exception("Cannot access GUI theme before it is initialised")
|
raise Exception("Cannot access GUI theme before it is initialised")
|
||||||
return self._theme
|
return self._themeObj
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mainWinSize(self):
|
def mainWinSize(self):
|
||||||
@@ -295,7 +297,7 @@ class Config:
|
|||||||
|
|
||||||
def setThemeInstance(self, theme: GuiTheme) -> None:
|
def setThemeInstance(self, theme: GuiTheme) -> None:
|
||||||
"""Set the applications theme instance."""
|
"""Set the applications theme instance."""
|
||||||
self._theme = theme
|
self._themeObj = theme
|
||||||
return
|
return
|
||||||
|
|
||||||
def setMainWinSize(self, newWidth, newHeight):
|
def setMainWinSize(self, newWidth, newHeight):
|
||||||
@@ -351,9 +353,9 @@ class Config:
|
|||||||
logger.debug("Last path updated: %s" % self._lastPath)
|
logger.debug("Last path updated: %s" % self._lastPath)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setBackupPath(self, backupPath: Path | None):
|
def setBackupPath(self, backupPath: Path | str):
|
||||||
"""Set the current backup path."""
|
"""Set the current backup path."""
|
||||||
self._backupPath = checkPath(backupPath, None)
|
self._backupPath = checkPath(backupPath, self._homePath)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setTextFont(self, family: str | None, pointSize: int = 12):
|
def setTextFont(self, family: str | None, pointSize: int = 12):
|
||||||
@@ -411,12 +413,12 @@ class Config:
|
|||||||
return self._lastPath
|
return self._lastPath
|
||||||
return self._homePath
|
return self._homePath
|
||||||
|
|
||||||
def backupPath(self) -> Path | None:
|
def backupPath(self) -> Path:
|
||||||
"""Return the backup path."""
|
"""Return the backup path."""
|
||||||
if isinstance(self._backupPath, Path):
|
if isinstance(self._backupPath, Path):
|
||||||
if self._backupPath.is_dir():
|
if self._backupPath.is_dir():
|
||||||
return self._backupPath
|
return self._backupPath
|
||||||
return None
|
return self._homePath
|
||||||
|
|
||||||
def errorText(self) -> str:
|
def errorText(self) -> str:
|
||||||
"""Compile and return error messages from the initialisation of
|
"""Compile and return error messages from the initialisation of
|
||||||
@@ -495,7 +497,7 @@ class Config:
|
|||||||
else:
|
else:
|
||||||
self.saveConfig()
|
self.saveConfig()
|
||||||
|
|
||||||
self._recent.loadCache()
|
self._recentObj.loadCache()
|
||||||
self._checkOptionalPackages()
|
self._checkOptionalPackages()
|
||||||
|
|
||||||
logger.debug("Config initialisation complete")
|
logger.debug("Config initialisation complete")
|
||||||
@@ -647,9 +649,6 @@ class Config:
|
|||||||
# Check Values
|
# Check Values
|
||||||
# ============
|
# ============
|
||||||
|
|
||||||
# Check Certain Values for None
|
|
||||||
self.spellLanguage = self._checkNone(self.spellLanguage)
|
|
||||||
|
|
||||||
# If we're using straight quotes, disable auto-replace
|
# If we're using straight quotes, disable auto-replace
|
||||||
if self.fmtSQuoteOpen == self.fmtSQuoteClose == "'" and self.doReplaceSQuote:
|
if self.fmtSQuoteOpen == self.fmtSQuoteClose == "'" and self.doReplaceSQuote:
|
||||||
logger.info("Using straight single quotes, so disabling auto-replace")
|
logger.info("Using straight single quotes, so disabling auto-replace")
|
||||||
@@ -697,7 +696,7 @@ class Config:
|
|||||||
"autosaveproject": str(self.autoSaveProj),
|
"autosaveproject": str(self.autoSaveProj),
|
||||||
"autosavedoc": str(self.autoSaveDoc),
|
"autosavedoc": str(self.autoSaveDoc),
|
||||||
"emphlabels": str(self.emphLabels),
|
"emphlabels": str(self.emphLabels),
|
||||||
"backuppath": str(self._backupPath or ""),
|
"backuppath": str(self._backupPath),
|
||||||
"backuponclose": str(self.backupOnClose),
|
"backuponclose": str(self.backupOnClose),
|
||||||
"askbeforebackup": str(self.askBeforeBackup),
|
"askbeforebackup": str(self.askBeforeBackup),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -416,14 +416,6 @@ class NWProject(QObject):
|
|||||||
logger.info("Backing up project")
|
logger.info("Backing up project")
|
||||||
self.mainGui.setStatus(self.tr("Backing up project ..."))
|
self.mainGui.setStatus(self.tr("Backing up project ..."))
|
||||||
|
|
||||||
backupPath = CONFIG.backupPath()
|
|
||||||
if not isinstance(backupPath, Path):
|
|
||||||
self.mainGui.makeAlert(self.tr(
|
|
||||||
"Cannot backup project because no valid backup path is set. "
|
|
||||||
"Please set a valid backup location in Preferences."
|
|
||||||
), level=nwAlert.ERROR)
|
|
||||||
return False
|
|
||||||
|
|
||||||
if not self._data.name:
|
if not self._data.name:
|
||||||
self.mainGui.makeAlert(self.tr(
|
self.mainGui.makeAlert(self.tr(
|
||||||
"Cannot backup project because no project name is set. "
|
"Cannot backup project because no project name is set. "
|
||||||
@@ -432,6 +424,7 @@ class NWProject(QObject):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
cleanName = makeFileNameSafe(self._data.name)
|
cleanName = makeFileNameSafe(self._data.name)
|
||||||
|
backupPath = CONFIG.backupPath()
|
||||||
baseDir = backupPath / cleanName
|
baseDir = backupPath / cleanName
|
||||||
try:
|
try:
|
||||||
baseDir.mkdir(exist_ok=True)
|
baseDir.mkdir(exist_ok=True)
|
||||||
@@ -444,11 +437,12 @@ class NWProject(QObject):
|
|||||||
timeStamp = formatTimeStamp(time(), fileSafe=True)
|
timeStamp = formatTimeStamp(time(), fileSafe=True)
|
||||||
archName = baseDir / f"{cleanName} {timeStamp}.zip"
|
archName = baseDir / f"{cleanName} {timeStamp}.zip"
|
||||||
if self._storage.zipIt(archName, compression=2):
|
if self._storage.zipIt(archName, compression=2):
|
||||||
size = archName.stat().st_size
|
size = formatInt(archName.stat().st_size)
|
||||||
if doNotify:
|
if doNotify:
|
||||||
self.mainGui.makeAlert(self.tr(
|
self.mainGui.makeAlert(
|
||||||
"Backup archive file written to: {0} [{1}B]"
|
self.tr("Created a backup of your project of size {0}B.").format(size),
|
||||||
).format(str(archName), formatInt(size)))
|
info=self.tr("Path: {0}").format(str(backupPath))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.mainGui.makeAlert(self.tr(
|
self.mainGui.makeAlert(self.tr(
|
||||||
"Could not write backup archive."
|
"Could not write backup archive."
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[Meta]
|
[Meta]
|
||||||
timestamp = 2023-08-02 14:53:36
|
timestamp = 2023-08-08 19:01:25
|
||||||
|
|
||||||
[Main]
|
[Main]
|
||||||
theme = default
|
theme = default
|
||||||
@@ -10,7 +10,7 @@ localisation = en_GB
|
|||||||
hidevscroll = False
|
hidevscroll = False
|
||||||
hidehscroll = False
|
hidehscroll = False
|
||||||
lastnotes = 0x0
|
lastnotes = 0x0
|
||||||
lastpath = /home/vkbo
|
lastpath =
|
||||||
|
|
||||||
[Sizes]
|
[Sizes]
|
||||||
mainwindow = 1200, 650
|
mainwindow = 1200, 650
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ def testBaseConfig_InitLoadSave(monkeypatch, fncPath, tstPaths):
|
|||||||
|
|
||||||
# Check that we have a default file
|
# Check that we have a default file
|
||||||
copyfile(confFile, testFile)
|
copyfile(confFile, testFile)
|
||||||
ignore = ("timestamp", "lastnotes", "localisation", "lastpath")
|
ignore = ("timestamp", "lastnotes", "localisation", "lastpath", "backuppath")
|
||||||
assert cmpFiles(testFile, compFile, ignoreStart=ignore)
|
assert cmpFiles(testFile, compFile, ignoreStart=ignore)
|
||||||
tstConf.errorText() # This clears the error cache
|
tstConf.errorText() # This clears the error cache
|
||||||
|
|
||||||
|
|||||||
@@ -590,10 +590,6 @@ def testCoreProject_Backup(monkeypatch, mockGUI, fncPath, tstPaths):
|
|||||||
# Invalid Settings
|
# Invalid Settings
|
||||||
# ================
|
# ================
|
||||||
|
|
||||||
# Invalid path
|
|
||||||
CONFIG._backupPath = None
|
|
||||||
assert theProject.backupProject(doNotify=False) is False
|
|
||||||
|
|
||||||
# Missing project name
|
# Missing project name
|
||||||
CONFIG._backupPath = tstPaths.tmpDir
|
CONFIG._backupPath = tstPaths.tmpDir
|
||||||
theProject.data.setName("")
|
theProject.data.setName("")
|
||||||
|
|||||||
Reference in New Issue
Block a user