Rewrite project consistency chech as part of the tree class

This commit is contained in:
Veronica Berglyd Olsen
2023-07-21 23:56:48 +02:00
parent f0e372b2ba
commit 3753f5b829
5 changed files with 86 additions and 129 deletions
+9 -116
View File
@@ -45,7 +45,7 @@ from novelwriter.core.sessions import NWSessionLog
from novelwriter.core.projectxml import ProjectXMLReader, ProjectXMLWriter, XMLReadState
from novelwriter.core.projectdata import NWProjectData
from novelwriter.common import (
checkStringNone, formatTimeStamp, hexToInt, isHandle, makeFileNameSafe, minmax
checkStringNone, formatTimeStamp, hexToInt, makeFileNameSafe, minmax
)
logger = logging.getLogger(__name__)
@@ -75,7 +75,6 @@ class NWProject(QObject):
# Project Status
self._projChanged = False # The project has unsaved changes
self._lockedBy = None # Data on which computer has the project open
self._projFiles = [] # A list of all files in the content folder on load
# Internal Mapping
self.tr = partial(QCoreApplication.translate, "NWProject")
@@ -121,10 +120,6 @@ class NWProject(QObject):
def projChanged(self):
return self._projChanged
@property
def projFiles(self):
return self._projFiles
##
# Item Methods
##
@@ -213,9 +208,6 @@ class NWProject(QObject):
self._data = NWProjectData(self)
self._session = NWSessionLog(self)
# Project Settings
self._projFiles = []
return
def openProject(self, projPath, overrideLock=False):
@@ -330,15 +322,13 @@ class NWProject(QObject):
)
# Check the project tree consistency
for tItem in self._tree:
if tItem:
tHandle = tItem.itemHandle
logger.debug("Checking item '%s'", tHandle)
if not self._tree.updateItemData(tHandle):
logger.error("There was a problem the item, and it has been removed")
del self._tree[tHandle] # The file will be re-added as orphaned
# This also handles any orphaned files found
orphans, recovered = self._tree.checkConsistency(self.tr("Recovered"))
if orphans > 0:
self.mainGui.makeAlert(self.tr(
"Found {0} orphaned file(s) in the project. {1} file(s) were recovered."
).format(orphans, recovered), nwAlert.WARN)
self._scanProjectFolder()
self._index.loadIndex()
if xmlReader.state == XMLReadState.WAS_LEGACY:
# Often, the index needs to be rebuilt when updating format
@@ -646,9 +636,8 @@ class NWProject(QObject):
return True
def _loadProjectLocalisation(self):
"""Load the language data for the current project language.
"""
def _loadProjectLocalisation(self) -> bool:
"""Load the language data for the current project language."""
if self._data.language is None or CONFIG._nwLangPath is None:
self._langData = {}
return False
@@ -661,7 +650,6 @@ class NWProject(QObject):
with open(langFile, mode="r", encoding="utf-8") as inFile:
self._langData = json.load(inFile)
logger.debug("Loaded project language file: %s", langFile.name)
except Exception:
logger.error("Failed to project language file")
logException()
@@ -669,99 +657,4 @@ class NWProject(QObject):
return True
def _scanProjectFolder(self):
"""Scan the project folder and check that the files in it are
also in the project XML file. If they aren't, import them as
orphaned files so the user can either delete them, or put them
back into the project tree.
"""
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 item in contentPath.iterdir():
itemName = item.name
if not itemName.endswith(".nwd"):
logger.warning("Skipping file: %s", itemName)
continue
if len(itemName) != 17:
logger.warning("Skipping file: %s", itemName)
continue
fHandle = itemName[:13]
if not isHandle(fHandle):
logger.warning("Skipping file: %s", itemName)
continue
if fHandle in self._tree:
self._projFiles.append(fHandle)
logger.debug("Checking file %s, handle '%s': OK", itemName, fHandle)
else:
logger.warning("Checking file %s, handle '%s': Orphaned", itemName, fHandle)
orphanFiles.append(fHandle)
# Report status
if len(orphanFiles) > 0:
self.mainGui.makeAlert(self.tr(
"Found {0} orphaned file(s) in project folder."
).format(len(orphanFiles)), nwAlert.WARN)
else:
logger.debug("File check OK")
return
# Handle orphans
nOrph = 0
noWhere = False
oPrefix = self.tr("Recovered")
for oHandle in orphanFiles:
# Look for meta data
oName = ""
oParent = None
oClass = None
oLayout = None
aDoc = self._storage.getDocument(oHandle)
if aDoc.readDocument(isOrphan=True) is not None:
oName, oParent, oClass, oLayout = aDoc.getMeta()
if oName:
oName = self.tr("[{0}] {1}").format(
oPrefix, oName.replace("[%s]" % oPrefix, "").strip()
)
else:
nOrph += 1
oName = self.tr("Recovered File {0}").format(nOrph)
# Recover file meta data
oClass = oClass or nwItemClass.NOVEL
oLayout = oLayout or nwItemLayout.NOTE
if oParent is None or oParent not in self._tree:
oParent = self._tree.findRoot(oClass)
if oParent is None:
oParent = self._tree.findRoot(nwItemClass.NOVEL)
# If the file still has no parent item, skip it
if oParent is None:
noWhere = True
continue
nHandle = self._tree.create(oName, oParent, nwItemType.FILE, oClass, oLayout)
if nHandle is not None:
(contentPath / f"{oHandle}.nwd").rename(contentPath / f"{nHandle}.nwd")
if noWhere:
self.mainGui.makeAlert(self.tr(
"One or more orphaned files could not be added back into the project. "
"Make sure at least a Novel root folder exists."
), nwAlert.WARN)
return True
# END Class NWProject