# -*- coding: utf-8 -*- # Copyright (C) 2018 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 . from __future__ import unicode_literals import os import stat import tempfile import contextlib from django.core.files.storage import default_storage from django.template.loader import get_template from django.utils.dateparse import parse_date from django.utils.encoding import force_bytes from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ from passerelle.base.models import BaseResource from passerelle.compat import json_loads from passerelle.utils.api import endpoint from passerelle.utils.jsonresponse import APIError from passerelle.utils.conversion import ensure_encoding @contextlib.contextmanager def named_tempfile(*args, **kwargs): with tempfile.NamedTemporaryFile(*args, **kwargs) as fp: yield fp class ActesWeb(BaseResource): category = _('Civil Status Connectors') class Meta: verbose_name = u"ActesWeb - Demande d'acte d'état civil" @property def basepath(self): return os.path.join(default_storage.path('actesweb'), self.slug) @endpoint(perm='can_access', methods=['post'], description=_('Create demand')) def create(self, request, *args, **kwargs): try: payload = json_loads(request.body) except (ValueError,): raise APIError('Invalid payload format: json expected') if payload.get('certificate_type') not in ('NA', 'DE', 'MA'): raise APIError("Invalid : expected ('NA', 'DE', 'MA')") payload['event_date_start'] = parse_date(payload['event_date_start']).strftime('%Y%m%d') template_name = 'actesweb/demand.txt' demand_content = get_template(template_name).render(payload) application_id = payload['application_id'] # create tmp dir tmp_dir = os.path.join(self.basepath, 'tmp') if not os.path.exists(tmp_dir): if default_storage.directory_permissions_mode: d_umask = os.umask(0) try: os.makedirs(tmp_dir, mode=default_storage.directory_permissions_mode) except OSError: pass finally: os.umask(d_umask) else: os.makedirs(tmp_dir) # ensure demand_content can be encoded to latin15 demand_content = ensure_encoding(demand_content, 'iso-8859-15') filename = '%s.DEM' % now().strftime('%Y-%m-%d_%H-%M-%S_%f') filepath = os.path.join(self.basepath, filename) with named_tempfile(dir=tmp_dir, suffix='.DEM', delete=False) as tpf: tpf.write(force_bytes(demand_content, 'iso-8859-15')) tpf.flush() os.fsync(tpf.file.fileno()) tempfile_name = tpf.name os.rename(tempfile_name, filepath) # set read only permission for owner and group os.chmod(filepath, stat.S_IRUSR | stat.S_IRGRP | stat.S_IWGRP) demand_id = '%s_%s' % (application_id, os.path.basename(filepath)) return {'data': {'demand_id': demand_id}}