Author: ianb
Date: 2004-04-14 00:22:14 -0600 (Wed, 14 Apr 2004)
New Revision: 56
Added:
Wiki/Context/exclamation.gif
Modified:
Wiki/Context/recentchanges.py
Wiki/lib/rfc822persist.py
Wiki/lib/wiki.py
Wiki/lib/wikiconfig.py
Wiki/lib/wikipage.py
Log:
Added better error handling during reST parsing; added error detection,
so errors could be summarized.
Added: Wiki/Context/exclamation.gif
===================================================================
(Binary files differ)
Property changes on: Wiki/Context/exclamation.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: Wiki/Context/recentchanges.py
===================================================================
--- Wiki/Context/recentchanges.py 2004-04-14 04:23:44 UTC (rev 55)
+++ Wiki/Context/recentchanges.py 2004-04-14 06:22:14 UTC (rev 56)
@@ -18,14 +18,21 @@
rowClass = 'even'
else:
rowClass = 'odd'
- self.write('<tr class="%s"><td><a href="%s">%s</a></td>\n'
- % (rowClass, page.link, page.title))
+ if page.hasParseErrors:
+ bang = ('<td><img src="%s" width=12 height=18 '
+ 'alt="errors"></td>\n'
+ % (self.wiki.linkTo('exclamation.gif')))
+ else:
+ bang = ''
+ self.write('<tr class="%s"><td><a href="%s">%s%s</a></td>\n'
+ % (rowClass, page.link, page.title, bang))
self.write('<td>%s</td>\n'
% self.formatDate(page.modifiedDate, nonbreaking=True))
self.write('<td>%s</td>\n'
% self.htmlEncode(page.lastChangeLog))
- self.write('<td>%s</td></tr>\n'
+ self.write('<td>%s</td>\n'
% self.htmlEncode(page.lastChangeUser))
+ self.write('</tr>\n')
self.write('</table><br><br>')
def title(self):
Modified: Wiki/lib/rfc822persist.py
===================================================================
--- Wiki/lib/rfc822persist.py 2004-04-14 04:23:44 UTC (rev 55)
+++ Wiki/lib/rfc822persist.py 2004-04-14 06:22:14 UTC (rev 56)
@@ -40,6 +40,7 @@
self.filename = filename
self._data = None
self.lazy = lazy
+ self.dirty = False
def __getitem__(self, key):
if self._data is None:
@@ -51,6 +52,7 @@
if self._data is None:
self._readData()
self._data[key] = value
+ self.dirty = True
if not self.lazy:
self._saveData()
@@ -58,6 +60,7 @@
if self._data is None:
self._readData()
del self._data[key]
+ self.dirty = True
if not self.lazy:
self._saveData()
@@ -70,6 +73,7 @@
self._data = None
def save(self):
+ self.dirty = False
self._saveData()
def _readData(self):
Modified: Wiki/lib/wiki.py
===================================================================
--- Wiki/lib/wiki.py 2004-04-14 04:23:44 UTC (rev 55)
+++ Wiki/lib/wiki.py 2004-04-14 06:22:14 UTC (rev 56)
@@ -89,6 +89,8 @@
else:
needRebuild = False
self.index = wikiindex.WikiIndex(self.config.basePath)
+ if config.rebuildHTML:
+ self._rebuildHTML()
if needRebuild:
self._rebuildIndex()
if config.rebuildStatic:
@@ -210,6 +212,11 @@
f.write(result)
f.close()
+ def _rebuildHTML(self):
+ print "Rerending HTML"
+ for page in self.allPages():
+ page.rerender()
+
def _rebuildStatic(self):
print "Rebuilding static pages"
for page in self.allPages():
Modified: Wiki/lib/wikiconfig.py
===================================================================
--- Wiki/lib/wikiconfig.py 2004-04-14 04:23:44 UTC (rev 55)
+++ Wiki/lib/wikiconfig.py 2004-04-14 06:22:14 UTC (rev 56)
@@ -94,8 +94,11 @@
return self._cascadeGet('rebuildindex', type='getboolean',
default=False)
def rebuildStatic__get(self):
- return self._cascadeGet('rebuildStatic', type='getboolean',
+ return self._cascadeGet('rebuildstatic', type='getboolean',
default=False)
+ def rebuildHTML__get(self):
+ return self._cascadeGet('rebuildhtml', type='getboolean',
+ default=False)
def staticPublish__get(self):
return self._cascadeGet('staticpublish',
Modified: Wiki/lib/wikipage.py
===================================================================
--- Wiki/lib/wikipage.py 2004-04-14 04:23:44 UTC (rev 55)
+++ Wiki/lib/wikipage.py 2004-04-14 06:22:14 UTC (rev 56)
@@ -11,8 +11,13 @@
import shutil
from datetime import datetime
from cgi import escape as cgiEscape
+import traceback
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
-__all__ = ['WikiPage']
+__all__ = ['WikiPage', 'canonicalName']
class WikiPage(object):
"""
@@ -93,15 +98,26 @@
return ''
filename = self.basePath + ".html"
if not os.path.exists(filename):
- f = open(filename, 'w')
- html = self._convertText(self.text)
- f.write(html)
- f.close()
- return html
+ return self.rerender()
else:
html = open(filename).read()
return html
+ def rerender(self):
+ filename = self.basePath + ".html"
+ f = open(filename, 'w')
+ html = self._convertText(self.text)
+ f.write(html)
+ f.close()
+ if self._checkErrors(html):
+ self.hasParseErrors = True
+ if not self.metadata.dirty:
+ # This means we can safely update the metadata
+ # immediately; otherwise we should wait for the
+ # caller to call .save()
+ self.metadata.save()
+ return html
+
def readOnly__get(self):
if self.version:
return True
@@ -179,30 +195,43 @@
parser_name='restructuredtext',
writer_name='html',
settings_overrides={'traceback': 1}))
- except SystemMessage, msg:
- return self._formatError(msg)
- except:
+ except SystemMessage, error:
+ return self._formatError(error, None)
+ except Exception, error:
print "Error in page: %s" % self.name
- raise
+ out = StringIO()
+ traceback.print_exc(file=out)
+ return self._formatError(error, out.getvalue())
- def _formatError(self, error):
- assert isinstance(error, SystemMessage)
- # We expect a format like col:line: (LEVEL/INT) Message\ntext
- msg = error.args[0]
- col, line, rest = msg.split(':', 2)
- level, rest = rest.split(')', 1)
- level = level.strip()[1:]
- message, text = rest.split('\n', 1)
- return '''<div class="system-message">
- <p class="system-message-title">
- SystemMessage: %s (%s:%s)</p>
- <p>%s</p>
- <pre>%s</pre>
- </div>''' % (htmlEncode(level),
- col, line,
- htmlEncode(message),
- htmlEncode(text))
+ def _formatError(self, error, traceback):
+ if isinstance(error, SystemMessage):
+ # We expect a format like col:line: (LEVEL/INT) Message\ntext
+ msg = error.args[0]
+ col, line, rest = msg.split(':', 2)
+ level, rest = rest.split(')', 1)
+ level = level.strip()[1:]
+ message, text = rest.split('\n', 1)
+ return '''<div class="system-message">
+ <p class="system-message-title">
+ SystemMessage: %s (%s:%s)</p>
+ <p>%s</p>
+ <pre>%s</pre>
+ </div>''' % (htmlEncode(level),
+ col, line,
+ htmlEncode(message),
+ htmlEncode(text))
+ else:
+ return '''<div class="system-message">
+ <p class="system-message-title">
+ <p class="system-message-title">%s</p>
+ <pre>%s</pre>
+ </div>''' % (htmlEncode(str(error)),
+ htmlEncode(traceback))
+ _checkErrorsRE = re.compile('class="system-message"')
+ def _checkErrors(self, html):
+ return self._checkErrorsRE.search(html)
+
def _cleanHTML(self, html):
return html[html.find('<body>')+6:html.find('</body>')]
@@ -259,6 +288,15 @@
def lastChangeUser__set(self, value):
self.metadata['lastChangeUser'] = value
+ def hasParseErrors__get(self):
+ return self.metadata.get('hasParseErrors', '').lower()=='true'
+ def hasParseErrors__set(self, value):
+ if not value:
+ if self.metadata.has_key('hasParseErrors'):
+ del self.metadata['hasParseErrors']
+ else:
+ self.metadata['hasParseErrors'] = 'True'
+
def save(self):
action = 'edit'
if not self.exists():
@@ -270,6 +308,7 @@
html = self._convertText(self._text)
f.write(html)
f.close()
+ self.hasParseErrors = self._checkErrors(html)
self._text = None
self.metadata.save()
self.backup()
|