Drop the project .bak file (#1670)
This commit is contained in:
@@ -33,7 +33,7 @@ itself. It is important to keep this file backed up, either through the built-in
|
|||||||
your own backup solution.
|
your own backup solution.
|
||||||
|
|
||||||
The project XML file is indent-formatted, and is suitable for diff tools and version control since
|
The project XML file is indent-formatted, and is suitable for diff tools and version control since
|
||||||
most of the file will stay static, although a timesetamp is set in the meta section on line 2, and
|
most of the file will stay static, although a timestamp is set in the meta section on line 2, and
|
||||||
various meta data entries incremented, on each save.
|
various meta data entries incremented, on each save.
|
||||||
|
|
||||||
.. only:: not html
|
.. only:: not html
|
||||||
@@ -91,11 +91,6 @@ If successful, the old data file is then removed, and the temporary file replace
|
|||||||
that the previously saved data is only replaced when the new data has been successfully saved to
|
that the previously saved data is only replaced when the new data has been successfully saved to
|
||||||
the storage medium.
|
the storage medium.
|
||||||
|
|
||||||
For the project XML file, a ``.bak`` file is in addition kept, which will always contain the
|
|
||||||
previous version of the file, although when auto-save is enabled, they may have the same content.
|
|
||||||
If the opening of a project file fails, novelWriter will automatically try to open the ``.bak``
|
|
||||||
file instead.
|
|
||||||
|
|
||||||
|
|
||||||
Project Meta Data
|
Project Meta Data
|
||||||
=================
|
=================
|
||||||
|
|||||||
@@ -110,7 +110,6 @@ class nwFiles:
|
|||||||
|
|
||||||
# Project Root Files
|
# Project Root Files
|
||||||
PROJ_FILE = "nwProject.nwx"
|
PROJ_FILE = "nwProject.nwx"
|
||||||
PROJ_BACKUP = "nwProject.bak"
|
|
||||||
PROJ_LOCK = "nwProject.lock"
|
PROJ_LOCK = "nwProject.lock"
|
||||||
TOC_TXT = "ToC.txt"
|
TOC_TXT = "ToC.txt"
|
||||||
|
|
||||||
|
|||||||
@@ -64,12 +64,11 @@ class XMLReadState(Enum):
|
|||||||
|
|
||||||
NO_ACTION = 0
|
NO_ACTION = 0
|
||||||
NO_ERROR = 1
|
NO_ERROR = 1
|
||||||
PARSED_BACKUP = 2
|
CANNOT_PARSE = 2
|
||||||
CANNOT_PARSE = 3
|
NOT_NWX_FILE = 3
|
||||||
NOT_NWX_FILE = 4
|
UNKNOWN_VERSION = 4
|
||||||
UNKNOWN_VERSION = 5
|
PARSED_OK = 5
|
||||||
PARSED_OK = 6
|
WAS_LEGACY = 6
|
||||||
WAS_LEGACY = 7
|
|
||||||
|
|
||||||
# END Class XMLReadState
|
# END Class XMLReadState
|
||||||
|
|
||||||
@@ -172,23 +171,9 @@ class ProjectXMLReader:
|
|||||||
xml = ET.parse(str(self._path))
|
xml = ET.parse(str(self._path))
|
||||||
self._state = XMLReadState.NO_ERROR
|
self._state = XMLReadState.NO_ERROR
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
# Trying to open backup file instead
|
|
||||||
logger.error("Failed to parse project XML", exc_info=exc)
|
logger.error("Failed to parse project XML", exc_info=exc)
|
||||||
self._state = XMLReadState.CANNOT_PARSE
|
self._state = XMLReadState.CANNOT_PARSE
|
||||||
|
return False
|
||||||
backFile = self._path.with_suffix(".bak")
|
|
||||||
if backFile.is_file():
|
|
||||||
try:
|
|
||||||
xml = ET.parse(str(backFile))
|
|
||||||
self._state = XMLReadState.PARSED_BACKUP
|
|
||||||
logger.info("Backup project file parsed")
|
|
||||||
except Exception as exc:
|
|
||||||
logger.error("Failed to parse backup project XML", exc_info=exc)
|
|
||||||
self._state = XMLReadState.CANNOT_PARSE
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
self._state = XMLReadState.CANNOT_PARSE
|
|
||||||
return False
|
|
||||||
|
|
||||||
xRoot = xml.getroot()
|
xRoot = xml.getroot()
|
||||||
self._root = str(xRoot.tag)
|
self._root = str(xRoot.tag)
|
||||||
@@ -555,22 +540,12 @@ class ProjectXMLWriter:
|
|||||||
xName.text = item["name"]
|
xName.text = item["name"]
|
||||||
|
|
||||||
# Write the XML tree to file
|
# Write the XML tree to file
|
||||||
tempFile = self._path.with_suffix(".tmp")
|
tmp = self._path.with_suffix(".tmp")
|
||||||
backFile = self._path.with_suffix(".bak")
|
|
||||||
try:
|
try:
|
||||||
xml = ET.ElementTree(xRoot)
|
xml = ET.ElementTree(xRoot)
|
||||||
xmlIndent(xml)
|
xmlIndent(xml)
|
||||||
xml.write(tempFile, encoding="utf-8", xml_declaration=True)
|
xml.write(tmp, encoding="utf-8", xml_declaration=True)
|
||||||
except Exception as exc:
|
tmp.replace(self._path)
|
||||||
self._error = exc
|
|
||||||
return False
|
|
||||||
|
|
||||||
# If we're here, the file was successfully saved,
|
|
||||||
# so let's sort out the temps and backups
|
|
||||||
try:
|
|
||||||
if self._path.exists():
|
|
||||||
self._path.replace(backFile)
|
|
||||||
tempFile.replace(self._path)
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self._error = exc
|
self._error = exc
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -307,7 +307,6 @@ class NWStorage:
|
|||||||
baseCont = basePath / "content"
|
baseCont = basePath / "content"
|
||||||
files = [
|
files = [
|
||||||
(basePath / nwFiles.PROJ_FILE, nwFiles.PROJ_FILE),
|
(basePath / nwFiles.PROJ_FILE, nwFiles.PROJ_FILE),
|
||||||
(basePath / nwFiles.PROJ_BACKUP, nwFiles.PROJ_BACKUP),
|
|
||||||
(baseMeta / nwFiles.BUILDS_FILE, f"meta/{nwFiles.BUILDS_FILE}"),
|
(baseMeta / nwFiles.BUILDS_FILE, f"meta/{nwFiles.BUILDS_FILE}"),
|
||||||
(baseMeta / nwFiles.INDEX_FILE, f"meta/{nwFiles.INDEX_FILE}"),
|
(baseMeta / nwFiles.INDEX_FILE, f"meta/{nwFiles.INDEX_FILE}"),
|
||||||
(baseMeta / nwFiles.OPTS_FILE, f"meta/{nwFiles.OPTS_FILE}"),
|
(baseMeta / nwFiles.OPTS_FILE, f"meta/{nwFiles.OPTS_FILE}"),
|
||||||
@@ -463,6 +462,7 @@ class _LegacyStorage:
|
|||||||
path / "cache" / "prevBuild.json", # Dropped in 2.1 Beta 1
|
path / "cache" / "prevBuild.json", # Dropped in 2.1 Beta 1
|
||||||
path / "cache", # Dropped in 2.1 Beta 1
|
path / "cache", # Dropped in 2.1 Beta 1
|
||||||
path / "ToC.json", # Dropped in 1.0 RC 1
|
path / "ToC.json", # Dropped in 1.0 RC 1
|
||||||
|
path / "nwProject.bak", # Dropped in 2.3 Beta 1
|
||||||
]
|
]
|
||||||
for item in remove:
|
for item in remove:
|
||||||
if item.exists():
|
if item.exists():
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, tstPaths, fncPath):
|
|||||||
refFile = tstPaths.filesDir / "nwProject-1.5.nwx"
|
refFile = tstPaths.filesDir / "nwProject-1.5.nwx"
|
||||||
tstFile = tstPaths.outDir / "ProjectXML_ReadCurrent.nwx"
|
tstFile = tstPaths.outDir / "ProjectXML_ReadCurrent.nwx"
|
||||||
xmlFile = fncPath / "nwProject-1.5.nwx"
|
xmlFile = fncPath / "nwProject-1.5.nwx"
|
||||||
bakFile = fncPath / "nwProject-1.5.bak"
|
|
||||||
outFile = fncPath / "nwProject.nwx"
|
outFile = fncPath / "nwProject.nwx"
|
||||||
|
|
||||||
xmlReader = ProjectXMLReader(xmlFile)
|
xmlReader = ProjectXMLReader(xmlFile)
|
||||||
@@ -71,16 +70,6 @@ def testCoreProjectXML_ReadCurrent(monkeypatch, tstPaths, fncPath):
|
|||||||
assert xmlReader.read(data, content) is False
|
assert xmlReader.read(data, content) is False
|
||||||
assert xmlReader.state == XMLReadState.CANNOT_PARSE
|
assert xmlReader.state == XMLReadState.CANNOT_PARSE
|
||||||
|
|
||||||
# Also add an invalid backup file
|
|
||||||
writeFile(bakFile, "")
|
|
||||||
assert xmlReader.read(data, content) is False
|
|
||||||
assert xmlReader.state == XMLReadState.CANNOT_PARSE
|
|
||||||
|
|
||||||
# Add a valid backup file, that is not novelWriter
|
|
||||||
writeFile(bakFile, "<xml/>")
|
|
||||||
assert xmlReader.read(data, content) is False
|
|
||||||
assert xmlReader.state == XMLReadState.NOT_NWX_FILE
|
|
||||||
|
|
||||||
# Add a valid project file, that is not novelWriter
|
# Add a valid project file, that is not novelWriter
|
||||||
writeFile(xmlFile, "<xml/>")
|
writeFile(xmlFile, "<xml/>")
|
||||||
assert xmlReader.read(data, content) is False
|
assert xmlReader.read(data, content) is False
|
||||||
|
|||||||
Reference in New Issue
Block a user