Mercurial > moin > 1.9
changeset 99:ce657f0e577b
implement restore backup subaction, with a already local backup file
imported from: moin--main--1.5--patch-101
author | Thomas Waldmann <tw@waldmann-edv.de> |
---|---|
date | Sat, 15 Oct 2005 13:56:10 +0000 |
parents | 8375a3795ff8 |
children | 9aa2836c997b |
files | MoinMoin/action/WikiBackup.py MoinMoin/action/backup.py MoinMoin/multiconfig.py |
diffstat | 3 files changed, 159 insertions(+), 81 deletions(-) [+] |
line wrap: on
line diff
--- a/MoinMoin/action/WikiBackup.py Sun Oct 09 02:20:53 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -# -*- coding: iso-8859-1 -*- -""" - MoinMoin - make a full backup of the wiki - - Triggering WikiBackup action will check if you are authorized to do - a backup and if yes, just send a - <siteid>-<date>--<time>.tar.<format> to you. - - @copyright: 2005 by MoinMoin:ThomasWaldmann - @license: GNU GPL, see COPYING for details. -""" - -import os, re, time, tarfile -from MoinMoin.util import MoinMoinNoFooter - - -defaultCompression = 'gz' -compressionOptions = ['gz', 'bz2'] - - -def addFiles(path, tar, exclude): - """ Add files in path to tar """ - for root, dirs, files in os.walk(path): - files.sort() # sorted page revs may compress better - for name in files: - path = os.path.join(root, name) - if exclude.search(path): - continue - tar.add(path) - - -def sendBackup(request, compression='gz'): - """ Send compressed tar file """ - tar = tarfile.open(fileobj=request, mode="w|%s" % compression) - # allow GNU tar's longer file/pathnames - tar.posix = False - exclude = re.compile("|".join(request.cfg.backup_exclude)) - - for path in request.cfg.backup_include: - addFiles(path, tar, exclude) - - tar.close() - - -def sendError(request, pagename, msg): - from MoinMoin import Page - return Page.Page(request, pagename).send_page(request, msg=msg) - - -def backupAllowed(request): - """ Return True if backup is allowed """ - action = __name__.split('.')[-1] - user = request.user - return (action not in request.cfg.actions_excluded and - user.valid and user.name in request.cfg.backup_users) - - -def execute(pagename, request): - _ = request.getText - if not backupAllowed(request): - return sendError(request, pagename, - msg=_('You are not allowed to do remote backup.')) - - compression = request.form.get('format', [defaultCompression])[0] - if compression not in compressionOptions: - return sendError(request, pagename, - msg=_('Unknown backup format: %s.' % compression)) - - dateStamp = time.strftime("%Y-%m-%d--%H-%M-%S-UTC", time.gmtime()) - filename = "%s-%s.tar.%s" % (request.cfg.siteid, dateStamp, compression) - - request.http_headers([ - # TODO: use more specific tar gz/bz2 content type? - "Content-Type: application/octet-stream", - "Content-Disposition: inline; filename=\"%s\"" % filename,]) - - sendBackup(request, compression) - - raise MoinMoinNoFooter -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MoinMoin/action/backup.py Sat Oct 15 13:56:10 2005 +0000 @@ -0,0 +1,155 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - make or restore a full backup of the wiki + + Triggering backup action will check if you are authorized to do + a backup and if yes, just send a + <siteid>-<date>--<time>.tar.<format> to you. + + @copyright: 2005 by MoinMoin:ThomasWaldmann + @license: GNU GPL, see COPYING for details. +""" + +import os, re, time, tarfile +import cStringIO +from MoinMoin import wikiutil +from MoinMoin.util import MoinMoinNoFooter + +def addFiles(path, tar, exclude): + """ Add files in path to tar """ + for root, dirs, files in os.walk(path): + files.sort() # sorted page revs may compress better + for name in files: + path = os.path.join(root, name) + if exclude.search(path): + continue + tar.add(path) + +def sendBackup(request): + """ Send compressed tar file """ + dateStamp = time.strftime("%Y-%m-%d--%H-%M-%S-UTC", time.gmtime()) + filename = "%s-%s.tar.%s" % (request.cfg.siteid, dateStamp, request.cfg.backup_compression) + request.http_headers([ + "Content-Type: application/octet-stream", + "Content-Disposition: inline; filename=\"%s\"" % filename,]) + + tar = tarfile.open(fileobj=request, mode="w|%s" % request.cfg.backup_compression) + # allow GNU tar's longer file/pathnames + tar.posix = False + exclude = re.compile("|".join(request.cfg.backup_exclude)) + for path in request.cfg.backup_include: + addFiles(path, tar, exclude) + tar.close() + raise MoinMoinNoFooter + +def restoreBackup(request, pagename): + _ = request.getText + path = request.cfg.backup_storage_dir + filename = "%s.tar.%s" % (request.cfg.siteid, request.cfg.backup_compression) + filename = os.path.join(path, filename) + targetdir = request.cfg.backup_restore_target_dir + try: + tar = tarfile.open(fileobj=file(filename), mode="r|%s" % request.cfg.backup_compression) + # allow GNU tar's longer file/pathnames + tar.posix = False + files = [] + dirs = [] + for m in tar: + if m.isdir(): + dirs.append("%s %s %s" % (m.name, m.size, m.mtime)) + else: + files.append("%s %s %s" % (m.name, m.size, m.mtime)) + tar.extract(m, targetdir) + tar.close() + #files = "<br>".join(files) + filecount = len(files) + dircount = len(dirs) + return sendMsg(request, pagename, msg=_( + 'Restored Backup: %(filename)s to target dir: %(targetdir)s.\nFiles: %(filecount)d, Directories: %(dircount)d' % + locals())) + except: + return sendMsg(request, pagename, msg=_("Restoring backup: %(filename)s to target dir: %(targetdir)s failed." % locals())) + +def sendBackupForm(request, pagename): + _ = request.getText + request.http_headers() + request.setContentLanguage(request.lang) + title = _('Wiki Backup / Restore') + wikiutil.send_title(request, title, form=request.form, pagename=pagename) + request.write(request.formatter.startContent("content")) + + request.write(_("""Some hints: + * To restore a backup: + * Restoring a backup will overwrite existing data, so be careful. + * Rename it to <siteid>.tar.<compression> (remove the --date--time--UTC stuff). + * Put the backup file into the backup_storage_dir (use scp, ftp, ...). + * Hit the [[GetText(Restore)]] button below. + + * To make a backup, just hit the [[GetText(Backup)]] button and save the file + you get to a secure place. + +Please make sure your wiki configuration backup_* values are correct and complete: + +""")) + +# does not work, why? +# request.write("""<p>\ +#backup_compression = %(backup_compression)s<br> +#backup_include = %(backup_include)r<br> +#backup_exclude = %(backup_exclude)r<br> +#backup_users = %(backup_users)r<br> +#backup_storage_dir = %(backup_storage_dir)s<br> +#backup_restore_target_dir = %(backup_restore_target_dir)s<br> +#</p> +#""" % request.cfg.__dict__) + + request.write(""" +<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"> +<input type="hidden" name="action" value="backup"> +<input type="hidden" name="do" value="backup"> +<input type="submit" value="%(backup_button)s"> +</form> + +<form action="%(baseurl)s/%(pagename)s" method="POST" enctype="multipart/form-data"> +<input type="hidden" name="action" value="backup"> +<input type="hidden" name="do" value="restore"> +<input type="submit" value="%(restore_button)s"> +</form> +""" % { + 'baseurl': request.getScriptname(), + 'pagename': wikiutil.quoteWikinameURL(pagename), + 'backup_button': _('Backup'), + 'restore_button': _('Restore'), +}) + + request.write(request.formatter.endContent()) + wikiutil.send_footer(request, pagename, editable=0, showactions=0, form=request.form) + +def sendMsg(request, pagename, msg): + from MoinMoin import Page + return Page.Page(request, pagename).send_page(request, msg=msg) + +def backupAllowed(request): + """ Return True if backup is allowed """ + action = __name__.split('.')[-1] + user = request.user + return (action not in request.cfg.actions_excluded and + user.valid and user.name in request.cfg.backup_users) + +def execute(pagename, request): + _ = request.getText + if not backupAllowed(request): + return sendMsg(request, pagename, + msg=_('You are not allowed to do remote backup.')) + + dowhat = request.form.get('do', [None])[0] + if dowhat == 'backup': + sendBackup(request) + elif dowhat == 'restore': + restoreBackup(request, pagename) + elif dowhat == None: + sendBackupForm(request, pagename) + else: + return sendMsg(request, pagename, + msg=_('Unknown backup subaction: %s.' % dowhat)) +
--- a/MoinMoin/multiconfig.py Sun Oct 09 02:20:53 2005 +0000 +++ b/MoinMoin/multiconfig.py Sat Oct 15 13:56:10 2005 +0000 @@ -174,6 +174,7 @@ attachments = None # {'dir': path, 'url': url-prefix} auth = [authmodule.moin_cookie] + backup_compression = 'gz' backup_users = [] backup_include = [] backup_exclude = [ @@ -182,7 +183,9 @@ r"%(/)spages%(/)s.+%(/)scache%(/)s[^%(/)s]+$" % {'/': os.sep}, r"%(/)s(edit-lock|event-log|\.DS_Store)$" % {'/': os.sep}, ] - + backup_storage_dir = '/tmp' + backup_restore_target_dir = '/tmp' + bang_meta = 1 caching_formats = ['text_html'] changed_time_fmt = '%H:%M'