76 lines
3.4 KiB
Python
76 lines
3.4 KiB
Python
# combo-plugin-gnm - Combo GNM plugin
|
|
# Copyright (C) 2017-2020 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/>.
|
|
|
|
import html
|
|
from io import BytesIO
|
|
import os
|
|
import re
|
|
import xml.etree.ElementTree as ET
|
|
import zipfile
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth import get_user_model
|
|
from django.core.files.storage import default_storage
|
|
from django.core.management.base import BaseCommand, CommandError
|
|
|
|
from combo.data.models import TextCell
|
|
from combo.utils import requests
|
|
|
|
|
|
class Command(BaseCommand):
|
|
def handle(self, *args, **options):
|
|
reporting_user_email = settings.TEMPLATE_VARS.get('reporting_user_email')
|
|
reporting_user = None
|
|
if reporting_user_email:
|
|
reporting_user = get_user_model().objects.get(email=reporting_user_email)
|
|
for cell in TextCell.objects.filter(slug='reporting', page__snapshot__isnull=True):
|
|
if not reporting_user:
|
|
raise CommandError('missing reporting user (%s)' % reporting_user_email)
|
|
sheets = []
|
|
for url in re.findall('href="(.*?)"', cell.text):
|
|
url = html.unescape(url)
|
|
url = re.sub(
|
|
r'/backoffice/management/([a-z0-9_-]+)(/[a-z0-9_-]+)?/?(\?)?',
|
|
r'/api/forms/\1/ods\2\3',
|
|
url,
|
|
)
|
|
resp = requests.get(url, remote_service='auto', user=reporting_user)
|
|
if not resp.ok:
|
|
continue
|
|
zipf = zipfile.ZipFile(BytesIO(resp.content))
|
|
sheets.append(
|
|
ET.parse(zipf.open('content.xml')).findall(
|
|
'.//{urn:oasis:names:tc:opendocument:xmlns:table:1.0}table'
|
|
)[0]
|
|
)
|
|
if sheets:
|
|
if not os.path.exists(default_storage.path('reporting')):
|
|
os.mkdir(default_storage.path('reporting'))
|
|
filepath = default_storage.path('reporting/%s.ods' % cell.id)
|
|
with zipfile.ZipFile(filepath, 'w') as new_ods:
|
|
for f in zipf.namelist():
|
|
if f != 'content.xml':
|
|
new_ods.writestr(f, zipf.read(f))
|
|
OFFICE_NS = 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'
|
|
root = ET.Element('{%s}document-content' % OFFICE_NS)
|
|
ET.SubElement(root, '{%s}scripts' % OFFICE_NS)
|
|
ET.SubElement(root, '{%s}font-face-decls' % OFFICE_NS)
|
|
body = ET.SubElement(root, '{%s}body' % OFFICE_NS)
|
|
spreadsheet = ET.SubElement(body, '{%s}spreadsheet' % OFFICE_NS)
|
|
for sheet in sheets:
|
|
spreadsheet.append(sheet)
|
|
new_ods.writestr('content.xml', ET.tostring(root))
|