Can now restore document label for orphaned files

This commit is contained in:
Veronica K. B. Olsen
2020-05-09 13:59:57 +02:00
parent d44dca6a21
commit 75adcdf679
4 changed files with 82 additions and 14 deletions
+17
View File
@@ -77,6 +77,20 @@ def checkBool(checkValue, defaultValue, allowNone=False):
return defaultValue return defaultValue
return defaultValue return defaultValue
def isHandle(theString):
"""Check if a string is a valid novelWriter handle.
Note: This is case sensitive. Must be lower case!
"""
if not isinstance(theString, str):
return False
if len(theString) != 13:
return False
invalidChar = False
for c in theString:
if c not in "0123456789abcdef":
invalidChar = True
return not invalidChar
def colRange(rgbStart, rgbEnd, nStep): def colRange(rgbStart, rgbEnd, nStep):
if len(rgbStart) != 3 and len(rgbEnd) != 3 and nStep < 1: if len(rgbStart) != 3 and len(rgbEnd) != 3 and nStep < 1:
@@ -127,6 +141,9 @@ def formatInt(theInt):
return "%d" % theInt return "%d" % theInt
def formatTimeStamp(theTime, fileSafe=False): def formatTimeStamp(theTime, fileSafe=False):
"""Take a number (on the format returned by time.time()) and convert
it to a timestamp string.
"""
if fileSafe: if fileSafe:
return datetime.fromtimestamp(theTime).strftime(nwConst.fStampFmt) return datetime.fromtimestamp(theTime).strftime(nwConst.fStampFmt)
else: else:
+52 -11
View File
@@ -31,6 +31,7 @@ import nw
from os import path, mkdir, rename, unlink from os import path, mkdir, rename, unlink
from nw.constants import nwAlert from nw.constants import nwAlert
from nw.common import isHandle
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -68,25 +69,29 @@ class NWDoc():
self.docMeta = "" self.docMeta = ""
return return
def openDocument(self, tHandle, showStatus=True): def openDocument(self, tHandle, showStatus=True, isOrphan=False):
"""Open a document from handle, capturing potential file system """Open a document from handle, capturing potential file system
errors and parse meta data. errors and parse meta data.
""" """
self.docHandle = tHandle self.docHandle = tHandle
self.theItem = self.theProject.projTree[tHandle] if not isOrphan:
self.theItem = self.theProject.projTree[tHandle]
else:
self.theItem = None
if self.theItem is None: if self.theItem is None and not isOrphan:
self.clearDocument() self.clearDocument()
return None return None
# By default, the document is editable. # By default, the document is editable.
# Except for files in the trash folder. # Except for files in the trash folder.
self.docEditable = True self.docEditable = True
if self.theItem.parHandle == self.theProject.projTree.trashRoot(): if self.theItem is not None:
self.docEditable = False if self.theItem.parHandle == self.theProject.projTree.trashRoot():
self.docEditable = False
docDir, docFile = self.assemblePath(self.docHandle, self.FILE_MN) docDir, docFile = self._assemblePath(self.docHandle, self.FILE_MN)
self.fileLoc = path.join(docDir,docFile) self.fileLoc = path.join(docDir,docFile)
logger.debug("Opening document %s" % self.fileLoc) logger.debug("Opening document %s" % self.fileLoc)
dataDir = path.join(self.theProject.projPath, docDir) dataDir = path.join(self.theProject.projPath, docDir)
@@ -100,7 +105,7 @@ class NWDoc():
fstLine = inFile.readline() fstLine = inFile.readline()
if fstLine.startswith("%%~ "): if fstLine.startswith("%%~ "):
# This is the meta line # This is the meta line
self.docMeta = fstLine.strip() self.docMeta = fstLine[4:].strip()
else: else:
theText = fstLine theText = fstLine
theText += inFile.read() theText += inFile.read()
@@ -120,7 +125,7 @@ class NWDoc():
logger.verbose("DocMeta: '%s'" % self.docMeta) logger.verbose("DocMeta: '%s'" % self.docMeta)
if showStatus: if showStatus and not isOrphan:
self.theParent.statusBar.setStatus("Opened Document: %s" % self.theItem.itemName) self.theParent.statusBar.setStatus("Opened Document: %s" % self.theItem.itemName)
return theText return theText
@@ -133,7 +138,7 @@ class NWDoc():
if self.docHandle is None or not self.docEditable: if self.docHandle is None or not self.docEditable:
return False return False
docDir, docFile = self.assemblePath(self.docHandle, self.FILE_MN) docDir, docFile = self._assemblePath(self.docHandle, self.FILE_MN)
logger.debug("Saving document %s" % path.join(docDir,docFile)) logger.debug("Saving document %s" % path.join(docDir,docFile))
dataPath = path.join(self.theProject.projPath, docDir) dataPath = path.join(self.theProject.projPath, docDir)
docPath = path.join(dataPath, docFile) docPath = path.join(dataPath, docFile)
@@ -171,7 +176,7 @@ class NWDoc():
"""Permanently delete a document source file and its backups """Permanently delete a document source file and its backups
from the project data folder. from the project data folder.
""" """
docDir, docFile = self.assemblePath(tHandle, self.FILE_MN) docDir, docFile = self._assemblePath(tHandle, self.FILE_MN)
dataPath = path.join(self.theProject.projPath, docDir) dataPath = path.join(self.theProject.projPath, docDir)
chkList = [] chkList = []
chkList.append(path.join(dataPath, docFile)) chkList.append(path.join(dataPath, docFile))
@@ -187,8 +192,44 @@ class NWDoc():
return False return False
return True return True
##
# Getters
##
def getMeta(self):
"""Parses the document meta tag and returns the path and name as
a list and a string.
"""
if len(self.docMeta) < 14:
# Not enough information
return "", []
theMeta = self.docMeta
# Scan for handles
thePath = []
for n in range(200):
if len(theMeta) < 14:
break
if theMeta[13] == ":":
theHandle = theMeta[:13]
if isHandle(theHandle):
thePath.append(theHandle)
theMeta = theMeta[14:]
else:
break
else:
break
return theMeta, thePath
##
# Internal Functions
##
@staticmethod @staticmethod
def assemblePath(tHandle, docExt): def _assemblePath(tHandle, docExt):
if tHandle is None: if tHandle is None:
return None, None return None, None
docDir = "data_"+tHandle[0] docDir = "data_"+tHandle[0]
+12 -2
View File
@@ -41,6 +41,7 @@ from shutil import make_archive
from nw.gui.tools import OptionState from nw.gui.tools import OptionState
from nw.core.tools import projectMaintenance from nw.core.tools import projectMaintenance
from nw.core.document import NWDoc
from nw.common import checkString, checkBool, checkInt, formatTimeStamp from nw.common import checkString, checkBool, checkInt, formatTimeStamp
from nw.constants import ( from nw.constants import (
nwFiles, nwConst, nwItemType, nwItemClass, nwItemLayout, nwAlert nwFiles, nwConst, nwItemType, nwItemClass, nwItemLayout, nwAlert
@@ -913,11 +914,20 @@ class NWProject():
return return
# Handle orphans # Handle orphans
aDoc = NWDoc(self, self.theParent)
nOrph = 0 nOrph = 0
for oHandle in orphanFiles: for oHandle in orphanFiles:
nOrph += 1
# Look for meta data
if aDoc.openDocument(oHandle, showStatus=False, isOrphan=True):
oName, oPath = aDoc.getMeta()
aDoc.clearDocument()
else:
nOrph += 1
oName = "Orphaned File %d" % nOrph
orphItem = NWItem(self) orphItem = NWItem(self)
orphItem.setName("Orphaned File %d" % nOrph) orphItem.setName(oName)
orphItem.setType(nwItemType.FILE) orphItem.setType(nwItemType.FILE)
orphItem.setClass(nwItemClass.NO_CLASS) orphItem.setClass(nwItemClass.NO_CLASS)
orphItem.setLayout(nwItemLayout.NO_LAYOUT) orphItem.setLayout(nwItemLayout.NO_LAYOUT)
+1 -1
View File
@@ -404,7 +404,7 @@ class GuiMain(QMainWindow):
else: else:
return False return False
# project is loaded # Project is loaded
self.hasProject = True self.hasProject = True
# Load the tag index # Load the tag index