Remove project content attribute from project class

This commit is contained in:
Veronica Berglyd Olsen
2022-11-06 00:15:24 +01:00
parent 972ed25a8c
commit 76a1421fde
10 changed files with 104 additions and 127 deletions
+33 -23
View File
@@ -23,9 +23,10 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import os
import logging
from pathlib import Path
from novelwriter.enum import nwItemLayout, nwItemClass
from novelwriter.error import formatException
from novelwriter.common import isHandle, sha256sum
@@ -73,7 +74,7 @@ class NWDoc:
empty string. If something went wrong, return None.
"""
self._docError = ""
if self._docHandle is None:
if not isinstance(self._docHandle, str):
logger.error("No document handle set")
return None
@@ -81,17 +82,22 @@ class NWDoc:
logger.error("Unknown novelWriter document")
return None
contentPath = self.theProject.storage.contentPath
if not isinstance(contentPath, Path):
logger.error("No content path set")
return None
docFile = self._docHandle+".nwd"
logger.debug("Opening document: %s", docFile)
docPath = os.path.join(self.theProject.projContent, docFile)
docPath = contentPath / docFile
self._fileLoc = docPath
theText = ""
self._docMeta = {}
self._prevHash = None
if os.path.isfile(docPath):
if docPath.exists():
self._prevHash = sha256sum(docPath)
try:
with open(docPath, mode="r", encoding="utf-8") as inFile:
@@ -125,17 +131,20 @@ class NWDoc:
if not.
"""
self._docError = ""
if self._docHandle is None:
if not isinstance(self._docHandle, str):
logger.error("No document handle set")
return False
self.theProject.ensureFolderStructure()
contentPath = self.theProject.storage.contentPath
if not isinstance(contentPath, Path):
logger.error("No content path set")
return None
docFile = self._docHandle+".nwd"
logger.debug("Saving document: %s", docFile)
docPath = os.path.join(self.theProject.projContent, docFile)
docTemp = os.path.join(self.theProject.projContent, docFile+"~")
docPath = contentPath / docFile
docTemp = docPath.with_suffix(".tmp")
if self._prevHash is not None and not forceWrite:
self._currHash = sha256sum(docPath)
@@ -164,7 +173,7 @@ class NWDoc:
# If we're here, the file was successfully saved, so we can
# replace the temp file with the actual file
try:
os.replace(docTemp, docPath)
docTemp.replace(docPath)
except OSError as exc:
self._docError = formatException(exc)
return False
@@ -179,23 +188,24 @@ class NWDoc:
from the project data folder.
"""
self._docError = ""
if self._docHandle is None:
if not isinstance(self._docHandle, str):
logger.error("No document handle set")
return False
chkList = [
os.path.join(self.theProject.projContent, f"{self._docHandle}.nwd"),
os.path.join(self.theProject.projContent, f"{self._docHandle}.nwd~"),
]
contentPath = self.theProject.storage.contentPath
if not isinstance(contentPath, Path):
logger.error("No content path set")
return None
for chkFile in chkList:
if os.path.isfile(chkFile):
try:
os.unlink(chkFile)
logger.debug("Deleted: %s", chkFile)
except Exception as exc:
self._docError = formatException(exc)
return False
docPath = contentPath / f"{self._docHandle}.nwd"
docTemp = docPath.with_suffix(".tmp")
try:
docPath.unlink(missing_ok=True)
docTemp.unlink(missing_ok=True)
except Exception as exc:
self._docError = formatException(exc)
return False
return True
@@ -206,7 +216,7 @@ class NWDoc:
def getFileLocation(self):
"""Return the file location of the current document.
"""
return self._fileLoc
return str(self._fileLoc)
def getCurrentItem(self):
"""Return a pointer to the currently open NWItem.
+20 -38
View File
@@ -27,12 +27,12 @@ from __future__ import annotations
import os
import json
from pathlib import Path
import shutil
import logging
import novelwriter
from time import time
from pathlib import Path
from functools import partial
from PyQt5.QtCore import QCoreApplication, QObject, pyqtSignal
@@ -84,10 +84,9 @@ class NWProject(QObject):
self.lockedBy = None # Data on which computer has the project open
# Class Settings
self.projPath = None # The full path to where the currently open project is saved
self.projContent = None # The full path to the project's content folder
self.projDict = None # The spell check dictionary
self.projFiles = [] # A list of all files in the content folder on load
self.projPath = None # The full path to where the currently open project is saved
self.projDict = None # The spell check dictionary
self.projFiles = [] # A list of all files in the content folder on load
# Internal Mapping
self.tr = partial(QCoreApplication.translate, "NWProject")
@@ -252,10 +251,9 @@ class NWProject(QObject):
self._data = NWProjectData(self)
# Project Settings
self.projPath = None
self.projContent = None
self.projDict = None
self.projFiles = []
self.projPath = None
self.projDict = None
self.projFiles = []
return
@@ -271,7 +269,6 @@ class NWProject(QObject):
# ToDo: These should not be set explicitly, and should stay as Path
self.projPath = str(self._storage.runtimePath)
self.projContent = str(self._storage.contentPath)
logger.info("Opening project: %s", self.projPath)
@@ -468,24 +465,6 @@ class NWProject(QObject):
self.lockedBy = None
return True
def ensureFolderStructure(self):
"""Ensure that all necessary folders exist in the project
folder.
"""
if self.projPath is None or self.projPath == "":
return False
self.projContent = os.path.join(self.projPath, "content")
if self.projPath == os.path.expanduser("~"):
# Don't make a mess in the user's home folder
return False
if not self._checkFolder(self.projContent):
return False
return True
def setDefaultStatusImport(self):
"""Set the default status and importance values.
"""
@@ -790,31 +769,34 @@ class NWProject(QObject):
orphaned files so the user can either delete them, or put them
back into the project tree.
"""
if self.projPath is None:
contentPath = self._storage.contentPath
if not isinstance(contentPath, Path):
return False
# Then check the files in the data folder
logger.debug("Checking files in project content folder")
orphanFiles = []
self.projFiles = []
for fileItem in os.listdir(self.projContent):
if not fileItem.endswith(".nwd"):
logger.warning("Skipping file: %s", fileItem)
for item in contentPath.iterdir():
itemName = item.name
if not itemName.endswith(".nwd"):
logger.warning("Skipping file: %s", itemName)
continue
if len(fileItem) != 17:
logger.warning("Skipping file: %s", fileItem)
if len(itemName) != 17:
logger.warning("Skipping file: %s", itemName)
continue
fHandle = fileItem[:13]
fHandle = itemName[:13]
if not isHandle(fHandle):
logger.warning("Skipping file: %s", fileItem)
logger.warning("Skipping file: %s", itemName)
continue
if fHandle in self._tree:
self.projFiles.append(fHandle)
logger.debug("Checking file %s, handle '%s': OK", fileItem, fHandle)
logger.debug("Checking file %s, handle '%s': OK", itemName, fHandle)
else:
logger.warning("Checking file %s, handle '%s': Orphaned", fileItem, fHandle)
logger.warning("Checking file %s, handle '%s': Orphaned", itemName, fHandle)
orphanFiles.append(fHandle)
# Report status
+2
View File
@@ -151,6 +151,8 @@ class NWStorage:
return xmlWriter
def getDocument(self, tHandle):
"""Return a document wrapper object.
"""
pass
def getMetaFile(self, fileName):
+11 -4
View File
@@ -23,10 +23,11 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import os
import random
import logging
from pathlib import Path
from novelwriter.enum import nwItemClass, nwItemLayout
from novelwriter.error import logException
from novelwriter.common import checkHandle
@@ -140,16 +141,22 @@ class NWTree:
"""Write the convenience table of contents file in the root of
the project directory.
"""
runtimePath = self.theProject.storage.runtimePath
contentPath = self.theProject.storage.contentPath
if not (isinstance(contentPath, Path) and isinstance(runtimePath, Path)):
return False
tocList = []
tocLen = 0
for tHandle in self._treeOrder:
tItem = self.__getitem__(tHandle)
if tItem is None:
continue
tFile = tHandle+".nwd"
if os.path.isfile(os.path.join(self.theProject.projContent, tFile)):
if (contentPath / tFile).is_file():
tocLine = "{0:<25s} {1:<9s} {2:<8s} {3:s}".format(
os.path.join("content", tFile),
str(Path("content") / tFile),
tItem.itemClass.name,
tItem.itemLayout.name,
tItem.itemName,
@@ -159,7 +166,7 @@ class NWTree:
try:
# Dump the text
tocText = os.path.join(self.theProject.projPath, nwFiles.TOC_TXT)
tocText = runtimePath / nwFiles.TOC_TXT
with open(tocText, mode="w", encoding="utf-8") as outFile:
outFile.write("\n")
outFile.write("Table of Contents\n")