Remove project content attribute from project class
This commit is contained in:
@@ -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
@@ -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
|
||||
|
||||
@@ -151,6 +151,8 @@ class NWStorage:
|
||||
return xmlWriter
|
||||
|
||||
def getDocument(self, tHandle):
|
||||
"""Return a document wrapper object.
|
||||
"""
|
||||
pass
|
||||
|
||||
def getMetaFile(self, fileName):
|
||||
|
||||
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user