18
18
Additionally to the usual stuff, we provide an ActionBase class here with
19
19
some of the usual base functionality for an action, like checking
20
20
actions_excluded, making and checking tickets, rendering some form,
21
displaying errors and doing stuff after an action.
21
displaying errors and doing stuff after an action. Also utility functions
22
regarding actions are located here.
23
24
@copyright: 2000-2004 Juergen Hermann <jh@web.de>,
24
25
2006 MoinMoin:ThomasWaldmann
26
2008 MoinMoin:FlorianKrupicka
25
27
@license: GNU GPL, see COPYING for details.
28
32
from MoinMoin.util import pysupport
29
33
from MoinMoin import config, wikiutil
30
34
from MoinMoin.Page import Page
35
from MoinMoin.support.python_compatibility import set
32
37
# create a list of extension actions from the package directory
33
38
modules = pysupport.getPackageModules(__file__)
136
141
'method': self.method,
137
'baseurl': self.request.getScriptname(),
142
'url': self.request.href(self.pagename),
138
143
'enctype': self.enctype,
139
144
'error_html': error_html,
140
145
'actionname': self.actionname,
141
'pagename': self.pagename,
142
'pagename_quoted': wikiutil.quoteWikinameURL(self.pagename),
143
146
'ticket_html': ticket_html,
144
147
'user_html': self.get_form_html(buttons_html),
149
<form action="%(baseurl)s/%(pagename_quoted)s" method="%(method)s" enctype="%(enctype)s">
152
<form action="%(url)s" method="%(method)s" enctype="%(enctype)s">
151
154
<input type="hidden" name="action" value="%(actionname)s">
228
231
# Builtin Actions ------------------------------------------------------------
233
MIMETYPE_CRE = re.compile('[a-zA-Z0-9.+\-]{1,100}/[a-zA-Z0-9.+\-]{1,100}')
230
235
def do_raw(pagename, request):
231
236
""" send raw content of a page (e.g. wiki markup) """
232
237
if not request.user.may.read(pagename):
233
238
Page(request, pagename).send_page()
235
240
rev = request.rev or 0
236
Page(request, pagename, rev=rev).send_raw()
241
mimetype = request.values.get('mimetype', None)
242
if mimetype and not MIMETYPE_CRE.match(mimetype):
244
Page(request, pagename, rev=rev).send_raw(mimetype=mimetype)
238
def do_show(pagename, request, content_only=0, count_hit=1, cacheable=1, print_mode=0):
239
""" show a page, either current revision or the revision given by rev form value.
246
def do_show(pagename, request, content_only=0, count_hit=1, cacheable=1, print_mode=0, mimetype=u'text/html'):
247
""" show a page, either current revision or the revision given by "rev=" value.
240
248
if count_hit is non-zero, we count the request for statistics.
242
250
# We must check if the current page has different ACLs.
243
251
if not request.user.may.read(pagename):
244
252
Page(request, pagename).send_page()
246
mimetype = request.form.get('mimetype', [u"text/html"])[0]
254
mimetype = request.values.get('mimetype', mimetype)
247
255
rev = request.rev or 0
249
257
request.cacheable = cacheable
256
264
def do_format(pagename, request):
257
""" send a page using a specific formatter given by mimetype form key.
265
""" send a page using a specific formatter given by "mimetype=" value.
258
266
Since 5.5.2006 this functionality is also done by do_show, but do_format
259
267
has a default of text/plain when no format is given.
260
268
It also does not count in statistics and also does not set the cacheable flag.
261
269
DEPRECATED: remove this action when we don't need it any more for compatibility.
263
if 'mimetype' not in request.form:
264
request.form['mimetype'] = [u"text/plain"]
265
do_show(pagename, request, count_hit=0, cacheable=0)
271
do_show(pagename, request, count_hit=0, cacheable=0, mimetype=u'text/plain')
267
273
def do_content(pagename, request):
268
274
""" same as do_show, but we only show the content """
269
275
# XXX temporary fix to make it work until Page.send_page gets refactored
270
request.setHttpHeader("Content-Type: text/html; charset=%s" % config.charset)
271
request.setHttpHeader('Status: 200 OK')
272
request.emit_http_headers()
276
request.mimetype = 'text/html'
277
request.status_code = 200
273
278
do_show(pagename, request, count_hit=0, content_only=1)
275
280
def do_print(pagename, request):
283
288
def do_refresh(pagename, request):
284
289
""" Handle refresh action """
285
290
# Without arguments, refresh action will refresh the page text_html cache.
286
arena = request.form.get('arena', ['Page.py'])[0]
291
arena = request.values.get('arena', 'Page.py')
287
292
if arena == 'Page.py':
288
293
arena = Page(request, pagename)
289
key = request.form.get('key', ['text_html'])[0]
294
key = request.values.get('key', 'text_html')
291
296
# Remove cache entry (if exists), and send the page
292
297
from MoinMoin import caching
297
302
def do_goto(pagename, request):
298
303
""" redirect to another page """
299
target = request.form.get('target', [''])[0]
304
target = request.values.get('target', '')
300
305
request.http_redirect(Page(request, target).url(request))
302
307
# Dispatching ----------------------------------------------------------------
304
if not hasattr(cfg.cache, 'action_names'):
306
lnames.extend(wikiutil.getPlugins('action', cfg))
307
cfg.cache.action_names = lnames # remember it
308
return cfg.cache.action_names
308
def get_names(config):
309
""" Get a list of known actions.
311
@param config: a config object
313
@return: set of known actions
315
if not hasattr(config.cache, 'action_names'):
317
actions.extend(wikiutil.getPlugins('action', config))
318
actions = set([action for action in actions
319
if not action in config.actions_excluded])
320
config.cache.action_names = actions # remember it
321
return config.cache.action_names
310
323
def getHandler(request, action, identifier="execute"):
311
""" return a handler function for a given action or None """
324
""" return a handler function for a given action or None.
326
TODO: remove request dependency
312
329
# check for excluded actions
313
if action in request.cfg.actions_excluded:
330
if action in cfg.actions_excluded:
317
handler = wikiutil.importPlugin(request.cfg, "action", action, identifier)
334
handler = wikiutil.importPlugin(cfg, "action", action, identifier)
318
335
except wikiutil.PluginMissingError:
319
336
handler = globals().get('do_' + action)
340
def get_available_actions(config, page, user):
341
""" Get a list of actions available on a particular page
342
for a particular user.
344
The set does not contain actions that starts with lower case.
345
Themes use this set to display the actions to the user.
347
@param config: a config object (for the per-wiki actions)
348
@param page: the page to which the actions should apply
349
@param user: the user which wants to apply an action
351
@return: set of avaiable actions
353
if not user.may.read(page.page_name):
357
actions = get_names(config)
359
# Filter non ui actions (starts with lower case letter)
360
actions = [action for action in actions if not action[0].islower()]
362
# Filter actions by page type, acl and user state
364
if (page.isUnderlayPage() and not page.isStandardPage()) or \
365
not user.may.write(page.page_name) or \
366
not user.may.delete(page.page_name):
367
# Prevent modification of underlay only pages, or pages
368
# the user can't write and can't delete
369
excluded = [u'RenamePage', u'DeletePage', ] # AttachFile must NOT be here!
370
return set([action for action in actions if not action in excluded])