Use the quick read feature wherever we only need document text

This commit is contained in:
Veronica Berglyd Olsen
2024-03-26 11:56:31 +01:00
parent 738f022212
commit 6a7262b817
7 changed files with 22 additions and 58 deletions
+5 -26
View File
@@ -32,7 +32,6 @@ import shutil
from collections.abc import Iterable from collections.abc import Iterable
from functools import partial from functools import partial
from pathlib import Path from pathlib import Path
from time import time
from zipfile import ZipFile, is_zipfile from zipfile import ZipFile, is_zipfile
from PyQt5.QtCore import QCoreApplication, QRegularExpression from PyQt5.QtCore import QCoreApplication, QRegularExpression
@@ -102,9 +101,7 @@ class DocMerger:
if srcItem is None: if srcItem is None:
return False return False
inDoc = self._project.storage.getDocument(srcHandle) docText = self._project.storage.getDocumentText(srcHandle).rstrip("\n")
docText = (inDoc.readDocument() or "").rstrip("\n")
if addComment: if addComment:
docInfo = srcItem.describeMe() docInfo = srcItem.describeMe()
docSt, _ = srcItem.getImportStatus(incIcon=False) docSt, _ = srcItem.getImportStatus(incIcon=False)
@@ -123,9 +120,8 @@ class DocMerger:
return False return False
outDoc = self._project.storage.getDocument(self._targetDoc) outDoc = self._project.storage.getDocument(self._targetDoc)
docText = (outDoc.readDocument() or "").rstrip("\n") if text := (outDoc.readDocument() or "").rstrip("\n"):
if docText: self._targetText.insert(0, text)
self._targetText.insert(0, docText)
status = outDoc.writeDocument("\n\n".join(self._targetText) + "\n\n") status = outDoc.writeDocument("\n\n".join(self._targetText) + "\n\n")
if not status: if not status:
@@ -293,11 +289,10 @@ class DocDuplicator:
newItem.setParent(hMap[newItem.itemParent]) newItem.setParent(hMap[newItem.itemParent])
self._project.tree.updateItemData(newItem.itemHandle) self._project.tree.updateItemData(newItem.itemHandle)
if newItem.isFileType(): if newItem.isFileType():
oldDoc = self._project.storage.getDocument(tHandle)
newDoc = self._project.storage.getDocument(newItem.itemHandle) newDoc = self._project.storage.getDocument(newItem.itemHandle)
if newDoc.fileExists(): if newDoc.fileExists():
return return
newDoc.writeDocument(oldDoc.readDocument() or "") newDoc.writeDocument(self._project.storage.getDocumentText(tHandle))
yield newItem.itemHandle, nHandle yield newItem.itemHandle, nHandle
nHandle = None nHandle = None
return return
@@ -308,17 +303,10 @@ class DocDuplicator:
class DocSearch: class DocSearch:
def __init__(self) -> None: def __init__(self) -> None:
# RegEx Object
self._regEx = QRegularExpression() self._regEx = QRegularExpression()
self.setCaseSensitive(False) self.setCaseSensitive(False)
self._words = False self._words = False
self._escape = True self._escape = True
# Project Cache
self._uuid = ""
self._time = 0.0
self._cache: dict[str, str] = {}
return return
## ##
@@ -347,11 +335,6 @@ class DocSearch:
self, project: NWProject, search: str self, project: NWProject, search: str
) -> Iterable[tuple[NWItem, list[tuple[int, int, str]], bool]]: ) -> Iterable[tuple[NWItem, list[tuple[int, int, str]], bool]]:
"""Iteratively search through documents in a project.""" """Iteratively search through documents in a project."""
if project.data.uuid != self._uuid or time() - self._time > 20.0:
self._cache = {}
self._uuid = project.data.uuid
self._time = time()
self._regEx.setPattern(self._buildPattern(search)) self._regEx.setPattern(self._buildPattern(search))
logger.debug("Searching with pattern '%s'", self._regEx.pattern()) logger.debug("Searching with pattern '%s'", self._regEx.pattern())
@@ -359,11 +342,7 @@ class DocSearch:
storage = project.storage storage = project.storage
for item in project.tree: for item in project.tree:
if item.isFileType(): if item.isFileType():
tHandle = item.itemHandle text = storage.getDocumentText(item.itemHandle)
if (text := self._cache.get(tHandle)) is None:
text = storage.getDocument(tHandle).readDocument() or ""
self._cache[tHandle] = text
rxItt = self._regEx.globalMatch(text) rxItt = self._regEx.globalMatch(text)
count = 0 count = 0
capped = False capped = False
+5 -8
View File
@@ -122,9 +122,8 @@ class NWIndex:
self.clearIndex() self.clearIndex()
for nwItem in self._project.tree: for nwItem in self._project.tree:
if nwItem.isFileType(): if nwItem.isFileType():
tHandle = nwItem.itemHandle text = self._project.storage.getDocumentText(nwItem.itemHandle)
doc = self._project.storage.getDocument(tHandle) self.scanText(nwItem.itemHandle, text, blockSignal=True)
self.scanText(tHandle, doc.readDocument() or "", blockSignal=True)
self._indexBroken = False self._indexBroken = False
SHARED.indexSignalProxy({"event": "buildIndex"}) SHARED.indexSignalProxy({"event": "buildIndex"})
return return
@@ -142,17 +141,15 @@ class NWIndex:
}) })
return return
def reIndexHandle(self, tHandle: str | None) -> bool: def reIndexHandle(self, tHandle: str | None) -> None:
"""Put a file back into the index. This is used when files are """Put a file back into the index. This is used when files are
moved from the archive or trash folders back into the active moved from the archive or trash folders back into the active
project. project.
""" """
if tHandle and self._project.tree.checkType(tHandle, nwItemType.FILE): if tHandle and self._project.tree.checkType(tHandle, nwItemType.FILE):
logger.debug("Re-indexing item '%s'", tHandle) logger.debug("Re-indexing item '%s'", tHandle)
doc = self._project.storage.getDocument(tHandle) self.scanText(tHandle, self._project.storage.getDocumentText(tHandle))
self.scanText(tHandle, doc.readDocument() or "") return
return True
return False
def indexChangedSince(self, checkTime: int | float) -> bool: def indexChangedSince(self, checkTime: int | float) -> bool:
"""Check if the index has changed since a given time.""" """Check if the index has changed since a given time."""
+8 -13
View File
@@ -175,12 +175,10 @@ class NWProject:
"""Write content to a new document after it is created. This """Write content to a new document after it is created. This
will not run if the file exists and is not empty. will not run if the file exists and is not empty.
""" """
tItem = self._tree[tHandle] if not ((tItem := self._tree[tHandle]) and tItem.isFileType()):
if not (tItem and tItem.isFileType()):
return False return False
newDoc = self._storage.getDocument(tHandle) if self._storage.getDocumentText(tHandle).strip():
if (newDoc.readDocument() or "").strip():
return False return False
indent = "#"*minmax(hLevel, 1, 4) indent = "#"*minmax(hLevel, 1, 4)
@@ -191,7 +189,7 @@ class NWProject:
else: else:
tItem.setLayout(nwItemLayout.NOTE) tItem.setLayout(nwItemLayout.NOTE)
newDoc.writeDocument(text) self._storage.getDocument(tHandle).writeDocument(text)
self._index.scanText(tHandle, text) self._index.scanText(tHandle, text)
return True return True
@@ -200,21 +198,18 @@ class NWProject:
"""Copy content to a new document after it is created. This """Copy content to a new document after it is created. This
will not run if the file exists and is not empty. will not run if the file exists and is not empty.
""" """
tItem = self._tree[tHandle] if not ((tItem := self._tree[tHandle]) and tItem.isFileType()):
if not (tItem and tItem.isFileType()):
return False return False
sItem = self._tree[sHandle] if not ((sItem := self._tree[sHandle]) and sItem.isFileType()):
if not (sItem and sItem.isFileType()):
return False return False
newDoc = self._storage.getDocument(tHandle) if self._storage.getDocumentText(tHandle).strip():
if (newDoc.readDocument() or "").strip():
return False return False
logger.debug("Populating '%s' with text from '%s'", tHandle, sHandle) logger.debug("Populating '%s' with text from '%s'", tHandle, sHandle)
text = self._storage.getDocument(sHandle).readDocument() or "" text = self._storage.getDocumentText(sHandle)
newDoc.writeDocument(text) self._storage.getDocument(tHandle).writeDocument(text)
sItem.setLayout(tItem.itemLayout) sItem.setLayout(tItem.itemLayout)
self._index.scanText(tHandle, text) self._index.scanText(tHandle, text)
+1 -3
View File
@@ -429,9 +429,7 @@ class Tokenizer(ABC):
self._text = "" self._text = ""
self._handle = None self._handle = None
if nwItem := self._project.tree[tHandle]: if nwItem := self._project.tree[tHandle]:
if text is None: self._text = text or self._project.storage.getDocumentText(tHandle)
text = self._project.storage.getDocument(tHandle).readDocument() or ""
self._text = text
self._handle = tHandle self._handle = tHandle
self._isNovel = nwItem.itemLayout == nwItemLayout.DOCUMENT self._isNovel = nwItem.itemLayout == nwItemLayout.DOCUMENT
return return
+1 -2
View File
@@ -214,8 +214,7 @@ class GuiDocSplit(QDialog):
spLevel = self.splitLevel.currentData() spLevel = self.splitLevel.currentData()
if not self._text: if not self._text:
inDoc = SHARED.project.storage.getDocument(sHandle) self._text = SHARED.project.storage.getDocumentText(sHandle).splitlines()
self._text = (inDoc.readDocument() or "").splitlines()
for lineNo, aLine in enumerate(self._text): for lineNo, aLine in enumerate(self._text):
-3
View File
@@ -423,9 +423,6 @@ def testCoreTools_DocSearch(monkeypatch, mockGUI, fncPath, mockRnd, ipsumText):
assert result[1] == (C.hChapterDoc, [], False) assert result[1] == (C.hChapterDoc, [], False)
assert result[2] == (C.hSceneDoc, [(8, 5, "Scene")], False) assert result[2] == (C.hSceneDoc, [(8, 5, "Scene")], False)
# Cache
assert list(search._cache.keys()) == [C.hTitlePage, C.hChapterDoc, C.hSceneDoc]
# Patterns # Patterns
# ======== # ========
+2 -3
View File
@@ -60,9 +60,8 @@ def testCoreIndex_LoadSave(qtbot, monkeypatch, prjLipsum, mockGUI, tstPaths):
"60bdf227455cc": False, # World ROOT "60bdf227455cc": False, # World ROOT
} }
for tItem in project.tree: for tItem in project.tree:
assert index.reIndexHandle(tItem.itemHandle) is notIndexable.get(tItem.itemHandle, True) index.reIndexHandle(tItem.itemHandle)
assert (tItem.itemHandle in index._itemIndex) is notIndexable.get(tItem.itemHandle, True)
assert index.reIndexHandle(None) is False
# No folder for saving # No folder for saving
with monkeypatch.context() as mp: with monkeypatch.context() as mp: