combo/combo/data/utils.py

88 lines
3.3 KiB
Python

# combo - content management system
# Copyright (C) 2017 Entr'ouvert
#
# 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/>.
from django.contrib.auth.models import Group
from django.db import transaction
from django.utils import six
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _
from combo.apps.assets.models import Asset
from combo.apps.maps.models import MapLayer
from combo.apps.pwa.models import PwaSettings, PwaNavigationEntry
from .models import Page
@python_2_unicode_compatible
class MissingGroups(Exception):
def __init__(self, names):
self.names = names
def __str__(self):
return _('Missing groups: %s') % ', '.join(self.names)
def export_site():
'''Dump site objects to JSON-dumpable dictionnary'''
return {'pages': Page.export_all_for_json(),
'map-layers': MapLayer.export_all_for_json(),
'assets': Asset.export_all_for_json(),
'pwa': {
'settings': PwaSettings.export_for_json(),
'navigation': PwaNavigationEntry.export_all_for_json(),
}
}
def import_site(data, if_empty=False, clean=False):
if isinstance(data, list):
# old export form with a list of pages, convert it to new dictionary
# format.
data = {'pages': data}
if if_empty and (Page.objects.count() or MapLayer.objects.count()):
return
# check groups used in access control are all available.
groups = set()
for page in data.get('pages') or []:
for group in page['fields']['groups']:
groups.add(group if isinstance(group, six.string_types) else group[0])
for cell in page['cells']:
for group in cell['fields']['groups']:
groups.add(group if isinstance(group, six.string_types) else group[0])
existing_groups = set([x.name for x in Group.objects.filter(name__in=groups)])
missing_groups = groups - existing_groups
if missing_groups:
raise MissingGroups(names=sorted([x for x in missing_groups]))
with transaction.atomic():
if clean:
MapLayer.objects.all().delete()
Asset.objects.all().delete()
Page.objects.all().delete()
PwaSettings.objects.all().delete()
PwaNavigationEntry.objects.all().delete()
MapLayer.load_serialized_objects(data.get('map-layers') or [])
Asset.load_serialized_objects(data.get('assets') or [])
Page.load_serialized_pages(data.get('pages') or [])
if data.get('pwa'):
PwaSettings.load_serialized_settings(data['pwa'].get('settings'))
PwaNavigationEntry.load_serialized_objects(data['pwa'].get('navigation'))