Index Updates (#840)
* Improve the index keyword checker function * Implement a more compact indented JSON encoder * Remove timestamp from reference, novel and note indices * Remove empty entries in reference index * Merge novel and note indices into a single file index
This commit is contained in:
committed by
GitHub
parent
e5c715695e
commit
c6973043e6
+127
-197
@@ -32,18 +32,20 @@ import os
|
||||
from time import time
|
||||
|
||||
from nw.enum import nwItemType, nwItemClass, nwItemLayout
|
||||
from nw.common import isHandle, isTitleTag, isItemClass, isItemLayout
|
||||
from nw.constants import nwFiles, nwKeyWords, nwUnicode
|
||||
from nw.core.document import NWDoc
|
||||
from nw.common import (
|
||||
isHandle, isTitleTag, isItemClass, isItemLayout, jsonEncode
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
H_VALID = ("H0", "H1", "H2", "H3", "H4")
|
||||
H_LEVEL = {"H0": 0, "H1": 1, "H2": 2, "H3": 3, "H4": 4}
|
||||
|
||||
|
||||
class NWIndex():
|
||||
|
||||
H_VALID = ("H0", "H1", "H2", "H3", "H4")
|
||||
H_LEVEL = {"H0": 0, "H1": 1, "H2": 2, "H3": 3, "H4": 4}
|
||||
|
||||
def __init__(self, theProject):
|
||||
|
||||
# Internal
|
||||
@@ -54,8 +56,7 @@ class NWIndex():
|
||||
# Indices
|
||||
self._tagIndex = {}
|
||||
self._refIndex = {}
|
||||
self._novelIndex = {}
|
||||
self._noteIndex = {}
|
||||
self._fileIndex = {}
|
||||
self._textCounts = {}
|
||||
|
||||
# TimeStamps
|
||||
@@ -74,8 +75,7 @@ class NWIndex():
|
||||
"""
|
||||
self._tagIndex = {}
|
||||
self._refIndex = {}
|
||||
self._novelIndex = {}
|
||||
self._noteIndex = {}
|
||||
self._fileIndex = {}
|
||||
self._textCounts = {}
|
||||
self._timeNovel = 0
|
||||
self._timeNotes = 0
|
||||
@@ -96,8 +96,7 @@ class NWIndex():
|
||||
self._tagIndex.pop(tTag, None)
|
||||
|
||||
self._refIndex.pop(tHandle, None)
|
||||
self._novelIndex.pop(tHandle, None)
|
||||
self._noteIndex.pop(tHandle, None)
|
||||
self._fileIndex.pop(tHandle, None)
|
||||
self._textCounts.pop(tHandle, None)
|
||||
|
||||
return
|
||||
@@ -146,12 +145,14 @@ class NWIndex():
|
||||
"""
|
||||
theData = {}
|
||||
indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
|
||||
tStart = time()
|
||||
|
||||
if os.path.isfile(indexFile):
|
||||
logger.debug("Loading index file")
|
||||
try:
|
||||
with open(indexFile, mode="r", encoding="utf-8") as inFile:
|
||||
theData = json.load(inFile)
|
||||
|
||||
except Exception:
|
||||
logger.error("Failed to load index file")
|
||||
nw.logException()
|
||||
@@ -160,8 +161,7 @@ class NWIndex():
|
||||
|
||||
self._tagIndex = theData.get("tagIndex", {})
|
||||
self._refIndex = theData.get("refIndex", {})
|
||||
self._novelIndex = theData.get("novelIndex", {})
|
||||
self._noteIndex = theData.get("noteIndex", {})
|
||||
self._fileIndex = theData.get("fileIndex", {})
|
||||
self._textCounts = theData.get("textCounts", {})
|
||||
|
||||
nowTime = round(time())
|
||||
@@ -169,6 +169,8 @@ class NWIndex():
|
||||
self._timeNotes = nowTime
|
||||
self._timeIndex = nowTime
|
||||
|
||||
logger.verbose("Index loaded in %.3f ms", (time() - tStart)*1000)
|
||||
|
||||
self.checkIndex()
|
||||
|
||||
return True
|
||||
@@ -179,21 +181,24 @@ class NWIndex():
|
||||
"""
|
||||
logger.debug("Saving index file")
|
||||
indexFile = os.path.join(self.theProject.projMeta, nwFiles.INDEX_FILE)
|
||||
tStart = time()
|
||||
|
||||
try:
|
||||
with open(indexFile, mode="w+", encoding="utf-8") as outFile:
|
||||
json.dump({
|
||||
"tagIndex": self._tagIndex,
|
||||
"refIndex": self._refIndex,
|
||||
"novelIndex": self._novelIndex,
|
||||
"noteIndex": self._noteIndex,
|
||||
"textCounts": self._textCounts,
|
||||
}, outFile, indent=2)
|
||||
outFile.write("{\n")
|
||||
outFile.write(f'"tagIndex": {jsonEncode(self._tagIndex, nmax=1)},\n')
|
||||
outFile.write(f'"refIndex": {jsonEncode(self._refIndex, nmax=2)},\n')
|
||||
outFile.write(f'"fileIndex": {jsonEncode(self._fileIndex, nmax=2)},\n')
|
||||
outFile.write(f'"textCounts": {jsonEncode(self._textCounts, nmax=1)}\n')
|
||||
outFile.write("}\n")
|
||||
|
||||
except Exception:
|
||||
logger.error("Failed to save index file")
|
||||
nw.logException()
|
||||
return False
|
||||
|
||||
logger.verbose("Index saved in %.3f ms", (time() - tStart)*1000)
|
||||
|
||||
return True
|
||||
|
||||
def checkIndex(self):
|
||||
@@ -206,8 +211,7 @@ class NWIndex():
|
||||
try:
|
||||
self._checkTagIndex()
|
||||
self._checkRefIndex()
|
||||
self._checkNovelNoteIndex("novelIndex")
|
||||
self._checkNovelNoteIndex("noteIndex")
|
||||
self._checkFileIndex()
|
||||
self._checkTextCounts()
|
||||
self.indexBroken = False
|
||||
|
||||
@@ -216,8 +220,7 @@ class NWIndex():
|
||||
nw.logException()
|
||||
self.indexBroken = True
|
||||
|
||||
tEnd = time()
|
||||
logger.debug("Index check took %.3f ms", (tEnd - tStart)*1000)
|
||||
logger.verbose("Index check took %.3f ms", (time() - tStart)*1000)
|
||||
logger.debug("Index check complete")
|
||||
|
||||
if self.indexBroken:
|
||||
@@ -268,21 +271,9 @@ class NWIndex():
|
||||
|
||||
logger.debug("Indexing item with handle '%s'", tHandle)
|
||||
|
||||
# Check file type, and reset its old index
|
||||
# Also add a default entry T000000 in case the file has no title
|
||||
self._refIndex[tHandle] = {}
|
||||
self._refIndex[tHandle]["T000000"] = {
|
||||
"tags": [],
|
||||
"updated": round(time()),
|
||||
}
|
||||
if itemLayout == nwItemLayout.NOTE:
|
||||
self._novelIndex.pop(tHandle, None)
|
||||
self._noteIndex[tHandle] = {}
|
||||
isNovel = False
|
||||
else:
|
||||
self._novelIndex[tHandle] = {}
|
||||
self._noteIndex.pop(tHandle, None)
|
||||
isNovel = True
|
||||
# Delete or reset old entries for the file
|
||||
self._refIndex.pop(tHandle, None)
|
||||
self._fileIndex[tHandle] = {}
|
||||
|
||||
# Also clear references to file in tag index
|
||||
clearTags = []
|
||||
@@ -292,6 +283,7 @@ class NWIndex():
|
||||
for aTag in clearTags:
|
||||
self._tagIndex.pop(aTag)
|
||||
|
||||
# Scan the text content
|
||||
nLine = 0
|
||||
nTitle = 0
|
||||
theLines = theText.splitlines()
|
||||
@@ -302,11 +294,11 @@ class NWIndex():
|
||||
continue
|
||||
|
||||
if aLine.startswith("#"):
|
||||
isTitle = self._indexTitle(tHandle, isNovel, aLine, nLine, itemLayout)
|
||||
isTitle = self._indexTitle(tHandle, aLine, nLine, itemLayout)
|
||||
if isTitle and nLine > 0:
|
||||
if nTitle > 0:
|
||||
lastText = "\n".join(theLines[nTitle-1:nLine-1])
|
||||
self._indexWordCounts(tHandle, isNovel, lastText, nTitle)
|
||||
self._indexWordCounts(tHandle, lastText, nTitle)
|
||||
nTitle = nLine
|
||||
|
||||
elif aLine.startswith("@"):
|
||||
@@ -320,25 +312,25 @@ class NWIndex():
|
||||
cLen = len(toCheck)
|
||||
cOff = tLen - cLen
|
||||
if synTag == "synopsis:":
|
||||
self._indexSynopsis(tHandle, isNovel, aLine[cOff+9:].strip(), nTitle)
|
||||
self._indexSynopsis(tHandle, aLine[cOff+9:].strip(), nTitle)
|
||||
|
||||
# Count words for remaining text after last heading
|
||||
if nTitle > 0:
|
||||
lastText = "\n".join(theLines[nTitle-1:])
|
||||
self._indexWordCounts(tHandle, isNovel, lastText, nTitle)
|
||||
self._indexWordCounts(tHandle, lastText, nTitle)
|
||||
|
||||
# Index page with no titles and references
|
||||
if nTitle == 0:
|
||||
self._indexPage(tHandle, isNovel, itemLayout)
|
||||
self._indexWordCounts(tHandle, isNovel, theText, nTitle)
|
||||
self._indexPage(tHandle, itemLayout)
|
||||
self._indexWordCounts(tHandle, theText, nTitle)
|
||||
|
||||
# Update timestamps for index changes
|
||||
nowTime = round(time())
|
||||
self._timeIndex = nowTime
|
||||
if isNovel:
|
||||
self._timeNovel = nowTime
|
||||
else:
|
||||
if itemLayout == nwItemLayout.NOTE:
|
||||
self._timeNotes = nowTime
|
||||
else:
|
||||
self._timeNovel = nowTime
|
||||
|
||||
return True
|
||||
|
||||
@@ -346,7 +338,7 @@ class NWIndex():
|
||||
# Internal Indexers
|
||||
##
|
||||
|
||||
def _indexTitle(self, tHandle, isNovel, aLine, nLine, itemLayout):
|
||||
def _indexTitle(self, tHandle, aLine, nLine, itemLayout):
|
||||
"""Save information about the title and its location in the
|
||||
file to the index.
|
||||
"""
|
||||
@@ -366,89 +358,52 @@ class NWIndex():
|
||||
return False
|
||||
|
||||
sTitle = "T%06d" % nLine
|
||||
self._refIndex[tHandle][sTitle] = {
|
||||
"tags": [],
|
||||
"updated": round(time()),
|
||||
}
|
||||
theData = {
|
||||
self._fileIndex[tHandle][sTitle] = {
|
||||
"level": hDepth,
|
||||
"title": hText,
|
||||
"layout": itemLayout.name,
|
||||
"synopsis": "",
|
||||
"cCount": 0,
|
||||
"wCount": 0,
|
||||
"pCount": 0,
|
||||
"updated": round(time()),
|
||||
"synopsis": "",
|
||||
}
|
||||
|
||||
if hText != "":
|
||||
if isNovel:
|
||||
if tHandle in self._novelIndex:
|
||||
self._novelIndex[tHandle][sTitle] = theData
|
||||
else:
|
||||
if tHandle in self._noteIndex:
|
||||
self._noteIndex[tHandle][sTitle] = theData
|
||||
|
||||
return True
|
||||
|
||||
def _indexPage(self, tHandle, isNovel, itemLayout):
|
||||
def _indexPage(self, tHandle, itemLayout):
|
||||
"""Index a page with no title.
|
||||
"""
|
||||
theData = {
|
||||
self._fileIndex[tHandle]["T000000"] = {
|
||||
"level": "H0",
|
||||
"title": "Untitled Page",
|
||||
"title": "",
|
||||
"layout": itemLayout.name,
|
||||
"synopsis": "",
|
||||
"cCount": 0,
|
||||
"wCount": 0,
|
||||
"pCount": 0,
|
||||
"updated": round(time()),
|
||||
"synopsis": "",
|
||||
}
|
||||
|
||||
if isNovel:
|
||||
if tHandle in self._novelIndex:
|
||||
self._novelIndex[tHandle]["T000000"] = theData
|
||||
else:
|
||||
if tHandle in self._noteIndex:
|
||||
self._noteIndex[tHandle]["T000000"] = theData
|
||||
|
||||
return
|
||||
|
||||
def _indexWordCounts(self, tHandle, isNovel, theText, nTitle):
|
||||
def _indexWordCounts(self, tHandle, theText, nTitle):
|
||||
"""Count text stats and save the counts to the index.
|
||||
"""
|
||||
cC, wC, pC = countWords(theText)
|
||||
sTitle = "T%06d" % nTitle
|
||||
if isNovel:
|
||||
if tHandle in self._novelIndex:
|
||||
if sTitle in self._novelIndex[tHandle]:
|
||||
self._novelIndex[tHandle][sTitle]["cCount"] = cC
|
||||
self._novelIndex[tHandle][sTitle]["wCount"] = wC
|
||||
self._novelIndex[tHandle][sTitle]["pCount"] = pC
|
||||
self._novelIndex[tHandle][sTitle]["updated"] = round(time())
|
||||
else:
|
||||
if tHandle in self._noteIndex:
|
||||
if sTitle in self._noteIndex[tHandle]:
|
||||
self._noteIndex[tHandle][sTitle]["cCount"] = cC
|
||||
self._noteIndex[tHandle][sTitle]["wCount"] = wC
|
||||
self._noteIndex[tHandle][sTitle]["pCount"] = pC
|
||||
self._noteIndex[tHandle][sTitle]["updated"] = round(time())
|
||||
if tHandle in self._fileIndex:
|
||||
if sTitle in self._fileIndex[tHandle]:
|
||||
self._fileIndex[tHandle][sTitle]["cCount"] = cC
|
||||
self._fileIndex[tHandle][sTitle]["wCount"] = wC
|
||||
self._fileIndex[tHandle][sTitle]["pCount"] = pC
|
||||
return
|
||||
|
||||
def _indexSynopsis(self, tHandle, isNovel, theText, nTitle):
|
||||
def _indexSynopsis(self, tHandle, theText, nTitle):
|
||||
"""Save the synopsis to the index.
|
||||
"""
|
||||
sTitle = "T%06d" % nTitle
|
||||
if isNovel:
|
||||
if tHandle in self._novelIndex:
|
||||
if sTitle in self._novelIndex[tHandle]:
|
||||
self._novelIndex[tHandle][sTitle]["synopsis"] = theText
|
||||
self._novelIndex[tHandle][sTitle]["updated"] = round(time())
|
||||
else:
|
||||
if tHandle in self._noteIndex:
|
||||
if sTitle in self._noteIndex[tHandle]:
|
||||
self._noteIndex[tHandle][sTitle]["synopsis"] = theText
|
||||
self._noteIndex[tHandle][sTitle]["updated"] = round(time())
|
||||
if tHandle in self._fileIndex:
|
||||
if sTitle in self._fileIndex[tHandle]:
|
||||
self._fileIndex[tHandle][sTitle]["synopsis"] = theText
|
||||
return
|
||||
|
||||
def _indexKeyword(self, tHandle, aLine, nLine, nTitle, itemClass):
|
||||
@@ -468,9 +423,13 @@ class NWIndex():
|
||||
if theBits[0] == nwKeyWords.TAG_KEY:
|
||||
self._tagIndex[theBits[1]] = [nLine, tHandle, itemClass.name, sTitle]
|
||||
|
||||
elif sTitle in self._refIndex[tHandle]:
|
||||
else:
|
||||
if tHandle not in self._refIndex:
|
||||
self._refIndex[tHandle] = {}
|
||||
if sTitle not in self._refIndex[tHandle]:
|
||||
self._refIndex[tHandle][sTitle] = []
|
||||
for aVal in theBits[1:]:
|
||||
self._refIndex[tHandle][sTitle]["tags"].append([nLine, theBits[0], aVal])
|
||||
self._refIndex[tHandle][sTitle].append([nLine, theBits[0], aVal])
|
||||
|
||||
return
|
||||
|
||||
@@ -530,23 +489,19 @@ class NWIndex():
|
||||
if not isGood[0] or nBits == 1:
|
||||
return isGood
|
||||
|
||||
# If we have a tag, only the first value is accepted, the rest
|
||||
# is ignored
|
||||
# For a tag, only the first value is accepted, the rest are ignored
|
||||
if theBits[0] == nwKeyWords.TAG_KEY and nBits > 1:
|
||||
isGood[0] = True
|
||||
if theBits[1] in self._tagIndex:
|
||||
if self._tagIndex[theBits[1]][1] == tItem.itemHandle:
|
||||
isGood[1] = True
|
||||
else:
|
||||
isGood[1] = False
|
||||
isGood[1] = self._tagIndex[theBits[1]][1] == tItem.itemHandle
|
||||
else:
|
||||
isGood[1] = True
|
||||
return isGood
|
||||
|
||||
# If we're still here, we better check that the references exist
|
||||
# If we're still here, we check that the references exist
|
||||
theKey = nwKeyWords.KEY_CLASS[theBits[0]].name
|
||||
for n in range(1, nBits):
|
||||
if theBits[n] in self._tagIndex:
|
||||
isGood[n] = nwKeyWords.KEY_CLASS[theBits[0]].name == self._tagIndex[theBits[n]][2]
|
||||
isGood[n] = theKey == self._tagIndex[theBits[n]][2]
|
||||
|
||||
return isGood
|
||||
|
||||
@@ -560,17 +515,17 @@ class NWIndex():
|
||||
files, but skipping all note files.
|
||||
"""
|
||||
for tHandle in self._listNovelHandles(skipExcluded):
|
||||
for sTitle in sorted(self._novelIndex[tHandle]):
|
||||
for sTitle in sorted(self._fileIndex[tHandle]):
|
||||
tKey = "%s:%s" % (tHandle, sTitle)
|
||||
yield tKey, tHandle, sTitle, self._novelIndex[tHandle][sTitle]
|
||||
yield tKey, tHandle, sTitle, self._fileIndex[tHandle][sTitle]
|
||||
|
||||
def getNovelWordCount(self, skipExcluded=True):
|
||||
"""Count the number of words in the novel project.
|
||||
"""
|
||||
wCount = 0
|
||||
for tHandle in self._listNovelHandles(skipExcluded):
|
||||
for sTitle in self._novelIndex[tHandle]:
|
||||
wCount += self._novelIndex[tHandle][sTitle]["wCount"]
|
||||
for sTitle in self._fileIndex[tHandle]:
|
||||
wCount += self._fileIndex[tHandle][sTitle]["wCount"]
|
||||
|
||||
return wCount
|
||||
|
||||
@@ -579,9 +534,9 @@ class NWIndex():
|
||||
"""
|
||||
hCount = [0, 0, 0, 0, 0]
|
||||
for tHandle in self._listNovelHandles(skipExcluded):
|
||||
for sTitle in self._novelIndex[tHandle]:
|
||||
theData = self._novelIndex[tHandle][sTitle]
|
||||
iLevel = self.H_LEVEL.get(theData["level"], 0)
|
||||
for sTitle in self._fileIndex[tHandle]:
|
||||
theData = self._fileIndex[tHandle][sTitle]
|
||||
iLevel = H_LEVEL.get(theData["level"], 0)
|
||||
hCount[iLevel] += 1
|
||||
|
||||
return hCount
|
||||
@@ -590,9 +545,7 @@ class NWIndex():
|
||||
"""Get all header word counts for a specific handle.
|
||||
"""
|
||||
theCounts = []
|
||||
hRecord = self._novelIndex.get(tHandle, None)
|
||||
if hRecord is None:
|
||||
hRecord = self._noteIndex.get(tHandle, None)
|
||||
hRecord = self._fileIndex.get(tHandle, None)
|
||||
if hRecord is None:
|
||||
return theCounts
|
||||
|
||||
@@ -605,9 +558,7 @@ class NWIndex():
|
||||
"""Get all headers for a specific handle.
|
||||
"""
|
||||
theHeaders = []
|
||||
hRecord = self._novelIndex.get(tHandle, None)
|
||||
if hRecord is None:
|
||||
hRecord = self._noteIndex.get(tHandle, None)
|
||||
hRecord = self._fileIndex.get(tHandle, None)
|
||||
if hRecord is None:
|
||||
return theHeaders
|
||||
|
||||
@@ -623,10 +574,10 @@ class NWIndex():
|
||||
tData = {}
|
||||
pKey = None
|
||||
for tHandle in self._listNovelHandles(skipExcluded):
|
||||
for sTitle in sorted(self._novelIndex[tHandle]):
|
||||
for sTitle in sorted(self._fileIndex[tHandle]):
|
||||
tKey = "%s:%s" % (tHandle, sTitle)
|
||||
theData = self._novelIndex[tHandle][sTitle]
|
||||
iLevel = self.H_LEVEL.get(theData["level"], 0)
|
||||
theData = self._fileIndex[tHandle][sTitle]
|
||||
iLevel = H_LEVEL.get(theData["level"], 0)
|
||||
if iLevel > maxDepth:
|
||||
if pKey in tData:
|
||||
theData["wCount"]
|
||||
@@ -665,16 +616,11 @@ class NWIndex():
|
||||
wC = self._textCounts[tHandle][1]
|
||||
pC = self._textCounts[tHandle][2]
|
||||
else:
|
||||
if tHandle in self._novelIndex:
|
||||
if sTitle in self._novelIndex[tHandle]:
|
||||
cC = self._novelIndex[tHandle][sTitle]["cCount"]
|
||||
wC = self._novelIndex[tHandle][sTitle]["wCount"]
|
||||
pC = self._novelIndex[tHandle][sTitle]["pCount"]
|
||||
elif tHandle in self._noteIndex:
|
||||
if sTitle in self._noteIndex[tHandle]:
|
||||
cC = self._noteIndex[tHandle][sTitle]["cCount"]
|
||||
wC = self._noteIndex[tHandle][sTitle]["wCount"]
|
||||
pC = self._noteIndex[tHandle][sTitle]["pCount"]
|
||||
if tHandle in self._fileIndex:
|
||||
if sTitle in self._fileIndex[tHandle]:
|
||||
cC = self._fileIndex[tHandle][sTitle]["cCount"]
|
||||
wC = self._fileIndex[tHandle][sTitle]["wCount"]
|
||||
pC = self._fileIndex[tHandle][sTitle]["pCount"]
|
||||
|
||||
return cC, wC, pC
|
||||
|
||||
@@ -690,7 +636,7 @@ class NWIndex():
|
||||
return theRefs
|
||||
|
||||
for refTitle in self._refIndex[tHandle]:
|
||||
for aTag in self._refIndex[tHandle][refTitle].get("tags", []):
|
||||
for aTag in self._refIndex[tHandle][refTitle]:
|
||||
if len(aTag) == 3 and (sTitle is None or sTitle == refTitle):
|
||||
if aTag[1] in theRefs:
|
||||
theRefs[aTag[1]].append(aTag[2])
|
||||
@@ -700,9 +646,9 @@ class NWIndex():
|
||||
def getNovelData(self, tHandle, sTitle):
|
||||
"""Return the novel data of a given handle and title.
|
||||
"""
|
||||
if tHandle in self._novelIndex:
|
||||
if sTitle in self._novelIndex[tHandle]:
|
||||
return self._novelIndex[tHandle][sTitle]
|
||||
if tHandle in self._fileIndex:
|
||||
if sTitle in self._fileIndex[tHandle]:
|
||||
return self._fileIndex[tHandle][sTitle]
|
||||
return None
|
||||
|
||||
def getBackReferenceList(self, tHandle):
|
||||
@@ -721,7 +667,7 @@ class NWIndex():
|
||||
if theTags:
|
||||
for tHandle in self._refIndex:
|
||||
for sTitle in self._refIndex[tHandle]:
|
||||
for _, _, tTag in self._refIndex[tHandle][sTitle]["tags"]:
|
||||
for _, _, tTag in self._refIndex[tHandle][sTitle]:
|
||||
if tTag in theTags and tHandle not in theRefs:
|
||||
theRefs[tHandle] = sTitle
|
||||
|
||||
@@ -749,7 +695,9 @@ class NWIndex():
|
||||
continue
|
||||
if not tItem.isExported and skipExcluded:
|
||||
continue
|
||||
if tItem.itemHandle in self._novelIndex:
|
||||
if tItem.itemLayout == nwItemLayout.NOTE:
|
||||
continue
|
||||
if tItem.itemHandle in self._fileIndex:
|
||||
theHandles.append(tItem.itemHandle)
|
||||
|
||||
return theHandles
|
||||
@@ -760,7 +708,7 @@ class NWIndex():
|
||||
|
||||
def _checkTagIndex(self):
|
||||
"""Scan the tag index for errors.
|
||||
Waring: This function raises exceptions.
|
||||
Warning: This function raises exceptions.
|
||||
"""
|
||||
for tTag in self._tagIndex:
|
||||
if not isinstance(tTag, str):
|
||||
@@ -782,7 +730,7 @@ class NWIndex():
|
||||
|
||||
def _checkRefIndex(self):
|
||||
"""Scan the reference index for errors.
|
||||
Waring: This function raises exceptions.
|
||||
Warning: This function raises exceptions.
|
||||
"""
|
||||
for tHandle in self._refIndex:
|
||||
if not isHandle(tHandle):
|
||||
@@ -794,88 +742,70 @@ class NWIndex():
|
||||
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"]:
|
||||
for tEntry in sEntry:
|
||||
if len(tEntry) != 3:
|
||||
raise IndexError("refIndex[a][b][tags][i] expected 3 values")
|
||||
raise IndexError("refIndex[a][b][i] expected 3 values")
|
||||
if not isinstance(tEntry[0], int):
|
||||
raise ValueError("refIndex[a][b][tags][i][0] is not an integer")
|
||||
raise ValueError("refIndex[a][b][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")
|
||||
raise ValueError("refIndex[a][b][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")
|
||||
raise ValueError("refIndex[a][b][i][2] is not a string")
|
||||
|
||||
return
|
||||
|
||||
def _checkNovelNoteIndex(self, idxName):
|
||||
"""Scan the novel or note index for errors.
|
||||
Waring: This function raises exceptions.
|
||||
def _checkFileIndex(self):
|
||||
"""Scan the file index for errors.
|
||||
Warning: 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:
|
||||
for tHandle in self._fileIndex:
|
||||
if not isHandle(tHandle):
|
||||
raise KeyError("%s key is not a handle" % idxName)
|
||||
raise KeyError("fileIndex key is not a handle")
|
||||
|
||||
hEntry = theIndex[tHandle]
|
||||
for sTitle in theIndex[tHandle]:
|
||||
hEntry = self._fileIndex[tHandle]
|
||||
for sTitle in self._fileIndex[tHandle]:
|
||||
if not isTitleTag(sTitle):
|
||||
raise KeyError("%s[a] key is not a title tag" % idxName)
|
||||
raise KeyError("fileIndex[a] key is not a title tag")
|
||||
|
||||
sEntry = hEntry[sTitle]
|
||||
if len(sEntry) != 8:
|
||||
raise IndexError("%s[a][b] expected 8 values" % idxName)
|
||||
if len(sEntry) != 7:
|
||||
raise IndexError("fileIndex[a][b] expected 7 values")
|
||||
|
||||
if "level" not in sEntry:
|
||||
raise KeyError("%s[a][b] has no 'level' key" % idxName)
|
||||
raise KeyError("fileIndex[a][b] has no 'level' key")
|
||||
if "title" not in sEntry:
|
||||
raise KeyError("%s[a][b] has no 'title' key" % idxName)
|
||||
raise KeyError("fileIndex[a][b] has no 'title' key")
|
||||
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)
|
||||
raise KeyError("fileIndex[a][b] has no 'layout' key")
|
||||
if "cCount" not in sEntry:
|
||||
raise KeyError("%s[a][b] has no 'cCount' key" % idxName)
|
||||
raise KeyError("fileIndex[a][b] has no 'cCount' key")
|
||||
if "wCount" not in sEntry:
|
||||
raise KeyError("%s[a][b] has no 'wCount' key" % idxName)
|
||||
raise KeyError("fileIndex[a][b] has no 'wCount' key")
|
||||
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)
|
||||
raise KeyError("fileIndex[a][b] has no 'pCount' key")
|
||||
if "synopsis" not in sEntry:
|
||||
raise KeyError("fileIndex[a][b] has no 'synopsis' key")
|
||||
|
||||
if not sEntry["level"] in self.H_VALID:
|
||||
raise ValueError("%s[a][b][level] is not a header level" % idxName)
|
||||
if not sEntry["level"] in H_VALID:
|
||||
raise ValueError("fileIndex[a][b][level] is not a header level")
|
||||
if not isinstance(sEntry["title"], str):
|
||||
raise ValueError("%s[a][b][title] is not a string" % idxName)
|
||||
raise ValueError("fileIndex[a][b][title] is not a string")
|
||||
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)
|
||||
raise ValueError("fileIndex[a][b][layout] is not an nwItemLayout")
|
||||
if not isinstance(sEntry["cCount"], int):
|
||||
raise ValueError("%s[a][b][cCount] is not an integer" % idxName)
|
||||
raise ValueError("fileIndex[a][b][cCount] is not an integer")
|
||||
if not isinstance(sEntry["wCount"], int):
|
||||
raise ValueError("%s[a][b][wCount] is not an integer" % idxName)
|
||||
raise ValueError("fileIndex[a][b][wCount] is not an integer")
|
||||
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)
|
||||
raise ValueError("fileIndex[a][b][pCount] is not an integer")
|
||||
if not isinstance(sEntry["synopsis"], str):
|
||||
raise ValueError("fileIndex[a][b][synopsis] is not a string")
|
||||
|
||||
return
|
||||
|
||||
def _checkTextCounts(self):
|
||||
"""Scan the text counts index for errors.
|
||||
Waring: This function raises exceptions.
|
||||
Warning: This function raises exceptions.
|
||||
"""
|
||||
for tHandle in self._textCounts:
|
||||
if not isHandle(tHandle):
|
||||
|
||||
Reference in New Issue
Block a user