diff --git a/apps/bootstrap/links.py b/apps/bootstrap/links.py index 73a2768bfa..5a742bbaca 100644 --- a/apps/bootstrap/links.py +++ b/apps/bootstrap/links.py @@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _ from .permissions import (PERMISSION_BOOTSTRAP_VIEW, PERMISSION_BOOTSTRAP_CREATE, PERMISSION_BOOTSTRAP_EDIT, PERMISSION_BOOTSTRAP_DELETE, PERMISSION_BOOTSTRAP_EXECUTE, PERMISSION_BOOTSTRAP_DUMP, - PERMISSION_NUKE_DATABASE) + PERMISSION_NUKE_DATABASE, PERMISSION_BOOTSTRAP_EXPORT) link_bootstrap_setup_tool = {'text': _(u'bootstrap'), 'view': 'bootstrap_setup_list', 'icon': 'lightning.png', 'permissions': [PERMISSION_BOOTSTRAP_VIEW]} link_bootstrap_setup_list = {'text': _(u'bootstrap setup list'), 'view': 'bootstrap_setup_list', 'famfam': 'lightning', 'permissions': [PERMISSION_BOOTSTRAP_VIEW]} @@ -15,4 +15,5 @@ link_bootstrap_setup_delete = {'text': _(u'delete'), 'view': 'bootstrap_setup_de link_bootstrap_setup_view = {'text': _(u'details'), 'view': 'bootstrap_setup_view', 'args': 'object.pk', 'famfam': 'lightning', 'permissions': [PERMISSION_BOOTSTRAP_VIEW]} link_bootstrap_setup_execute = {'text': _(u'execute'), 'view': 'bootstrap_setup_execute', 'args': 'object.pk', 'famfam': 'lightning_go', 'permissions': [PERMISSION_BOOTSTRAP_EXECUTE]} link_bootstrap_setup_dump = {'text': _(u'dump current setup'), 'view': 'bootstrap_setup_dump', 'famfam': 'arrow_down', 'permissions': [PERMISSION_BOOTSTRAP_DUMP]} +link_bootstrap_setup_export = {'text': _(u'export'), 'view': 'bootstrap_setup_export', 'args': 'object.pk', 'famfam': 'disk', 'permissions': [PERMISSION_BOOTSTRAP_EXPORT]} link_erase_database = {'text': _(u'erase database'), 'view': 'erase_database_view', 'icon': 'radioactivity.png', 'permissions': [PERMISSION_NUKE_DATABASE]} diff --git a/apps/bootstrap/literals.py b/apps/bootstrap/literals.py index 6cdad14e78..d828c137f3 100644 --- a/apps/bootstrap/literals.py +++ b/apps/bootstrap/literals.py @@ -71,3 +71,5 @@ FIXTURE_METADATA_MAYAN_VERSION = 'mayan_edms_version' FIXTURE_METADATA_FORMAT = 'format' FIXTURE_METADATA_NAME = 'name' FIXTURE_METADATA_DESCRIPTION = 'description' + +BOOTSTRAP_EXTENSION = 'txt' diff --git a/apps/bootstrap/models.py b/apps/bootstrap/models.py index c26e9f335f..312841b52e 100644 --- a/apps/bootstrap/models.py +++ b/apps/bootstrap/models.py @@ -13,8 +13,10 @@ except ImportError: from django.db import models from django.utils.translation import ugettext_lazy as _ from django.core import management +from django.core.files.uploadedfile import SimpleUploadedFile -from .literals import (FIXTURE_TYPES_CHOICES, FIXTURE_FILE_TYPE, COMMAND_LOADDATA) +from .literals import (FIXTURE_TYPES_CHOICES, FIXTURE_FILE_TYPE, COMMAND_LOADDATA, + BOOTSTRAP_EXTENSION) from .managers import BootstrapSetupManager from .classes import BootstrapModel, FixtureMetadata @@ -84,6 +86,12 @@ class BootstrapSetup(models.Model): """ return FixtureMetadata.generate_all(self) + def get_filename(self): + return os.extsep.join([self.name, BOOTSTRAP_EXTENSION]) + + def as_file(self): + return SimpleUploadedFile(name=self.get_filename(), content=self.fixture) + def save(self, *args, **kwargs): self.fixture = '%s\n\n%s' % ( self.get_metadata_string(), diff --git a/apps/bootstrap/permissions.py b/apps/bootstrap/permissions.py index f954e31c67..f69d9b746d 100644 --- a/apps/bootstrap/permissions.py +++ b/apps/bootstrap/permissions.py @@ -12,4 +12,5 @@ PERMISSION_BOOTSTRAP_EDIT = Permission.objects.register(namespace, 'bootstrap_ed PERMISSION_BOOTSTRAP_DELETE = Permission.objects.register(namespace, 'bootstrap_delete', _(u'Delete bootstrap setups')) PERMISSION_BOOTSTRAP_EXECUTE = Permission.objects.register(namespace, 'bootstrap_execute', _(u'Execute bootstrap setups')) PERMISSION_BOOTSTRAP_DUMP = Permission.objects.register(namespace, 'bootstrap_dump', _(u'Dump the current project\s setup into a bootstrap setup')) +PERMISSION_BOOTSTRAP_EXPORT = Permission.objects.register(namespace, 'bootstrap_export', _(u'Export the bootstrap setup as files')) PERMISSION_NUKE_DATABASE = Permission.objects.register(namespace, 'nuke_database', _(u'Erase the entire database and document storage')) diff --git a/apps/bootstrap/post_init.py b/apps/bootstrap/post_init.py index de50aaccf3..88d16e6441 100644 --- a/apps/bootstrap/post_init.py +++ b/apps/bootstrap/post_init.py @@ -7,14 +7,14 @@ from main import __version__ from .links import (link_bootstrap_setup_create, link_bootstrap_setup_execute, link_bootstrap_setup_list, link_bootstrap_setup_edit, link_bootstrap_setup_delete, - link_bootstrap_setup_view, link_bootstrap_setup_dump) + link_bootstrap_setup_view, link_bootstrap_setup_dump, link_bootstrap_setup_export) from .models import BootstrapSetup from .classes import FixtureMetadata from .literals import (FIXTURE_METADATA_CREATED, FIXTURE_METADATA_EDITED, FIXTURE_METADATA_MAYAN_VERSION, FIXTURE_METADATA_FORMAT, FIXTURE_METADATA_NAME, FIXTURE_METADATA_DESCRIPTION, DATETIME_STRING_FORMAT) -register_links([BootstrapSetup], [link_bootstrap_setup_view, link_bootstrap_setup_edit, link_bootstrap_setup_delete, link_bootstrap_setup_execute]) +register_links([BootstrapSetup], [link_bootstrap_setup_view, link_bootstrap_setup_edit, link_bootstrap_setup_delete, link_bootstrap_setup_execute, link_bootstrap_setup_export]) register_links([BootstrapSetup], [link_bootstrap_setup_list, link_bootstrap_setup_create, link_bootstrap_setup_dump], menu_name='secondary_menu') register_links(['bootstrap_setup_list', 'bootstrap_setup_create', 'bootstrap_setup_dump'], [link_bootstrap_setup_list, link_bootstrap_setup_create, link_bootstrap_setup_dump], menu_name='secondary_menu') diff --git a/apps/bootstrap/urls.py b/apps/bootstrap/urls.py index 8a91228f4f..73a1ce013f 100644 --- a/apps/bootstrap/urls.py +++ b/apps/bootstrap/urls.py @@ -7,6 +7,7 @@ urlpatterns = patterns('bootstrap.views', url(r'^setup/(?P\d+)/delete/$', 'bootstrap_setup_delete', (), 'bootstrap_setup_delete'), url(r'^setup/(?P\d+)/$', 'bootstrap_setup_view', (), 'bootstrap_setup_view'), url(r'^setup/(?P\d+)/execute/$', 'bootstrap_setup_execute', (), 'bootstrap_setup_execute'), + url(r'^setup/(?P\d+)/export/$', 'bootstrap_setup_export', (), 'bootstrap_setup_export'), url(r'^setup/dump/$', 'bootstrap_setup_dump', (), 'bootstrap_setup_dump'), url(r'^nuke/$', 'erase_database_view', (), 'erase_database_view'), ) diff --git a/apps/bootstrap/views.py b/apps/bootstrap/views.py index 41b0281eea..5e6c48dff9 100644 --- a/apps/bootstrap/views.py +++ b/apps/bootstrap/views.py @@ -6,6 +6,9 @@ from django.shortcuts import render_to_response, get_object_or_404 from django.template import RequestContext from django.contrib import messages from django.core.urlresolvers import reverse +from django.core.files import File + +from filetransfers.api import serve_file from permissions.models import Permission @@ -13,7 +16,8 @@ from .models import BootstrapSetup from .classes import Cleanup, BootstrapModel from .permissions import (PERMISSION_BOOTSTRAP_VIEW, PERMISSION_BOOTSTRAP_CREATE, PERMISSION_BOOTSTRAP_EDIT, PERMISSION_BOOTSTRAP_DELETE, - PERMISSION_BOOTSTRAP_EXECUTE, PERMISSION_NUKE_DATABASE, PERMISSION_BOOTSTRAP_DUMP) + PERMISSION_BOOTSTRAP_EXECUTE, PERMISSION_NUKE_DATABASE, PERMISSION_BOOTSTRAP_DUMP, + PERMISSION_BOOTSTRAP_EXPORT) from .forms import (BootstrapSetupForm, BootstrapSetupForm_view, BootstrapSetupForm_dump, BootstrapSetupForm_edit) from .exceptions import ExistingData @@ -205,6 +209,24 @@ def bootstrap_setup_dump(request): context_instance=RequestContext(request)) +def bootstrap_setup_export(request, bootstrap_setup_pk): + previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', '/'))) + + bootstrap = get_object_or_404(BootstrapSetup, pk=bootstrap_setup_pk) + + try: + Permission.objects.check_permissions(request.user, [PERMISSION_BOOTSTRAP_EXPORT]) + except PermissionDenied: + AccessEntry.objects.check_access(PERMISSION_BOOTSTRAP_EXPORT, request.user, bootstrap) + + return serve_file( + request, + bootstrap.as_file(), + save_as=u'"%s"' % bootstrap.get_filename(), + content_type='text/plain; charset=us-ascii' + ) + + def erase_database_view(request): Permission.objects.check_permissions(request.user, [PERMISSION_NUKE_DATABASE])