import os import streamlit as st import zipfile from pathlib import Path import io # Fix permission errors by setting environment variables BEFORE importing streamlit os.environ["STREAMLIT_BROWSER_GATHER_USAGE_STATS"] = "false" os.environ["STREAMLIT_SERVER_HEADLESS"] = "true" os.environ["STREAMLIT_SERVER_ENABLE_CORS"] = "false" os.environ["STREAMLIT_SERVER_ENABLE_XSRF_PROTECTION"] = "false" def is_safe_extension(extension): """Check if the extension is safe to convert to""" dangerous_extensions = ['.exe', '.bin', '.bat', '.cmd', '.com', '.scr', '.pif', '.vbs', '.js'] return extension.lower() not in dangerous_extensions def change_file_extension(file_content, original_name, new_extension): """Change file extension and return new filename""" if new_extension.startswith('.'): new_extension = new_extension[1:] base_name = Path(original_name).stem new_filename = f"{base_name}.{new_extension}" return new_filename, file_content def create_download_zip(files_data): """Create a zip file containing all converted files""" zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zipf: for filename, content in files_data: zipf.writestr(filename, content) zip_buffer.seek(0) return zip_buffer.getvalue() # Configure page st.set_page_config( page_title="File Extension Converter", page_icon="🔄", layout="wide" ) st.title("🔄 File Extension Converter") st.markdown("Convert any file extension to another (safely)") # Sidebar with instructions with st.sidebar: st.header("📋 Instructions") st.markdown(""" 1. Upload one or more files 2. Enter the target extension 3. Download converted files **Safety Note:** - .exe and .bin files are blocked for security - Only the extension is changed, not the file content """) st.header("⚠️ Blocked Extensions") st.code(".exe, .bin, .bat, .cmd, .com, .scr, .pif, .vbs, .js") # Main interface col1, col2 = st.columns([2, 1]) with col1: st.header("Upload Files") uploaded_files = st.file_uploader( "Choose files to convert", accept_multiple_files=True, help="Upload any files you want to change the extension for" ) with col2: st.header("Target Extension") new_extension = st.text_input( "New extension", placeholder="e.g., txt, pdf, jpg", help="Enter the extension you want to convert to (without the dot)" ).strip() if uploaded_files and new_extension: if new_extension.startswith('.'): new_extension = new_extension[1:] full_extension = f".{new_extension}" if not is_safe_extension(full_extension): st.error(f"❌ Extension '{full_extension}' is not allowed for security reasons") st.stop() st.success(f"✅ Converting to: **{full_extension}**") converted_files = [] st.header("📁 Conversion Results") for uploaded_file in uploaded_files: original_name = uploaded_file.name file_content = uploaded_file.read() new_filename, new_content = change_file_extension( file_content, original_name, new_extension ) converted_files.append((new_filename, new_content)) col_orig, col_arrow, col_new = st.columns([3, 1, 3]) with col_orig: st.text(f"📄 {original_name}") with col_arrow: st.text("➡️") with col_new: st.text(f"📄 {new_filename}") st.divider() st.header("💾 Download") if len(converted_files) == 1: filename, content = converted_files[0] st.download_button( label=f"📥 Download {filename}", data=content, file_name=filename, mime="application/octet-stream" ) else: try: zip_content = create_download_zip(converted_files) st.download_button( label=f"📥 Download All Files ({len(converted_files)} files)", data=zip_content, file_name="converted_files.zip", mime="application/zip" ) st.info(f"💡 {len(converted_files)} files will be downloaded as a ZIP archive") except Exception as e: st.error(f"Error creating ZIP file: {str(e)}") elif uploaded_files and not new_extension: st.warning("⚠️ Please enter a target extension") elif new_extension and not uploaded_files: st.warning("⚠️ Please upload files to convert") st.divider() st.markdown("""