# chrono - agendas system # Copyright (C) 2016-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 . import collections import itertools from django.contrib.auth.models import Group from django.db import transaction from django.db.models import Q from chrono.agendas.models import ( Agenda, AgendaImportError, Category, EventsType, Resource, SharedCustodySettings, UnavailabilityCalendar, ) def export_site( agendas=True, unavailability_calendars=True, events_types=True, resources=True, categories=True, shared_custody=True, ): '''Dump site objects to JSON-dumpable dictionnary''' data = collections.OrderedDict() if categories: data['categories'] = [x.export_json() for x in Category.objects.all()] if resources: data['resources'] = [x.export_json() for x in Resource.objects.all()] if events_types: data['events_types'] = [x.export_json() for x in EventsType.objects.all()] if unavailability_calendars: data['unavailability_calendars'] = [x.export_json() for x in UnavailabilityCalendar.objects.all()] if agendas: qs1 = Agenda.objects.filter(~Q(kind='virtual')) qs2 = Agenda.objects.filter(kind='virtual') data['agendas'] = [x.export_json() for x in itertools.chain(qs1, qs2)] if shared_custody: data['shared_custody_settings'] = SharedCustodySettings.get_singleton().export_json() return data def import_site(data, if_empty=False, clean=False, overwrite=False): # pylint: disable=too-many-boolean-expressions if if_empty and ( Agenda.objects.exists() or UnavailabilityCalendar.objects.exists() or EventsType.objects.exists() or Resource.objects.exists() or Category.objects.exists() ): return if clean: Agenda.objects.all().delete() SharedCustodySettings.objects.all().delete() UnavailabilityCalendar.objects.all().delete() EventsType.objects.all().delete() Resource.objects.all().delete() Category.objects.all().delete() results = { key: collections.defaultdict(list) for key in [ 'agendas', 'unavailability_calendars', 'events_types', 'resources', 'categories', ] } role_names = set() for key in ['agendas', 'unavailability_calendars']: objs = data.get(key, []) role_names = role_names.union( {name for data in objs for _, name in data.get('permissions', {}).items() if name} ) shared_custody_settings = data.get('shared_custody_settings') if shared_custody_settings and shared_custody_settings['management_role']: role_names.add(shared_custody_settings['management_role']) existing_roles = Group.objects.filter(name__in=role_names) if existing_roles.count() != len(role_names): existing_roles_names = set(existing_roles.values_list('name', flat=True)) raise AgendaImportError('Missing roles: "%s"' % ', '.join(role_names - existing_roles_names)) with transaction.atomic(): for cls, key in ( (Category, 'categories'), (Resource, 'resources'), (EventsType, 'events_types'), (UnavailabilityCalendar, 'unavailability_calendars'), (Agenda, 'agendas'), ): objs = data.get(key, []) for obj in objs: created, obj = cls.import_json(obj, overwrite=overwrite) results[key]['all'].append(obj) if created: results[key]['created'].append(obj) else: results[key]['updated'].append(obj) SharedCustodySettings.import_json(data.get('shared_custody_settings', {})) return results