view MoinMoin/script/export/ @ 3060:dae64bd781ad

Added a --dump-user option to the moin dump command. Thanks to Oliver O'Halloran. (ported from 1.6)
author Reimar Bauer <rb.proj AT googlemail DOT com>
date Thu, 21 Feb 2008 20:49:28 +0100
parents 3d08f1cb4429
children 861407f630b4
line wrap: on
line source

# -*- coding: iso-8859-1 -*-
    MoinMoin - Dump a MoinMoin wiki to static pages

    You must run this script as owner of the wiki files, usually this is the
    web server user.

    @copyright: 2002-2004 Juergen Hermann <>,
                2005-2006 MoinMoin:ThomasWaldmann
    @license: GNU GPL, see COPYING for details.


import sys, os, time, codecs, shutil, re, errno

from MoinMoin import config, wikiutil, Page, user
from MoinMoin import script
from MoinMoin.action import AttachFile

url_prefix_static = "."
logo_html = '<img src="logo.png">'
HTML_SUFFIX = ".html"

page_template = u'''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "">
<meta http-equiv="content-type" content="text/html; charset=%(charset)s">
<link rel="stylesheet" type="text/css" media="all" charset="utf-8" href="%(theme)s/css/common.css">
<link rel="stylesheet" type="text/css" media="screen" charset="utf-8" href="%(theme)s/css/screen.css">
<link rel="stylesheet" type="text/css" media="print" charset="utf-8" href="%(theme)s/css/print.css">
<div id="page">
<h1 id="title">%(pagename)s</h1>

def _attachment(request, pagename, filename, outputdir):
    filename = filename.encode(config.charset)
    source_dir = AttachFile.getAttachDir(request, pagename)
    source_file = os.path.join(source_dir, filename)
    dest_dir = os.path.join(outputdir, "attachments", wikiutil.quoteWikinameFS(pagename))
    dest_file = os.path.join(dest_dir, filename)
    dest_url = "attachments/%s/%s" % (wikiutil.quoteWikinameFS(pagename), wikiutil.url_quote(filename))
    if os.access(source_file, os.R_OK):
        if not os.access(dest_dir, os.F_OK):
                script.fatal("Cannot create attachment directory '%s'" % dest_dir)
        elif not os.path.isdir(dest_dir):
            script.fatal("'%s' is not a directory" % dest_dir)

        shutil.copyfile(source_file, dest_file)
        script.log('Writing "%s"...' % dest_url)
        return dest_url
        return ""

class PluginScript(script.MoinScript):
    """ Dump script class """

    def __init__(self, argv=None, def_values=None):
        script.MoinScript.__init__(self, argv, def_values)
            "-t", "--target-dir", dest = "target_dir",
            help = "Write html dump to DIRECTORY"
            "-u", "--username", dest = "dump_user",
            help = "User the dump will be performed as (for ACL checks, etc)"

    def mainloop(self):
        """ moin-dump's main code. """

        # Prepare output directory
        if not self.options.target_dir:
            script.fatal("you must use --target-dir=/your/output/path to specify the directory we write the html files to")
        outputdir = os.path.abspath(self.options.target_dir)
            script.log("Created output directory '%s'!" % outputdir)
        except OSError, err:
            if err.errno != errno.EEXIST:
                script.fatal("Cannot create output directory '%s'!" % outputdir)

        # Insert config dir or the current directory to the start of the path.
        config_dir = self.options.config_dir
        if config_dir and os.path.isfile(config_dir):
            config_dir = os.path.dirname(config_dir)
        if config_dir and not os.path.isdir(config_dir):
            script.fatal("bad path given to --config-dir option")
        sys.path.insert(0, os.path.abspath(config_dir or os.curdir))

        request = self.request

        # fix url_prefix_static so we get relative paths in output html
        request.cfg.url_prefix_static = url_prefix_static

        # use this user for permissions checks
        request.user = user.User(request, auth_username = self.options.dump_user)

        pages = request.rootpage.getPageList(user='') # get list of all pages in wiki
        if # did user request a particular page or group of pages?
                namematch = re.compile(
                pages = [page for page in pages if namematch.match(page)]
                if not pages:
                    pages = []
                pages = []

        wikiutil.quoteWikinameURL = lambda pagename, qfn=wikiutil.quoteWikinameFS: (qfn(pagename) + HTML_SUFFIX)

        AttachFile.getAttachUrl = lambda pagename, filename, request: (_attachment(request, pagename, filename, outputdir))

        errfile = os.path.join(outputdir, 'error.log')
        errlog = open(errfile, 'w')
        errcnt = 0

        page_front_page = wikiutil.getLocalizedPage(request, request.cfg.page_front_page).page_name
        page_title_index = wikiutil.getLocalizedPage(request, 'TitleIndex').page_name
        page_word_index = wikiutil.getLocalizedPage(request, 'WordIndex').page_name

        navibar_html = ''
        for p in [page_front_page, page_title_index, page_word_index]:
            navibar_html += '&nbsp;[<a href="%s">%s</a>]' % (wikiutil.quoteWikinameURL(p), wikiutil.escape(p))

        urlbase = request.url # save wiki base url
        for pagename in pages:
            # we have the same name in URL and FS
            file = wikiutil.quoteWikinameURL(pagename)
            script.log('Writing "%s"...' % file)
                pagehtml = ''
                request.url = urlbase + pagename # add current pagename to url base
                page = Page.Page(request, pagename)
       = page
                    pagehtml = request.redirectedOutput(page.send_page, count_hit=0, content_only=1)
                    errcnt = errcnt + 1
                    print >> sys.stderr, "*** Caught exception while writing page!"
                    print >> errlog, "~" * 78
                    print >> errlog, file # page filename
                    import traceback
                    traceback.print_exc(None, errlog)
                timestamp = time.strftime("%Y-%m-%d %H:%M")
                filepath = os.path.join(outputdir, file)
                fileout =, 'w', config.charset)
                fileout.write(page_template % {
                    'charset': config.charset,
                    'pagename': pagename,
                    'pagehtml': pagehtml,
                    'logo_html': logo_html,
                    'navibar_html': navibar_html,
                    'timestamp': timestamp,
                    'theme': request.cfg.theme_default,

        # copy FrontPage to "index.html"
        indexpage = page_front_page
            indexpage = pages[0] # index page has limited use when dumping specific pages, but create one anyway
            os.path.join(outputdir, wikiutil.quoteWikinameFS(indexpage) + HTML_SUFFIX),
            os.path.join(outputdir, 'index' + HTML_SUFFIX)

        if errcnt:
            print >> sys.stderr, "*** %d error(s) occurred, see '%s'!" % (errcnt, errfile)