コード例 #1
0
    def _parseMeta(self, metaLine):
        """Parse a line from the document statting with the characters
        %%~ that may contain meta data.
        """
        if metaLine.startswith("%%~name:"):
            self._docMeta["name"] = metaLine[8:].strip()

        elif metaLine.startswith("%%~path:"):
            metaVal = metaLine[8:].strip()
            metaBits = metaVal.split("/")
            if len(metaBits) == 2:
                if isHandle(metaBits[0]):
                    self._docMeta["parent"] = metaBits[0]
                if isHandle(metaBits[1]):
                    self._docMeta["handle"] = metaBits[1]

        elif metaLine.startswith("%%~kind:"):
            metaVal = metaLine[8:].strip()
            metaBits = metaVal.split("/")
            if len(metaBits) == 2:
                if metaBits[0] in nwItemClass.__members__:
                    self._docMeta["class"] = nwItemClass[metaBits[0]]
                if metaBits[1] in nwItemLayout.__members__:
                    self._docMeta["layout"] = nwItemLayout[metaBits[1]]

        else:
            logger.debug("Ignoring meta data: '%s'" % metaLine.strip())

        return
コード例 #2
0
    def deleteDocument(self, tHandle):
        """Permanently delete a document source file and related files
        from the project data folder.
        """
        if not isHandle(tHandle):
            return False

        docFile = tHandle + ".nwd"

        chkList = []
        chkList.append(os.path.join(self.theProject.projContent, docFile))
        chkList.append(os.path.join(self.theProject.projContent,
                                    docFile + "~"))

        for chkFile in chkList:
            if os.path.isfile(chkFile):
                try:
                    os.unlink(chkFile)
                    logger.debug("Deleted: %s" % chkFile)
                except Exception as e:
                    self.makeAlert(
                        [self.tr("Could not delete document file."),
                         str(e)], nwAlert.ERROR)
                    return False

        return True
コード例 #3
0
    def _checkRefIndex(self):
        """Scan the reference index for errors.
        Waring: This function raises exceptions.
        """
        for tHandle in self._refIndex:
            if not isHandle(tHandle):
                raise KeyError("refIndex key is not a handle")

            hEntry = self._refIndex[tHandle]
            for sTitle in hEntry:
                if not isTitleTag(sTitle):
                    raise KeyError("refIndex[a] key is not a title tag")

                sEntry = hEntry[sTitle]
                if "tags" not in sEntry:
                    raise KeyError("refIndex[a][b] has no 'tag' key")
                for tEntry in sEntry["tags"]:
                    if len(tEntry) != 3:
                        raise IndexError("refIndex[a][b][tags][i] expected 3 values")
                    if not isinstance(tEntry[0], int):
                        raise ValueError("refIndex[a][b][tags][i][0] is not an integer")
                    if not tEntry[1] in nwKeyWords.VALID_KEYS:
                        raise ValueError("refIndex[a][b][tags][i][1] is not a keyword")
                    if not isinstance(tEntry[2], str):
                        raise ValueError("refIndex[a][b][tags][i][2] is not a string")

                if "updated" not in sEntry:
                    raise KeyError("refIndex[a][b] has no 'updated' key")
                if not isinstance(sEntry["updated"], int):
                    raise ValueError("%refIndex[a][b][updated] is not an integer")

        return
コード例 #4
0
    def _checkNovelNoteIndex(self, idxName):
        """Scan the novel or note index for errors.
        Waring: This function raises exceptions.
        """
        if idxName == "novelIndex":
            theIndex = self._novelIndex
        elif idxName == "noteIndex":
            theIndex = self._noteIndex
        else:
            raise IndexError("Unknown index %s" % idxName)

        for tHandle in theIndex:
            if not isHandle(tHandle):
                raise KeyError("%s key is not a handle" % idxName)

            hEntry = theIndex[tHandle]
            for sTitle in theIndex[tHandle]:
                if not isTitleTag(sTitle):
                    raise KeyError("%s[a] key is not a title tag" % idxName)

                sEntry = hEntry[sTitle]
                if len(sEntry) != 8:
                    raise IndexError("%s[a][b] expected 8 values" % idxName)

                if "level" not in sEntry:
                    raise KeyError("%s[a][b] has no 'level' key" % idxName)
                if "title" not in sEntry:
                    raise KeyError("%s[a][b] has no 'title' key" % idxName)
                if "layout" not in sEntry:
                    raise KeyError("%s[a][b] has no 'layout' key" % idxName)
                if "synopsis" not in sEntry:
                    raise KeyError("%s[a][b] has no 'synopsis' key" % idxName)
                if "cCount" not in sEntry:
                    raise KeyError("%s[a][b] has no 'cCount' key" % idxName)
                if "wCount" not in sEntry:
                    raise KeyError("%s[a][b] has no 'wCount' key" % idxName)
                if "pCount" not in sEntry:
                    raise KeyError("%s[a][b] has no 'pCount' key" % idxName)
                if "updated" not in sEntry:
                    raise KeyError("%s[a][b] has no 'updated' key" % idxName)

                if not sEntry["level"] in self.H_VALID:
                    raise ValueError("%s[a][b][level] is not a header level" % idxName)
                if not isinstance(sEntry["title"], str):
                    raise ValueError("%s[a][b][title] is not a string" % idxName)
                if not isItemLayout(sEntry["layout"]):
                    raise ValueError("%s[a][b][layout] is not an nwItemLayout" % idxName)
                if not isinstance(sEntry["synopsis"], str):
                    raise ValueError("%s[a][b][synopsis] is not a string" % idxName)
                if not isinstance(sEntry["cCount"], int):
                    raise ValueError("%s[a][b][cCount] is not an integer" % idxName)
                if not isinstance(sEntry["wCount"], int):
                    raise ValueError("%s[a][b][wCount] is not an integer" % idxName)
                if not isinstance(sEntry["pCount"], int):
                    raise ValueError("%s[a][b][pCount] is not an integer" % idxName)
                if not isinstance(sEntry["updated"], int):
                    raise ValueError("%s[a][b][updated] is not an integer" % idxName)

        return
コード例 #5
0
 def setHandle(self, theHandle):
     """Set the item handle, and ensure it is valid.
     """
     if isinstance(theHandle, str):
         if isHandle(theHandle):
             self.itemHandle = theHandle
         else:
             self.itemHandle = None
     else:
         self.itemHandle = None
     return
コード例 #6
0
 def setParent(self, theParent):
     """Set the parent handle, and ensure that it is valid.
     """
     if theParent is None:
         self.itemParent = None
     elif isinstance(theParent, str):
         if isHandle(theParent):
             self.itemParent = theParent
         else:
             self.itemParent = None
     else:
         self.itemParent = None
     return
コード例 #7
0
def testBaseCommon_IsHandle():
    """Test the isHandle function.
    """
    assert isHandle("47666c91c7ccf")

    assert not isHandle("47666C91C7CCF")
    assert not isHandle("h7666c91c7ccf")
    assert not isHandle("None")
    assert not isHandle(None)
    assert not isHandle("STUFF")
コード例 #8
0
    def _checkTextCounts(self):
        """Scan the text counts index for errors.
        Waring: This function raises exceptions.
        """
        for tHandle in self._textCounts:
            if not isHandle(tHandle):
                raise KeyError("textCounts key is not a handle")

            tEntry = self._textCounts[tHandle]
            if len(tEntry) != 3:
                raise IndexError("textCounts[a] expected 3 values")
            if not isinstance(tEntry[0], int):
                raise ValueError("textCounts[a][0] is not an integer")
            if not isinstance(tEntry[1], int):
                raise ValueError("textCounts[a][1] is not an integer")
            if not isinstance(tEntry[2], int):
                raise ValueError("textCounts[a][2] is not an integer")

        return
コード例 #9
0
    def _checkTagIndex(self):
        """Scan the tag index for errors.
        Waring: This function raises exceptions.
        """
        for tTag in self._tagIndex:
            if not isinstance(tTag, str):
                raise KeyError("tagIndex key is not a string")

            tEntry = self._tagIndex[tTag]
            if len(tEntry) != 4:
                raise IndexError("tagIndex[a] expected 4 values")
            if not isinstance(tEntry[0], int):
                raise ValueError("tagIndex[a][0] is not an integer")
            if not isHandle(tEntry[1]):
                raise ValueError("tagIndex[a][1] is not a handle")
            if not isItemClass(tEntry[2]):
                raise ValueError("tagIndex[a][2] is not an nwItemClass")
            if not isTitleTag(tEntry[3]):
                raise ValueError("tagIndex[a][3] is not a title tag")

        return
コード例 #10
0
    def openDocument(self, tHandle, showStatus=True, isOrphan=False):
        """Open a document from handle, capturing potential file system
        errors and parse meta data. If the document doesn't exist on
        disk, return an empty string. If something went wrong, return
        None.
        """
        if not isHandle(tHandle):
            return None

        # Always clear first, since the object will often be reused.
        self.clearDocument()

        self._docHandle = tHandle
        if not isOrphan:
            self._theItem = self.theProject.projTree[tHandle]
        else:
            self._theItem = None

        if self._theItem is None and not isOrphan:
            self.clearDocument()
            return None

        docFile = self._docHandle + ".nwd"
        logger.debug("Opening document %s" % docFile)

        docPath = os.path.join(self.theProject.projContent, docFile)
        self._fileLoc = docPath

        theText = ""
        self._docMeta = {}
        if os.path.isfile(docPath):
            try:
                with open(docPath, mode="r", encoding="utf8") as inFile:

                    # Check the first <= 10 lines for metadata
                    for i in range(10):
                        inLine = inFile.readline()
                        if inLine.startswith(r"%%~"):
                            self._parseMeta(inLine)
                        else:
                            theText = inLine
                            break

                    # Load the rest of the file
                    theText += inFile.read()

            except Exception as e:
                self.makeAlert(
                    [self.tr("Failed to open document file."),
                     str(e)], nwAlert.ERROR)
                # Note: Document must be cleared in case of an io error,
                # or else the auto-save or save will try to overwrite it
                # with an empty file. Return None to alert the caller.
                self.clearDocument()
                return None
        else:
            # The document file does not exist, so we assume it's a new
            # document and initialise an empty text string.
            logger.debug("The requested document does not exist.")
            return ""

        if showStatus and not isOrphan:
            self.theParent.setStatus(
                self.tr("Opened Document: {0}").format(self._theItem.itemName))

        return theText