Add file copy feature to project class
This commit is contained in:
@@ -175,24 +175,47 @@ class NWProject:
|
|||||||
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]
|
tItem = self._tree[tHandle]
|
||||||
if tItem is None:
|
if not (tItem and tItem.isFileType()):
|
||||||
return False
|
|
||||||
if not tItem.isFileType():
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
newDoc = self._storage.getDocument(tHandle)
|
newDoc = self._storage.getDocument(tHandle)
|
||||||
if (newDoc.readDocument() or "").strip():
|
if (newDoc.readDocument() or "").strip():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
hshText = "#"*minmax(hLevel, 1, 4)
|
indent = "#"*minmax(hLevel, 1, 4)
|
||||||
newText = f"{hshText} {tItem.itemName}\n\n{text}"
|
text = f"{indent} {tItem.itemName}\n\n{text}"
|
||||||
|
|
||||||
if tItem.isNovelLike() and isDocument:
|
if tItem.isNovelLike() and isDocument:
|
||||||
tItem.setLayout(nwItemLayout.DOCUMENT)
|
tItem.setLayout(nwItemLayout.DOCUMENT)
|
||||||
else:
|
else:
|
||||||
tItem.setLayout(nwItemLayout.NOTE)
|
tItem.setLayout(nwItemLayout.NOTE)
|
||||||
|
|
||||||
newDoc.writeDocument(newText)
|
newDoc.writeDocument(text)
|
||||||
self._index.scanText(tHandle, newText)
|
self._index.scanText(tHandle, text)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def copyFileContent(self, tHandle: str, sHandle: str) -> bool:
|
||||||
|
"""Copy content to a new document after it is created. This
|
||||||
|
will not run if the file exists and is not empty.
|
||||||
|
"""
|
||||||
|
tItem = self._tree[tHandle]
|
||||||
|
if not (tItem and tItem.isFileType()):
|
||||||
|
return False
|
||||||
|
|
||||||
|
sItem = self._tree[sHandle]
|
||||||
|
if not (sItem and sItem.isFileType()):
|
||||||
|
return False
|
||||||
|
|
||||||
|
newDoc = self._storage.getDocument(tHandle)
|
||||||
|
if (newDoc.readDocument() or "").strip():
|
||||||
|
return False
|
||||||
|
|
||||||
|
logger.debug("Populating '%s' with text from '%s'", tHandle, sHandle)
|
||||||
|
text = self._storage.getDocument(sHandle).readDocument() or ""
|
||||||
|
newDoc.writeDocument(text)
|
||||||
|
sItem.setLayout(tItem.itemLayout)
|
||||||
|
self._index.scanText(tHandle, text)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -102,34 +102,61 @@ def testCoreProject_NewFileFolder(monkeypatch, fncPath, tstPaths, mockGUI, mockR
|
|||||||
mockRnd.reset()
|
mockRnd.reset()
|
||||||
buildTestProject(project, fncPath)
|
buildTestProject(project, fncPath)
|
||||||
|
|
||||||
|
aHandle = "0000000000010"
|
||||||
|
bHandle = "0000000000011"
|
||||||
|
cHandle = "0000000000012"
|
||||||
|
dHandle = "0000000000013"
|
||||||
|
xHandle = "1234567890abc"
|
||||||
|
|
||||||
# Invalid call
|
# Invalid call
|
||||||
assert project.newFolder("New Folder", "1234567890abc") is None
|
assert project.newFolder("New Folder", xHandle) is None
|
||||||
assert project.newFile("New File", "1234567890abc") is None
|
assert project.newFile("New File", xHandle) is None
|
||||||
|
|
||||||
# Add files properly
|
# Add files properly
|
||||||
assert project.newFolder("Stuff", C.hNovelRoot) == "0000000000010"
|
assert project.newFolder("Stuff", C.hNovelRoot) == aHandle
|
||||||
assert project.newFile("Hello", "0000000000010") == "0000000000011"
|
assert project.newFile("Hello", aHandle) == bHandle
|
||||||
assert project.newFile("Jane", C.hCharRoot) == "0000000000012"
|
assert project.newFile("Jane", C.hCharRoot) == cHandle
|
||||||
|
assert project.newFile("John", C.hCharRoot) == dHandle
|
||||||
|
|
||||||
assert "0000000000010" in project.tree
|
assert aHandle in project.tree
|
||||||
assert "0000000000011" in project.tree
|
assert bHandle in project.tree
|
||||||
assert "0000000000012" in project.tree
|
assert cHandle in project.tree
|
||||||
|
assert dHandle in project.tree
|
||||||
|
|
||||||
# Write to file, failed
|
# Write to file, failed
|
||||||
assert project.writeNewFile("blabla", 1, True) is False # Not a handle
|
assert project.writeNewFile("blabla", 1, True) is False # Not a handle
|
||||||
assert project.writeNewFile("0000000000010", 1, True) is False # Not a file
|
assert project.writeNewFile(aHandle, 1, True) is False # Not a file
|
||||||
assert project.writeNewFile(C.hTitlePage, 1, True) is False # Already has content
|
assert project.writeNewFile(C.hTitlePage, 1, True) is False # Already has content
|
||||||
|
|
||||||
# Write to file, success
|
# Write to file, success
|
||||||
assert project.writeNewFile("0000000000011", 2, True) is True
|
assert project.writeNewFile(bHandle, 2, True) is True
|
||||||
assert project.storage.getDocument("0000000000011").readDocument() == "## Hello\n\n"
|
assert project.storage.getDocument(bHandle).readDocument() == "## Hello\n\n"
|
||||||
|
|
||||||
# Write to file with additional text, success
|
# Write to file with additional text, success
|
||||||
assert project.writeNewFile("0000000000012", 1, False, "Hi Jane\n\n") is True
|
assert project.writeNewFile(cHandle, 1, False, "Hi Jane\n\n") is True
|
||||||
assert project.storage.getDocument("0000000000012").readDocument() == (
|
assert project.storage.getDocument(cHandle).readDocument() == (
|
||||||
"# Jane\n\nHi Jane\n\n"
|
"# Jane\n\nHi Jane\n\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Copy file content, invalid target
|
||||||
|
assert project.copyFileContent(xHandle, cHandle) is False # Unknown handle
|
||||||
|
assert project.copyFileContent(aHandle, cHandle) is False # Target is a folder
|
||||||
|
|
||||||
|
# Copy file content, invalid source
|
||||||
|
assert project.copyFileContent(dHandle, xHandle) is False # Unknown handle
|
||||||
|
assert project.copyFileContent(dHandle, aHandle) is False # Source is a folder
|
||||||
|
|
||||||
|
# Copy file content, target not empty
|
||||||
|
assert project.copyFileContent(bHandle, cHandle) is False
|
||||||
|
|
||||||
|
# Copy file content, success
|
||||||
|
assert project.copyFileContent(dHandle, cHandle) is True
|
||||||
|
|
||||||
|
cText = project.storage.getDocument(cHandle).readDocument()
|
||||||
|
dText = project.storage.getDocument(dHandle).readDocument()
|
||||||
|
|
||||||
|
assert dText == cText
|
||||||
|
|
||||||
# Save, close and check
|
# Save, close and check
|
||||||
assert project.projChanged is True
|
assert project.projChanged is True
|
||||||
assert project.saveProject() is True
|
assert project.saveProject() is True
|
||||||
@@ -141,23 +168,27 @@ def testCoreProject_NewFileFolder(monkeypatch, fncPath, tstPaths, mockGUI, mockR
|
|||||||
# Delete new file, but block access
|
# Delete new file, but block access
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
mp.setattr("pathlib.Path.unlink", causeOSError)
|
mp.setattr("pathlib.Path.unlink", causeOSError)
|
||||||
assert project.removeItem("0000000000011") is False
|
assert project.removeItem(bHandle) is False
|
||||||
assert "0000000000011" in project.tree
|
assert bHandle in project.tree
|
||||||
|
|
||||||
# Delete new files and folders
|
# Delete new files and folders
|
||||||
assert (fncPath / "content" / "0000000000012.nwd").exists()
|
assert (fncPath / "content" / f"{dHandle}.nwd").exists()
|
||||||
assert (fncPath / "content" / "0000000000011.nwd").exists()
|
assert (fncPath / "content" / f"{cHandle}.nwd").exists()
|
||||||
|
assert (fncPath / "content" / f"{bHandle}.nwd").exists()
|
||||||
|
|
||||||
assert project.removeItem("0000000000012") is True
|
assert project.removeItem(dHandle) is True
|
||||||
assert project.removeItem("0000000000011") is True
|
assert project.removeItem(cHandle) is True
|
||||||
assert project.removeItem("0000000000010") is True
|
assert project.removeItem(bHandle) is True
|
||||||
|
assert project.removeItem(aHandle) is True
|
||||||
|
|
||||||
assert not (fncPath / "content" / "0000000000012.nwd").exists()
|
assert not (fncPath / "content" / f"{dHandle}.nwd").exists()
|
||||||
assert not (fncPath / "content" / "0000000000011.nwd").exists()
|
assert not (fncPath / "content" / f"{cHandle}.nwd").exists()
|
||||||
|
assert not (fncPath / "content" / f"{bHandle}.nwd").exists()
|
||||||
|
|
||||||
assert "0000000000010" not in project.tree
|
assert aHandle not in project.tree
|
||||||
assert "0000000000011" not in project.tree
|
assert bHandle not in project.tree
|
||||||
assert "0000000000012" not in project.tree
|
assert cHandle not in project.tree
|
||||||
|
assert dHandle not in project.tree
|
||||||
|
|
||||||
project.closeProject()
|
project.closeProject()
|
||||||
|
|
||||||
@@ -177,6 +208,8 @@ def testCoreProject_Open(monkeypatch, caplog, mockGUI, fncPath, mockRnd):
|
|||||||
caplog.clear()
|
caplog.clear()
|
||||||
assert project.openProject(fooBar) is False
|
assert project.openProject(fooBar) is False
|
||||||
assert "Not a known project file format." in caplog.text
|
assert "Not a known project file format." in caplog.text
|
||||||
|
assert project.isValid is False
|
||||||
|
assert project.lockStatus is None
|
||||||
|
|
||||||
# No project file
|
# No project file
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
@@ -204,10 +237,14 @@ def testCoreProject_Open(monkeypatch, caplog, mockGUI, fncPath, mockRnd):
|
|||||||
# Open again should fail on lock file
|
# Open again should fail on lock file
|
||||||
assert project.openProject(fncPath) is False
|
assert project.openProject(fncPath) is False
|
||||||
assert project.state == NWProjectState.LOCKED
|
assert project.state == NWProjectState.LOCKED
|
||||||
|
assert project.isValid is True
|
||||||
|
assert project.lockStatus is not None
|
||||||
|
|
||||||
# Force re-open
|
# Force re-open
|
||||||
assert project.openProject(fncPath, clearLock=True) is True
|
assert project.openProject(fncPath, clearLock=True) is True
|
||||||
assert project.state == NWProjectState.READY
|
assert project.state == NWProjectState.READY
|
||||||
|
assert project.isValid is True
|
||||||
|
assert project.lockStatus is None
|
||||||
|
|
||||||
# Fail getting xml reader
|
# Fail getting xml reader
|
||||||
with monkeypatch.context() as mp:
|
with monkeypatch.context() as mp:
|
||||||
|
|||||||
Reference in New Issue
Block a user