From 6e4c911e9bfed3ecd83427f5329ed024be9c62c6 Mon Sep 17 00:00:00 2001 From: hernani Date: Thu, 24 Feb 2011 18:21:55 +0000 Subject: [PATCH] Adds a file format option to xml backups. git-svn-id: http://svn.osqa.net/svnroot/osqa/trunk@777 0cfe37f9-358a-4d5e-be75-b63607b5c754 --- forum_modules/exporter/exporter.py | 61 +++++++++++-------- forum_modules/exporter/forms.py | 7 +++ forum_modules/exporter/templates/running.html | 3 +- forum_modules/exporter/views.py | 18 ++++-- 4 files changed, 59 insertions(+), 30 deletions(-) diff --git a/forum_modules/exporter/exporter.py b/forum_modules/exporter/exporter.py index c54e758..e9983d2 100644 --- a/forum_modules/exporter/exporter.py +++ b/forum_modules/exporter/exporter.py @@ -1,4 +1,4 @@ -import os, tarfile, datetime, logging, re, ConfigParser, shutil +import os, tarfile, datetime, logging, re, ConfigParser, shutil, zipfile from django.core.cache import cache from django.utils.translation import ugettext as _ @@ -16,7 +16,6 @@ CACHE_KEY = "%s_exporter_state" % APP_URL EXPORT_STEPS = [] TMP_FOLDER = os.path.join(os.path.dirname(__file__), 'tmp') -LAST_BACKUP = os.path.join(TMP_FOLDER, 'backup.tar.gz') DATE_AND_AUTHOR_INF_SECTION = 'DateAndAuthor' OPTIONS_INF_SECTION = 'Options' @@ -90,7 +89,10 @@ def ET_Element_add_tag(el, tag_name, content = None, **attrs): tag = ET.SubElement(el, tag_name) if content: - tag.text = unicode(content) + try: + tag.text = unicode(content) + except: + tag.text = u'' for k, v in attrs.items(): tag.set(k, unicode(v)) @@ -130,17 +132,36 @@ def write_to_file(root, tmp, filename): tree = ET.ElementTree(root) tree.write(os.path.join(tmp, filename), encoding='UTF-8') -def create_targz(tmp, files, start_time, options, user, state, set_state): - if os.path.exists(LAST_BACKUP): - os.remove(LAST_BACKUP) - - t = tarfile.open(name=LAST_BACKUP, mode = 'w:gz') +def create_targz(tmp, files, start_time, options, user, state, set_state, file_format): + now = datetime.datetime.now() + domain = re.match('[\w-]+\.[\w-]+(\.[\w-]+)*', djsettings.APP_URL) + if domain: + domain = '_'.join(domain.get(0).split('.')) + else: + domain = 'localhost' + + fname = "%s-%s" % (domain, now.strftime('%Y%m%d%H%M')) + if file_format == 'zip': + full_fname = "%s.zip" % fname + else: + full_fname = "%s.tar.gz" % fname + + if file_format == 'zip': + t = zipfile.ZipFile(os.path.join(selfsettings.EXPORTER_BACKUP_STORAGE, full_fname), 'w') + + def add_to_file(f, a): + t.write(f, a) + else: + t = tarfile.open(os.path.join(selfsettings.EXPORTER_BACKUP_STORAGE, full_fname), mode = 'w:gz') + + def add_to_file(f, a): + t.add(f, a) state['overall']['status'] = _('Compressing xml files') set_state() for f in files: - t.add(os.path.join(tmp, f), arcname="/%s" % f) + add_to_file(os.path.join(tmp, f), "/%s" % f) if options.get('uplodaded_files', False): state['overall']['status'] = _('Importing uploaded files') @@ -155,20 +176,11 @@ def create_targz(tmp, files, start_time, options, user, state, set_state): state['overall']['status'] = _('Writing inf file.') set_state() - now = datetime.datetime.now() - domain = re.match('[\w-]+\.[\w-]+(\.[\w-]+)*', djsettings.APP_URL) - if domain: - domain = '_'.join(domain.get(0).split('.')) - else: - domain = 'localhost' - - fname = "%s-%s" % (domain, now.strftime('%Y%m%d%H%M')) - inf = ConfigParser.SafeConfigParser() inf.add_section(DATE_AND_AUTHOR_INF_SECTION) - inf.set(DATE_AND_AUTHOR_INF_SECTION, 'file-name', "%s.tar.gz" % fname) + inf.set(DATE_AND_AUTHOR_INF_SECTION, 'file-name', full_fname) inf.set(DATE_AND_AUTHOR_INF_SECTION, 'author', unicode(user.id)) inf.set(DATE_AND_AUTHOR_INF_SECTION, 'site', djsettings.APP_URL) inf.set(DATE_AND_AUTHOR_INF_SECTION, 'started', start_time.strftime(DATETIME_FORMAT)) @@ -184,17 +196,15 @@ def create_targz(tmp, files, start_time, options, user, state, set_state): for id, s in state.items(): inf.set(META_INF_SECTION, id, str(s['count'])) - with open(os.path.join(tmp, 'backup.inf'), 'wb') as inffile: + with open(os.path.join(tmp, '%s.backup.inf' % fname), 'wb') as inffile: inf.write(inffile) - t.add(os.path.join(tmp, 'backup.inf'), arcname='backup.inf') + add_to_file(os.path.join(tmp, '%s.backup.inf' % fname), '/backup.inf') state['overall']['status'] = _('Saving backup file') set_state() t.close() - shutil.copyfile(LAST_BACKUP, os.path.join(selfsettings.EXPORTER_BACKUP_STORAGE, "%s.tar.gz" % fname)) - shutil.copyfile(os.path.join(tmp, 'backup.inf'), os.path.join(selfsettings.EXPORTER_BACKUP_STORAGE, "%s.backup.inf" % fname)) + return full_fname - def export_upfiles(tf): folder = str(settings.UPFILES_FOLDER) @@ -272,10 +282,11 @@ def export(options, user): state['overall']['status'] = _('Compressing files') set_state() - create_targz(tmp, dump_files, start_time, options, user, state, set_state) + fname = create_targz(tmp, dump_files, start_time, options, user, state, set_state, options['file_format']) full_state['running'] = False full_state['errors'] = False state['overall']['status'] = _('Done') + state['overall']['fname'] = fname set_state() except Exception, e: diff --git a/forum_modules/exporter/forms.py b/forum_modules/exporter/forms.py index 464712d..275580f 100644 --- a/forum_modules/exporter/forms.py +++ b/forum_modules/exporter/forms.py @@ -1,7 +1,14 @@ from django import forms from django.utils.translation import ugettext as _ +FORMAT_CHOICES = ( +('tgz', _('tar.gz')), +('zip', _('zip')) +) + class ExporterForm(forms.Form): + file_format = forms.ChoiceField(widget=forms.Select, choices=FORMAT_CHOICES, initial='zip', + label=_('File format'), help_text=_("File format of the compressed backup"), required=True) anon_data = forms.BooleanField(label=_('Anonymized data'), help_text=_('Don\'t export user data and make all content anonymous'), required=False) uplodaded_files = forms.BooleanField(label=_('Uploaded files'), help_text=_('Include uploaded files in the backup'), required=False, initial=True) import_skins_folder = forms.BooleanField(label=_('Skins folder'), help_text=_('Include skins folder in the backup'), required=False, initial=False) diff --git a/forum_modules/exporter/templates/running.html b/forum_modules/exporter/templates/running.html index 5936dcb..718db90 100644 --- a/forum_modules/exporter/templates/running.html +++ b/forum_modules/exporter/templates/running.html @@ -94,6 +94,7 @@ if (data.errors == false) { if (exporting) { $('#wait_message').html('{% trans "Your backup is ready to be downloaded."%}'); + $('#download_link_a').attr('href', '{% url exporter_download %}?file=' + data.state.overall.fname) $('#download_link').slideDown(); } else { $('#wait_message').html('{% trans "All data sucessfully imported."%}') @@ -139,7 +140,7 @@ Started {% endblocktrans %}

- +
diff --git a/forum_modules/exporter/views.py b/forum_modules/exporter/views.py index 3709037..af77f5b 100644 --- a/forum_modules/exporter/views.py +++ b/forum_modules/exporter/views.py @@ -13,7 +13,7 @@ from threading import Thread import settings as selsettings from forum import settings -from exporter import export, CACHE_KEY, EXPORT_STEPS, LAST_BACKUP, DATE_AND_AUTHOR_INF_SECTION, DATETIME_FORMAT +from exporter import export, CACHE_KEY, EXPORT_STEPS, DATE_AND_AUTHOR_INF_SECTION, DATETIME_FORMAT from importer import start_import @@ -77,14 +77,24 @@ def state(request): @admin_page def download(request): - fname = LAST_BACKUP + if request.GET and request.GET.get('file', None): + fname = os.path.join(selsettings.EXPORTER_BACKUP_STORAGE, request.GET.get('file')) + else: + raise Http404 if not os.path.exists(fname): raise Http404 - response = HttpResponse(open(fname, 'rb').read(), content_type='application/x-gzip') + if fname.endswith('.gz'): + content_type='application/x-gzip' + filename = 'backup.tar.gz' + else: + content_type='application/zip' + filename = 'backup.zip' + + response = HttpResponse(open(fname, 'rb').read(), content_type=content_type) response['Content-Length'] = os.path.getsize(fname) - response['Content-Disposition'] = 'attachment; filename=backup.tar.gz' + response['Content-Disposition'] = 'attachment; filename=%s' % filename return response -- 2.39.5