Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import binascii | |
| import os | |
| import subprocess | |
| import tempfile | |
| from pathlib import Path | |
| from typing import Tuple, List # Added Tuple import here | |
| # Document Converter Class | |
| class DocumentConverter: | |
| def __init__(self): | |
| self.temp_dir = tempfile.mkdtemp() | |
| self.supported_conversions = { | |
| ".pdf": [".docx", ".txt", ".html"], | |
| ".docx": [".pdf", ".txt", ".html"], | |
| ".txt": [".pdf", ".docx", ".html"], | |
| ".html": [".pdf", ".docx", ".txt"] | |
| } | |
| def convert_document(self, input_path: str, output_ext: str) -> str: | |
| """Convert documents using LibreOffice""" | |
| try: | |
| output_path = os.path.join(self.temp_dir, f"{Path(input_path).stem}_converted{output_ext}") | |
| subprocess.run([ | |
| "libreoffice", "--headless", "--convert-to", | |
| output_ext[1:], "--outdir", self.temp_dir, input_path | |
| ], check=True) | |
| return output_path | |
| except Exception as e: | |
| raise RuntimeError(f"Document conversion failed: {str(e)}") | |
| # EXE to DOC Converter | |
| def convert_exe_to_doc(input_path: str, output_name: str = "output.doc") -> str: | |
| """Convert EXE to DOC with embedded data""" | |
| try: | |
| with open(input_path, 'rb') as f: | |
| file_content = f.read() | |
| # RTF template (shortened for brevity) | |
| rtf_template = "{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fswiss\\fcharset0 Arial;}}" | |
| hex_data = binascii.b2a_hex(file_content).decode() | |
| output_dir = "outputs" | |
| os.makedirs(output_dir, exist_ok=True) | |
| output_path = os.path.join(output_dir, output_name if output_name.endswith('.doc') else f"{output_name}.doc") | |
| with open(output_path, 'w', encoding='latin-1') as f: | |
| f.write(rtf_template + hex_data + "{}}}}}}") | |
| return output_path | |
| except Exception as e: | |
| raise RuntimeError(f"EXE conversion failed: {str(e)}") | |
| def update_ui(file_info: gr.File) -> List: | |
| """Update UI components based on file type""" | |
| if not file_info: | |
| return [ | |
| gr.Dropdown(visible=False), # format_dropdown | |
| gr.Textbox(visible=False), # exe_name_input | |
| gr.Button(visible=False) # convert_btn | |
| ] | |
| filename = file_info.name.lower() | |
| if filename.endswith('.exe'): | |
| return [ | |
| gr.Dropdown(visible=False), | |
| gr.Textbox(visible=True, value="converted.doc"), | |
| gr.Button(visible=True) | |
| ] | |
| else: | |
| ext = Path(filename).suffix.lower() | |
| doc_converter = DocumentConverter() | |
| formats = doc_converter.supported_conversions.get(ext, []) | |
| return [ | |
| gr.Dropdown( | |
| visible=bool(formats), | |
| choices=[f[1:].upper() for f in formats], # Remove dot and uppercase | |
| value=formats[0][1:].upper() if formats else None | |
| ), | |
| gr.Textbox(visible=False), | |
| gr.Button(visible=bool(formats)) | |
| ] | |
| def convert_file(file_info: gr.File, output_format: str, exe_output_name: str) -> Tuple[str, str]: | |
| """Handle file conversion""" | |
| if not file_info: | |
| raise gr.Error("Please upload a file first") | |
| filename = file_info.name.lower() | |
| try: | |
| if filename.endswith('.exe'): | |
| output_path = convert_exe_to_doc(file_info.name, exe_output_name) | |
| return output_path, "EXE to DOC conversion successful!" | |
| else: | |
| if not output_format: | |
| raise gr.Error("Please select an output format") | |
| output_path = DocumentConverter().convert_document(file_info.name, f".{output_format.lower()}") | |
| return output_path, f"Converted to {output_format.upper()} successfully!" | |
| except Exception as e: | |
| raise gr.Error(str(e)) | |
| with gr.Blocks(title="Universal Converter") as app: | |
| gr.Markdown("# Universal File Converter") | |
| gr.Markdown("Convert EXE to DOC or between document formats") | |
| with gr.Row(): | |
| with gr.Column(): | |
| file_input = gr.File(label="Upload File") | |
| format_dropdown = gr.Dropdown( | |
| label="Output Format", | |
| visible=False, | |
| interactive=True | |
| ) | |
| exe_name_input = gr.Textbox( | |
| label="Output DOC Name", | |
| visible=False, | |
| value="converted.doc" | |
| ) | |
| convert_btn = gr.Button("Convert", visible=False) | |
| with gr.Column(): | |
| output_file = gr.File(label="Download Converted File") | |
| status = gr.Textbox(label="Status", interactive=False) | |
| # Update UI when file is uploaded | |
| file_input.change( | |
| update_ui, | |
| inputs=file_input, | |
| outputs=[format_dropdown, exe_name_input, convert_btn] | |
| ) | |
| # Handle conversion | |
| convert_btn.click( | |
| convert_file, | |
| inputs=[file_input, format_dropdown, exe_name_input], | |
| outputs=[output_file, status] | |
| ) | |
| if __name__ == "__main__": | |
| app.launch() |