def generate_tmp_folder(root_path=None) -> str: """ This method create a temporary folder where all the temporary files will be stored. :param root_path: path where the folder is going to be created if specified. :return: string that contain the absolute path of the temporary folder. """ try: if not root_path: # The folder will be placed in the Temp directory e.g. on Windows C:\users\<user>\AppData\Local\Temp folder_path = mkdtemp() else: folder_path = mkdtemp(dir=root_path) return folder_path except (OSError, TypeError, PermissionError) as e: with open("pdf_converter_log.txt", "a") as f: print(log_handler(e, action="creating tmp_folder"), file=f) if root_path: remove_tmp_folder(root_path) exit(1) except Exception as e1: # For any unknown exception so far with open("pdf_converter_log.txt", "a") as f: print(log_handler(e1, action="creating tmp_folder"), file=f) if root_path: remove_tmp_folder(root_path) exit(1)
def remove_tmp_folder(root_path: str) -> None: """ Method that deletes the temporary folder. :param root_path: Folder that contain all the temporary files. :return: None """ try: shutil.rmtree(root_path) except (OSError, FileNotFoundError, TypeError, PermissionError) as e: with open("pdf_converter_log.txt", "a") as f: print(log_handler(e, action="deleting tmp_folder"), file=f) # TODO: Try to find a case of PermissionError and provide a fix to force the deletion of the folder except Exception as e1: # For any unknown exception so far with open("pdf_converter_log.txt", "a") as f: print(log_handler(e1, action="deleting tmp_folder"), file=f)
def merge_pdf(pdf_to_be_merged: list, compression: bool) -> None: """ Method that merges each temporary pdf file created from the requested pictures. :param pdf_to_be_merged: list that contains the names of each temporary pdf. :param compression: flag for the compression mode. :return: None """ try: merger = PdfFileMerger() for pdf in pdf_to_be_merged: merger.append(pdf) merger.write("compressed_mypdf.pdf" if compression else "mypdf.pdf") merger.close() except (RuntimeError, OSError, PermissionError) as e: with open("pdf_converter_log.txt", "a") as f: print(log_handler(e, action="merging mode"), file=f) except Exception as e1: # For any unknown exception so far with open("pdf_converter_log.txt", "a") as f: print(log_handler(e1, action="merging mode"), file=f)
def create_pdf_from_image(root_path: str, list_images: list) -> list: """ Since that PyFPDF is not smart enough to allow us to change the format of the PDF after it's instantiation we need with this method to generate for each picture one pdf file, in order that in the final one each PDF pages will entirely fit the pictures. :param root_path: absolute path of the temporary folder. :param list_images: list that contain the path of the pictures. :return: list that contains the name of each temporary PDF files. """ list_pdf_from_image = list() try: for i, image in enumerate(list_images): with Image.open(image) as img: width, height = img.size new_width = width * 0.75 # Conversion formula from px to pt for the width and the height new_height = height * 0.75 pdf = FPDF(orientation='L', unit="pt", format=(new_height, new_width)) pdf.add_page() pdf.image(image, x=0, y=0, w=new_width, h=new_height) # With the aid of the enumerate we place a counter name for each temporary pdf pdf_path = path.join(root_path, "{}.pdf".format(i)) pdf.output(pdf_path) list_pdf_from_image.append(pdf_path) return list_pdf_from_image except (RuntimeError, OSError, PermissionError) as e: with open("pdf_converter_log.txt", "a") as f: print(log_handler(e, action="creation mode"), file=f) utilities.remove_tmp_folder( root_path) # We need anyway to delete the temporary folder exit(1) except Exception as e1: # For any unknown exception so far with open("pdf_converter_log.txt", "a") as f: print(log_handler(e1, action="creation mode"), file=f) utilities.remove_tmp_folder( root_path) # We need anyway to delete the temporary folder exit(1)
def create_pdf_from_images(self) -> None: """ Method that builds the final PDF from the pictures, it is handling the compression mode as well. :return: None """ try: # Let's retrieve the path of the application folder self.main_root_path = path.dirname(path.abspath(__package__)) # Storing in a list the path of the images self.list_images = retriever.retrieve_images(self.main_root_path) # If no images were retrieved or there is already a generated PDF file with the same name we are done if not (utilities.check_mandatory_dependencies( self.list_images, self.main_root_path, self.is_compressed)): return # Creation of the temporary folder that will contain all the files necessary for the computation self.root_path = utilities.generate_tmp_folder() # Recomputing list_images with the path of the rotated pictures if any retriever.create_and_retrieve_rotated_images( self.root_path, self.list_images) if self.is_compressed: # Recomputing list_images with the path of the compressed pictures retriever.create_and_retrieve_compressed_images( self.root_path, self.list_images) else: # Recomputing list_images with the path of the de-interlaced pictures if any retriever.create_and_retrieve_de_interlaced_images( self.root_path, self.list_images) # Creating a pdf file for each picture stored self.list_pdf = creator.create_pdf_from_image( self.root_path, self.list_images) # Let's create the final pdf that will be returned to the user if self.list_pdf: merger.merge_pdf(self.list_pdf, self.is_compressed) # Deletion of all the temporary files that are required no more utilities.remove_tmp_folder(self.root_path) except Exception as e: # For any unknown exception so far with open("pdf_converter_log.txt", "a") as f: print(log_handler(e, action="execution of the main module"), file=f) if self.root_path: utilities.remove_tmp_folder(self.root_path)