appy.gen: bugfixes.

This commit is contained in:
Gaetan Delannay 2011-12-05 18:15:45 +01:00
parent c5a8968bd3
commit d5f26dd1df
7 changed files with 44 additions and 39 deletions

View file

@ -398,4 +398,6 @@ class ZopeInstaller:
self.installCatalog() self.installCatalog()
self.installTool() self.installTool()
self.installUi() self.installUi()
# Empty the fake REQUEST object, only used at Zope startup.
del self.app.config.getProductConfig().fakeRequest.wrappers
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -1,5 +1,5 @@
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
import re, os, os.path, time, random, types, base64, urllib import os, os.path, sys, re, time, random, types, base64, urllib
from appy.shared import mimeTypes from appy.shared import mimeTypes
from appy.shared.utils import getOsTempFolder from appy.shared.utils import getOsTempFolder
from appy.shared.data import languages from appy.shared.data import languages
@ -96,17 +96,14 @@ class ToolMixin(BaseMixin):
p_code.''' p_code.'''
return languages.get(code)[2] return languages.get(code)[2]
def getMessages(self): def consumeMessages(self):
'''Returns the list of messages to return to the user.''' '''Returns the list of messages to show to a web page and clean it in
if hasattr(self.REQUEST, 'messages'): the session.'''
# Empty the messages and return it rq = self.REQUEST
res = self.REQUEST.messages res = rq.SESSION.get('messages', '')
del self.REQUEST.messages if res:
else: del rq.SESSION['messages']
res = [] res = ' '.join([m[1] for m in res])
# Add portal_status_message key if present
if 'portal_status_message' in self.REQUEST:
res.append( ('info', self.REQUEST['portal_status_message']) )
return res return res
def getRootClasses(self): def getRootClasses(self):
@ -960,4 +957,15 @@ class ToolMixin(BaseMixin):
randomNumber = str(random.random()).split('.')[1] randomNumber = str(random.random()).split('.')[1]
timestamp = ('%f' % time.time()).replace('.', '') timestamp = ('%f' % time.time()).replace('.', '')
return '%s%s%s' % (name, timestamp, randomNumber) return '%s%s%s' % (name, timestamp, randomNumber)
def manageError(self, error):
'''Manages an error.'''
tb = sys.exc_info()
from zExceptions.ExceptionFormatter import format_exception
htmlMessage = format_exception(tb[0], tb[1], tb[2], as_html=1)
textMessage = format_exception(tb[0], tb[1], tb[2], as_html=0)
self.log(''.join(textMessage).strip(), type='error')
return '<table class="main" align="center" cellpadding="0"><tr>' \
'<td style="padding: 1em 1em 1em 1em">An error occurred. %s' \
'</td></tr></table>' % '\n'.join(htmlMessage)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -314,15 +314,13 @@ class BaseMixin:
def say(self, msg, type='info'): def say(self, msg, type='info'):
'''Prints a p_msg in the user interface. p_logLevel may be "info", '''Prints a p_msg in the user interface. p_logLevel may be "info",
"warning" or "error".''' "warning" or "error".'''
mType = type
rq = self.REQUEST rq = self.REQUEST
if not hasattr(rq, 'messages'): if 'messages' not in rq.SESSION.keys():
messages = rq.messages = [] plist = self.getProductConfig().PersistentList
messages = rq.SESSION['messages'] = plist()
else: else:
messages = rq.messages messages = rq.SESSION['messages']
if mType == 'warning': mType = 'warn' messages.append( (type, msg) )
elif mType == 'error': mType = 'stop'
messages.append( (mType, msg) )
def log(self, msg, type='info'): def log(self, msg, type='info'):
'''Logs a p_msg in the log file. p_logLevel may be "info", "warning" '''Logs a p_msg in the log file. p_logLevel may be "info", "warning"
@ -409,13 +407,7 @@ class BaseMixin:
def goto(self, url, msg=None): def goto(self, url, msg=None):
'''Brings the user to some p_url after an action has been executed.''' '''Brings the user to some p_url after an action has been executed.'''
if msg: if msg: self.say(msg)
# Remove previous message if any
if 'portal_status_message=' in url:
url = url[:url.find('portal_status_message=')-1]
if '?' in url: op = '&'
else: op = '?'
url += op + urllib.urlencode([('portal_status_message',msg)])
return self.REQUEST.RESPONSE.redirect(url) return self.REQUEST.RESPONSE.redirect(url)
def gotoEdit(self): def gotoEdit(self):
@ -1085,9 +1077,12 @@ class BaseMixin:
way.''' way.'''
# Create the dict for storing Appy wrapper on the REQUEST if needed. # Create the dict for storing Appy wrapper on the REQUEST if needed.
rq = getattr(self, 'REQUEST', None) rq = getattr(self, 'REQUEST', None)
if not rq: rq = Object() if not rq:
# We are in test mode or Zope is starting. Use static variable
# config.fakeRequest instead.
rq = self.getProductConfig().fakeRequest
if not hasattr(rq, 'wrappers'): rq.wrappers = {} if not hasattr(rq, 'wrappers'): rq.wrappers = {}
# Return the Appy wrapper from rq.wrappers if already there # Return the Appy wrapper if already present in the cache
uid = self.UID() uid = self.UID()
if uid in rq.wrappers: return rq.wrappers[uid] if uid in rq.wrappers: return rq.wrappers[uid]
# Create the Appy wrapper, cache it in rq.wrappers and return it # Create the Appy wrapper, cache it in rq.wrappers and return it
@ -1293,14 +1288,8 @@ class BaseMixin:
return self.__class__.config return self.__class__.config
def index_html(self): def index_html(self):
"""Redirects to /ui. Transfers the status message if any.""" '''Redirects to /ui.'''
rq = self.REQUEST return self.REQUEST.RESPONSE.redirect(self.getUrl())
msg = rq.get('portal_status_message', '')
if msg:
url = self.getUrl(portal_status_message=msg)
else:
url = self.getUrl()
return rq.RESPONSE.redirect(url)
def userIsAnon(self): def userIsAnon(self):
'''Is the currently logged user anonymous ?''' '''Is the currently logged user anonymous ?'''

View file

@ -1,5 +1,6 @@
<!codeHeader!> <!codeHeader!>
import os, os.path, sys, copy import os, os.path, sys, copy
import appy
import appy.gen import appy.gen
import wrappers import wrappers
<!imports!> <!imports!>
@ -46,4 +47,8 @@ grantableRoles = [<!grRoles!>]
languages = [<!languages!>] languages = [<!languages!>]
languageSelector = <!languageSelector!> languageSelector = <!languageSelector!>
sourceLanguage = '<!sourceLanguage!>' sourceLanguage = '<!sourceLanguage!>'
# When Zope is starting or runs in test mode, there is no request object. We
# create here a fake one for storing Appy wrappers.
fakeRequest = appy.Object()
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View file

@ -1,4 +1,5 @@
body { font: 70% Lucida,Helvetica,Arial,sans-serif; background-color: #EAEAEA; } body { font: 70% Lucida,Helvetica,Arial,sans-serif; background-color: #EAEAEA; }
pre { font: 100% Lucida,Helvetica,Arial,sans-serif; margin: 0}
h1 { font-size: 11pt; margin:0;} h1 { font-size: 11pt; margin:0;}
h2 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;} h2 { font-size: 10pt; margin:0; font-style: italic; font-weight: normal;}
h3 { font-size: 9pt; margin:0; font-weight: bold;} h3 { font-size: 9pt; margin:0; font-weight: bold;}

View file

@ -313,6 +313,6 @@
<tal:comment replace="nothing"> <tal:comment replace="nothing">
This macro displays the global message on the page. This macro displays the global message on the page.
</tal:comment> </tal:comment>
<metal:message define-macro="message" tal:define="messages tool/getMessages" tal:condition="messages"> <metal:message define-macro="message" tal:define="messages tool/consumeMessages" tal:condition="messages">
<div class="message" tal:content="structure python: ''.join([m[1] for m in messages])"></div> <div class="message" tal:content="structure messages"></div>
</metal:message> </metal:message>

View file

@ -18,7 +18,7 @@
<script type="text/javascript" tal:attributes="src string:$appUrl/ui/appy.js"></script> <script type="text/javascript" tal:attributes="src string:$appUrl/ui/appy.js"></script>
</head> </head>
<body> <body tal:on-error="structure python: tool.manageError(error)">
<table class="main" align="center" cellpadding="0"> <table class="main" align="center" cellpadding="0">
<tal:comment replace="nothing">Top banner</tal:comment> <tal:comment replace="nothing">Top banner</tal:comment>
<tr class="top" metal:define-slot="top"> <tr class="top" metal:define-slot="top">