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!!
