Change dataPath to a Path object
This commit is contained in:
@@ -27,8 +27,6 @@ import sys
|
||||
import getopt
|
||||
import logging
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QApplication, QErrorMessage
|
||||
|
||||
@@ -158,7 +156,7 @@ def main(sysArgs=None):
|
||||
elif inOpt == "--style":
|
||||
qtStyle = inArg
|
||||
elif inOpt == "--config":
|
||||
confPath = Path(inArg)
|
||||
confPath = inArg
|
||||
elif inOpt == "--data":
|
||||
dataPath = inArg
|
||||
elif inOpt == "--testmode":
|
||||
|
||||
+27
-34
@@ -38,7 +38,7 @@ from PyQt5.QtCore import (
|
||||
)
|
||||
|
||||
from novelwriter.error import logException, formatException
|
||||
from novelwriter.common import ensureFolder, splitVersionNumber, formatTimeStamp, NWConfigParser
|
||||
from novelwriter.common import splitVersionNumber, formatTimeStamp, NWConfigParser
|
||||
from novelwriter.constants import nwFiles, nwUnicode
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -55,12 +55,14 @@ class Config:
|
||||
self.appName = "novelWriter"
|
||||
self.appHandle = "novelwriter"
|
||||
|
||||
confRoot = Path(QStandardPaths.writableLocation(QStandardPaths.ConfigLocation))
|
||||
self._confPath = confRoot.absolute() / self.appHandle # The user config location
|
||||
|
||||
# Set Paths
|
||||
confRoot = Path(QStandardPaths.writableLocation(QStandardPaths.ConfigLocation))
|
||||
dataRoot = Path(QStandardPaths.writableLocation(QStandardPaths.AppDataLocation))
|
||||
|
||||
self._confPath = confRoot.absolute() / self.appHandle # The user config location
|
||||
self._dataPath = dataRoot.absolute() / self.appHandle # The user data location
|
||||
|
||||
self.cmdOpen = None # Path from command line for project to be opened on launch
|
||||
self.dataPath = None # Folder where app data is stored
|
||||
self.lastPath = None # The last user-selected folder (browse dialogs)
|
||||
self.appPath = None # The full path to the novelwriter package folder
|
||||
self.appRoot = None # The full path to the novelwriter root folder
|
||||
@@ -245,6 +247,13 @@ class Config:
|
||||
"""
|
||||
return int(theSize/self.guiScale)
|
||||
|
||||
def getDataPath(self, target=None):
|
||||
"""Return a path in the data folder.
|
||||
"""
|
||||
if isinstance(target, str):
|
||||
return self._dataPath / target
|
||||
return self._dataPath
|
||||
|
||||
##
|
||||
# Config Actions
|
||||
##
|
||||
@@ -254,19 +263,16 @@ class Config:
|
||||
and dataPath is mainly intended for the test suite.
|
||||
"""
|
||||
logger.debug("Initialising Config ...")
|
||||
if isinstance(confPath, Path):
|
||||
if isinstance(confPath, (str, Path)):
|
||||
logger.info("Setting config from alternative path: %s", confPath)
|
||||
self._confPath = confPath
|
||||
self._confPath = Path(confPath)
|
||||
|
||||
if dataPath is None:
|
||||
dataRoot = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation)
|
||||
self.dataPath = os.path.join(os.path.abspath(dataRoot), self.appHandle)
|
||||
else:
|
||||
if isinstance(dataPath, (str, Path)):
|
||||
logger.info("Setting data path from alternative path: %s", dataPath)
|
||||
self.dataPath = dataPath
|
||||
self._dataPath = Path(dataPath)
|
||||
|
||||
logger.debug("Config path: %s", self._confPath)
|
||||
logger.debug("Data path: %s", self.dataPath)
|
||||
logger.debug("Data path: %s", self._dataPath)
|
||||
|
||||
self.lastPath = os.path.expanduser("~")
|
||||
self.appPath = getattr(sys, "_MEIPASS", os.path.abspath(os.path.dirname(__file__)))
|
||||
@@ -293,15 +299,12 @@ class Config:
|
||||
# If the config and data folders don't not exist, create them
|
||||
# This assumes that the os config and data folders exist
|
||||
self._confPath.mkdir(exist_ok=True)
|
||||
|
||||
if not ensureFolder(self.dataPath, errLog=self.errData):
|
||||
self.hasError = True
|
||||
self.dataPath = None
|
||||
self._dataPath.mkdir(exist_ok=True)
|
||||
|
||||
# We don't error on these failing since they are not essential
|
||||
if self.dataPath is not None:
|
||||
ensureFolder("syntax", parent=self.dataPath)
|
||||
ensureFolder("themes", parent=self.dataPath)
|
||||
if self._dataPath.is_dir():
|
||||
(self._dataPath / "syntax").mkdir(exist_ok=True)
|
||||
(self._dataPath / "themes").mkdir(exist_ok=True)
|
||||
|
||||
# Check if config file exists
|
||||
if (self._confPath / nwFiles.CONF_FILE).is_file():
|
||||
@@ -618,12 +621,9 @@ class Config:
|
||||
def loadRecentCache(self):
|
||||
"""Load the cache file for recent projects.
|
||||
"""
|
||||
if self.dataPath is None:
|
||||
return False
|
||||
|
||||
self.recentProj = {}
|
||||
|
||||
cacheFile = os.path.join(self.dataPath, nwFiles.RECENT_FILE)
|
||||
cacheFile = self._dataPath / nwFiles.RECENT_FILE
|
||||
if not os.path.isfile(cacheFile):
|
||||
return True
|
||||
|
||||
@@ -649,25 +649,18 @@ class Config:
|
||||
def saveRecentCache(self):
|
||||
"""Save the cache dictionary of recent projects.
|
||||
"""
|
||||
if self.dataPath is None:
|
||||
return False
|
||||
|
||||
cacheFile = os.path.join(self.dataPath, nwFiles.RECENT_FILE)
|
||||
cacheTemp = os.path.join(self.dataPath, nwFiles.RECENT_FILE+"~")
|
||||
|
||||
cacheFile = self._dataPath / nwFiles.RECENT_FILE
|
||||
cacheTemp = cacheFile.with_suffix(".tmp")
|
||||
try:
|
||||
with open(cacheTemp, mode="w+", encoding="utf-8") as outFile:
|
||||
json.dump(self.recentProj, outFile, indent=2)
|
||||
cacheTemp.replace(cacheFile)
|
||||
except Exception as exc:
|
||||
self.hasError = True
|
||||
self.errData.append("Could not save recent project cache")
|
||||
self.errData.append(formatException(exc))
|
||||
return False
|
||||
|
||||
if os.path.isfile(cacheFile):
|
||||
os.unlink(cacheFile)
|
||||
os.rename(cacheTemp, cacheFile)
|
||||
|
||||
return True
|
||||
|
||||
def updateRecentCache(self, projPath, projTitle, wordCount, saveTime):
|
||||
|
||||
@@ -29,6 +29,7 @@ import logging
|
||||
import novelwriter
|
||||
|
||||
from math import ceil
|
||||
from pathlib import Path
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import qApp
|
||||
@@ -122,9 +123,8 @@ class GuiTheme:
|
||||
self._listConf(self._availSyntax, os.path.join(self.mainConf.assetPath, "syntax"))
|
||||
self._listConf(self._availThemes, os.path.join(self.mainConf.assetPath, "themes"))
|
||||
|
||||
if self.mainConf.dataPath: # Not guaranteed to be set
|
||||
self._listConf(self._availSyntax, os.path.join(self.mainConf.dataPath, "syntax"))
|
||||
self._listConf(self._availThemes, os.path.join(self.mainConf.dataPath, "themes"))
|
||||
self._listConf(self._availSyntax, self.mainConf.getDataPath("syntax"))
|
||||
self._listConf(self._availThemes, self.mainConf.getDataPath("themes"))
|
||||
|
||||
self.loadTheme()
|
||||
self.loadSyntax()
|
||||
@@ -380,13 +380,13 @@ class GuiTheme:
|
||||
def _listConf(self, targetDict, checkDir):
|
||||
"""Scan for theme config files and populate the dictionary.
|
||||
"""
|
||||
if not os.path.isdir(checkDir):
|
||||
checkDir = Path(checkDir)
|
||||
if not checkDir.is_dir():
|
||||
return False
|
||||
|
||||
for checkFile in os.listdir(checkDir):
|
||||
confPath = os.path.join(checkDir, checkFile)
|
||||
if os.path.isfile(confPath) and confPath.endswith(".conf"):
|
||||
targetDict[checkFile[:-5]] = confPath
|
||||
for checkFile in checkDir.iterdir():
|
||||
if checkFile.is_file() and checkFile.name.endswith(".conf"):
|
||||
targetDict[checkFile.name[:-5]] = checkFile
|
||||
|
||||
return True
|
||||
|
||||
|
||||
+2
-2
@@ -165,7 +165,7 @@ def tmpConf(tmpPath):
|
||||
if confFile.is_file():
|
||||
confFile.unlink()
|
||||
theConf = Config()
|
||||
theConf.initConfig(tmpPath, str(tmpPath))
|
||||
theConf.initConfig(tmpPath, tmpPath)
|
||||
theConf.setLastPath("")
|
||||
theConf.guiLang = "en_GB"
|
||||
return theConf
|
||||
@@ -179,7 +179,7 @@ def fncConf(fncPath):
|
||||
if confFile.is_file():
|
||||
confFile.unlink()
|
||||
theConf = Config()
|
||||
theConf.initConfig(fncPath, str(fncPath))
|
||||
theConf.initConfig(fncPath, fncPath)
|
||||
theConf.setLastPath("")
|
||||
theConf.guiLang = "en_GB"
|
||||
return theConf
|
||||
|
||||
@@ -99,7 +99,7 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
|
||||
mp.setattr("PyQt5.QtCore.QStandardPaths.writableLocation", lambda *a: fncDir)
|
||||
tstConf.initConfig()
|
||||
assert tstConf._confPath == os.path.join(fncDir, tstConf.appHandle)
|
||||
assert tstConf.dataPath == os.path.join(fncDir, tstConf.appHandle)
|
||||
assert tstConf._dataPath == os.path.join(fncDir, tstConf.appHandle)
|
||||
assert not os.path.isfile(confFile)
|
||||
|
||||
# Fail to make folders
|
||||
@@ -109,13 +109,13 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
|
||||
tstConfDir = os.path.join(fncDir, "test_conf")
|
||||
tstConf.initConfig(confPath=tstConfDir, dataPath=tmpDir)
|
||||
assert tstConf._confPath is None
|
||||
assert tstConf.dataPath == tmpDir
|
||||
assert tstConf._dataPath == tmpDir
|
||||
assert not os.path.isfile(confFile)
|
||||
|
||||
tstDataDir = os.path.join(fncDir, "test_data")
|
||||
tstConf.initConfig(confPath=tmpDir, dataPath=tstDataDir)
|
||||
assert tstConf._confPath == tmpDir
|
||||
assert tstConf.dataPath is None
|
||||
assert tstConf._dataPath is None
|
||||
assert os.path.isfile(confFile)
|
||||
os.unlink(confFile)
|
||||
|
||||
@@ -130,7 +130,7 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
|
||||
mp.setattr("os.path.expanduser", lambda *a: "")
|
||||
tstConf.initConfig(confPath=tmpDir, dataPath=tmpDir)
|
||||
assert tstConf._confPath == tmpDir
|
||||
assert tstConf.dataPath == tmpDir
|
||||
assert tstConf._dataPath == tmpDir
|
||||
assert os.path.isfile(confFile)
|
||||
|
||||
copyfile(confFile, testFile)
|
||||
@@ -158,13 +158,13 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
|
||||
with monkeypatch.context() as mp:
|
||||
tstConf.initConfig(confPath=tmpDir, dataPath=tmpDir)
|
||||
assert tstConf._confPath == tmpDir
|
||||
assert tstConf.dataPath == tmpDir
|
||||
assert tstConf._dataPath == tmpDir
|
||||
appRoot = tstConf.appRoot
|
||||
|
||||
mp.setattr("os.path.isfile", lambda *a: True)
|
||||
tstConf.initConfig(confPath=tmpDir, dataPath=tmpDir)
|
||||
assert tstConf._confPath == tmpDir
|
||||
assert tstConf.dataPath == tmpDir
|
||||
assert tstConf._dataPath == tmpDir
|
||||
assert tstConf.appRoot == os.path.dirname(appRoot)
|
||||
assert tstConf.appPath == os.path.dirname(appRoot)
|
||||
|
||||
@@ -233,12 +233,6 @@ def testBaseConfig_Init(monkeypatch, tmpDir, fncDir, outDir, refDir, filesDir):
|
||||
def testBaseConfig_RecentCache(monkeypatch, tmpConf, tmpDir, fncDir):
|
||||
"""Test recent cache file.
|
||||
"""
|
||||
# Check failing
|
||||
tmpConf.dataPath = None
|
||||
assert not tmpConf.loadRecentCache()
|
||||
assert not tmpConf.saveRecentCache()
|
||||
tmpConf.dataPath = tmpDir
|
||||
|
||||
# Add a couple of values
|
||||
pathOne = os.path.join(fncDir, "projPathOne", nwFiles.PROJ_FILE)
|
||||
pathTwo = os.path.join(fncDir, "projPathTwo", nwFiles.PROJ_FILE)
|
||||
|
||||
Reference in New Issue
Block a user