Example #1
0
def simplify_pdf(pdf: str, select: str, outfile: typing.TextIO):
    """
    Given a PDF and a metric by which to select the first or last page in a range of pages with the same name,
    remove the unnecessary pages
    """
    in_pdf = pdfrw.PdfFileReader(pdf)
    out_pdf = pdfrw.PdfFileWriter(trailer=in_pdf)
    for index in calculate_pages(in_pdf, select):
        out_pdf.addPage(in_pdf.getPage(index))
    out_pdf.write(outfile)
Example #2
0
def add_metadata_to_pdf(ctx: Context):
    """
    Adds metadata about EDLM version and source files after
    PDF create

    Args:
        ctx: Context
    """
    out_file = str(ctx.out_file.absolute())
    trailer = pdfrw.PdfReader(out_file)
    trailer.Info.Creator = 'EDLM ' + __version__
    trailer.Info.Producer = 'EDLM ' + _get_document_hash(ctx)
    pdfrw.PdfFileWriter(out_file, trailer=trailer).write()
Example #3
0
    def draw_image(self,
                   page_number,
                   image_file,
                   x,
                   y,
                   width,
                   height,
                   rotation=0):
        image_path = os.path.join(current.request.folder, "temp",
                                  uuid.uuid4().hex + ".jpg")
        with open(image_path, "wb+") as f:
            f.write(image_file.read())

        if rotation:
            image = Image.open(image_path)
            image.rotate(rotation, expand=True).save(image_path)

        layer_path = os.path.join(current.request.folder, "temp",
                                  uuid.uuid4().hex + ".pdf")

        canv = canvas.Canvas(layer_path,
                             pagesize=(self._LAYER_SIZE_X, self._LAYER_SIZE_Y))
        canv.drawImage(image_path, x, y, width=width, height=height)
        canv.save()

        layer = pdfrw.PdfReader(layer_path)
        output_file = pdfrw.PdfFileWriter()

        input_path = os.path.join(current.request.folder, "temp",
                                  uuid.uuid4().hex + ".pdf")
        with open(input_path, "wb+") as f:
            f.write(self.pdf_stream)

        input_file = pdfrw.PdfReader(input_path)

        for i in range(len(input_file.pages)):
            if i == page_number - 1:
                merger = pdfrw.PageMerge(input_file.pages[i])
                merger.add(layer.pages[0]).render()

        output_file.write(self._final_path_with_image, input_file)

        with open(self._final_path_with_image, "rb+") as f:
            self.pdf_stream = f.read()

        os.remove(image_path)
        os.remove(layer_path)
        os.remove(input_path)
        os.remove(self._final_path_with_image)

        return self
Example #4
0
    def draw_text(
        self,
        text: str,
        page_number: int,
        x: Union[float, int],
        y: Union[float, int],
    ) -> "_PyPDFForm":
        """Draw a text on a PDF form."""

        self._validate_template(self.stream)
        self._validate_draw_text_inputs(text, page_number, x, y)

        input_file = pdfrw.PdfReader(fdata=self.stream)

        canv_buff = BytesIO()

        c = canv.Canvas(
            canv_buff,
            pagesize=(
                float(input_file.pages[page_number - 1].MediaBox[2]),
                float(input_file.pages[page_number - 1].MediaBox[3]),
            ),
        )

        c.drawString(x, y, text)
        c.save()
        canv_buff.seek(0)

        output_file = pdfrw.PdfFileWriter()

        for i in range(len(input_file.pages)):
            if i == page_number - 1:
                merger = pdfrw.PageMerge(input_file.pages[i])
                merger.add(
                    pdfrw.PdfReader(fdata=canv_buff.read()).pages[0]).render()

        result_stream = BytesIO()
        output_file.write(result_stream, input_file)
        result_stream.seek(0)
        self.stream = result_stream.read()

        canv_buff.close()
        result_stream.close()

        return self
Example #5
0
    def draw_image(
        self,
        image_stream: bytes,
        page_number: int,
        x: Union[float, int],
        y: Union[float, int],
        width: Union[float, int],
        height: Union[float, int],
        rotation: Union[float, int],
    ) -> "_PyPDFForm":
        """Draw an image on a PDF form."""

        self._validate_template(self.stream)
        self._validate_draw_image_inputs(page_number, x, y, width, height,
                                         rotation)

        input_file = pdfrw.PdfReader(fdata=self.stream)

        buff = BytesIO()
        buff.write(image_stream)
        buff.seek(0)

        try:
            image = Image.open(buff)
        except Exception:
            raise InvalidImageError

        image_buff = BytesIO()
        image.rotate(rotation, expand=True).save(image_buff,
                                                 format=image.format)
        image_buff.seek(0)

        canv_buff = BytesIO()

        c = canv.Canvas(
            canv_buff,
            pagesize=(
                float(input_file.pages[page_number - 1].MediaBox[2]),
                float(input_file.pages[page_number - 1].MediaBox[3]),
            ),
        )

        c.drawImage(ImageReader(image_buff), x, y, width=width, height=height)
        c.save()
        canv_buff.seek(0)

        output_file = pdfrw.PdfFileWriter()

        for i in range(len(input_file.pages)):
            if i == page_number - 1:
                merger = pdfrw.PageMerge(input_file.pages[i])
                merger.add(
                    pdfrw.PdfReader(fdata=canv_buff.read()).pages[0]).render()

        result_stream = BytesIO()
        output_file.write(result_stream, input_file)
        result_stream.seek(0)
        self.stream = result_stream.read()

        buff.close()
        image_buff.close()
        canv_buff.close()
        result_stream.close()

        return self
Example #6
0
    def _fill_pdf_canvas(self):
        template_pdf = pdfrw.PdfReader(self._template_path)
        layers = []

        for i in range(len(template_pdf.pages)):
            layer_path = os.path.join(current.request.folder, "temp",
                                      uuid.uuid4().hex + ".pdf")
            layers.append(layer_path)

            canv = canvas.Canvas(layer_path,
                                 pagesize=(self._LAYER_SIZE_X,
                                           self._LAYER_SIZE_Y))
            canv.setFont(self._CANVAS_FONT, self._global_font_size)

            annotations = template_pdf.pages[i][self._ANNOT_KEY]
            if annotations:
                for j in reversed(range(len(annotations))):
                    annotation = annotations[j]

                    if (annotation[self._SUBTYPE_KEY]
                            == self._WIDGET_SUBTYPE_KEY
                            and annotation[self._ANNOT_FIELD_KEY]):
                        key = annotation[self._ANNOT_FIELD_KEY][1:-1]
                        if key in self._data_dict.keys():
                            if self._data_dict[key] in [
                                    pdfrw.PdfName.Yes,
                                    pdfrw.PdfName.Off,
                            ]:
                                annotation.update(
                                    pdfrw.PdfDict(AS=self._data_dict[key],
                                                  Ff=pdfrw.PdfObject(1)))
                            else:
                                coordinates = annotation[self._ANNOT_RECT_KEY]
                                annotations.pop(j)
                                if len(self._data_dict[key]
                                       ) < self._max_txt_length:
                                    canv.drawString(
                                        float(coordinates[0]),
                                        (float(coordinates[1]) +
                                         float(coordinates[3])) / 2 - 2,
                                        self._data_dict[key],
                                    )
                                else:
                                    txt_obj = canv.beginText(0, 0)

                                    start = 0
                                    end = self._max_txt_length

                                    while end < len(self._data_dict[key]):
                                        txt_obj.textLine(
                                            (self._data_dict[key][start:end]))
                                        start += self._max_txt_length
                                        end += self._max_txt_length
                                    txt_obj.textLine(
                                        self._data_dict[key][start:])
                                    canv.saveState()
                                    canv.translate(
                                        float(coordinates[0]),
                                        (float(coordinates[1]) +
                                         float(coordinates[3])) / 2 - 2,
                                    )
                                    canv.drawText(txt_obj)
                                    canv.restoreState()
                        else:
                            annotations.pop(j)

            canv.save()
        pdfrw.PdfWriter().write(self._output_path, template_pdf)

        output_file = pdfrw.PdfFileWriter()
        input_file = pdfrw.PdfReader(self._output_path)

        for i in range(len(template_pdf.pages)):
            layer_pdf = pdfrw.PdfReader(layers[i])
            os.remove(layers[i])
            input_page = input_file.pages[i]
            merger = pdfrw.PageMerge(input_page)
            if len(layer_pdf.pages) > 0:
                merger.add(layer_pdf.pages[0]).render()

        output_file.write(self._final_path, input_file)