Spaces:
Sleeping
Sleeping
| import os | |
| from fpdf import FPDF | |
| from PyPDF2 import PdfMerger | |
| from PIL import Image | |
| import gradio as gr | |
| #import aspose.words as aw | |
| import pypandoc | |
| def docx_to_pdf(docx_file, pdf_file): | |
| try: | |
| pypandoc.convert_file( | |
| docx_file, 'pdf', outputfile=pdf_file, extra_args=['--pdf-engine=pdflatex'] | |
| ) | |
| except OSError: | |
| # Download pandoc programmatically if it's not found | |
| print("Pandoc not found. Downloading pandoc...") | |
| pypandoc.download_pandoc() | |
| pypandoc.convert_file( | |
| docx_file, 'pdf', outputfile=pdf_file, extra_args=['--pdf-engine=pdflatex'] | |
| ) | |
| # Function to add a single text input as a new page in an FPDF object | |
| def add_text_as_page(pdf, text): | |
| pdf.add_page() | |
| pdf.set_auto_page_break(auto=True, margin=15) | |
| pdf.set_font("Arial", size=12) | |
| pdf.multi_cell(0, 10, text) | |
| # Function to convert an image to a standalone PDF | |
| def image_to_pdf(image_file): | |
| img = Image.open(image_file) | |
| pdf_path = image_file + ".pdf" | |
| img.convert('RGB').save(pdf_path) | |
| return pdf_path | |
| # Function to merge multiple PDFs | |
| def merge_pdfs(pdfs): | |
| merger = PdfMerger() | |
| for pdf in pdfs: | |
| merger.append(pdf) | |
| output_path = "merged_output.pdf" | |
| merger.write(output_path) | |
| merger.close() | |
| return output_path | |
| # Convert DOCX to PDF | |
| #def docx_to_pdf(docx_file, pdf_file): | |
| # doc = aw.Document(docx_file) | |
| # doc.save(pdf_file) | |
| # Main function to process uploaded files and manual text inputs | |
| def process_files_and_text(files, manual_texts, file_order): | |
| pdfs = [] | |
| manual_text_pdf = "manual_texts.pdf" | |
| pdf = FPDF() | |
| # Process uploaded files according to file_order | |
| for file_name in file_order: | |
| file = next(f for f in files if f.name == file_name) | |
| file_name, file_extension = os.path.splitext(file.name) | |
| if file_extension.lower() == ".pdf": | |
| pdfs.append(file.name) | |
| elif file_extension.lower() == ".txt": | |
| text = file.read().decode("utf-8") | |
| add_text_as_page(pdf, text) | |
| elif file_extension.lower() == ".docx": | |
| docx_to_pdf(file.name, file_name + ".pdf") | |
| #pdf_file = file_name + ".pdf" | |
| #docx_to_pdf(file.name, pdf_file) | |
| pdfs.append(file_name + ".pdf") | |
| elif file_extension.lower() in [".png", ".jpg", ".jpeg"]: | |
| pdf_output = image_to_pdf(file.name) | |
| pdfs.append(pdf_output) | |
| # Add manual text inputs, with each input becoming a new page | |
| for text in manual_texts: | |
| if text.strip(): # Add only non-empty text | |
| add_text_as_page(pdf, text) | |
| # Save manual text inputs to PDF if any pages were added | |
| if len(pdf.pages) > 0: | |
| pdf.output(manual_text_pdf) | |
| pdfs.append(manual_text_pdf) | |
| # Merge all PDFs into one | |
| merged_pdf = merge_pdfs(pdfs) | |
| return merged_pdf | |
| # Function to move items up or down in the list | |
| def reorder_files(file_list, direction, index): | |
| if direction == "up" and index > 0: | |
| file_list[index], file_list[index - 1] = file_list[index - 1], file_list[index] | |
| elif direction == "down" and index < len(file_list) - 1: | |
| file_list[index], file_list[index + 1] = file_list[index + 1], file_list[index] | |
| return file_list | |
| # Gradio interface function | |
| def file_merger(files, texts, file_order): | |
| merged_pdf = process_files_and_text(files, texts, file_order) | |
| return merged_pdf | |
| # Define Gradio interface | |
| with gr.Blocks() as iface: | |
| gr.Markdown("### File Merger: Merge PDF, TXT, DOCX, Image files, and manual text inputs into a single PDF.") | |
| with gr.Row(): | |
| file_input = gr.File(file_count="multiple", label="Upload Files") | |
| manual_text_inputs = gr.Textbox( | |
| lines=5, | |
| placeholder="Enter text here...", | |
| label="Manual Text Inputs", | |
| elem_id="manual_text_inputs", | |
| interactive=True | |
| ) | |
| file_list_state = gr.State([]) | |
| file_display = gr.Textbox( | |
| label="Uploaded Files (Reorder Below)", | |
| interactive=False, | |
| lines=10 | |
| ) | |
| file_index = gr.Number(label="File Index to Move (Starting from 0)", value=0, interactive=True) | |
| with gr.Row(): | |
| move_up_button = gr.Button("Move Up") | |
| move_down_button = gr.Button("Move Down") | |
| add_more_button = gr.Button("Add More Text") | |
| merge_button = gr.Button("Merge Files and Text") | |
| output = gr.File(label="Download Merged PDF") | |
| # Maintain a dynamic list for manual inputs | |
| manual_texts_state = gr.State(value=[]) | |
| def add_text_to_state(current_text, state_texts): | |
| state_texts.append(current_text) | |
| return "", state_texts # Clear the input box and update the state | |
| def update_file_list(files): | |
| file_names = [file.name for file in files] | |
| return file_names, "\n".join(file_names) | |
| def handle_reorder(file_list, direction, index): | |
| if 0 <= index < len(file_list): | |
| reordered_list = reorder_files(file_list, direction, index) | |
| return reordered_list, "\n".join(reordered_list) | |
| return file_list, "\n".join(file_list) # No change if index is out of range | |
| # Add functionality to add more text | |
| add_more_button.click(add_text_to_state, inputs=[manual_text_inputs, manual_texts_state], outputs=[manual_text_inputs, manual_texts_state]) | |
| # Update file list when files are uploaded | |
| file_input.change(update_file_list, inputs=[file_input], outputs=[file_list_state, file_display]) | |
| # Move files up or down | |
| move_up_button.click(handle_reorder, inputs=[file_list_state, gr.Text("up"), file_index], outputs=[file_list_state, file_display]) | |
| move_down_button.click(handle_reorder, inputs=[file_list_state, gr.Text("down"), file_index], outputs=[file_list_state, file_display]) | |
| # Merge files and text | |
| merge_button.click(file_merger, inputs=[file_input, manual_texts_state, file_list_state], outputs=output) | |
| iface.launch(share=True) | |