Completed coverage of setProjectPath and made all os imports explicit

This commit is contained in:
Veronica K. B. Olsen
2020-09-29 23:27:51 +02:00
parent 0b7cd71b92
commit e251ddacd2
23 changed files with 565 additions and 486 deletions
+5 -6
View File
@@ -28,8 +28,7 @@
import sys
import getopt
import logging
from os import path, remove, rename
import os
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QErrorMessage
@@ -203,10 +202,10 @@ def main(sysArgs=None):
logFmt = logging.Formatter(fmt=logFormat, style="{")
if not logFile == "" and toFile:
if path.isfile(logFile+".bak"):
remove(logFile+".bak")
if path.isfile(logFile):
rename(logFile, logFile+".bak")
if os.path.isfile(logFile+".bak"):
os.remove(logFile+".bak")
if os.path.isfile(logFile):
os.rename(logFile, logFile+".bak")
fHandle = logging.FileHandler(logFile)
fHandle.setLevel(debugLevel)
+35 -35
View File
@@ -29,8 +29,8 @@ import logging
import configparser
import json
import sys
import os
from os import path, mkdir, unlink, rename
from time import time
from shutil import which
@@ -238,7 +238,7 @@ class Config:
logger.debug("Initialising Config ...")
if confPath is None:
confRoot = QStandardPaths.writableLocation(QStandardPaths.ConfigLocation)
self.confPath = path.join(path.abspath(confRoot), self.appHandle)
self.confPath = os.path.join(os.path.abspath(confRoot), self.appHandle)
else:
logger.info("Setting config from alternative path: %s" % confPath)
self.confPath = confPath
@@ -248,7 +248,7 @@ class Config:
dataRoot = QStandardPaths.writableLocation(QStandardPaths.AppDataLocation)
else:
dataRoot = QStandardPaths.writableLocation(QStandardPaths.DataLocation)
self.dataPath = path.join(path.abspath(dataRoot), self.appHandle)
self.dataPath = os.path.join(os.path.abspath(dataRoot), self.appHandle)
else:
logger.info("Setting data path from alternative path: %s" % dataPath)
self.dataPath = dataPath
@@ -257,24 +257,24 @@ class Config:
logger.verbose("Data path: %s" % self.dataPath)
self.confFile = self.appHandle+".conf"
self.homePath = path.expanduser("~")
self.homePath = os.path.expanduser("~")
self.lastPath = self.homePath
self.appPath = getattr(sys, "_MEIPASS", path.abspath(path.dirname(__file__)))
self.appRoot = path.join(self.appPath, path.pardir)
self.assetPath = path.join(self.appPath, "assets")
self.themeRoot = path.join(self.assetPath, "themes")
self.dictPath = path.join(self.assetPath, "dict")
self.iconPath = path.join(self.assetPath, "icons")
self.appIcon = path.join(self.iconPath, "novelwriter.svg")
self.appPath = getattr(sys, "_MEIPASS", os.path.abspath(os.path.dirname(__file__)))
self.appRoot = os.path.join(self.appPath, os.path.pardir)
self.assetPath = os.path.join(self.appPath, "assets")
self.themeRoot = os.path.join(self.assetPath, "themes")
self.dictPath = os.path.join(self.assetPath, "dict")
self.iconPath = os.path.join(self.assetPath, "icons")
self.appIcon = os.path.join(self.iconPath, "novelwriter.svg")
logger.verbose("App path: %s" % self.appPath)
logger.verbose("Home path: %s" % self.homePath)
# If config folder does not exist, make it.
# This assumes that the os config folder itself exists.
if not path.isdir(self.confPath):
if not os.path.isdir(self.confPath):
try:
mkdir(self.confPath)
os.mkdir(self.confPath)
except Exception as e:
logger.error("Could not create folder: %s" % self.confPath)
logger.error(str(e))
@@ -285,7 +285,7 @@ class Config:
# Check if config file exists
if self.confPath is not None:
if path.isfile(path.join(self.confPath, self.confFile)):
if os.path.isfile(os.path.join(self.confPath, self.confFile)):
# If it exists, load it
self.loadConfig()
else:
@@ -295,9 +295,9 @@ class Config:
# If data folder does not exist, make it.
# This assumes that the os data folder itself exists.
if self.dataPath is not None:
if not path.isdir(self.dataPath):
if not os.path.isdir(self.dataPath):
try:
mkdir(self.dataPath)
os.mkdir(self.dataPath)
except Exception as e:
logger.error("Could not create folder: %s" % self.dataPath)
logger.error(str(e))
@@ -318,9 +318,9 @@ class Config:
self.spellLanguage = "en"
# Check if local help files exist
self.helpPath = path.join(self.assetPath, "help", "novelWriter.qhc")
self.hasHelp = path.isfile(self.helpPath)
self.hasHelp &= path.isfile(path.join(self.assetPath, "help", "novelWriter.qch"))
self.helpPath = os.path.join(self.assetPath, "help", "novelWriter.qhc")
self.hasHelp = os.path.isfile(self.helpPath)
self.hasHelp &= os.path.isfile(os.path.join(self.assetPath, "help", "novelWriter.qch"))
logger.debug("Config initialisation complete")
@@ -334,7 +334,7 @@ class Config:
return False
cnfParse = configparser.ConfigParser()
cnfPath = path.join(self.confPath, self.confFile)
cnfPath = os.path.join(self.confPath, self.confFile)
try:
with open(cnfPath, mode="r", encoding="utf8") as inFile:
cnfParse.read_file(inFile)
@@ -629,7 +629,7 @@ class Config:
cnfParse.set(cnfSec, "lastpath", str(self.lastPath))
# Write config file
cnfPath = path.join(self.confPath, self.confFile)
cnfPath = os.path.join(self.confPath, self.confFile)
try:
with open(cnfPath, mode="w", encoding="utf8") as outFile:
cnfParse.write(outFile)
@@ -650,10 +650,10 @@ class Config:
if self.dataPath is None:
return False
cacheFile = path.join(self.dataPath, nwFiles.RECENT_FILE)
cacheFile = os.path.join(self.dataPath, nwFiles.RECENT_FILE)
self.recentProj = {}
if path.isfile(cacheFile):
if os.path.isfile(cacheFile):
try:
with open(cacheFile, mode="r", encoding="utf8") as inFile:
theJson = inFile.read()
@@ -690,8 +690,8 @@ class Config:
if self.dataPath is None:
return False
cacheFile = path.join(self.dataPath, nwFiles.RECENT_FILE)
cacheTemp = path.join(self.dataPath, nwFiles.RECENT_FILE+"~")
cacheFile = os.path.join(self.dataPath, nwFiles.RECENT_FILE)
cacheTemp = os.path.join(self.dataPath, nwFiles.RECENT_FILE+"~")
try:
with open(cacheTemp, mode="w+", encoding="utf8") as outFile:
@@ -702,16 +702,16 @@ class Config:
self.errData.append(str(e))
return False
if path.isfile(cacheFile):
unlink(cacheFile)
rename(cacheTemp, cacheFile)
if os.path.isfile(cacheFile):
os.unlink(cacheFile)
os.rename(cacheTemp, cacheFile)
return True
def updateRecentCache(self, projPath, projTitle, wordCount, saveTime):
"""Add or update recent cache information o9n a given project.
"""
self.recentProj[path.abspath(projPath)] = {
self.recentProj[os.path.abspath(projPath)] = {
"title" : projTitle,
"time" : int(saveTime),
"words" : int(wordCount),
@@ -737,27 +737,27 @@ class Config:
def setConfPath(self, newPath):
if newPath is None:
return True
if not path.isfile(newPath):
if not os.path.isfile(newPath):
logger.error("File not found, using default config path instead")
return False
self.confPath = path.dirname(newPath)
self.confFile = path.basename(newPath)
self.confPath = os.path.dirname(newPath)
self.confFile = os.path.basename(newPath)
return True
def setDataPath(self, newPath):
if newPath is None:
return True
if not path.isdir(newPath):
if not os.path.isdir(newPath):
logger.error("Path not found, using default data path instead")
return False
self.dataPath = path.abspath(newPath)
self.dataPath = os.path.abspath(newPath)
return True
def setLastPath(self, lastPath):
if lastPath is None or lastPath == "":
self.lastPath = ""
else:
self.lastPath = path.dirname(lastPath)
self.lastPath = os.path.dirname(lastPath)
return True
def setWinSize(self, newWidth, newHeight):
+12 -13
View File
@@ -26,8 +26,7 @@
"""
import logging
from os import path, rename, unlink
import os
from nw.constants import nwAlert
from nw.common import isHandle
@@ -89,12 +88,12 @@ class NWDoc():
docFile = self._docHandle+".nwd"
logger.debug("Opening document %s" % docFile)
docPath = path.join(self.theProject.projContent, docFile)
docPath = os.path.join(self.theProject.projContent, docFile)
self._fileLoc = docPath
theText = ""
self._docMeta = ""
if path.isfile(docPath):
if os.path.isfile(docPath):
try:
with open(docPath, mode="r", encoding="utf8") as inFile:
fstLine = inFile.readline()
@@ -137,8 +136,8 @@ class NWDoc():
docFile = self._docHandle+".nwd"
logger.debug("Saving document %s" % docFile)
docPath = path.join(self.theProject.projContent, docFile)
docTemp = path.join(self.theProject.projContent, docFile+"~")
docPath = os.path.join(self.theProject.projContent, docFile)
docTemp = os.path.join(self.theProject.projContent, docFile+"~")
if self._theItem is None:
docMeta = ""
@@ -163,9 +162,9 @@ class NWDoc():
# If we're here, the file was successfully saved, so we can
# replace the temp file with the actual file
if path.isfile(docPath):
unlink(docPath)
rename(docTemp, docPath)
if os.path.isfile(docPath):
os.unlink(docPath)
os.rename(docTemp, docPath)
self.theParent.statusBar.setStatus("Saved Document: %s" % self._theItem.itemName)
@@ -181,13 +180,13 @@ class NWDoc():
docFile = tHandle+".nwd"
chkList = []
chkList.append(path.join(self.theProject.projContent, docFile))
chkList.append(path.join(self.theProject.projContent, docFile+"~"))
chkList.append(os.path.join(self.theProject.projContent, docFile))
chkList.append(os.path.join(self.theProject.projContent, docFile+"~"))
for chkFile in chkList:
if path.isfile(chkFile):
if os.path.isfile(chkFile):
try:
unlink(chkFile)
os.unlink(chkFile)
logger.debug("Deleted: %s" % chkFile)
except Exception as e:
self.makeAlert(["Could not delete document file.", str(e)], nwAlert.ERROR)
+4 -4
View File
@@ -28,8 +28,8 @@
import nw
import logging
import json
import os
from os import path
from time import time
from nw.constants import (
@@ -153,9 +153,9 @@ class NWIndex():
"""Load index from last session from the project meta folder.
"""
theData = {}
indexFile = path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
if path.isfile(indexFile):
if os.path.isfile(indexFile):
logger.debug("Loading index file")
try:
with open(indexFile, mode="r", encoding="utf8") as inFile:
@@ -190,7 +190,7 @@ class NWIndex():
"""Save the current index as a json file in the project meta
data folder.
"""
indexFile = path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
logger.debug("Saving index file")
if self.mainConf.debugInfo:
+4 -5
View File
@@ -28,8 +28,7 @@
import logging
import json
from os import path
import os
from nw.constants import nwFiles
@@ -100,10 +99,10 @@ class OptionState():
if self.theProject.projMeta is None:
return False
stateFile = path.join(self.theProject.projMeta, nwFiles.OPTS_FILE)
stateFile = os.path.join(self.theProject.projMeta, nwFiles.OPTS_FILE)
theState = {}
if path.isfile(stateFile):
if os.path.isfile(stateFile):
logger.debug("Loading GUI options file")
try:
with open(stateFile, mode="r", encoding="utf8") as inFile:
@@ -130,7 +129,7 @@ class OptionState():
if self.theProject.projMeta is None:
return False
stateFile = path.join(self.theProject.projMeta, nwFiles.OPTS_FILE)
stateFile = os.path.join(self.theProject.projMeta, nwFiles.OPTS_FILE)
logger.debug("Saving GUI options file")
try:
+90 -93
View File
@@ -27,8 +27,8 @@
import nw
import logging
import os
from os import path, mkdir, listdir, unlink, rename, rmdir
from lxml import etree
from time import time
from shutil import make_archive, unpack_archive, copyfile
@@ -351,14 +351,11 @@ class NWProject():
aDoc.saveDocument("### %s\n\n" % scTitle)
aDoc.clearDocument()
else:
# Fallback just in case. We shouldn't reach here.
self.newRoot("Novel", nwItemClass.NOVEL)
# Finalise
self.projOpened = time()
self.setProjectChanged(True)
self.saveProject(autoSave=True)
if popCustom or popMinimal:
self.projOpened = time()
self.setProjectChanged(True)
self.saveProject(autoSave=True)
return True
@@ -368,14 +365,14 @@ class NWProject():
parse the XML of the file and populate the project variables and
build the tree of project items.
"""
if not path.isfile(fileName):
fileName = path.join(fileName, nwFiles.PROJ_FILE)
if not path.isfile(fileName):
if not os.path.isfile(fileName):
fileName = os.path.join(fileName, nwFiles.PROJ_FILE)
if not os.path.isfile(fileName):
self.makeAlert("File not found: %s" % fileName, nwAlert.ERROR)
return False
self.clearProject()
self.projPath = path.abspath(path.dirname(fileName))
self.projPath = os.path.abspath(os.path.dirname(fileName))
logger.debug("Opening project: %s" % self.projPath)
# Standard Folders and Files
@@ -385,13 +382,13 @@ class NWProject():
self.clearProject()
return False
self.projDict = path.join(self.projMeta, nwFiles.PROJ_DICT)
self.projDict = os.path.join(self.projMeta, nwFiles.PROJ_DICT)
# Check for Old Legacy Data
# =========================
legacyList = [] # Cleanup is done later
for projItem in listdir(self.projPath):
for projItem in os.listdir(self.projPath):
logger.verbose("Project contains: %s" % projItem)
if projItem.startswith("data_"):
legacyList.append(projItem)
@@ -424,7 +421,7 @@ class NWProject():
# Trying to open backup file instead
backFile = fileName[:-3]+"bak"
if path.isfile(backFile):
if os.path.isfile(backFile):
self.makeAlert("Attempting to open backup project file instead.", nwAlert.INFO)
try:
nwXML = etree.parse(backFile)
@@ -706,9 +703,9 @@ class NWProject():
self.projTree.packXML(nwXML)
# Write the xml tree to file
tempFile = path.join(self.projPath, self.projFile+"~")
saveFile = path.join(self.projPath, self.projFile)
backFile = path.join(self.projPath, self.projFile[:-3]+"bak")
tempFile = os.path.join(self.projPath, self.projFile+"~")
saveFile = os.path.join(self.projPath, self.projFile)
backFile = os.path.join(self.projPath, self.projFile[:-3]+"bak")
try:
with open(tempFile, mode="wb") as outFile:
outFile.write(etree.tostring(
@@ -723,11 +720,11 @@ class NWProject():
# If we're here, the file was successfully saved,
# so let's sort out the temps and backups
if path.isfile(backFile):
unlink(backFile)
if path.isfile(saveFile):
rename(saveFile, backFile)
rename(tempFile, saveFile)
if os.path.isfile(backFile):
os.unlink(backFile)
if os.path.isfile(saveFile):
os.rename(saveFile, backFile)
os.rename(tempFile, saveFile)
# Save project GUI options
self.optState.saveSettings()
@@ -760,9 +757,9 @@ class NWProject():
if self.projPath is None or self.projPath == "":
return False
self.projMeta = path.join(self.projPath, "meta")
self.projCache = path.join(self.projPath, "cache")
self.projContent = path.join(self.projPath, "content")
self.projMeta = os.path.join(self.projPath, "meta")
self.projCache = os.path.join(self.projPath, "cache")
self.projContent = os.path.join(self.projPath, "content")
if not self._checkFolder(self.projMeta):
return False
@@ -797,7 +794,7 @@ class NWProject():
), nwAlert.ERROR)
return False
if not path.isdir(self.mainConf.backupPath):
if not os.path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert((
"Cannot backup project because the backup path does not exist. "
"Please set a valid backup location in Tools > Preferences."
@@ -805,10 +802,10 @@ class NWProject():
return False
cleanName = makeFileNameSafe(self.projName)
baseDir = path.abspath(path.join(self.mainConf.backupPath, cleanName))
if not path.isdir(baseDir):
baseDir = os.path.abspath(os.path.join(self.mainConf.backupPath, cleanName))
if not os.path.isdir(baseDir):
try:
mkdir(baseDir)
os.mkdir(baseDir)
logger.debug("Created folder %s" % baseDir)
except Exception as e:
self.theParent.makeAlert(
@@ -817,7 +814,7 @@ class NWProject():
)
return False
if path.commonpath([self.projPath, baseDir]) == self.projPath:
if os.path.commonpath([self.projPath, baseDir]) == self.projPath:
self.theParent.makeAlert((
"Cannot backup project because the backup path is within the "
"project folder to be backed up. Please choose a different "
@@ -826,7 +823,7 @@ class NWProject():
return False
archName = "Backup from %s" % formatTimeStamp(time(), fileSafe=True)
baseName = path.join(baseDir, archName)
baseName = os.path.join(baseDir, archName)
try:
self._clearLockFile()
@@ -834,7 +831,7 @@ class NWProject():
self._writeLockFile()
if doNotify:
self.theParent.makeAlert(
"Backup archive file written to: %s.zip" % path.join(cleanName, archName),
"Backup archive file written to: %s.zip" % os.path.join(cleanName, archName),
nwAlert.INFO
)
else:
@@ -861,11 +858,11 @@ class NWProject():
logger.error("No project path set for the example project")
return False
srcSample = path.abspath(path.join(self.mainConf.appRoot, "sample"))
pkgSample = path.join(self.mainConf.assetPath, "sample.zip")
srcSample = os.path.abspath(os.path.join(self.mainConf.appRoot, "sample"))
pkgSample = os.path.join(self.mainConf.assetPath, "sample.zip")
isSuccess = False
if path.isfile(pkgSample):
if os.path.isfile(pkgSample):
self.setProjectPath(projPath, newProject=True)
try:
@@ -876,19 +873,19 @@ class NWProject():
["Failed to create a new example project.", str(e)], nwAlert.ERROR
)
elif path.isdir(srcSample):
elif os.path.isdir(srcSample):
self.setProjectPath(projPath, newProject=True)
try:
srcProj = path.join(srcSample, nwFiles.PROJ_FILE)
dstProj = path.join(projPath, nwFiles.PROJ_FILE)
srcProj = os.path.join(srcSample, nwFiles.PROJ_FILE)
dstProj = os.path.join(projPath, nwFiles.PROJ_FILE)
copyfile(srcProj, dstProj)
srcContent = path.join(srcSample, "content")
dstContent = path.join(projPath, "content")
for srcFile in listdir(srcContent):
srcDoc = path.join(srcContent, srcFile)
dstDoc = path.join(dstContent, srcFile)
srcContent = os.path.join(srcSample, "content")
dstContent = os.path.join(projPath, "content")
for srcFile in os.listdir(srcContent):
srcDoc = os.path.join(srcContent, srcFile)
dstDoc = os.path.join(dstContent, srcFile)
copyfile(srcDoc, dstDoc)
isSuccess = True
@@ -923,13 +920,13 @@ class NWProject():
self.projPath = None
else:
if projPath.startswith("~"):
projPath = path.expanduser(projPath)
self.projPath = path.abspath(projPath)
projPath = os.path.expanduser(projPath)
self.projPath = os.path.abspath(projPath)
if newProject:
if not path.isdir(projPath):
if not os.path.isdir(projPath):
try:
mkdir(projPath)
os.mkdir(projPath)
logger.debug("Created folder %s" % projPath)
except Exception as e:
self.theParent.makeAlert((
@@ -937,8 +934,8 @@ class NWProject():
), nwAlert.ERROR)
return False
if path.isdir(projPath):
if listdir(self.projPath):
if os.path.isdir(projPath):
if os.listdir(self.projPath):
self.theParent.makeAlert((
"New project folder is not empty. "
"Each project requires a dedicated project folder."
@@ -988,7 +985,7 @@ class NWProject():
"""
self.doBackup = doBackup
if doBackup:
if not path.isdir(self.mainConf.backupPath):
if not os.path.isdir(self.mainConf.backupPath):
self.theParent.makeAlert((
"You must set a valid backup path in preferences to use "
"the automatic project backup feature."
@@ -1187,8 +1184,8 @@ class NWProject():
if self.projPath is None:
return ["ERROR"]
lockFile = path.join(self.projPath, nwFiles.PROJ_LOCK)
if not path.isfile(lockFile):
lockFile = os.path.join(self.projPath, nwFiles.PROJ_LOCK)
if not os.path.isfile(lockFile):
return []
try:
@@ -1213,7 +1210,7 @@ class NWProject():
if self.projPath is None:
return False
lockFile = path.join(self.projPath, nwFiles.PROJ_LOCK)
lockFile = os.path.join(self.projPath, nwFiles.PROJ_LOCK)
try:
with open(lockFile, mode="w+", encoding="utf8") as outFile:
outFile.write("%s\n" % self.mainConf.hostName)
@@ -1234,10 +1231,10 @@ class NWProject():
if self.projPath is None:
return False
lockFile = path.join(self.projPath, nwFiles.PROJ_LOCK)
if path.isfile(lockFile):
lockFile = os.path.join(self.projPath, nwFiles.PROJ_LOCK)
if os.path.isfile(lockFile):
try:
unlink(lockFile)
os.unlink(lockFile)
return True
except Exception as e:
logger.error("Failed to remove project lockfile")
@@ -1249,9 +1246,9 @@ class NWProject():
def _checkFolder(self, thePath):
"""Check if a folder exists, and if it doesn't, create it.
"""
if not path.isdir(thePath):
if not os.path.isdir(thePath):
try:
mkdir(thePath)
os.mkdir(thePath)
logger.debug("Created folder %s" % thePath)
except Exception as e:
self.makeAlert(["Could not create folder.", str(e)], nwAlert.ERROR)
@@ -1292,7 +1289,7 @@ class NWProject():
# Then check the files in the data folder
logger.debug("Checking files in project content folder")
orphanFiles = []
for fileItem in listdir(self.projContent):
for fileItem in os.listdir(self.projContent):
if not fileItem.endswith(".nwd"):
logger.warning("Skipping file %s" % fileItem)
continue
@@ -1355,8 +1352,8 @@ class NWProject():
if not self.ensureFolderStructure():
return False
sessionFile = path.join(self.projMeta, nwFiles.SESS_STATS)
isFile = path.isfile(sessionFile)
sessionFile = os.path.join(self.projMeta, nwFiles.SESS_STATS)
isFile = os.path.isfile(sessionFile)
with open(sessionFile, mode="a+", encoding="utf8") as outFile:
if not isFile:
@@ -1383,8 +1380,8 @@ class NWProject():
def _legacyDataFolder(self, theFolder, errList):
"""Clean up legacy data folders.
"""
theData = path.join(self.projPath, theFolder)
if not path.isdir(theData):
theData = os.path.join(self.projPath, theFolder)
if not os.path.isdir(theData):
errList.append("Not a folder: %s" % theData)
return errList
@@ -1392,9 +1389,9 @@ class NWProject():
# Move Documents to Content
# =========================
for dataItem in listdir(theData):
theFile = path.join(theData, dataItem)
if not path.isfile(theFile):
for dataItem in os.listdir(theData):
theFile = os.path.join(theData, dataItem)
if not os.path.isfile(theFile):
theErr = self._moveUnknownItem(theData, dataItem)
if theErr:
errList.append(theErr)
@@ -1402,9 +1399,9 @@ class NWProject():
if len(dataItem) == 21 and dataItem.endswith("_main.nwd"):
tHandle = theFolder[-1]+dataItem[:12]
newPath = path.join(self.projContent, tHandle+".nwd")
newPath = os.path.join(self.projContent, tHandle+".nwd")
try:
rename(theFile, newPath)
os.rename(theFile, newPath)
logger.info("Moved file: %s" % theFile)
logger.info("New location: %s" % newPath)
except Exception as e:
@@ -1413,7 +1410,7 @@ class NWProject():
elif len(dataItem) == 21 and dataItem.endswith("_main.bak"):
try:
unlink(theFile)
os.unlink(theFile)
logger.info("Deleted file: %s" % theFile)
except Exception as e:
logger.error(str(e))
@@ -1427,7 +1424,7 @@ class NWProject():
# Remove Data Folder
# ==================
try:
rmdir(theData)
os.rmdir(theData)
logger.info("Removed folder: %s" % theFolder)
except Exception as e:
logger.error(str(e))
@@ -1439,15 +1436,15 @@ class NWProject():
"""Move an item that doesn't belong in the project folder to
a junk folder.
"""
theJunk = path.join(self.projPath, "junk")
theJunk = os.path.join(self.projPath, "junk")
if not self._checkFolder(theJunk):
return "Could not make folder: %s" % theJunk
theSrc = path.join(theDir, theItem)
theDst = path.join(theJunk, theItem)
theSrc = os.path.join(theDir, theItem)
theDst = os.path.join(theJunk, theItem)
try:
rename(theSrc, theDst)
os.rename(theSrc, theDst)
logger.info("Moved to junk: %s" % theSrc)
except Exception as e:
logger.error(str(e))
@@ -1459,29 +1456,29 @@ class NWProject():
"""Delete files that are no longer used by novelWriter.
"""
rmList = [
path.join(self.projCache, "nwProject.nwx.0"),
path.join(self.projCache, "nwProject.nwx.1"),
path.join(self.projCache, "nwProject.nwx.2"),
path.join(self.projCache, "nwProject.nwx.3"),
path.join(self.projCache, "nwProject.nwx.4"),
path.join(self.projCache, "nwProject.nwx.5"),
path.join(self.projCache, "nwProject.nwx.6"),
path.join(self.projCache, "nwProject.nwx.7"),
path.join(self.projCache, "nwProject.nwx.8"),
path.join(self.projCache, "nwProject.nwx.9"),
path.join(self.projMeta, "mainOptions.json"),
path.join(self.projMeta, "exportOptions.json"),
path.join(self.projMeta, "outlineOptions.json"),
path.join(self.projMeta, "timelineOptions.json"),
path.join(self.projMeta, "docMergeOptions.json"),
path.join(self.projMeta, "sessionLogOptions.json"),
os.path.join(self.projCache, "nwProject.nwx.0"),
os.path.join(self.projCache, "nwProject.nwx.1"),
os.path.join(self.projCache, "nwProject.nwx.2"),
os.path.join(self.projCache, "nwProject.nwx.3"),
os.path.join(self.projCache, "nwProject.nwx.4"),
os.path.join(self.projCache, "nwProject.nwx.5"),
os.path.join(self.projCache, "nwProject.nwx.6"),
os.path.join(self.projCache, "nwProject.nwx.7"),
os.path.join(self.projCache, "nwProject.nwx.8"),
os.path.join(self.projCache, "nwProject.nwx.9"),
os.path.join(self.projMeta, "mainOptions.json"),
os.path.join(self.projMeta, "exportOptions.json"),
os.path.join(self.projMeta, "outlineOptions.json"),
os.path.join(self.projMeta, "timelineOptions.json"),
os.path.join(self.projMeta, "docMergeOptions.json"),
os.path.join(self.projMeta, "sessionLogOptions.json"),
]
for rmFile in rmList:
if path.isfile(rmFile):
if os.path.isfile(rmFile):
logger.info("Deleting: %s" % rmFile)
try:
unlink(rmFile)
os.unlink(rmFile)
except Exception as e:
logger.error(str(e))
+5 -5
View File
@@ -27,8 +27,8 @@
import nw
import logging
import os
from os import path, listdir
from difflib import get_close_matches
from nw.constants import isoLanguage
@@ -108,7 +108,7 @@ class NWSpellCheck():
self.PROJW = []
if projectDict is not None:
self.projectDict = projectDict
if not path.isfile(projectDict):
if not os.path.isfile(projectDict):
return
try:
logger.debug("Loading project word list")
@@ -228,7 +228,7 @@ class NWSpellSimple(NWSpellCheck):
"""Load a dictionary as a list from the app assets folder.
"""
self.WORDS = []
dictFile = path.join(self.mainConf.dictPath, theLang+".dict")
dictFile = os.path.join(self.mainConf.dictPath, theLang+".dict")
try:
with open(dictFile, mode="r", encoding="utf-8") as wordsFile:
for theLine in wordsFile:
@@ -297,9 +297,9 @@ class NWSpellSimple(NWSpellCheck):
"""Lists the dictionary files in the app assets folder.
"""
retList = []
for dictFile in listdir(self.mainConf.dictPath):
for dictFile in os.listdir(self.mainConf.dictPath):
theBits = path.splitext(dictFile)
theBits = os.path.splitext(dictFile)
if len(theBits) != 2:
continue
if theBits[1] != ".dict":
+6 -6
View File
@@ -27,8 +27,8 @@
import logging
import json
import os
from os import path
from lxml import etree
from hashlib import sha256
from time import time
@@ -144,8 +144,8 @@ class NWTree():
the project directory. These files are there to assist the user
if they wish to browse the stored files.
"""
tocText = path.join(self.theProject.projPath, nwFiles.TOC_TXT)
tocJson = path.join(self.theProject.projPath, nwFiles.TOC_JSON)
tocText = os.path.join(self.theProject.projPath, nwFiles.TOC_TXT)
tocJson = os.path.join(self.theProject.projPath, nwFiles.TOC_JSON)
jsonData = []
try:
@@ -162,14 +162,14 @@ class NWTree():
if tItem is None:
continue
tFile = tHandle+".nwd"
if path.isfile(path.join(self.theProject.projContent, tFile)):
if os.path.isfile(os.path.join(self.theProject.projContent, tFile)):
outFile.write(" %-25s %-9s %s\n" % (
path.join("content", tFile),
os.path.join("content", tFile),
tItem.itemClass.name,
tItem.itemName,
))
jsonData.append([
path.join("content", tFile),
os.path.join("content", tFile),
tItem.itemClass.name,
tItem.itemName,
])
+3 -3
View File
@@ -27,8 +27,8 @@
import nw
import logging
import os
from os import path
from datetime import datetime
from PyQt5.QtCore import Qt
@@ -197,8 +197,8 @@ class GuiAbout(QDialog):
"""Load the content for the License page.
"""
docName = "gplv3_%s.htm" % self.mainConf.guiLang
docPath = path.join(self.mainConf.assetPath, "text", docName)
if path.isfile(docPath):
docPath = os.path.join(self.mainConf.assetPath, "text", docName)
if os.path.isfile(docPath):
with open(docPath, mode="r", encoding="utf8") as inFile:
helpText = inFile.read()
self.pageLicense.setHtml(helpText)
+6 -6
View File
@@ -28,8 +28,8 @@
import nw
import logging
import json
import os
from os import path
from time import time
from datetime import datetime
@@ -630,8 +630,8 @@ class GuiBuildNovel(QDialog):
cleanName = makeFileNameSafe(self.theProject.projName)
fileName = "%s.%s" % (cleanName, fileExt)
saveDir = self.mainConf.lastPath
savePath = path.join(saveDir, fileName)
if not path.isdir(saveDir):
savePath = os.path.join(saveDir, fileName)
if not os.path.isdir(saveDir):
saveDir = self.mainConf.homePath
if self.mainConf.showGUI:
@@ -792,9 +792,9 @@ class GuiBuildNovel(QDialog):
def _loadCache(self):
"""Save the current data to cache.
"""
buildCache = path.join(self.theProject.projCache, nwFiles.BUILD_CACHE)
buildCache = os.path.join(self.theProject.projCache, nwFiles.BUILD_CACHE)
dataCount = 0
if path.isfile(buildCache):
if os.path.isfile(buildCache):
logger.debug("Loading build cache")
try:
@@ -823,7 +823,7 @@ class GuiBuildNovel(QDialog):
def _saveCache(self):
"""Save the current data to cache.
"""
buildCache = path.join(self.theProject.projCache, nwFiles.BUILD_CACHE)
buildCache = os.path.join(self.theProject.projCache, nwFiles.BUILD_CACHE)
if self.mainConf.debugInfo:
nIndent = 2
+2 -3
View File
@@ -27,8 +27,7 @@
import nw
import logging
from os import path
import os
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
@@ -335,7 +334,7 @@ class GuiConfigEditGeneralTab(QWidget):
"""Open a dialog to select the backup folder.
"""
currDir = self.backupPath
if not path.isdir(currDir):
if not os.path.isdir(currDir):
currDir = ""
dlgOpt = QFileDialog.Options()
+2 -2
View File
@@ -27,8 +27,8 @@
import nw
import logging
import os
from os import path
from datetime import datetime
from PyQt5.QtCore import Qt, QSize
@@ -186,7 +186,7 @@ class GuiProjectLoad(QDialog):
options=dlgOpt
)
if projFile:
thePath = path.abspath(path.dirname(projFile))
thePath = os.path.abspath(os.path.dirname(projFile))
self.selPath.setText(thePath)
self.openPath = thePath
self.openState = self.OPEN_STATE
+3 -4
View File
@@ -27,8 +27,7 @@
import nw
import logging
from os import path
import os
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (
@@ -208,7 +207,7 @@ class ProjWizardFolderPage(QWizardPage):
"""Select a project folder.
"""
lastPath = self.mainConf.lastPath
if not path.isdir(lastPath):
if not os.path.isdir(lastPath):
lastPath = ""
dlgOpt = QFileDialog.Options()
@@ -220,7 +219,7 @@ class ProjWizardFolderPage(QWizardPage):
if projDir:
projName = self.field("projName")
if projName is not None:
fullDir = path.join(path.abspath(projDir), makeFileNameSafe(projName))
fullDir = os.path.join(os.path.abspath(projDir), makeFileNameSafe(projName))
self.projPath.setText(fullDir)
else:
self.projPath.setText("")
+38 -38
View File
@@ -29,8 +29,8 @@
import nw
import logging
import configparser
import os
from os import path, listdir
from math import ceil
from PyQt5.QtCore import Qt
@@ -182,21 +182,21 @@ class GuiTheme:
"""Add the fonts in the assets fonts folder to the app.
"""
ttfList = []
fontAssets = path.join(self.mainConf.assetPath, self.fontPath)
for fontFam in listdir(fontAssets):
fontDir = path.join(fontAssets, fontFam)
if path.isdir(fontDir):
fontAssets = os.path.join(self.mainConf.assetPath, self.fontPath)
for fontFam in os.listdir(fontAssets):
fontDir = os.path.join(fontAssets, fontFam)
if os.path.isdir(fontDir):
if fontFam not in self.guiFontDB.families():
for fontFile in listdir(fontDir):
ttfFile = path.join(fontDir, fontFile)
if path.isfile(ttfFile) and fontFile.endswith(".ttf"):
for fontFile in os.listdir(fontDir):
ttfFile = os.path.join(fontDir, fontFile)
if os.path.isfile(ttfFile) and fontFile.endswith(".ttf"):
ttfList.append(ttfFile)
for ttfFile in ttfList:
logger.verbose("Font asset: %s" % path.relpath(ttfFile))
logger.verbose("Font asset: %s" % os.path.relpath(ttfFile))
fontID = self.guiFontDB.addApplicationFont(ttfFile)
if fontID < 0:
logger.error("Failed to add font: %s" % path.relpath(ttfFile))
logger.error("Failed to add font: %s" % os.path.relpath(ttfFile))
return
@@ -227,10 +227,10 @@ class GuiTheme:
self.guiTheme = self.mainConf.guiTheme
self.guiSyntax = self.mainConf.guiSyntax
self.themeRoot = self.mainConf.themeRoot
self.themePath = path.join(self.mainConf.themeRoot, self.guiPath, self.guiTheme)
self.syntaxFile = path.join(self.themeRoot, self.syntaxPath, self.guiSyntax+".conf")
self.confFile = path.join(self.themePath, self.confName)
self.cssFile = path.join(self.themePath, self.cssName)
self.themePath = os.path.join(self.mainConf.themeRoot, self.guiPath, self.guiTheme)
self.syntaxFile = os.path.join(self.themeRoot, self.syntaxPath, self.guiSyntax+".conf")
self.confFile = os.path.join(self.themePath, self.confName)
self.cssFile = os.path.join(self.themePath, self.cssName)
self.loadTheme()
self.loadSyntax()
@@ -259,7 +259,7 @@ class GuiTheme:
# CSS File
cssData = ""
try:
if path.isfile(self.cssFile):
if os.path.isfile(self.cssFile):
with open(self.cssFile, mode="r", encoding="utf8") as inFile:
cssData = inFile.read()
except Exception as e:
@@ -375,8 +375,8 @@ class GuiTheme:
return self.themeList
confParser = configparser.ConfigParser()
for themeDir in listdir(path.join(self.mainConf.themeRoot, self.guiPath)):
themeConf = path.join(self.mainConf.themeRoot, self.guiPath, themeDir, self.confName)
for themeDir in os.listdir(os.path.join(self.mainConf.themeRoot, self.guiPath)):
themeConf = os.path.join(self.mainConf.themeRoot, self.guiPath, themeDir, self.confName)
logger.verbose("Checking theme config for '%s'" % themeDir)
try:
with open(themeConf, mode="r", encoding="utf8") as inFile:
@@ -405,10 +405,10 @@ class GuiTheme:
return self.syntaxList
confParser = configparser.ConfigParser()
syntaxDir = path.join(self.mainConf.themeRoot, self.syntaxPath)
for syntaxFile in listdir(syntaxDir):
syntaxPath = path.join(syntaxDir, syntaxFile)
if not path.isfile(syntaxPath):
syntaxDir = os.path.join(self.mainConf.themeRoot, self.syntaxPath)
for syntaxFile in os.listdir(syntaxDir):
syntaxPath = os.path.join(syntaxDir, syntaxFile)
if not os.path.isfile(syntaxPath):
continue
logger.verbose("Checking theme syntax for '%s'" % syntaxFile)
try:
@@ -612,11 +612,11 @@ class GuiIcons:
logger.debug("Loading icon theme files")
self.themeMap = {}
checkPath = path.join(self.mainConf.iconPath, self.mainConf.guiIcons)
if path.isdir(checkPath):
checkPath = os.path.join(self.mainConf.iconPath, self.mainConf.guiIcons)
if os.path.isdir(checkPath):
logger.debug("Loading icon theme '%s'" % self.mainConf.guiIcons)
self.iconPath = checkPath
self.confFile = path.join(checkPath, self.confName)
self.confFile = os.path.join(checkPath, self.confName)
else:
return False
@@ -648,8 +648,8 @@ class GuiIcons:
if iconName not in self.ICON_MAP:
logger.error("Unknown icon name '%s' in config file" % iconName)
else:
iconPath = path.join(self.iconPath, iconFile)
if path.isfile(iconPath):
iconPath = os.path.join(self.iconPath, iconFile)
if os.path.isfile(iconPath):
self.themeMap[iconName] = iconPath
logger.verbose("Icon slot '%s' using file '%s'" % (iconName, iconFile))
else:
@@ -671,10 +671,10 @@ class GuiIcons:
logger.error("Decoration with name '%s' does not exist" % decoKey)
return QPixmap()
imgPath = path.join(
imgPath = os.path.join(
self.mainConf.assetPath, "images", self.DECO_MAP[decoKey]
)
if not path.isfile(imgPath):
if not os.path.isfile(imgPath):
logger.error("Decoration file '%s' not in assets folder" % self.DECO_MAP[decoKey])
return QPixmap()
@@ -714,11 +714,11 @@ class GuiIcons:
return self.themeList
confParser = configparser.ConfigParser()
for themeDir in listdir(self.mainConf.iconPath):
themePath = path.join(self.mainConf.iconPath, themeDir)
if not path.isdir(themePath) or themeDir == self.fbackName:
for themeDir in os.listdir(self.mainConf.iconPath):
themePath = os.path.join(self.mainConf.iconPath, themeDir)
if not os.path.isdir(themePath) or themeDir == self.fbackName:
continue
themeConf = path.join(themePath, self.confName)
themeConf = os.path.join(themePath, self.confName)
logger.verbose("Checking icon theme config for '%s'" % themeDir)
try:
with open(themeConf, mode="r", encoding="utf8") as inFile:
@@ -756,12 +756,12 @@ class GuiIcons:
# If we just want the app icon, return it right away
if iconKey == "novelwriter":
return QIcon(path.join(self.mainConf.iconPath, "novelwriter.svg"))
return QIcon(os.path.join(self.mainConf.iconPath, "novelwriter.svg"))
# Otherwise, we start looking for it
# First in the theme folder
if iconKey in self.themeMap:
logger.verbose("Loading: %s" % path.relpath(self.themeMap[iconKey]))
logger.verbose("Loading: %s" % os.path.relpath(self.themeMap[iconKey]))
return QIcon(self.themeMap[iconKey])
# Next, we try to load the Qt style icons
@@ -777,14 +777,14 @@ class GuiIcons:
# Finally. we check if we have a fallback icon
if self.mainConf.guiDark:
fbackIcon = path.join(
fbackIcon = os.path.join(
self.mainConf.iconPath, self.fbackName, "%s-dark.svg" % iconKey
)
if path.isfile(fbackIcon):
if os.path.isfile(fbackIcon):
logger.verbose("Loading icon '%s' from fallback theme (dark mode)" % iconKey)
return QIcon(fbackIcon)
fbackIcon = path.join(self.mainConf.iconPath, self.fbackName, "%s.svg" % iconKey)
if path.isfile(fbackIcon):
fbackIcon = os.path.join(self.mainConf.iconPath, self.fbackName, "%s.svg" % iconKey)
if os.path.isfile(fbackIcon):
logger.verbose("Loading icon '%s' from fallback theme (light mode)" % iconKey)
return QIcon(fbackIcon)
+4 -4
View File
@@ -28,8 +28,8 @@
import nw
import logging
import json
import os
from os import path
from datetime import datetime
from PyQt5.QtCore import Qt
@@ -322,8 +322,8 @@ class GuiWritingStats(QDialog):
if fileExt:
fileName = "sessionStats.%s" % fileExt
saveDir = self.mainConf.lastPath
savePath = path.join(saveDir, fileName)
if not path.isdir(saveDir):
savePath = os.path.join(saveDir, fileName)
if not os.path.isdir(saveDir):
saveDir = self.mainConf.homePath
dlgOpt = QFileDialog.Options()
@@ -410,7 +410,7 @@ class GuiWritingStats(QDialog):
ttTime = 0
try:
logFile = path.join(self.theProject.projMeta, nwFiles.SESS_STATS)
logFile = os.path.join(self.theProject.projMeta, nwFiles.SESS_STATS)
with open(logFile, mode="r", encoding="utf8") as inFile:
for inLine in inFile:
if inLine.startswith("#"):
+2 -2
View File
@@ -27,8 +27,8 @@
import nw
import logging
import os
from os import path
from datetime import datetime
from time import time
@@ -268,7 +268,7 @@ class GuiMain(QMainWindow):
logger.error("No projData or projPath set")
return False
if path.isfile(path.join(projPath, self.theProject.projFile)):
if os.path.isfile(os.path.join(projPath, self.theProject.projFile)):
self.makeAlert(
"A project already exists in that location. Please choose another folder.",
nwAlert.ERROR