From 23d5e33864a844436a19cb78d211816f49dfbc3e Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Tue, 6 Oct 2020 14:29:33 +0200
Subject: [PATCH] Added large size handling to build tool
---
nw/core/tokenizer.py | 18 +++++++++++++++++-
nw/gui/build.py | 44 ++++++++++++++++++++++++++++++++++++++++----
2 files changed, 57 insertions(+), 5 deletions(-)
diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py
index eb6b98d8..2f172ca7 100644
--- a/nw/core/tokenizer.py
+++ b/nw/core/tokenizer.py
@@ -33,7 +33,7 @@ from PyQt5.QtCore import QRegularExpression
from nw.core.document import NWDoc
from nw.core.tools import numberToWord, numberToRoman
-from nw.constants import nwItemLayout, nwItemType, nwRegEx
+from nw.constants import nwConst, nwItemLayout, nwItemType, nwRegEx
logger = logging.getLogger(__name__)
@@ -120,6 +120,9 @@ class Tokenizer():
self.isNote = False
self.isNovel = False
+ # Error Handling
+ self.errData = []
+
return
##
@@ -212,6 +215,14 @@ class Tokenizer():
theDocument = NWDoc(self.theProject, self.theParent)
self.theText = theDocument.openDocument(theHandle)
+ docSize = len(self.theText)
+ if docSize > nwConst.maxDocSize:
+ errVal = "Document '%s' is too big (%.2f MB). Skipping." % (
+ self.theItem.itemName, docSize/1.0e6
+ )
+ self.theText = "# ERROR\n\n%s\n\n" % errVal
+ self.errData.append(errVal)
+
self.isNone = self.theItem.itemLayout == nwItemLayout.NO_LAYOUT
self.isTitle = self.theItem.itemLayout == nwItemLayout.TITLE
self.isBook = self.theItem.itemLayout == nwItemLayout.BOOK
@@ -230,6 +241,11 @@ class Tokenizer():
"""
return self.theResult
+ def getResultSize(self):
+ """Return the size of the result from the conversion.
+ """
+ return len(self.theResult)
+
def getFilteredMarkdown(self):
"""Return the novelWriter markdown after the filters have been applied.
"""
diff --git a/nw/gui/build.py b/nw/gui/build.py
index 5d36e026..52ceb549 100644
--- a/nw/gui/build.py
+++ b/nw/gui/build.py
@@ -49,7 +49,7 @@ from nw.common import fuzzyTime, makeFileNameSafe
from nw.gui.custom import QSwitch
from nw.core import ToHtml
from nw.constants import (
- nwAlert, nwFiles, nwItemType, nwItemLayout, nwItemClass
+ nwConst, nwAlert, nwFiles, nwItemType, nwItemLayout, nwItemClass
)
logger = logging.getLogger(__name__)
@@ -77,7 +77,7 @@ class GuiBuildNovel(QDialog):
self.theTheme = theParent.theTheme
self.optState = self.theProject.optState
- self.htmlText = [] # List of html document
+ self.htmlText = [] # List of html documents
self.htmlStyle = [] # List of html styles
self.nwdText = [] # List of markdown documents
self.buildTime = 0 # The timestamp of the last build
@@ -494,7 +494,15 @@ class GuiBuildNovel(QDialog):
self.docView.clearStyleSheet()
else:
self.docView.setStyleSheet(self.htmlStyle)
- self.docView.setContent(self.htmlText, self.buildTime)
+
+ htmlSize = sum([len(x) for x in self.htmlText])
+ if htmlSize < nwConst.maxBuildSize:
+ self.docView.setContent(self.htmlText, self.buildTime)
+ else:
+ self.docView.setText(
+ "Failed to generate preview. The result is too big."
+ )
+ self._enableQtSave(False)
else:
self.htmlText = []
self.htmlStyle = []
@@ -554,6 +562,8 @@ class GuiBuildNovel(QDialog):
self.htmlStyle = []
self.nwdText = []
+ htmlSize = 0
+
for nItt, tItem in enumerate(self.theProject.projTree):
noteRoot = noteFiles
@@ -578,6 +588,7 @@ class GuiBuildNovel(QDialog):
makeHtml.doPostProcessing()
self.htmlText.append(makeHtml.getResult())
self.nwdText.append(makeHtml.getFilteredMarkdown())
+ htmlSize += makeHtml.getResultSize()
except Exception as e:
logger.error("Failed to generate html of document '%s'" % tItem.itemHandle)
@@ -591,6 +602,12 @@ class GuiBuildNovel(QDialog):
# Update progress bar, also for skipped items
self.buildProgress.setValue(nItt+1)
+ if makeHtml.errData:
+ self.theParent.makeAlert((
+ "There were problems when building the project:"
+ "
- %s"
+ ) % "
- ".join(makeHtml.errData), nwAlert.ERROR)
+
if replaceTabs:
htmlText = []
eightSpace = " "*8
@@ -615,7 +632,16 @@ class GuiBuildNovel(QDialog):
self.docView.clearStyleSheet()
else:
self.docView.setStyleSheet(self.htmlStyle)
- self.docView.setContent(self.htmlText, self.buildTime)
+
+ if htmlSize < nwConst.maxBuildSize:
+ self.docView.setContent(self.htmlText, self.buildTime)
+ self._enableQtSave(True)
+ else:
+ self.docView.setText(
+ "Failed to generate preview. The result is too big."
+ )
+ allowQtSave = False
+ self._enableQtSave(False)
self._saveCache()
@@ -962,6 +988,16 @@ class GuiBuildNovel(QDialog):
# Internal Functions
##
+ def _enableQtSave(self, theState):
+ """Set the enabled status of Save menu entries that depend on
+ the QTextDocument.
+ """
+ self.saveODT.setEnabled(theState)
+ self.savePDF.setEnabled(theState)
+ self.saveMD.setEnabled(theState)
+ self.saveTXT.setEnabled(theState)
+ return
+
def _saveSettings(self):
"""Save the various user settings.
"""