Spaces:
Running
Running
import streamlit as st | |
import os | |
import zipfile | |
from pathlib import Path | |
import tempfile | |
import shutil | |
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""" | |
# Remove the dot if user includes it | |
if new_extension.startswith('.'): | |
new_extension = new_extension[1:] | |
# Get the base name without extension | |
base_name = Path(original_name).stem | |
# Create new filename | |
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""" | |
# Create a temporary directory | |
with tempfile.TemporaryDirectory() as temp_dir: | |
zip_path = os.path.join(temp_dir, "converted_files.zip") | |
with zipfile.ZipFile(zip_path, 'w') as zipf: | |
for filename, content in files_data: | |
zipf.writestr(filename, content) | |
# Read the zip file content | |
with open(zip_path, 'rb') as f: | |
zip_content = f.read() | |
return zip_content | |
def main(): | |
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: | |
# Validate 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") | |
return | |
st.success(f"β Converting to: **{full_extension}**") | |
# Process files | |
converted_files = [] | |
results_data = [] | |
st.header("π Conversion Results") | |
for uploaded_file in uploaded_files: | |
original_name = uploaded_file.name | |
file_content = uploaded_file.read() | |
# Convert extension | |
new_filename, new_content = change_file_extension( | |
file_content, original_name, new_extension | |
) | |
converted_files.append((new_filename, new_content)) | |
# Display result | |
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() | |
# Download options | |
st.header("πΎ Download") | |
if len(converted_files) == 1: | |
# Single file download | |
filename, content = converted_files[0] | |
st.download_button( | |
label=f"π₯ Download {filename}", | |
data=content, | |
file_name=filename, | |
mime="application/octet-stream" | |
) | |
else: | |
# Multiple files - create zip | |
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") | |
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") | |
# Footer | |
st.divider() | |
st.markdown(""" | |
<div style='text-align: center; color: #666; font-size: 0.8em;'> | |
Built with Streamlit π | Safe file extension conversion | |
</div> | |
""", unsafe_allow_html=True) | |
if __name__ == "__main__": | |
main() |