[gen] Moved action-related stuff from mixins/__init__.py to field/action.py.
This commit is contained in:
parent
5de5372bec
commit
b5d38ad150
|
@ -15,6 +15,7 @@
|
||||||
# Appy. If not, see <http://www.gnu.org/licenses/>.
|
# Appy. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
import os.path
|
||||||
from appy.fields import Field
|
from appy.fields import Field
|
||||||
from appy.px import Px
|
from appy.px import Px
|
||||||
from appy.shared import utils as sutils
|
from appy.shared import utils as sutils
|
||||||
|
@ -26,11 +27,10 @@ class Action(Field):
|
||||||
|
|
||||||
# PX for viewing the Action button.
|
# PX for viewing the Action button.
|
||||||
pxView = pxCell = Px('''
|
pxView = pxCell = Px('''
|
||||||
<form name="executeAppyAction"
|
<form var="formId='%s_%s_form' % (zobj.id, name);
|
||||||
var="formId='%s_%s_form' % (zobj.UID(), name);
|
|
||||||
label=_(field.labelId)"
|
label=_(field.labelId)"
|
||||||
id=":formId" action=":ztool.absolute_url() + '/do'">
|
id=":formId" action=":ztool.absolute_url() + '/do'">
|
||||||
<input type="hidden" name="action" value="ExecuteAppyAction"/>
|
<input type="hidden" name="action" value="ExecuteAction"/>
|
||||||
<input type="hidden" name="objectUid" value=":zobj.id"/>
|
<input type="hidden" name="objectUid" value=":zobj.id"/>
|
||||||
<input type="hidden" name="fieldName" value=":name"/>
|
<input type="hidden" name="fieldName" value=":name"/>
|
||||||
<input if="field.confirm" type="button" class="button"
|
<input if="field.confirm" type="button" class="button"
|
||||||
|
@ -62,8 +62,6 @@ class Action(Field):
|
||||||
# message about execution of the action;
|
# message about execution of the action;
|
||||||
# * 'file' means that the result is the binary content of a file that
|
# * 'file' means that the result is the binary content of a file that
|
||||||
# the user will download.
|
# the user will download.
|
||||||
# * 'filetmp' is similar to file, but the file is a temp file and Appy
|
|
||||||
# will delete it as soon as it will be served to the browser.
|
|
||||||
# * 'redirect' means that the action will lead to the user being
|
# * 'redirect' means that the action will lead to the user being
|
||||||
# redirected to some other page.
|
# redirected to some other page.
|
||||||
self.result = result
|
self.result = result
|
||||||
|
@ -107,6 +105,38 @@ class Action(Field):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def isShowable(self, obj, layoutType):
|
def isShowable(self, obj, layoutType):
|
||||||
if layoutType == 'edit': return False
|
if layoutType == 'edit': return
|
||||||
else: return Field.isShowable(self, obj, layoutType)
|
return Field.isShowable(self, obj, layoutType)
|
||||||
|
|
||||||
|
def onUiRequest(self, obj, rq):
|
||||||
|
'''This method is called when a user triggers the execution of this
|
||||||
|
action from the user interface.'''
|
||||||
|
# Execute the action (method __call__).
|
||||||
|
actionRes = self(obj.appy())
|
||||||
|
parent = obj.getParentNode()
|
||||||
|
parentAq = getattr(parent, 'aq_base', parent)
|
||||||
|
if not hasattr(parentAq, obj.id):
|
||||||
|
# The action has led to obj's deletion.
|
||||||
|
obj.reindex()
|
||||||
|
# Unwrap action results.
|
||||||
|
successfull, msg = actionRes
|
||||||
|
if not msg:
|
||||||
|
# Use the default i18n messages.
|
||||||
|
suffix = successfull and 'done' or 'ko'
|
||||||
|
msg = obj.translate('action_%s' % suffix)
|
||||||
|
if (self.result == 'computation') or not successfull:
|
||||||
|
obj.say(msg)
|
||||||
|
return obj.goto(obj.getUrl(rq['HTTP_REFERER']))
|
||||||
|
elif self.result == 'file':
|
||||||
|
# msg does not contain a message, but a file instance.
|
||||||
|
response = rq.RESPONSE
|
||||||
|
response.setHeader('Content-Type', sutils.getMimeType(msg.name))
|
||||||
|
response.setHeader('Content-Disposition', 'inline;filename="%s"' %\
|
||||||
|
os.path.basename(msg.name))
|
||||||
|
response.write(msg.read())
|
||||||
|
msg.close()
|
||||||
|
elif self.result == 'redirect':
|
||||||
|
# msg does not contain a message, but the URL where to redirect
|
||||||
|
# the user.
|
||||||
|
return obj.goto(msg)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1155,54 +1155,11 @@ class BaseMixin:
|
||||||
if hasattr(appyObj, 'mayEdit'): return appyObj.mayEdit()
|
if hasattr(appyObj, 'mayEdit'): return appyObj.mayEdit()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def executeAppyAction(self, actionName, reindex=True):
|
def onExecuteAction(self):
|
||||||
'''Executes action with p_fieldName on this object.'''
|
|
||||||
appyType = self.getAppyType(actionName)
|
|
||||||
actionRes = appyType(self.appy())
|
|
||||||
parent = self.getParentNode()
|
|
||||||
parentAq = getattr(parent, 'aq_base', parent)
|
|
||||||
if not hasattr(parentAq, self.id):
|
|
||||||
# Else, it means that the action has led to self's deletion.
|
|
||||||
self.reindex()
|
|
||||||
return appyType.result, actionRes
|
|
||||||
|
|
||||||
def onExecuteAppyAction(self):
|
|
||||||
'''This method is called every time a user wants to execute an Appy
|
'''This method is called every time a user wants to execute an Appy
|
||||||
action on an object.'''
|
action on an object.'''
|
||||||
rq = self.REQUEST
|
rq = self.REQUEST
|
||||||
resultType, actionResult = self.executeAppyAction(rq['fieldName'])
|
return self.getAppyType(rq['fieldName']).onUiRequest(self, rq)
|
||||||
successfull, msg = actionResult
|
|
||||||
if not msg:
|
|
||||||
# Use the default i18n messages
|
|
||||||
suffix = 'ko'
|
|
||||||
if successfull: suffix = 'done'
|
|
||||||
msg = self.translate('action_%s' % suffix)
|
|
||||||
if (resultType == 'computation') or not successfull:
|
|
||||||
self.say(msg)
|
|
||||||
return self.goto(self.getUrl(rq['HTTP_REFERER']))
|
|
||||||
elif resultType.startswith('file'):
|
|
||||||
# msg does not contain a message, but a file instance.
|
|
||||||
response = self.REQUEST.RESPONSE
|
|
||||||
response.setHeader('Content-Type', sutils.getMimeType(msg.name))
|
|
||||||
response.setHeader('Content-Disposition', 'inline;filename="%s"' %\
|
|
||||||
os.path.basename(msg.name))
|
|
||||||
response.write(msg.read())
|
|
||||||
msg.close()
|
|
||||||
if resultType == 'filetmp':
|
|
||||||
# p_msg is a temp file. We need to delete it.
|
|
||||||
try:
|
|
||||||
os.remove(msg.name)
|
|
||||||
self.log('Temp file "%s" was deleted.' % msg.name)
|
|
||||||
except IOError, err:
|
|
||||||
self.log('Could not remove temp "%s" (%s).' % \
|
|
||||||
(msg.name, str(err)), type='warning')
|
|
||||||
except OSError, err:
|
|
||||||
self.log('Could not remove temp "%s" (%s).' % \
|
|
||||||
(msg.name, str(err)), type='warning')
|
|
||||||
elif resultType == 'redirect':
|
|
||||||
# msg does not contain a message, but the URL where to redirect
|
|
||||||
# the user.
|
|
||||||
return self.goto(msg)
|
|
||||||
|
|
||||||
def trigger(self, transitionName, comment='', doAction=True, doNotify=True,
|
def trigger(self, transitionName, comment='', doAction=True, doNotify=True,
|
||||||
doHistory=True, doSay=True, noSecurity=False):
|
doHistory=True, doSay=True, noSecurity=False):
|
||||||
|
|
Loading…
Reference in a new issue