view MoinMoin/action/PackagePages.py @ 1777:ed44b93599b5

remove unneeded request param from page.send_page()
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 18 Feb 2007 21:39:36 +0100
parents f4ead22f4a0e
children 6dd2e29acffe
line wrap: on
line source
# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - PackagePages action

    This action allows you to package pages.

    TODO: use ActionBase class

    @copyright: 2005 MoinMoin:AlexanderSchremmer
    @license: GNU GPL, see COPYING for details.
"""

import os
import zipfile
from datetime import datetime

from MoinMoin import wikiutil, config, user
from MoinMoin.PageEditor import PageEditor
from MoinMoin.Page import Page
from MoinMoin.action.AttachFile import _addLogEntry
from MoinMoin.packages import MOIN_PACKAGE_FILE, packLine, unpackLine
from MoinMoin.action import AttachFile
from MoinMoin.action.AttachFile import _get_files

class ActionError(Exception): pass

class PackagePages:
    def __init__(self, pagename, request):
        self.request = request
        self.pagename = pagename
        self.page = Page(request, pagename)

    def allowed(self):
        """ Check if user is allowed to do this. """
        may = self.request.user.may
        return (not self.__class__.__name__ in self.request.cfg.actions_excluded and
                may.write(self.pagename))

    def render(self):
        """ Render action

        This action returns a wiki page with optional message, or
        redirects to new page.
        """
        _ = self.request.getText
        form = self.request.form

        if form.has_key('cancel'):
            # User canceled
            return self.page.send_page()

        try:
            if not self.allowed():
                raise ActionError(_('You are not allowed to edit this page.'))
            elif not self.page.exists():
                raise ActionError(_('This page is already deleted or was never created!'))

            self.package()
        except ActionError, e:
            return self.page.send_page(msg=e.args[0])

    def package(self):
        """ Packages pages. """
        _ = self.request.getText
        form = self.request.form
        COMPRESSION_LEVEL = zipfile.ZIP_DEFLATED

        # Get new name from form and normalize.
        pagelist = form.get('pagelist', [u''])[0]
        packagename = form.get('packagename', [u''])[0]

        if not form.get('submit', [None])[0]:
            raise ActionError(self.makeform())

        pages = []
        for pagename in unpackLine(pagelist, ","):
            pagename = self.request.normalizePagename(pagename)
            if pagename:
                page = Page(self.request, pagename)
                if page.exists() and self.request.user.may.read(pagename):
                    pages.append(page)
        if not pages:
            raise ActionError(self.makeform(_('No pages like "%s"!') % wikiutil.escape(pagelist)))

        pagelist = ', '.join([getattr(page, "page_name") for page in  pages])
        target = wikiutil.taintfilename(packagename)

        if not target:
            raise ActionError(self.makeform(_('Invalid filename "%s"!') % wikiutil.escape(packagename)))

        # get directory, and possibly create it
        attach_dir = Page(self.request, self.page.page_name).getPagePath("attachments", check_create=1)
        fpath = os.path.join(attach_dir, target).encode(config.charset)
        if os.path.exists(fpath):
            raise ActionError(_("Attachment '%(target)s' (remote name '%(filename)s') already exists.") % {
                'target': wikiutil.escape(target), 'filename': wikiutil.escape(target)})

        zf = zipfile.ZipFile(fpath, "w", COMPRESSION_LEVEL)

        cnt = 0
        script = [packLine(['MoinMoinPackage', '1']),
                  ]

        for page in pages:
            cnt += 1
            files = _get_files(self.request, page.page_name)
            script.append(packLine(["AddRevision", str(cnt), page.page_name, user.getUserIdentification(self.request), "Created by the PackagePages action."]))

            timestamp = wikiutil.version2timestamp(page.mtime_usecs())
            zi = zipfile.ZipInfo(filename=str(cnt), date_time=datetime.fromtimestamp(timestamp).timetuple()[:6])
            zi.compress_type = COMPRESSION_LEVEL
            zf.writestr(zi, page.get_raw_body().encode("utf-8"))
            for attname in files:
                if attname != packagename:
                    cnt += 1
                    zipname = "%d_attachment" % cnt
                    script.append(packLine(["AddAttachment", zipname, attname, page.page_name, user.getUserIdentification(self.request), "Created by the PackagePages action."]))
                    filename = AttachFile.getFilename(self.request, page.page_name, attname)
                    zf.write(filename.encode("cp437"), zipname)
        script += [packLine(['Print', 'Thank you for using PackagePages!'])]

        zf.writestr(MOIN_PACKAGE_FILE, u"\n".join(script).encode("utf-8"))
        zf.close()

        _addLogEntry(self.request, 'ATTNEW', self.pagename, target)

        raise ActionError(_("Created the package %s containing the pages %s.") % (wikiutil.escape(target), wikiutil.escape(pagelist)))

    def makeform(self, error=""):
        """ Display a rename page form

        The form might contain an error that happened when trying to rename.
        """
        from MoinMoin.widget.dialog import Dialog
        _ = self.request.getText

        error = u'<p class="error">%s</p>\n' % error

        d = {
            'error': error,
            'action': self.__class__.__name__,
            'pagename': wikiutil.escape(self.pagename),
            'package': _('Package pages'),
            'cancel': _('Cancel'),
            'newname_label': _("Package name"),
            'list_label': _("List of page names - separated by a comma"),
        }
        form = '''
%(error)s
<form method="post" action="">
<input type="hidden" name="action" value="%(action)s">
<table>
    <tr>
        <td class="label"><label>%(newname_label)s</label></td>
        <td class="content">
            <input type="text" name="packagename" value="package.zip">
        </td>
    </tr>
    <tr>
        <td class="label"><label>%(list_label)s</label></td>
        <td class="content">
            <input type="text" name="pagelist" maxlength="200" value=%(pagename)s>
        </td>
    </tr>
    <tr>
        <td></td>
        <td class="buttons">
            <input type="submit" name="submit" value="%(package)s">
            <input type="submit" name="cancel" value="%(cancel)s">
        </td>
    </tr>
</table>
</form>''' % d

        return Dialog(self.request, content=form)

def execute(pagename, request):
    """ Glue code for actions """
    PackagePages(pagename, request).render()