| import gradio as gr |
| import shutil |
| import os |
|
|
| FORMATS = { |
| "π Word Document (.docx)": ".docx", |
| "π PowerPoint (.pptx)": ".pptx", |
| "π Excel Spreadsheet (.xlsx)": ".xlsx", |
| "πΌοΈ JPEG Image (.jpg)": ".jpg", |
| "πΌοΈ PNG Image (.png)": ".png", |
| "π PDF (.pdf)": ".pdf", |
| "π Text File (.txt)": ".txt", |
| "π¬ MP4 Video (.mp4)": ".mp4", |
| "π΅ MP3 Audio (.mp3)": ".mp3", |
| "π¦ RAR Archive (.rar)": ".rar", |
| "π¦ 7-Zip Archive (.7z)": ".7z", |
| "π¦ TAR Archive (.tar)": ".tar", |
| "π HTML File (.html)": ".html", |
| "π CSV File (.csv)": ".csv", |
| "π§ JSON File (.json)": ".json", |
| } |
|
|
| def convert_zip(zip_file, format_label): |
| if zip_file is None: |
| return None, "β Please upload a ZIP file first.", "" |
|
|
| ext = FORMATS.get(format_label) |
| if not ext: |
| return None, "β Please select a valid target format.", "" |
|
|
| original_name = os.path.basename(zip_file.name) |
| base_name = os.path.splitext(original_name)[0] |
| output_filename = base_name + ext |
| output_path = os.path.join("/tmp", output_filename) |
|
|
| print(f"Converting: {original_name} β {output_filename}") |
| shutil.copy(zip_file.name, output_path) |
|
|
| ext_label = ext.lstrip('.') |
| prompt = ( |
| f"I have changed the ZIP file to {ext_label} format. " |
| f"Please change the file extension back to .zip before processing." |
| ) |
|
|
| status = ( |
| f"β
Done! `{original_name}` β `{output_filename}`\n\n" |
| f"π Download the file below, then copy the prompt and paste it alongside your upload." |
| ) |
|
|
| return output_path, status, prompt |
|
|
|
|
| theme = gr.themes.Soft( |
| primary_hue="red", |
| neutral_hue="gray", |
| font=[gr.themes.GoogleFont("DM Sans"), "sans-serif"], |
| ) |
|
|
| css = """ |
| body, .gradio-container { font-family: 'DM Sans', sans-serif !important; } |
| #title { text-align: center; margin-bottom: 0.2em; font-size: 2em; } |
| #subtitle { text-align: center; color: #64748b; font-size: 0.95em; margin-bottom: 1.5em; } |
| #github_link { text-align: center; margin-bottom: 0.5em; } |
| .prompt-box textarea { font-family: 'DM Sans', sans-serif !important; font-size: 0.9em !important; } |
| footer { display: none !important; } |
| """ |
|
|
| with gr.Blocks(title="ZipSlip β Upload ZIPs Anywhere") as demo: |
|
|
| gr.Markdown("# π¦ ZipSlip", elem_id="title") |
| gr.Markdown( |
| "**https://github.com/SanshruthR/ZipSlip/**", |
| elem_id="github_link", |
| ) |
| gr.Markdown( |
| "Rename your ZIP so you can upload it to AI tools that block ZIP files β " |
| "Kimi and other web interfaces. " |
| "A ready-to-paste prompt is generated so the AI knows to treat it as a ZIP.", |
| elem_id="subtitle", |
| ) |
|
|
| with gr.Row(): |
| with gr.Column(scale=1): |
| zip_input = gr.File( |
| label="π Upload your ZIP file", |
| file_types=[".zip"], |
| type="filepath", |
| ) |
| format_dropdown = gr.Dropdown( |
| choices=list(FORMATS.keys()), |
| value="π Word Document (.docx)", |
| label="π Disguise as format", |
| ) |
| convert_btn = gr.Button("π Disguise & Generate Prompt", variant="primary", size="lg") |
|
|
| with gr.Column(scale=1): |
| status_box = gr.Markdown(label="Status") |
| file_output = gr.File(label="β¬οΈ Download disguised file") |
| prompt_output = gr.Textbox( |
| label="π Paste this prompt alongside your upload", |
| lines=3, |
| interactive=True, |
| elem_classes=["prompt-box"], |
| placeholder="Your prompt will appear here after convertingβ¦", |
| ) |
|
|
| gr.Markdown( |
| "---\n" |
| "**How to use:** Upload your ZIP β choose a disguise format β download the renamed file " |
| "β upload it to the AI tool β paste the prompt so the AI knows to treat it as a ZIP.\n\n" |
| "> β οΈ This tool only renames the file β no actual conversion happens. " |
| "The AI needs to rename it back to `.zip` before extracting." |
| ) |
|
|
| convert_btn.click( |
| fn=convert_zip, |
| inputs=[zip_input, format_dropdown], |
| outputs=[file_output, status_box, prompt_output], |
| ) |
|
|
| if __name__ == "__main__": |
| demo.launch(theme=theme, css=css) |