Best Python code snippet using playwright-python
main.py
Source:main.py
...178 r = convert_checkboxes_and_radio_buttons(record, md)179 r = convert_dropdowns_to_strings(r, md)180 r = collapse_radio_groups(r, md)181 return r182def fill_pdf(input_pdf_path: Path, output_pdf_path: Path, data_dict: dict) -> None:183 '''Main function to handle filling in PDF fields.184 Uses data_dict to populate fields from the template in input_pdf_path, writing the filled-in PDF to output_pdf_path.185 '''186 template_pdf = pdfrw.PdfReader(input_pdf_path)187 for page in template_pdf.pages:188 annotations = page[ANNOT_KEY]189 if annotations is None:190 continue191 for annotation in annotations:192 if annotation[SUBTYPE_KEY] == WIDGET_SUBTYPE_KEY:193 if annotation[ANNOT_FIELD_KEY]: ### Isolated fields (has a '/T' key)194 key = annotation[ANNOT_FIELD_KEY][1:-1]195 if key in data_dict.keys():196 if type(data_dict[key]) == bool: # Checkboxes197 if data_dict[key] == True:198 annotation.update(pdfrw.PdfDict(199 AS=pdfrw.PdfName('Yes'), V=pdfrw.PdfName('Yes'))200 )201 else:202 annotation.update(pdfrw.PdfDict(203 AS=pdfrw.PdfName('Off'), V=pdfrw.PdfName('Off'))204 )205 else: # Text field206 annotation.update(pdfrw.PdfDict(207 AP='', V=data_dict[key])208 )209 210 elif annotation[PARENT_KEY][ANNOT_FIELD_KEY]: ### Grouped fields (has a '/Parent' -> '/T' key)211 group = annotation[PARENT_KEY][ANNOT_FIELD_KEY][1:-1]212 if group in data_dict.keys():213 if type(data_dict[group]) == dict and len(data_dict[group]) != 0: # Radio buttons214 selected_radio_button = pdfrw.PdfName(list(data_dict[group].keys())[0])215 if(selected_radio_button in annotation[APPEARANCE_KEY][D_KEY].keys()):216 # Page 441 of:217 # https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/PDF32000_2008.pdf218 annotation[PARENT_KEY].update(pdfrw.PdfDict(219 V=selected_radio_button)220 )221 annotation.update(pdfrw.PdfDict(222 AS=selected_radio_button)223 )224 elif type(data_dict[group]) == bool: # Linked checkboxes (across multiple pages?)225 if data_dict[group] == True:226 annotation.update(pdfrw.PdfDict(227 AS=pdfrw.PdfName('Yes'), V=pdfrw.PdfName('Yes'))228 )229 else:230 annotation.update(pdfrw.PdfDict(231 AS=pdfrw.PdfName('Off'), V=pdfrw.PdfName('Off'))232 )233 else: # Linked text fields (across multiple pages?)234 annotation[PARENT_KEY].update(pdfrw.PdfDict(235 AP='', V=data_dict[group])236 )237 238 if not output_pdf_path.parent.exists():239 print(f" Location of output PDF '{output_pdf_path}' doesn't exist; creating: {output_pdf_path.parent}")240 output_pdf_path.parent.mkdir(parents=True, exist_ok=True)241 242 template_pdf.Root.AcroForm.update(pdfrw.PdfDict(NeedAppearances=pdfrw.PdfObject('true')))243 pdfrw.PdfWriter().write(output_pdf_path, template_pdf)244 return245################################################################246################################################################247if __name__ == '__main__':248 RECORD,REDCAP_UNIQUE_IDENTIFIER,PDF_TEMPLATE,OUTPUT = get_cmd_line_input(parser.parse_args())249 print()250 secrets = load_secrets(SECRETS_FILE)251 print("Loaded secrets file")252 proj_metadata = redcap_helpers.get_metadata(secrets)253 print("Got project metadata")254 # print(redcap_helpers.get_fields_and_types(proj_metadata))255 # proj_multiple_choice_text = redcap_helpers.get_multiple_choice_text(proj_metadata)256 # print(proj_multiple_choice_text)257 record = redcap_helpers.get_record(secrets, REDCAP_UNIQUE_IDENTIFIER, RECORD)258 print(f"Got record {RECORD} (identified by '{REDCAP_UNIQUE_IDENTIFIER}')")259 prepared_data_dict = prepare_for_fill(record, proj_metadata)260 print("Prepared Python dictionary:", prepared_data_dict)261 print("Using PDF template: " + str(PDF_TEMPLATE))262 fill_pdf(PDF_TEMPLATE, OUTPUT, prepared_data_dict)263 print("PDF written to: " + str(OUTPUT))...
pdf_tenant.py
Source:pdf_tenant.py
1from tablesdb import Sql_database2from pathlib import Path3import os4# pdf function generator5class Pdf_tenant:6 def __init__(self, pdf, nom, prenom, adresse, ville, loyer, charge, day, month, years, cat,7 sci_nom, sci_adresse, sci_cp_ville, sci_tel, sci_mail, sci_siret):8 self.month_list = {1: "Janvier", 2: "Fevrier", 3: "Mars",9 4: "Avril", 5: "Mai", 6: "Juin",10 7: "Juillet", 8: "Aout", 9: "Septembre",11 10: "Octobre", 11: "Novembre", 12: "Decembre"}12 self.pdf = pdf13 self.nom = nom14 self.prenom = prenom15 self.adresse = adresse16 self.ville = ville17 self.loyer = loyer18 self.charge = charge19 self.day = day20 self.month = month21 self.year = years22 self.cat = cat23 self.sci_nom = sci_nom24 self.sci_adresse = sci_adresse25 self.sci_cp_ville = sci_cp_ville26 self.sci_tel = sci_tel27 self.sci_mail = sci_mail28 self.sci_siret = sci_siret29 self.database = Sql_database()30 def generator(self):31 self.pdf.setFont("Helvetica", 15)32 if self.cat == 0: # habitation case33 self.pdf.drawString(150, 550,34 f"Loyer pour le mois de {self.month_list[int(self.month)]} {self.year}")35 self.pdf.drawString(140, 450, "Loyer")36 self.pdf.drawString(340, 450, f"{float(self.loyer):0.2f} â¬")37 self.pdf.drawString(140, 420, "Provision pour charges")38 self.pdf.drawString(345, 420, f"{float(self.charge):0.2f} â¬")39 self.pdf.drawString(140, 400, "Total")40 self.pdf.drawString(340, 400, f"{float(self.loyer) + float(self.charge):0.2f} â¬")41 else:42 self.pdf.drawString(150, 570, f"FACTURE N° {self.month}/{self.year}")43 self.pdf.drawString(100, 530,44 f"Loyer pour le mois de {self.month_list[int(self.month)]} {self.year}")45 self.pdf.drawString(100, 450, "Loyer hors taxes")46 loyer_ht = (float(self.loyer / 1.20))47 self.pdf.drawString(350, 450, f"{loyer_ht:0.2f} â¬")48 self.pdf.drawString(100, 430, "TVA 20 %")49 self.pdf.drawString(355, 430, f"{(float(self.loyer) - loyer_ht):0.2f} â¬")50 self.pdf.drawString(100, 410, "Provision pour charges")51 self.pdf.drawString(355, 410, f"{float(self.charge):0.2f} â¬")52 self.pdf.drawString(100, 390, "Montant TTC")53 self.pdf.drawString(350, 390, f"{float(self.loyer) + float(self.charge):0.2f} â¬")54 # Coordonnées de la SCI55 self.pdf.drawString(20, 800, f"{self.sci_nom}") # colon, row ( 0 down / 800 up) ( 0 left / 600 right)56 self.pdf.drawString(20, 785, f"{self.sci_adresse}")57 self.pdf.drawString(20, 770, f"{self.sci_cp_ville}")58 self.pdf.drawString(20, 755, f"{self.sci_tel}")59 self.pdf.drawString(20, 740, f"{self.sci_siret}")60 # Coordonnées du locataire61 self.pdf.drawString(350, 700, f"{self.nom} {self.prenom}")62 self.pdf.drawString(350, 685, f"{self.adresse}")63 self.pdf.drawString(350, 670, f"{self.ville}")64 # Date65 self.pdf.drawString(350, 600, f"A {self.sci_cp_ville.split(' ', 1)[1]} le {self.day}/{self.month}/{self.year}")66 # corps67 self.pdf.drawCentredString(160, 613, "QUITTANCE DE LOYER")68 # graphic elements69 self.pdf.line(10, 630, 590, 630)70 self.pdf.line(10, 595, 590, 595)71 self.pdf.line(10, 630, 10, 595)72 self.pdf.line(590, 630, 590, 595)73 p = Path()74 s = p / 'sign.PNG'75 if s.exists():76 self.pdf.drawImage("sign.PNG", 350, 80, width=120, height=120)77 # ending78 self.pdf.showPage()79 self.pdf.save()80class IndexLetter:81 def __init__(self, pdf, nom, prenom, adresse, ville, loyer, charge, day, month, year,82 sci_nom, sci_adresse, sci_cp_ville, sci_tel, sci_mail, sci_siret, indice_base, indice_new, cat, date_entree):83 self.month_list = {1: ["Janvier", "1er trimestre"], 2: ["Fevrier", "1er trimestre"], 3: ["Mars", "1er trimestre"],84 4: ["Avril", "2eme trimestre"], 5: ["Mai", "2eme trimestre"], 6: ["Juin", "2eme trimestre"],85 7: ["Juillet", "3eme trimestre"], 8: ["Aout", "3eme trimestre"], 9: ["Septembre", "3eme trimestre"],86 10: ["Octobre", "3eme trimestre"], 11: ["Novembre", "3eme trimestre"], 12: ["Decembre", "3eme trimestre"]}87 self.pdf = pdf88 self.nom = nom89 self.prenom = prenom90 self.adresse = adresse91 self.ville = ville92 self.loyer = float(loyer) * float(indice_new) / float(indice_base)93 self.charge = charge94 self.day = day95 self.month = month96 self.year = year97 self.sci_nom = sci_nom98 self.sci_adresse = sci_adresse99 self.sci_cp_ville = sci_cp_ville100 self.sci_tel = sci_tel101 self.sci_mail = sci_mail102 self.sci_siret = sci_siret103 self.indice_base = indice_base104 self.new_indice = indice_new105 self.cat = cat106 self.date_entree = date_entree107 self.database = Sql_database()108 if self.cat == 1:109 self.type ="loyers commerciaux"110 else:111 self.type ="de références des loyers"112 def generator(self):113 self.pdf.setFont("Helvetica", 15)114 if self.cat == 1:115 self.pdf.drawString(60, 300, "Loyer hors charges")116 self.pdf.drawString(250, 300, f"{float(self.loyer) / 1.20:0.2f} â¬")117 self.pdf.drawString(60, 280, "TVA")118 self.pdf.drawString(250, 280, f"{float(self.loyer) - float(self.loyer) / 1.20:0.2f} â¬")119 self.pdf.drawString(60, 260, "Provisions pour charges")120 self.pdf.drawString(255, 260, f"{self.charge:0.2f} â¬")121 self.pdf.drawString(60, 240, "Total")122 self.pdf.drawString(250, 240, f"{float(self.loyer) + float(self.charge):0.2f} â¬")123 else:124 self.pdf.drawString(60, 300, "Loyer")125 self.pdf.drawString(250, 300, f"{float(self.loyer):0.2f} â¬")126 self.pdf.drawString(60, 280, "Provisions pour charges")127 self.pdf.drawString(255, 280, f"{self.charge:0.2f} â¬")128 self.pdf.drawString(60, 260, "Total")129 self.pdf.drawString(250, 260, f"{float(self.loyer) + float(self.charge):0.2f} â¬")130 # Coordonnées de la SCI131 self.pdf.drawString(20, 800, f"{self.sci_nom}") # colon, row ( 0 down / 800 up) ( 0 left / 600 right)132 self.pdf.drawString(20, 785, f"{self.sci_adresse}")133 self.pdf.drawString(20, 770, f"{self.sci_cp_ville}")134 self.pdf.drawString(20, 755, f"{self.sci_tel}")135 self.pdf.drawString(20, 740, f"{self.sci_siret}")136 # Coordonnées du locataire137 self.pdf.drawString(350, 700, f"{self.nom} {self.prenom}")138 self.pdf.drawString(350, 685, f"{self.adresse}")139 self.pdf.drawString(350, 670, f"{self.ville}")140 # Date141 self.pdf.drawString(350, 613, f"A {self.sci_cp_ville.split(' ', 1)[1]} le {self.day}/{self.month}/{self.year}")142 # Corps143 self.pdf.drawString(20, 560, "OBJET : REVISION DU LOYER")144 self.pdf.drawString(20, 500, "Madame, Monsieur")145 self.pdf.drawString(20, 460, f"Par la présente, je vous informe qu'à compter du {self.day} {self.month_list[int(self.month)][0]} {self.year} , votre loyer principal")146 self.pdf.drawString(20, 440, f"mensuel s'élèvera à la somme de {self.loyer:0.2f} ⬠TTC.Cette variation a été calculée")147 self.pdf.drawString(20, 420, f"selon l'indice de révision (indice national des {self.type} prévu dans ")148 self.pdf.drawString(20, 400, "votre bail conformément à la législation en vigeur. Le loyer hors charges est augmenté")149 self.pdf.drawString(20, 380, f"de {float(self.new_indice) / float(self.indice_base):0.2f} %. Les deux indices considérés sont :")150 self.pdf.drawString(60, 360, f"- {self.month_list[int(self.month)][1]} {self.date_entree.split('/')[2]}: {self.indice_base}")151 self.pdf.drawString(60, 340, f"- {self.month_list[int(self.month)][1]} {self.year} : {self.new_indice}")152 self.pdf.drawString(20, 320, "Les nouvelles données de votre quittance seront dorénavant les suivantes :")153 self.pdf.drawString(20, 220, "Je reste à votre dispositionpour de plus amples renseignements. Dans cette attente")154 self.pdf.drawString(20, 200, "veuillez agréer, Madame, Monsieur, l'expression de mes salutaions distinguées")155 self.pdf.drawString(20, 160, "Le Gérant.")156 p = Path()157 s = p / 'sign.PNG'158 if s.exists():159 self.pdf.drawImage("sign.PNG", 20, 30, width=120, height=120)160 self.pdf.showPage()161 self.pdf.save()162class Pdf_shareholder:163 def __init__(self, pdf, nom, prenom, sci, date, montant):164 self.pdf = pdf165 self.nom = nom166 self.prenom = prenom167 self.sci = sci168 self.date = date169 self.montant = montant170 def generator(self):171 self.pdf.drawString(20, 800, f"SCI {self.sci}")172 self.pdf.drawString(350, 613, f"le {self.date}")173 self.pdf.drawString(350, 700, f"{self.nom} {self.prenom}")174 self.pdf.drawString(20, 460, f" Un virement de {self.montant} à été éffectué sur votre compte")175 self.pdf.drawString(20, 220,176 "Je reste à votre dispositionpour de plus amples renseignements. Dans cette attente")177 self.pdf.drawString(20, 200, "veuillez agréer, Madame, Monsieur, l'expression de mes salutaions distinguées")178 self.pdf.drawString(20, 160, "Le Gérant.")179 p = Path()180 s = p / 'sign.PNG'181 if s.exists():182 self.pdf.drawImage("sign.PNG", 20, 30, width=120, height=120)183 self.pdf.showPage()184 self.pdf.save()185if __name__ == "__main__":186 from reportlab.pdfgen import canvas187 directory = Path(__file__).parent188 directory.mkdir(parents=True, exist_ok=True)189 path = directory.joinpath("test.pdf")190 pdf = canvas.Canvas(str(path))191 pdf_gen = Pdf_tenant(pdf, nom="SEBAN", prenom="Emmanuel", adresse="7 rue ducis", ville="78000 VERSAILLES",192 loyer=1000, charge="200", day="12", month="05", years="2020", cat=1,193 sci_nom="JOMO",194 sci_adresse="19 rue laurent Gaudet", sci_cp_ville="78150 LE CHESNAY",195 sci_tel="01 39 55 16 69", sci_mail="marcelseban@hotmail.fr", sci_siret="155522220")196 #pdf_gen = IndexLetter(pdf, nom="SEBAN", prenom="Emmanuel", adresse="7 rue ducis", ville="78000 VERSAILLES",197 # loyer="1000", charge="200", day="12", month="5", year="2020", sci_nom="JOMO",198 # sci_adresse="19 rue laurent Gaudet", sci_cp_ville="78150 LE CHESNAY", sci_tel="01 39 55 16 69"199 # , sci_mail="marcelseban@hotmail.fr", sci_siret="155522220", indice_base="110", indice_new="115", cat=0)...
views.py
Source:views.py
1from __future__ import print_function2from django.shortcuts import render3from django.urls import reverse4from django.http import HttpResponseRedirect, Http404, FileResponse5from django.contrib.auth import authenticate, login, logout6from django.db.models import Value, Count, CharField7from django.core.files.storage import FileSystemStorage8from .models import User_profile9from datetime import datetime 10from tzlocal import get_localzone11from PyPDF2 import PdfFileReader, PdfFileWriter, PdfFileMerger12from .forms import PDFMergeForm, PDFSplitForm, PDFDeleteForm13import os14import io15from zipfile import ZipFile16from apiclient.discovery import build17from google.oauth2 import service_account18from oauth2client import file, client, tools19from httplib2 import Http20from . import auth21from users.facadeGoogleDrive import GoogleDrive22# Create your views here.23def index(request):24 return render(request, "pdf/upload.html")25def upload(request ,name , file_path , mimetype):26 GoogleDrive().upload(request,name, file_path, mimetype)27def download(request , file_id , file_name , mimeType) :28 return GoogleDrive().download(file_id, file_name, mimeType)29def get_user_history(folder_id) :30 return GoogleDrive().get_user_history(folder_id)31def merge(request):32 if request.method == 'POST':33 form = PDFMergeForm(request.POST, request.FILES)34 if form.is_valid():35 # get file input from merge form36 file1 = form.cleaned_data['file1']37 file2 = form.cleaned_data['file2']38 # make sure that both input files is pdf39 if ((os.path.splitext(str(file1))[1] != '.pdf') or (os.path.splitext(str(file2))[1] != '.pdf')):40 return render(request, 'pdf/pdf_split.html', {'form':form})41 # merge two file42 pdfMerge = PdfFileMerger()43 pdfMerge.append(PdfFileReader(file1))44 pdfMerge.append(PdfFileReader(file2))45 # write merged file46 pdfMerge.write('merged_file.pdf')47 # output merged file48 response = FileResponse(open('merged_file.pdf', 'rb'))49 response['content_type'] = "application/pdf"50 response['Content-Disposition'] = 'attachment;filename="merged_file.pdf"'51 52 # check if user is not anonymous (authenticated user)53 # upload processed file to google drive54 if not request.user.is_anonymous:55 date_time = datetime.fromtimestamp(datetime.now().timestamp(),get_localzone()).strftime("%d/%m/%Y %H:%M:%S")56 upload(request,"merged file {}.pdf".format(date_time) , "merged_file.pdf" , "pdf")57 # remove processed file58 os.remove('merged_file.pdf')59 return response60 else:61 form = PDFMergeForm()62 else:63 form = PDFMergeForm()64 return render(request, 'pdf/pdf_merge.html', {'form':form})65def split(request):66 if request.method == 'POST':67 form = PDFSplitForm(request.POST, request.FILES)68 if form.is_valid():69 # get file input from split form70 inputFile = form.cleaned_data['file1']71 pageNum = form.cleaned_data['pageNum']72 # make sure that input file is pdf73 if (os.path.splitext(str(inputFile))[1] != '.pdf'):74 return render(request, 'pdf/pdf_split.html', {'form':form})75 # read input pdf76 inputPDF = PdfFileReader(inputFile)77 outputPDF1 = PdfFileWriter()78 outputPDF2 = PdfFileWriter()79 # make sure that page number is valid80 if ((int(pageNum) <= 0) or (int(pageNum) > inputPDF.getNumPages()) or (inputPDF.getNumPages() == 1)):81 return render(request, 'pdf/pdf_split.html', {82 'message': 'Invalid',83 'form': form,84 })85 # split first half of the pdf from 0 to page number86 for i in range(pageNum):87 outputPDF1.addPage(inputPDF.getPage(i))88 with open('splited_file_1.pdf', 'wb') as outfile:89 outputPDF1.write(outfile)90 # split second half of the pdf from (page number+1) to last page91 for i in range(pageNum, inputPDF.getNumPages()):92 outputPDF2.addPage(inputPDF.getPage(i))93 with open('splited_file_2.pdf', 'wb') as outfile:94 outputPDF2.write(outfile)95 # zip two file for output96 zf = ZipFile('splited_files.zip', "w")97 zf.write('splited_file_1.pdf', 'splited_file_1.pdf')98 zf.write('splited_file_2.pdf', 'splited_file_2.pdf')99 zf.close()100 # output splited file101 response = FileResponse(open('splited_files.zip', 'rb'))102 response['content_type'] = "application/pdf"103 response['Content-Disposition'] = 'attachment;filename="splited_files.zip"'104 # check if user is not anonymous (authenticated user)105 # upload processed file to google drive106 if not request.user.is_anonymous:107 date_time = datetime.fromtimestamp(datetime.now().timestamp(),get_localzone()).strftime("%d/%m/%Y %H:%M:%S")108 upload(request,"splited file {}.zip".format(date_time) , "splited_files.zip" , "zip")109 110 # remove processed file111 os.remove('splited_files.zip')112 os.remove('splited_file_1.pdf')113 os.remove('splited_file_2.pdf')114 return response115 else:116 form = PDFSplitForm()117 else:118 form = PDFSplitForm()119 return render(request, 'pdf/pdf_split.html', {'form':form})120def delete(request):121 if request.method == 'POST':122 form = PDFDeleteForm(request.POST, request.FILES)123 if form.is_valid():124 # get file input from delete form125 inputFile = form.cleaned_data['file1']126 # make sure that input file is pdf127 if (os.path.splitext(str(inputFile))[1] != '.pdf'):128 return render(request, 'pdf/pdf_split.html', {'form':form})129 # read input pdf130 inputPDF = PdfFileReader(inputFile)131 outputPDF = PdfFileWriter()132 133 # get the correct page(s) to delete134 pageNum = form.cleaned_data['pageNum'].replace(" ", "").split(',')135 pageToDeleteDup = []136 for page in pageNum:137 pageInt = [int(i) for i in page.split('-')]138 if (len(pageInt) == 2):139 for i in range(pageInt[0], pageInt[-1] + 1):140 pageToDeleteDup += [i]141 else:142 pageToDeleteDup += pageInt143 pageToDelete = []144 # delete duplication page number in list145 for num in pageToDeleteDup:146 if num not in pageToDelete:147 pageToDelete.append(num)148 # make sure that page number is valid149 if ((max(pageToDelete) > inputPDF.getNumPages()) or (min(pageToDelete) <= 0) or (inputPDF.getNumPages() == 1)):150 return render(request, 'pdf/pdf_delete.html', {151 'message': 'Invalid',152 'form': form,153 })154 # delete page(s)155 for i in range(inputPDF.getNumPages()):156 if (i + 1) not in pageToDelete:157 outputPDF.addPage(inputPDF.getPage(i))158 with open('deleted_file.pdf', 'wb') as outfile:159 outputPDF.write(outfile)160 # output deleted file161 response = FileResponse(open('deleted_file.pdf', 'rb'))162 response['content_type'] = "application/pdf"163 response['Content-Disposition'] = 'attachment;filename="deleted_file.pdf"'164 # check if user is not anonymous (authenticated user)165 # upload processed file to google drive166 if not request.user.is_anonymous:167 date_time = datetime.fromtimestamp(datetime.now().timestamp(),get_localzone()).strftime("%d/%m/%Y %H:%M:%S")168 upload(request,"deleted file {}.pdf".format(date_time) , "deleted_file.pdf" , "pdf")169 170 # remove processed file171 os.remove('deleted_file.pdf')172 return response173 else:174 form = PDFDeleteForm()175 else:176 form = PDFDeleteForm()...
PdfImagePlugin.py
Source:PdfImagePlugin.py
1#2# The Python Imaging Library.3# $Id$4#5# PDF (Acrobat) file handling6#7# History:8# 1996-07-16 fl Created9# 1997-01-18 fl Fixed header10# 2004-02-21 fl Fixes for 1/L/CMYK images, etc.11# 2004-02-24 fl Fixes for 1 and P images.12#13# Copyright (c) 1997-2004 by Secret Labs AB. All rights reserved.14# Copyright (c) 1996-1997 by Fredrik Lundh.15#16# See the README file for information on usage and redistribution.17#18##19# Image plugin for PDF images (output only).20##21from . import Image, ImageFile, ImageSequence, PdfParser22import io23__version__ = "0.5"24#25# --------------------------------------------------------------------26# object ids:27# 1. catalogue28# 2. pages29# 3. image30# 4. page31# 5. page contents32def _save_all(im, fp, filename):33 _save(im, fp, filename, save_all=True)34##35# (Internal) Image save plugin for the PDF format.36def _save(im, fp, filename, save_all=False):37 resolution = im.encoderinfo.get("resolution", 72.0)38 is_appending = im.encoderinfo.get("append", False)39 title = im.encoderinfo.get("title", None)40 author = im.encoderinfo.get("author", None)41 subject = im.encoderinfo.get("subject", None)42 keywords = im.encoderinfo.get("keywords", None)43 creator = im.encoderinfo.get("creator", None)44 producer = im.encoderinfo.get("producer", None)45 if is_appending:46 existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="r+b")47 else:48 existing_pdf = PdfParser.PdfParser(f=fp, filename=filename, mode="w+b")49 if title:50 existing_pdf.info.Title = title51 if author:52 existing_pdf.info.Author = author53 if subject:54 existing_pdf.info.Subject = subject55 if keywords:56 existing_pdf.info.Keywords = keywords57 if creator:58 existing_pdf.info.Creator = creator59 if producer:60 existing_pdf.info.Producer = producer61 #62 # make sure image data is available63 im.load()64 existing_pdf.start_writing()65 existing_pdf.write_header()66 existing_pdf.write_comment("created by PIL PDF driver " + __version__)67 #68 # pages69 ims = [im]70 if save_all:71 append_images = im.encoderinfo.get("append_images", [])72 for append_im in append_images:73 append_im.encoderinfo = im.encoderinfo.copy()74 ims.append(append_im)75 numberOfPages = 076 image_refs = []77 page_refs = []78 contents_refs = []79 for im in ims:80 im_numberOfPages = 181 if save_all:82 try:83 im_numberOfPages = im.n_frames84 except AttributeError:85 # Image format does not have n_frames. It is a single frame image86 pass87 numberOfPages += im_numberOfPages88 for i in range(im_numberOfPages):89 image_refs.append(existing_pdf.next_object_id(0))90 page_refs.append(existing_pdf.next_object_id(0))91 contents_refs.append(existing_pdf.next_object_id(0))92 existing_pdf.pages.append(page_refs[-1])93 #94 # catalog and list of pages95 existing_pdf.write_catalog()96 pageNumber = 097 for imSequence in ims:98 for im in ImageSequence.Iterator(imSequence):99 # FIXME: Should replace ASCIIHexDecode with RunLengthDecode (packbits)100 # or LZWDecode (tiff/lzw compression). Note that PDF 1.2 also supports101 # Flatedecode (zip compression).102 bits = 8103 params = None104 if im.mode == "1":105 filter = "ASCIIHexDecode"106 colorspace = PdfParser.PdfName("DeviceGray")107 procset = "ImageB" # grayscale108 bits = 1109 elif im.mode == "L":110 filter = "DCTDecode"111 # params = "<< /Predictor 15 /Columns %d >>" % (width-2)112 colorspace = PdfParser.PdfName("DeviceGray")113 procset = "ImageB" # grayscale114 elif im.mode == "P":115 filter = "ASCIIHexDecode"116 palette = im.im.getpalette("RGB")117 colorspace = [PdfParser.PdfName("Indexed"), PdfParser.PdfName("DeviceRGB"), 255, PdfParser.PdfBinary(palette)]118 procset = "ImageI" # indexed color119 elif im.mode == "RGB":120 filter = "DCTDecode"121 colorspace = PdfParser.PdfName("DeviceRGB")122 procset = "ImageC" # color images123 elif im.mode == "CMYK":124 filter = "DCTDecode"125 colorspace = PdfParser.PdfName("DeviceCMYK")126 procset = "ImageC" # color images127 else:128 raise ValueError("cannot save mode %s" % im.mode)129 #130 # image131 op = io.BytesIO()132 if filter == "ASCIIHexDecode":133 if bits == 1:134 # FIXME: the hex encoder doesn't support packed 1-bit135 # images; do things the hard way...136 data = im.tobytes("raw", "1")137 im = Image.new("L", (len(data), 1), None)138 im.putdata(data)139 ImageFile._save(im, op, [("hex", (0, 0)+im.size, 0, im.mode)])140 elif filter == "DCTDecode":141 Image.SAVE["JPEG"](im, op, filename)142 elif filter == "FlateDecode":143 ImageFile._save(im, op, [("zip", (0, 0)+im.size, 0, im.mode)])144 elif filter == "RunLengthDecode":145 ImageFile._save(im, op, [("packbits", (0, 0)+im.size, 0, im.mode)])146 else:147 raise ValueError("unsupported PDF filter (%s)" % filter)148 #149 # Get image characteristics150 width, height = im.size151 existing_pdf.write_obj(image_refs[pageNumber], stream=op.getvalue(),152 Type=PdfParser.PdfName("XObject"),153 Subtype=PdfParser.PdfName("Image"),154 Width=width, # * 72.0 / resolution,155 Height=height, # * 72.0 / resolution,156 Filter=PdfParser.PdfName(filter),157 BitsPerComponent=bits,158 DecodeParams=params,159 ColorSpace=colorspace)160 #161 # page162 existing_pdf.write_page(page_refs[pageNumber],163 Resources=PdfParser.PdfDict(164 ProcSet=[PdfParser.PdfName("PDF"), PdfParser.PdfName(procset)],165 XObject=PdfParser.PdfDict(image=image_refs[pageNumber])),166 MediaBox=[0, 0, int(width * 72.0 / resolution), int(height * 72.0 / resolution)],167 Contents=contents_refs[pageNumber]168 )169 #170 # page contents171 page_contents = PdfParser.make_bytes(172 "q %d 0 0 %d 0 0 cm /image Do Q\n" % (173 int(width * 72.0 / resolution),174 int(height * 72.0 / resolution)))175 existing_pdf.write_obj(contents_refs[pageNumber], stream=page_contents)176 pageNumber += 1177 #178 # trailer179 existing_pdf.write_xref_and_trailer()180 if hasattr(fp, "flush"):181 fp.flush()182 existing_pdf.close()183#184# --------------------------------------------------------------------185Image.register_save("PDF", _save)186Image.register_save_all("PDF", _save_all)187Image.register_extension("PDF", ".pdf")...
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!