from io import BytesIO from typing import BinaryIO from fpdf import FPDF import pdfrw from pdfrw import PdfReader from pdfrw.objects.pdfdict import PdfDict class PdfMaker: def __init__(self, size: tuple): self.size = size self.writer = pdfrw.PdfWriter() def clear(self): del self.writer self.writer = pdfrw.PdfWriter() def add_image(self, image_data): size = self.size fpdf = FPDF(format=size, unit="pt") width, height = self.size fpdf.add_page() fpdf.image(image_data, 0, 0, width, height) fpdf_reader: pdfrw.PdfReader = pdfrw.PdfReader(fdata=bytes(fpdf.output())) self.writer.addpage(fpdf_reader.getPage(0)) def add_pdf(self, pdf_data: BytesIO): pdf_reader = pdfrw.PdfReader(fdata=bytes(pdf_data.read())) self.writer.addpage(pdf_reader.getPage(0)) def add_pdfs(self, pdf_data: BytesIO): pdf_reader = pdfrw.PdfReader(fdata=bytes(pdf_data.read())) self.writer.addpages(pdf_reader.readpages(pdf_reader.Root)) def get_bytes(self): result_io = BytesIO() self.writer.write(result_io) result_io.seek(0) return result_io @staticmethod def check_is_correct_aspects_ratio(file: BinaryIO): pdf = PdfReader(file) allowed_aspects_ratio = 1.45 page: PdfDict try: page: PdfDict = pdf.getPage(0) except IndexError: raise Exception("Ошибка. В документе нет страниц.") try: pdf.getPage(1) raise Exception("Ошибка. В документе должна быть только одна страница.") except IndexError: pass media_box = page.MediaBox width = float(media_box[2]) - float(media_box[0]) height = float(media_box[3]) - float(media_box[1]) aspect_ratio = width / height if abs(aspect_ratio - allowed_aspects_ratio) > 0.01: raise Exception("Ошибка. Страница документа должна быть размером 58х40.") file.seek(0)