Spaces:
Sleeping
Sleeping
| import os | |
| import uuid | |
| import io | |
| import shutil | |
| import fitz # PyMuPDF | |
| import gradio as gr | |
| from pptx import Presentation | |
| from pptx.util import Inches | |
| from docx import Document | |
| from docx.shared import Cm | |
| from PIL import Image | |
| # ------------------------- | |
| # Configuration | |
| # ------------------------- | |
| UPLOAD_DIR = "uploads" | |
| os.makedirs(UPLOAD_DIR, exist_ok=True) | |
| MAX_FILE_SIZE_MB = 500 | |
| # ------------------------- | |
| # Core Conversion Logic | |
| # ------------------------- | |
| def convert_pdf(file_path, target_format): | |
| if file_path is None: | |
| raise gr.Error("Please upload a PDF file.") | |
| if not file_path.lower().endswith(".pdf"): | |
| raise gr.Error("Only PDF files are supported.") | |
| unique_id = str(uuid.uuid4()) | |
| pdf_path = os.path.join(UPLOAD_DIR, f"{unique_id}.pdf") | |
| # ✅ FIX: copy file instead of file.read() | |
| shutil.copy(file_path, pdf_path) | |
| doc = fitz.open(pdf_path) | |
| if len(doc) == 0: | |
| doc.close() | |
| os.remove(pdf_path) | |
| raise gr.Error("The uploaded PDF is empty.") | |
| # ---------- PDF → PPT ---------- | |
| if target_format == "PowerPoint (.pptx)": | |
| output_path = os.path.join(UPLOAD_DIR, f"{unique_id}.pptx") | |
| prs = Presentation() | |
| prs.slide_width = Inches(13.333) | |
| prs.slide_height = Inches(7.5) | |
| for page in doc: | |
| pix = page.get_pixmap(matrix=fitz.Matrix(1.5, 1.5), alpha=False) | |
| img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples) | |
| img_stream = io.BytesIO() | |
| img.save(img_stream, format="JPEG", quality=80) | |
| img_stream.seek(0) | |
| slide = prs.slides.add_slide(prs.slide_layouts[6]) | |
| slide.shapes.add_picture( | |
| img_stream, 0, 0, | |
| width=prs.slide_width, | |
| height=prs.slide_height | |
| ) | |
| img_stream.close() | |
| prs.save(output_path) | |
| # ---------- PDF → Word ---------- | |
| else: | |
| output_path = os.path.join(UPLOAD_DIR, f"{unique_id}.docx") | |
| word_doc = Document() | |
| for section in word_doc.sections: | |
| section.top_margin = Cm(0.5) | |
| section.bottom_margin = Cm(0.5) | |
| section.left_margin = Cm(0.5) | |
| section.right_margin = Cm(0.5) | |
| for i, page in enumerate(doc): | |
| pix = page.get_pixmap(matrix=fitz.Matrix(1.5, 1.5), alpha=False) | |
| img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples) | |
| img_stream = io.BytesIO() | |
| img.save(img_stream, format="JPEG", quality=80) | |
| img_stream.seek(0) | |
| word_doc.add_picture(img_stream, width=Cm(20)) | |
| if i < len(doc) - 1: | |
| word_doc.add_page_break() | |
| img_stream.close() | |
| word_doc.save(output_path) | |
| doc.close() | |
| os.remove(pdf_path) | |
| return output_path | |
| # ------------------------- | |
| # Utility: Clear Files | |
| # ------------------------- | |
| def clear_files(): | |
| for f in os.listdir(UPLOAD_DIR): | |
| try: | |
| os.remove(os.path.join(UPLOAD_DIR, f)) | |
| except: | |
| pass | |
| return None | |
| # ------------------------- | |
| # Gradio UI | |
| # ------------------------- | |
| with gr.Blocks(title="PDF Converter | Developer: Najaf Ali Sharqi") as demo: | |
| gr.Markdown(""" | |
| # 📄 PDF Conversion Tool | |
| **Developer:** Najaf Ali Sharqi | |
| Convert PDF files generated by NotebookLM into **editable PowerPoint or Word documents** | |
| without modifying original content, layout, or images. | |
| """) | |
| with gr.Row(): | |
| pdf_input = gr.File( | |
| label="Upload PDF File", | |
| file_types=[".pdf"] | |
| ) | |
| format_choice = gr.Radio( | |
| choices=["PowerPoint (.pptx)", "Word Document (.docx)"], | |
| value="PowerPoint (.pptx)", | |
| label="Select Output Format" | |
| ) | |
| with gr.Row(): | |
| convert_btn = gr.Button("Convert") | |
| clear_btn = gr.Button("Clear Uploaded Files") | |
| output_file = gr.File(label="Download Converted File") | |
| convert_btn.click( | |
| fn=convert_pdf, | |
| inputs=[pdf_input, format_choice], | |
| outputs=output_file | |
| ) | |
| clear_btn.click( | |
| fn=clear_files, | |
| outputs=output_file | |
| ) | |
| gr.Markdown(""" | |
| --- | |
| ⚠️ **Important Notes** | |
| - UI instructions are provided in English only | |
| - The tool does **not** add, remove, or modify content | |
| - Output files preserve original visuals exactly | |
| - Designed for Hugging Face deployment using Gradio | |
| """) | |
| # ------------------------- | |
| # Launch (HF Compatible) | |
| # ------------------------- | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=7860, | |
| ssr_mode=False | |
| ) | |