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()
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
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)
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
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)
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, }
def __init__(self, model): logger.info("ReportView::__init__:model={}".format(model)) self.model = model self.context = model self.request = getRequest()
def __init__(self, collection): logger.info( "MultiReportView::__init__:collection={}".format(collection)) self.collection = collection self.context = collection self.request = getRequest()
def __init__(self, type="senaite.publisher.reports"): logger.info("TemplateFinder::init:type={}".format(type)) self.type = type