Mercurial > moin > 1.9
changeset 6018:b85dc05a75e1
AttachFile: move or delete multiple attachments
author | Thomas Waldmann <tw AT waldmann-edv DOT de> |
---|---|
date | Fri, 31 Jan 2014 18:33:18 +0100 |
parents | 06af086f97f5 |
children | 926d83725c3a |
files | MoinMoin/action/AttachFile.py |
diffstat | 1 files changed, 131 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/MoinMoin/action/AttachFile.py Sat Jan 11 03:53:05 2014 +0100 +++ b/MoinMoin/action/AttachFile.py Fri Jan 31 18:33:18 2014 +0100 @@ -265,6 +265,54 @@ return target, filesize +class SamePath(Exception): + """ + raised if an attachment move is attempted to same target path + """ + +class DestPathExists(Exception): + """ + raised if an attachment move is attempted to an existing target path + """ + + +def move_attachment(request, pagename, dest_pagename, target, dest_target, + overwrite=False): + """ move attachment <target> of page <pagename> + to attachment <dest_target> of page <dest_pagename> + + note: this is lowlevel code, acl permissions need to be checked before + and also the target page should somehow exist (can be "deleted", + but the pagedir should be there) + """ + # replace illegal chars + target = wikiutil.taintfilename(target) + dest_target = wikiutil.taintfilename(dest_target) + + attachment_path = os.path.join(getAttachDir(request, pagename), + target).encode(config.charset) + dest_attachment_path = os.path.join(getAttachDir(request, dest_pagename, create=1), + dest_target).encode(config.charset) + if not overwrite and os.path.exists(dest_attachment_path): + raise DestPathExists + if dest_attachment_path == attachment_path: + raise SamePath + filesize = os.path.getsize(attachment_path) + try: + filesys.rename(attachment_path, dest_attachment_path) + except Exception: + raise + else: + _addLogEntry(request, 'ATTDEL', pagename, target) + event = FileRemovedEvent(request, pagename, target, filesize) + send_event(event) + _addLogEntry(request, 'ATTNEW', dest_pagename, dest_target) + event = FileAttachedEvent(request, dest_pagename, dest_target, filesize) + send_event(event) + + return dest_target, filesize + + ############################################################################# ### Internal helpers ############################################################################# @@ -346,6 +394,22 @@ may_write = request.user.may.write(pagename) may_delete = request.user.may.delete(pagename) + html.append(u"""\ +<script> +function checkAll(bx, targets_name) { + var cbs = document.getElementsByTagName('input'); + for(var i=0; i < cbs.length; i++) { + if(cbs[i].type == 'checkbox' && cbs[i].name == targets_name) { + cbs[i].checked = bx.checked; + } + } +} +</script> +<form method="POST"> +<input type="hidden" name="action" value="AttachFile"> +<input type="hidden" name="do" value="multifile"> +""") + html.append(fmt.bullet_list(1)) for file in files: mt = wikiutil.MimeType(filename=file) @@ -410,9 +474,26 @@ html.append(fmt.listitem(1)) html.append("[%s]" % " | ".join(links)) + html.append('''<input type="checkbox" name="fn" value="%s">''' % file) html.append(" (%(fmtime)s, %(fsize)s KB) [[attachment:%(file)s]]" % parmdict) html.append(fmt.listitem(0)) html.append(fmt.bullet_list(0)) + html.append(u"""\ +<input type="checkbox" onclick="checkAll(this, 'fn')">\ + %(all_files)s | %(sel_files)s +<input type="radio" name="multifile" value="rm">%(delete)s</input> +<input type="radio" name="multifile" value="mv">%(move)s</input> +<input type="text" name="multi_dest_pagename" value="%(pagename)s"> +<input type="submit" value="%(submit)s"> +""" % dict( + all_files=_('All files'), + sel_files=_("Selected Files:"), + delete=_("delete"), + move=_("move to page"), + pagename=pagename, + submit=_("Do it."), +)) + html.append("</form>") else: if showheader: @@ -424,6 +505,35 @@ return ''.join(html) +def _do_multifile(pagename, request): + _ = request.getText + action = request.form.get('multifile') + fnames = request.form.getlist('fn') + if action == 'rm': + if not request.user.may.delete(pagename): + return _('You are not allowed to delete attachments on this page.') + for fn in fnames: + remove_attachment(request, pagename, fn) + msg = _("Attachment '%(filename)s' deleted.") % dict( + filename=u'{%s}' % ','.join(fnames)) + return upload_form(pagename, request, msg=msg) + if action == 'mv': + if not request.user.may.delete(pagename): + return _('You are not allowed to move attachments from this page.') + dest_pagename = request.form.get('multi_dest_pagename') + if not request.user.may.write(dest_pagename): + return _('You are not allowed to attach a file to this page.') + for fn in fnames: + move_attachment(request, pagename, dest_pagename, fn, fn) + msg = _("Attachment '%(pagename)s/%(filename)s' moved to '%(new_pagename)s/%(new_filename)s'.") % dict( + pagename=pagename, + filename=u'{%s}' % ','.join(fnames), + new_pagename=dest_pagename, + new_filename=u'*') + return upload_form(pagename, request, msg=msg) + return u'unsupported multifile operation' + + def _get_files(request, pagename): attach_dir = getAttachDir(request, pagename) if os.path.isdir(attach_dir): @@ -695,39 +805,30 @@ _ = request.getText newpage = Page(request, new_pagename) - if newpage.exists(includeDeleted=1) and request.user.may.write(new_pagename) and request.user.may.delete(pagename): - new_attachment_path = os.path.join(getAttachDir(request, new_pagename, - create=1), new_attachment).encode(config.charset) - attachment_path = os.path.join(getAttachDir(request, pagename), - attachment).encode(config.charset) - - if os.path.exists(new_attachment_path): - upload_form(pagename, request, - msg=_("Attachment '%(new_pagename)s/%(new_filename)s' already exists.") % { + if (newpage.exists(includeDeleted=1) + and + request.user.may.write(new_pagename) + and + request.user.may.delete(pagename)): + try: + move_attachment(request, pagename, new_pagename, + attachment, new_attachment) + except DestPathExists: + msg = _("Attachment '%(new_pagename)s/%(new_filename)s' already exists.") % { 'new_pagename': new_pagename, - 'new_filename': new_attachment}) - return - - if new_attachment_path != attachment_path: - filesize = os.path.getsize(attachment_path) - filesys.rename(attachment_path, new_attachment_path) - _addLogEntry(request, 'ATTDEL', pagename, attachment) - event = FileRemovedEvent(request, pagename, attachment, filesize) - send_event(event) - _addLogEntry(request, 'ATTNEW', new_pagename, new_attachment) - event = FileAttachedEvent(request, new_pagename, new_attachment, filesize) - send_event(event) - upload_form(pagename, request, - msg=_("Attachment '%(pagename)s/%(filename)s' moved to '%(new_pagename)s/%(new_filename)s'.") % { - 'pagename': pagename, - 'filename': attachment, - 'new_pagename': new_pagename, - 'new_filename': new_attachment}) + 'new_filename': new_attachment} + except SamePath: + msg = _("Nothing changed") else: - upload_form(pagename, request, msg=_("Nothing changed")) + msg = _("Attachment '%(pagename)s/%(filename)s' moved to '%(new_pagename)s/%(new_filename)s'.") % { + 'pagename': pagename, + 'filename': attachment, + 'new_pagename': new_pagename, + 'new_filename': new_attachment} else: - upload_form(pagename, request, msg=_("Page '%(new_pagename)s' does not exist or you don't have enough rights.") % { - 'new_pagename': new_pagename}) + msg = _("Page '%(new_pagename)s' does not exist or you don't have enough rights.") % { + 'new_pagename': new_pagename} + upload_form(pagename, request, msg=msg) def _do_attachment_move(pagename, request):