views.py 6.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#
# This file is part of FreedomBox.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
"""
Views for the backups app.
"""

21 22
from datetime import datetime

23 24 25 26 27 28 29
from django.contrib import messages
from django.contrib.messages.views import SuccessMessageMixin
from django.http import Http404
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.utils.translation import ugettext as _
from django.views.generic import FormView, TemplateView
30
from urllib.parse import unquote
31 32

from plinth.modules import backups
33
from . import find_exported_archive, get_export_apps
34
from .backups import _list_of_all_apps_for_backup
35
from .forms import CreateArchiveForm, ExportArchiveForm, RestoreForm
36 37 38 39 40 41 42 43 44 45 46 47 48


class IndexView(TemplateView):
    """View to show list of archives."""
    template_name = 'backups.html'

    def get_context_data(self, **kwargs):
        """Return additional context for rendering the template."""
        context = super().get_context_data(**kwargs)
        context['title'] = backups.name
        context['description'] = backups.description
        context['info'] = backups.get_info()
        context['archives'] = backups.list_archives()
49
        context['exports'] = backups.get_export_files()
50 51
        apps = _list_of_all_apps_for_backup()
        context['available_apps'] = [x[0] for x in apps]
52 53 54 55 56 57 58 59 60 61 62 63 64 65
        return context


class CreateArchiveView(SuccessMessageMixin, FormView):
    """View to create a new archive."""
    form_class = CreateArchiveForm
    prefix = 'backups'
    template_name = 'backups_form.html'
    success_url = reverse_lazy('backups:index')
    success_message = _('Archive created.')

    def get_context_data(self, **kwargs):
        """Return additional context for rendering the template."""
        context = super().get_context_data(**kwargs)
66
        context['title'] = _('New Backup')
67 68
        return context

69 70 71
    def get_initial(self):
        """Return the initial data to use for forms on this view."""
        initial = super().get_initial()
72 73
        initial['name'] = 'FreedomBox_backup_' + datetime.now().strftime(
            '%Y-%m-%d:%H:%M')
74 75
        return initial

76 77 78
    def form_valid(self, form):
        """Create the archive on valid form submission."""
        backups.create_archive(form.cleaned_data['name'],
79
                               form.cleaned_data['selected_apps'])
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
        return super().form_valid(form)


class DeleteArchiveView(SuccessMessageMixin, TemplateView):
    """View to delete an archive."""
    template_name = 'backups_delete.html'

    def get_context_data(self, **kwargs):
        """Return additional context for rendering the template."""
        context = super().get_context_data(**kwargs)
        context['title'] = _('Delete Archive')
        context['archive'] = backups.get_archive(self.kwargs['name'])
        if context['archive'] is None:
            raise Http404

        return context

    def post(self, request, name):
        """Delete the archive."""
        backups.delete_archive(name)
        messages.success(request, _('Archive deleted.'))
        return redirect(reverse_lazy('backups:index'))


104 105 106
class ExportArchiveView(SuccessMessageMixin, FormView):
    """View to export an archive."""
    form_class = ExportArchiveForm
107 108 109
    prefix = 'backups'
    template_name = 'backups_form.html'
    success_url = reverse_lazy('backups:index')
110
    success_message = _('Archive exported.')
111 112 113 114

    def get_context_data(self, **kwargs):
        """Return additional context for rendering the template."""
        context = super().get_context_data(**kwargs)
115
        context['title'] = _('Export Archive')
116 117 118 119 120 121 122 123
        context['archive'] = backups.get_archive(self.kwargs['name'])
        if context['archive'] is None:
            raise Http404

        return context

    def form_valid(self, form):
        """Create the archive on valid form submission."""
124 125
        backups.export_archive(self.kwargs['name'],
                               form.cleaned_data['disk'])
126 127 128
        return super().form_valid(form)


129
class RestoreView(SuccessMessageMixin, FormView):
130
    """View to restore files from an exported archive."""
131 132
    form_class = RestoreForm
    prefix = 'backups'
133
    template_name = 'backups_restore.html'
134 135
    success_url = reverse_lazy('backups:index')
    success_message = _('Restored files from backup.')
136

137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
    def collect_data(self, label, name):
        """Save some data used to instantiate the form."""
        self.label = unquote(label)
        self.name = unquote(name)
        self.filename = find_exported_archive(self.label, self.name)
        self.installed_apps = _list_of_all_apps_for_backup()
        self.included_apps = get_export_apps(self.filename)

    def get(self, request, *args, **kwargs):
        """Save request parameters for later."""
        self.collect_data(kwargs['label'], kwargs['name'])
        return super().get(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        """Save request parameters for later."""
        self.collect_data(kwargs['label'], kwargs['name'])
        return super().post(request, *args, **kwargs)

    def get_form_kwargs(self):
        """Pass additional keyword args for instantiating the form."""
        kwargs = super().get_form_kwargs()
        kwargs['apps'] = [
            x for x in self.installed_apps if x[0] in self.included_apps]
        return kwargs

162 163 164
    def get_context_data(self, **kwargs):
        """Return additional context for rendering the template."""
        context = super().get_context_data(**kwargs)
165 166 167
        context['title'] = _('Restore from backup')
        context['label'] = unquote(self.kwargs['label'])
        context['name'] = self.kwargs['name']
168 169
        return context

170
    def form_valid(self, form):
171
        """Restore files from the archive on valid form submission."""
172 173 174 175
        backups.restore_exported(unquote(self.kwargs['label']),
                                 self.kwargs['name'],
                                 form.cleaned_data['selected_apps'])
        return super().form_valid(form)