Example #1
0
 def decorator(*args, **kwargs):
     try:
         logger.info("==> {}::Acquire Semaphore ...".format(func.__name__))
         semaphore.acquire()
         return func(*args, **kwargs)
     finally:
         logger.info("<== {}::Release Semaphore ...".format(func.__name__))
         semaphore.release()
Example #2
0
    def _layout_and_paginate(self, html):
        """Layout and paginate the given HTML into WeasyPrint `Document` objects

        http://weasyprint.readthedocs.io/en/stable/api.html#python-api
        """
        start = time.time()
        # Lay out and paginate the document
        html = HTML(string=html,
                    url_fetcher=self.url_fetcher,
                    base_url=self.base_url)
        document = html.render(stylesheets=self.css)
        end = time.time()
        logger.info("Publisher::Layout step took {:.2f}s for {} pages".format(
            end - start, len(document.pages)))
        return document
Example #3
0
    def ajax_get(self, uid, *args, **kwargs):
        """Return the JSONified

        Any additional positional parameter in *args will pick only these keys
        from the returned dictionary.
        """
        logger.info("ajaxPrintView::ajax_get_uid:UID={} args={}".format(
            uid, args))

        wrapped = ReportModel(uid)
        if not wrapped.is_valid():
            return self.fail("No object found for UID '{}'".format(uid),
                             status=404)

        def converter(value):
            return wrapped.stringify(value)

        return self.pick(wrapped, converter=converter, *args)
Example #4
0
    def ajax_load_preview(self):
        """Recalculate the HTML of one rendered report after all the embedded
        JavaScripts modified the report on the client side.
        """
        # This is the html after it was rendered by the client browser and
        # eventually extended by JavaScript, e.g. Barcodes or Graphs added etc.
        # N.B. It might also contain multiple reports!
        html = self.request.form.get("html").decode("utf8")
        css = self.css

        publisher = IPublisher(html)
        publisher.link_css_file("bootstrap.min.css")
        publisher.link_css_file("print.css")
        publisher.add_inline_css(css)
        merge = self.request.get("merge") in ["on", "true", "yes", "1"]

        logger.info("Preview CSS: {}".format(css))
        images = publisher.write_png(merge=merge)

        preview = ""
        for image in images:
            preview += publisher.png_to_img(*image)
        preview += "<style type='text/css'>{}</style>".format(css)
        return preview
Example #5
0
    def download(self):
        # This is the html after it was rendered by the client browser and
        # eventually extended by JavaScript, e.g. Barcodes or Graphs added etc.
        # N.B. It might also contain multiple reports!
        html = self.request.form.get("html").decode("utf8")
        css = self.css

        publisher = IPublisher(html)
        publisher.link_css_file("bootstrap.min.css")
        # publisher.link_css_file("print.css")
        publisher.add_inline_css(css)
        merge = self.request.get("merge") in ["on", "true", "yes", "1"]

        logger.info("PDF CSS: {}".format(css))
        pdf = publisher.write_pdf(merge=merge)

        filename = "_".join(map(lambda r: r.id, self.collection))
        self.request.response.setHeader(
            "Content-Disposition", "attachment; filename=%s.pdf" % filename)
        self.request.response.setHeader("Content-Type", "application/pdf")
        self.request.response.setHeader("Content-Length", len(pdf))
        self.request.response.setHeader("Cache-Control", "no-store")
        self.request.response.setHeader("Pragma", "no-cache")
        self.request.response.write(pdf)
Example #6
0
    def url_fetcher(self, url):
        """Fetches internal URLs by path and not via an external request.

        N.B. Multiple calls to this method might exhaust the available threads
             of the server, which causes a hanging instance.
        """
        if url.startswith("data"):
            logger.info("Data URL, delegate to default URL fetcher...")
            return default_url_fetcher(url)

        logger.info("Fetching URL '{}' for WeasyPrint".format(url))

        # get the pyhsical path from the URL
        request = api.get_request()
        host = request.get_header("HOST")
        path = "/".join(request.physicalPathFromURL(url))

        # fetch the object by sub-request
        portal = api.get_portal()
        context = portal.restrictedTraverse(path, None)

        if context is None or host not in url:
            logger.info("External URL, delegate to default URL fetcher...")
            return default_url_fetcher(url)

        logger.info("Local URL, fetching data by path '{}'".format(path))

        # get the data via an authenticated subrequest
        response = subrequest(path)

        # Prepare the return data as required by WeasyPrint
        string = response.getBody()
        filename = url.split("/")[-1]
        mime_type = mimetypes.guess_type(url)[0]
        redirected_url = url

        return {
            "string": string,
            "filename": filename,
            "mime_type": mime_type,
            "redirected_url": redirected_url,
        }
Example #7
0
 def __init__(self, model):
     logger.info("ReportView::__init__:model={}".format(model))
     self.model = model
     self.context = model
     self.request = getRequest()
Example #8
0
 def __init__(self, collection):
     logger.info(
         "MultiReportView::__init__:collection={}".format(collection))
     self.collection = collection
     self.context = collection
     self.request = getRequest()
Example #9
0
 def __init__(self, type="senaite.publisher.reports"):
     logger.info("TemplateFinder::init:type={}".format(type))
     self.type = type