changeset 3062:94941d9d30ee

refactored action.PackagePages for CloneWikiPagesByPackagePages (Thanks to Federico Lorenzi) (ported from 1.6)
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Thu, 21 Feb 2008 21:11:06 +0100
parents 861407f630b4
children 726f96c0f12e
files MoinMoin/action/PackagePages.py MoinMoin/script/export/package.py
diffstat 2 files changed, 164 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/PackagePages.py	Thu Feb 21 20:51:11 2008 +0100
+++ b/MoinMoin/action/PackagePages.py	Thu Feb 21 21:11:06 2008 +0100
@@ -20,6 +20,7 @@
 from MoinMoin.packages import MOIN_PACKAGE_FILE, packLine, unpackLine
 from MoinMoin.action import AttachFile
 from MoinMoin.action.AttachFile import _get_files
+from MoinMoin.search import searchPages
 
 class ActionError(Exception):
     pass
@@ -62,10 +63,9 @@
             return self.page.send_page()
 
     def package(self):
-        """ Packages pages. """
+        """ Calls collectpackage() with the arguments specified. """
         _ = 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]
@@ -75,18 +75,6 @@
             self.request.theme.add_msg(self.makeform(), "dialog")
             raise ActionError
 
-        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:
-            self.request.theme.add_msg(self.makeform(_('No pages like "%s"!') % wikiutil.escape(pagelist)), "error")
-            raise ActionError
-
-        pagelist = ', '.join([getattr(page, "page_name") for page in pages])
         target = wikiutil.taintfilename(packagename)
 
         if not target:
@@ -101,32 +89,13 @@
                 'target': wikiutil.escape(target), 'filename': wikiutil.escape(target)}, "error")
             raise ActionError
 
-        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."]))
+         # Generate a package
+        output = open(fpath, "wb")
+        package = self.collectpackage(unpackLine(pagelist, ","), output, target)
 
-            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()
+        if package:
+            self.request.theme.add_msg(self.makeform(), "dialog")
+            raise ActionError
 
         _addLogEntry(self.request, 'ATTNEW', self.pagename, target)
 
@@ -183,6 +152,77 @@
 
         return Dialog(self.request, content=form)
 
+    def searchpackage(self, request, searchkey):
+        """ Search MoinMoin for the string specified and return a list of
+        matching pages, provided they are not system pages and not
+        present in the underlay.
+        
+        @param request: current request
+        @param searchkey: string to search for
+        @rtype: list
+        @return: list of pages matching searchkey
+        """
+
+        pagelist = searchPages(request, searchkey)
+        
+        titles = []
+        for title in pagelist.hits:
+            if not wikiutil.isSystemPage(request, title.page_name) or not title.page.getPageStatus()[0]:
+                titles.append(title.page_name)
+        return titles
+
+    def collectpackage(self, pagelist, fileobject, pkgname=""):
+        """ Expects a list of pages as an argument, and fileobject to be an open
+        file object, which a zipfile will get written to.
+        
+        @param pagelist: pages to package
+        @param fileobject: open file object to write to
+        @param pkgname: optional file name, to prevent self packaging
+        @rtype: string or None
+        @return: error message, if one happened
+        """
+        _ = self.request.getText
+        form = self.request.form
+        COMPRESSION_LEVEL = zipfile.ZIP_DEFLATED
+
+        pages = []
+        for pagename in 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:
+            return (_('No pages like "%s"!', formatted=False) % wikiutil.escape(pagelist))
+
+        # Set zipfile output
+        zf = zipfile.ZipFile(fileobject, "w", COMPRESSION_LEVEL)
+
+        cnt = 0
+        userid = user.getUserIdentification(self.request)
+        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, userid, "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 != pkgname:
+                    cnt += 1
+                    zipname = "%d_attachment" % cnt
+                    script.append(packLine(["AddAttachment", zipname, attname, page.page_name, userid, "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()
+
 def execute(pagename, request):
     """ Glue code for actions """
     PackagePages(pagename, request).render()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MoinMoin/script/export/package.py	Thu Feb 21 21:11:06 2008 +0100
@@ -0,0 +1,85 @@
+# -*- coding: iso-8859-1 -*-
+"""
+    MoinMoin - Create a MoinMoin package from wiki pages specified.
+
+    You must run this script as owner of the wiki files, usually this is the
+    web server user.
+
+    @copyright: 2002-2004 Juergen Hermann <jh@web.de>,
+                2005-2006 MoinMoin:ThomasWaldmann,
+                2007 Federico Lorenzi
+    @license: GNU GPL, see COPYING for details.
+
+"""
+
+import codecs, errno, os, re, shutil, sys, time
+
+from MoinMoin import config, wikiutil, Page, user
+from MoinMoin import script
+
+
+class PluginScript(script.MoinScript):
+    """ Create package class """
+
+    def __init__(self, argv=None, def_values=None):
+        script.MoinScript.__init__(self, argv, def_values)
+        self.parser.add_option(
+            "-p", "--pages", dest="pages",
+            help="List of pages to package. Can be regular expressions, comma seperated lists, or a lone * for everything."
+        )
+        self.parser.add_option(
+            "-o", "--output", dest="output",
+            help="Output file for the package."
+        )
+        self.parser.add_option(
+            "-s", "--search", dest="search",
+            help="Search string to match."
+        )
+        
+        self.parser.add_option(
+            "-u", "--user", dest="package_user",
+            help="User as whom the package operation will be performed as. "
+            )
+
+    def mainloop(self):
+        """ moin-package's main code. """
+        
+        # Initalize request
+        self.init_request()
+        request = self.request
+        _ = self.request.getText
+        
+        # Check our command line args
+        if self.options.pages and self.options.search:
+            script.fatal(_("Options --pages and --search are mutually exclusive!"))
+        elif not self.options.output:
+            script.fatal(_("You must specify an output file!"))
+        elif not self.options.pages and not self.options.search:
+            script.log(_("No pages specified using --pages or --search, assuming full package."))
+
+        # Sanity checks
+        if os.path.exists(self.options.output):
+            script.fatal(_("Output file already exists! Cowardly refusing to continue!"))
+        
+        # Check for user
+        if self.options.package_user:
+            request.user = user.User(request, name=self.options.package_user)
+        
+        # Import PackagePages here, as we now have an initalized request.
+        from MoinMoin.action.PackagePages import PackagePages
+        
+        # Perform actual packaging.
+        package = PackagePages(request.rootpage.page_name, request)
+        packageoutput = open(self.options.output, "wb")
+        if self.options.search:
+            packagedata = package.collectpackage(package.searchpackage(request,
+                                                                       self.options.search), packageoutput)
+        elif self.options.pages:
+                packagedata = package.collectpackage(self.options.pages.split(","), packageoutput)
+        else:
+                packagedata = package.collectpackage(request.rootpage.getPageList(
+                                include_underlay=False, 
+                                filter=lambda name: not wikiutil.isSystemPage(request, name)), 
+                                packageoutput)
+        if packagedata:
+            script.fatal(packagedata)