<commit_before>import asyncio
import functools
import requests
import subprocess


from pdfjinja import PdfJinja
from PIL import Image
from pyramid.config import Configurator
from pyramid.response import FileResponse
from pyramid.renderers import JSONP
from pyramid.view import view_config
from secretary import Renderer
from tempfile import NamedTemporaryFile
from io import BytesIO

WMS_HEADERS = {'Referer': 'http://localhost'}
LAYER_DPI = 25.4 / 0.28


def main(global_config, **settings):
    config = Configurator(settings=settings)
    config.add_renderer('jsonp', JSONP(param_name='callback', indent=None, separators=(',', ':')))
    config.add_route('mapprint', '/print')

    config.scan()

    return config.make_wsgi_app()


@view_config(route_name='mapprint')
def mapprint(request):
    output = None

    payload = request.json_body

    loop = asyncio.new_event_loop()
    images = get_images(payload, loop)

    for img in images:
        if not isinstance(img, Image.Image):
            img = Image.open(BytesIO(img.content)).convert('RGBA')

        if img.size != (1240, 1743):
            img = img.resize((1240, 1743))

        if output is None:
            output = Image.new('RGBA', (1240, 1743))
        output = Image.alpha_composite(output, img)

    return create_pdf(request, output)


def create_pdf(request, output):
    return _create_pdf_libreoffice(request, output)
    #return _create_pdf_pdftk(request, output)


def _create_pdf_libreoffice(request, output):
    my_map = BytesIO()
    output.save(my_map, 'PNG')

    render = Renderer(media_path='.')
    result = render.render('template.odt', my_map=my_map)
    with NamedTemporaryFile(
            mode='wb+',
            prefix='geo-pyprint',
            delete=True) as output:
        output.write(result)
        output.flush()

        subprocess.call(['unoconv', '-f', 'pdf', '-o', output.name + '.pdf', output.name], timeout=None)

        response = FileResponse(
            output.name + '.pdf',
            request=request
        )
        response.headers['Content-Disposition'] = ('attachement; filename="{}"'
                                                   .format(output.name + '.pdf'))
        response.headers['Content-Type'] = 'application/pdf'

        return response


def _create_pdf_pdftk(request, output):
    with NamedTemporaryFile(
        mode='wb+',
        prefix='geo-pypring',
        delete=False
    ) as output_img:
        output.save(output_img, 'PNG')
        output_img.flush()

        pdfjinja = PdfJinja('pdfjinja-template.pdf')
        pdfout = pdfjinja(dict(map=output_img.name))

        with NamedTemporaryFile(
            mode='wb+',
            prefix='geo-pypring',
            delete=False
        ) as output_pdf:
            pdfout.write(output_pdf)
            output_pdf.flush()

            response = FileResponse(
                output_pdf.name,
                request=request
            )
            response.headers['Content-Disposition'] = ('attachement; filename="{}"'
                                                       .format('pdfjinja.pdf'))
            response.headers['Content-Type'] = 'application/pdf'

            return response


def get_images(payload, loop):
    """
/ows/geojb?MAP_RESOLUTION=150&DPI=150&TRANSPARENT=true&LANG=fr&MAP.RESOLUTION=150&FORMAT=image%2Fpng&REQUEST=GetMap&SRS=EPSG%3A21781&BBOX=578059.45%2C217911.5%2C591940.5499999999%2C237088.5V&ERSION=1.1.1&STYLES=&SERVICE=WMS&WIDTH=1093&HEIGHT=1510&LAYERS=CADASTRE_A"
/ows/geojb?MAP_RESOLUTION=150&DPI=150&TRANSPARENT=true&LANG=fr&MAP.RESOLUTION=150&FORMAT=image%2Fpng&REQUEST=GetMap&SRS=EPSG%3A21781&BBOX=578059.45%2C217911.5%2C591940.5499999999%2C237088.5&VERSION=1.1.1&STYLES=&SERVICE=WMS&WIDTH=1093&HEIGHT=1510&LAYERS=CADASTRE_C"

BBOX=578059.45 217911.5 591940.5499999999 237088.5
WIDTH=1093
HEIGHT=1510
    """
    images = []

    map = payload['attributes']['map']
    epsg = map['projection']
    scale = map['scale']
    center = map['center']<commit_msg>Allow the create_pdf function to work outside pyramid<commit_after>import asyncio
import functools
import os
import requests
import subprocess


from pdfjinja import PdfJinja
from PIL import Image
from pyramid.config import Configurator
from pyramid.response import FileResponse
from pyramid.renderers import JSONP
from pyramid.view import view_config
from secretary import Renderer
from tempfile import NamedTemporaryFile
from io import BytesIO

WMS_HEADERS = {'Referer': 'http://localhost'}
LAYER_DPI = 25.4 / 0.28


def main(global_config, **settings):
    config = Configurator(settings=settings)
    config.add_renderer('jsonp', JSONP(param_name='callback', indent=None, separators=(',', ':')))
    config.add_route('mapprint', '/print')

    config.scan()

    return config.make_wsgi_app()


@view_config(route_name='mapprint')
def mapprint(request):
    map_image = None

    payload = request.json_body

    loop = asyncio.new_event_loop()
    images = get_images(payload, loop)

    for img in images:
        if not isinstance(img, Image.Image):
            img = Image.open(BytesIO(img.content)).convert('RGBA')

        if img.size != (1240, 1743):
            img = img.resize((1240, 1743))

        if map_image is None:
            map_image = Image.new('RGBA', (1240, 1743))
        map_image = Image.alpha_composite(map_image, img)

    output_file_name = create_pdf(map_image)

    response = FileResponse(
        output_file_name,
        request=request
    )
    response.headers['Content-Disposition'] = ('attachement; filename="{}"'
                                               .format(output_file_name + '.pdf'))
    response.headers['Content-Type'] = 'application/pdf'

    if os.path.exists(output_file_name):
        os.remove(output_file_name)

    return response


def create_pdf(output):
    return _create_pdf_libreoffice(output)
    #return _create_pdf_pdftk(output)


def _create_pdf_libreoffice(map_image):
    output_image = BytesIO()
    map_image.save(output_image, 'PNG')

    render = Renderer(media_path='.')
    # TODO: use the configuration to select the template
    # TODO: use the configuration to select the name of the key in the template
    result = render.render('template.odt', my_map=output_image)
    with NamedTemporaryFile(
            mode='wb+',
            prefix='geo-pyprint_',
            delete=True
    ) as generated_odt:
        generated_odt.write(result)
        generated_odt.flush()

        output_name = generated_odt.name + '.pdf'
        cmd = [
            'unoconv',
            '-f',
            'pdf',
            '-o',
            output_name,
            generated_odt.name
        ]
        subprocess.call(cmd, timeout=None)

        return output_name


def _create_pdf_pdftk(map_image):
    with NamedTemporaryFile(
        mode='wb+',
        prefix='geo-pyprint_',
        delete=True
    ) as map_image_file:
        map_image.save(map_image_file, 'PNG')
        map_image_file.flush()

        # TODO: use the configuration to select the template
        # TODO: use the configuration to select the name of the key in the template
        pdfjinja = PdfJinja('pdfjinja-template.pdf')
        pdfout = pdfjinja(dict(map=map_image_file.name))

        with NamedTemporaryFile(
            mode='wb+',
            prefix='geo-pyprint_',
            suffix='.pdf',
            delete=False
        ) as output_file:
            pdfout.write(output_file)
            output_file.flush()

            return output_file.name


def get_images(payload, loop):
    """
/ows/geojb?MAP_RESOLUTION=150&DPI=150&TRANSPARENT=true&LANG=fr&MAP.RESOLUTION=150&FORMAT=image%2Fpng&REQUEST=GetMap&SRS=EPSG%3A21781&BBOX=578059.45%2C217911.5%2C591940.5499999999%2C237088.5V&ERSION=1.1.1&STYLES=&SERVICE=WMS&WIDTH=1093&HEIGHT=1510&LAYERS=CADASTRE_A"
/ows/geojb?MAP_RESOLUTION=150&DPI=150&TRANSPARENT=true&LANG=fr&MAP.RESOLUTION=150&FORMAT=image%2Fpng&REQUEST=GetMap&SRS=EPSG%3A21781&BBOX=578059.45%2C217911.5%2C591940.5499999999%2C237088.5&VERSION=1.1.1&STYLES=&SERVICE=WMS&WIDTH=1093&HEIGHT=1510&LAYERS=CADASTRE_C"

BBOX=578059.45 217911.5 591940.5499999999 237088.5
WIDTH=1093
HEIGHT=1510
    """
    images = []

    map = payload['attributes']['map']
    epsg = map['projection']
    scale = map['scale']
    center = map['center']
{'fraction_non_alphanumeric': 0.11938861475508485, 'fraction_numerical': 0.051029004693705624, 'mean_word_length': 3.06158357771261, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 6, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3477012', 'n_tokens_mistral': 3048, 'n_tokens_neox': 2708, 'n_words': 479}