Spaces:
Running
Running
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
import os, sys, shutil, subprocess, tempfile, uuid | |
from pathlib import Path | |
import gradio as gr | |
# Import font installation function | |
from install_fonts import install_fonts_from_repository | |
BASE_DIR = Path(__file__).parent.resolve() | |
BINARY_PATH = BASE_DIR / "PptxToJpgZip" | |
os.chmod(BINARY_PATH, 0o755) # Ignore exceptions | |
def _safe_name() -> str: | |
"""Generate ASCII-only temporary filename""" | |
return f"input_{uuid.uuid4().hex}.pptx" | |
def convert_pptx_to_zip(pptx_file) -> str: | |
"""Call PptxToJpgZip to convert PPTX to JPG images ZIP; auto-zip if only folder exists.""" | |
tmpdir = Path(tempfile.mkdtemp()) | |
src = tmpdir / _safe_name() | |
shutil.copy(pptx_file.name, src) | |
# Call external executable | |
proc = subprocess.run( | |
[str(BINARY_PATH), str(src)], | |
cwd=tmpdir, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
) | |
if proc.returncode != 0: | |
raise RuntimeError( | |
f"PptxToJpgZip failed with exit code {proc.returncode}\n" | |
f"stderr:\n{proc.stderr.decode(errors='ignore')}" | |
) | |
# ---- β Priority: find *_images.zip ---- | |
zips = list(tmpdir.glob("*_images.zip")) | |
if zips: | |
return str(zips[0]) | |
# ---- β‘ If no ZIP, find *_images directory and auto-package ---- | |
img_dirs = [p for p in tmpdir.glob("*_images") if p.is_dir()] | |
if img_dirs: | |
folder = img_dirs[0] | |
zip_path = folder.with_suffix(".zip") # <name>_images.zip | |
shutil.make_archive(zip_path.with_suffix(""), "zip", folder) | |
return str(zip_path) | |
# ---- β’ Still not found: list tmpdir contents for debugging ---- | |
contents = "\n".join([" β’ " + p.name for p in tmpdir.iterdir()]) | |
raise FileNotFoundError( | |
"Output ZIP not found, and no *_images folder discovered.\n" | |
f"Temporary directory contents:\n{contents}" | |
) | |
# ----------------- Enhanced Gradio UI with English Interface ----------------- # | |
with gr.Blocks( | |
title="PPTX to JPG ZIP Converter", | |
theme=gr.themes.Soft(), | |
css=""" | |
.download-btn { | |
background: linear-gradient(45deg, #4CAF50, #45a049) !important; | |
color: white !important; | |
font-weight: bold !important; | |
font-size: 16px !important; | |
padding: 12px 24px !important; | |
border-radius: 8px !important; | |
border: none !important; | |
box-shadow: 0 4px 8px rgba(0,0,0,0.2) !important; | |
transition: all 0.3s ease !important; | |
} | |
.download-btn:hover { | |
background: linear-gradient(45deg, #45a049, #4CAF50) !important; | |
transform: translateY(-2px) !important; | |
box-shadow: 0 6px 12px rgba(0,0,0,0.3) !important; | |
} | |
.main-container { | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
.header-section { | |
text-align: center; | |
margin-bottom: 30px; | |
padding: 20px; | |
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
border-radius: 12px; | |
color: white; | |
} | |
.instructions-section { | |
background: #f8f9fa; | |
padding: 20px; | |
border-radius: 8px; | |
margin-bottom: 20px; | |
border-left: 4px solid #007bff; | |
} | |
""" | |
) as demo: | |
with gr.Column(elem_classes="main-container"): | |
# Header Section | |
with gr.Column(elem_classes="header-section"): | |
gr.Markdown( | |
""" | |
# π― PPTX to JPG ZIP Converter | |
### Transform your PowerPoint presentations into high-quality JPG images | |
**Fast β’ Reliable β’ Easy to Use** | |
""", | |
elem_classes="header-content" | |
) | |
# Instructions Section | |
with gr.Column(elem_classes="instructions-section"): | |
gr.Markdown( | |
""" | |
## π How to Use | |
**Step 1:** Click "Upload PPTX File" and select your PowerPoint presentation (.pptx) | |
**Step 2:** Click "π Convert to JPG ZIP" to start the conversion process | |
**Step 3:** Wait for processing to complete (usually takes 10-30 seconds) | |
**Step 4:** Click the green "π₯ Download ZIP" button to get your converted images | |
### β¨ Features | |
- **High Quality**: Converts each slide to crisp JPG images | |
- **Batch Processing**: All slides converted in one go | |
- **ZIP Package**: Convenient download as a single ZIP file | |
- **Font Support**: Automatic font installation for better rendering | |
""" | |
) | |
# Main Conversion Interface | |
gr.Markdown("## π Conversion Interface") | |
with gr.Row(): | |
with gr.Column(scale=2): | |
pptx_input = gr.File( | |
label="π Upload PPTX File", | |
file_types=[".pptx"], | |
elem_id="pptx_upload" | |
) | |
with gr.Column(scale=1): | |
convert_btn = gr.Button( | |
"π Convert to JPG ZIP", | |
variant="primary", | |
size="lg", | |
elem_id="convert_button" | |
) | |
# Download Section | |
gr.Markdown("## π₯ Download Results") | |
with gr.Row(): | |
with gr.Column(scale=2): | |
zip_output = gr.File( | |
label="π¦ Converted ZIP File", | |
elem_id="zip_output" | |
) | |
with gr.Column(scale=1): | |
download_btn = gr.Button( | |
"π₯ Download ZIP", | |
variant="secondary", | |
size="lg", | |
elem_classes="download-btn", | |
elem_id="download_button" | |
) | |
# Status Section | |
with gr.Row(): | |
status_text = gr.Textbox( | |
label="π Status", | |
interactive=False, | |
value="π Please upload a PPTX file to begin conversion...", | |
elem_id="status_display" | |
) | |
# Footer Section | |
gr.Markdown( | |
""" | |
--- | |
### π‘ Tips | |
- **Supported Format**: Only .pptx files (PowerPoint 2007+) | |
- **File Size**: Works best with files under 100MB | |
- **Processing Time**: Depends on slide count and complexity | |
- **Output**: High-resolution JPG images (300 DPI) | |
### π§ Technical Info | |
- **Engine**: PptxToJpgZip binary converter | |
- **Image Format**: JPG (JPEG) | |
- **Compression**: ZIP archive | |
- **Font Rendering**: Enhanced with system fonts | |
""", | |
elem_classes="footer-info" | |
) | |
# Event Handlers | |
def process_conversion(pptx_file): | |
if pptx_file is None: | |
return None, "β Please upload a PPTX file first" | |
try: | |
# Update status | |
yield None, "π Processing your PPTX file..." | |
# Perform conversion | |
result_zip = convert_pptx_to_zip(pptx_file) | |
# Success | |
yield result_zip, "β Conversion completed successfully! Click 'Download ZIP' to get your files." | |
except Exception as e: | |
yield None, f"β Conversion failed: {str(e)}" | |
def handle_download(zip_file): | |
"""Handle download button - create a new downloadable file""" | |
if zip_file and hasattr(zip_file, 'name') and os.path.exists(zip_file.name): | |
return gr.File(value=zip_file.name), "π₯ Download started! File will be downloaded automatically." | |
elif zip_file and isinstance(zip_file, str) and os.path.exists(zip_file): | |
return gr.File(value=zip_file), "π₯ Download started! File will be downloaded automatically." | |
else: | |
return None, "β No file available for download. Please convert a file first." | |
# Connect events | |
convert_btn.click( | |
fn=process_conversion, | |
inputs=[pptx_input], | |
outputs=[zip_output, status_text], | |
show_progress=True | |
) | |
# Download button - creates a downloadable file output | |
download_output = gr.File(label="Download", visible=False) | |
download_btn.click( | |
fn=handle_download, | |
inputs=[zip_output], | |
outputs=[download_output, status_text], | |
show_progress=False | |
) | |
if __name__ == "__main__": | |
# Install fonts before starting the application | |
print("π§ Installing fonts for better rendering...") | |
install_fonts_from_repository() | |
print("β Font installation completed!") | |
print("π Starting PPTX to JPG ZIP Converter...") | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False, | |
show_error=True, | |
quiet=False | |
) | |