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()