Backup module: Implement downloading archives

Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Michael Pimmer 2018-09-15 22:33:45 +00:00 committed by James Valleroy
parent 9b509e2610
commit 35446f2ca4
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808
3 changed files with 31 additions and 5 deletions

View File

@ -118,6 +118,10 @@
<td class="export-label">{{ label }}</td> <td class="export-label">{{ label }}</td>
<td class="export-name">{{ name }}</td> <td class="export-name">{{ name }}</td>
<td class="export-operations"> <td class="export-operations">
<a class="download btn btn-sm btn-default" target="_blank"
href="{% url 'backups:download' label|urlencode name|urlencode %}">
{% trans "Download" %}
</a>
<a class="restore btn btn-sm btn-default" <a class="restore btn btn-sm btn-default"
href="{% url 'backups:restore' label|urlencode name|urlencode %}"> href="{% url 'backups:restore' label|urlencode name|urlencode %}">
{% trans "Restore" %} {% trans "Restore" %}

View File

@ -20,14 +20,16 @@ URLs for the backups module.
from django.conf.urls import url from django.conf.urls import url
from .views import IndexView, CreateArchiveView, ExportArchiveView, \ from .views import IndexView, CreateArchiveView, DownloadArchiveView, \
DeleteArchiveView, RestoreView ExportArchiveView, DeleteArchiveView, RestoreView
urlpatterns = [ urlpatterns = [
url(r'^sys/backups/$', IndexView.as_view(), name='index'), url(r'^sys/backups/$', IndexView.as_view(), name='index'),
url(r'^sys/backups/create/$', CreateArchiveView.as_view(), name='create'), url(r'^sys/backups/create/$', CreateArchiveView.as_view(), name='create'),
url(r'^sys/backups/export/(?P<name>[^/]+)/$', url(r'^sys/backups/export/(?P<name>[^/]+)/$',
ExportArchiveView.as_view(), name='export'), ExportArchiveView.as_view(), name='export'),
url(r'^sys/backups/download/(?P<label>[^/]+)/(?P<name>[^/]+)/$',
DownloadArchiveView.as_view(), name='download'),
url(r'^sys/backups/delete/(?P<name>[^/]+)/$', url(r'^sys/backups/delete/(?P<name>[^/]+)/$',
DeleteArchiveView.as_view(), name='delete'), DeleteArchiveView.as_view(), name='delete'),
url(r'^sys/backups/restore/(?P<label>[^/]+)/(?P<name>[^/]+)/$', url(r'^sys/backups/restore/(?P<label>[^/]+)/(?P<name>[^/]+)/$',

View File

@ -18,20 +18,22 @@
Views for the backups app. Views for the backups app.
""" """
import mimetypes
from datetime import datetime from datetime import datetime
from urllib.parse import unquote from urllib.parse import unquote
from django.contrib import messages from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.http import Http404 from django.core.files.base import File
from django.http import Http404, HttpResponse
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.generic import FormView, TemplateView from django.views.generic import View, FormView, TemplateView
from plinth.modules import backups from plinth.modules import backups
from . import backups as backups_api from . import backups as backups_api, find_exported_archive
from .forms import CreateArchiveForm, ExportArchiveForm, RestoreForm from .forms import CreateArchiveForm, ExportArchiveForm, RestoreForm
@ -101,6 +103,24 @@ class DeleteArchiveView(SuccessMessageMixin, TemplateView):
return redirect(reverse_lazy('backups:index')) return redirect(reverse_lazy('backups:index'))
class DownloadArchiveView(View):
"""View to download an archive."""
def get(self, request, label, name):
label = unquote(label)
name = unquote(name)
filepath = find_exported_archive(label, name)
(content_type, encoding) = mimetypes.guess_type(name)
with open(filepath, 'rb') as file_handle:
response = HttpResponse(File(file_handle),
content_type=content_type)
content_disposition = 'attachment; filename="%s"' % name
response['Content-Disposition'] = content_disposition
if encoding:
response['Content-Encoding'] = encoding
return response
class ExportArchiveView(SuccessMessageMixin, FormView): class ExportArchiveView(SuccessMessageMixin, FormView):
"""View to export an archive.""" """View to export an archive."""
form_class = ExportArchiveForm form_class = ExportArchiveForm