Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| from pathlib import Path | |
| from datetime import datetime | |
| import zipfile | |
| from PIL import Image | |
| import time | |
| # Page configuration | |
| st.set_page_config( | |
| page_title="مدیریت فایل", | |
| page_icon="📂", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Custom CSS with Farsi font and modern theme | |
| st.markdown(""" | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;700&display=swap'); | |
| * { | |
| font-family: 'Vazirmatn', sans-serif; | |
| } | |
| .main { | |
| background-color: #f0f2f6; | |
| } | |
| .stButton>button { | |
| width: 100%; | |
| border-radius: 10px; | |
| background-color: #4c78af; | |
| color: white; | |
| border: none; | |
| padding: 0.5rem 1rem; | |
| margin: 0.25rem 0; | |
| transition: all 0.3s ease; | |
| } | |
| .stButton>button:hover { | |
| background-color: #3a5d8f; | |
| box-shadow: 0 4px 8px rgba(0,0,0,0.1); | |
| } | |
| .uploadedFile { | |
| border: 2px dashed #4c78af; | |
| border-radius: 10px; | |
| padding: 1rem; | |
| margin: 1rem 0; | |
| } | |
| .css-1d391kg { | |
| padding: 1rem; | |
| border-radius: 10px; | |
| background-color: white; | |
| box-shadow: 0 2px 4px rgba(0,0,0,0.05); | |
| } | |
| h1, h2, h3 { | |
| color: #1e3d59; | |
| } | |
| .stProgress .st-bo { | |
| background-color: #4c78af; | |
| } | |
| .stSelectbox, .stMultiSelect { | |
| border-radius: 10px; | |
| } | |
| </style> | |
| """, unsafe_allow_html=True) | |
| # FileManager class for file operations | |
| class FileManager: | |
| def __init__(self): | |
| self.root_path = Path("uploads") | |
| self.root_path.mkdir(exist_ok=True) | |
| def upload_file(self, file): | |
| """آپلود فایل با نمایش نوار پیشرفت""" | |
| progress_text = st.empty() | |
| progress_bar = st.progress(0) | |
| dest_path = self.root_path / file.name | |
| with open(dest_path, "wb") as f: | |
| total_size = file.size | |
| chunk_size = 1024 | |
| bytes_read = 0 | |
| while bytes_read < total_size: | |
| data = file.read(chunk_size) | |
| f.write(data) | |
| bytes_read += len(data) | |
| progress = bytes_read / total_size | |
| progress_bar.progress(progress) | |
| progress_text.text(f"در حال آپلود... {int(progress * 100)}%") | |
| progress_text.empty() | |
| progress_bar.empty() | |
| return f"فایل '{file.name}' با موفقیت آپلود شد!" | |
| def list_files(self, file_type=None): | |
| """لیست فایلها با امکان فیلتر بر اساس نوع فایل""" | |
| files = [ | |
| f.name for f in self.root_path.iterdir() | |
| if f.is_file() and (not file_type or f.suffix.lower() == file_type.lower()) | |
| ] | |
| return sorted(files) | |
| def delete_file(self, filename): | |
| """حذف فایل""" | |
| try: | |
| path = self.root_path / filename | |
| if path.exists(): | |
| path.unlink() | |
| return "success", f"فایل '{filename}' با موفقیت حذف شد" | |
| return "error", f"فایل '{filename}' یافت نشد" | |
| except Exception as e: | |
| return "error", f"خطا در حذف فایل: {str(e)}" | |
| def preview_file(self, filename): | |
| """پیشنمایش فایل""" | |
| path = self.root_path / filename | |
| try: | |
| if path.suffix.lower() in ['.jpg', '.jpeg', '.png', '.gif']: | |
| return Image.open(path) | |
| elif path.suffix.lower() == '.txt': | |
| with open(path, "r", encoding="utf-8") as f: | |
| return f.read(500) + "\n...(ادامه دارد)" if path.stat().st_size > 500 else f.read() | |
| return "پیشنمایش برای این نوع فایل در دسترس نیست" | |
| except Exception as e: | |
| return f"خطا در نمایش فایل: {str(e)}" | |
| def compress_files(self, files): | |
| """فشردهسازی فایلهای انتخاب شده به ZIP""" | |
| if not files: | |
| return "error", "لطفاً فایلهایی را برای فشردهسازی انتخاب کنید" | |
| try: | |
| zip_name = f"compressed_{datetime.now().strftime('%Y%m%d_%H%M%S')}.zip" | |
| zip_path = self.root_path / zip_name | |
| progress_text = st.empty() | |
| progress_bar = st.progress(0) | |
| with zipfile.ZipFile(zip_path, 'w') as zipf: | |
| for i, file in enumerate(files, 1): | |
| file_path = self.root_path / file | |
| zipf.write(file_path, file) | |
| progress = i / len(files) | |
| progress_bar.progress(progress) | |
| progress_text.text(f"در حال فشردهسازی... {int(progress * 100)}%") | |
| progress_text.empty() | |
| progress_bar.empty() | |
| return "success", f"فایلها با موفقیت فشردهسازی شد: '{zip_name}'" | |
| except Exception as e: | |
| return "error", f"خطا در فشردهسازی فایلها: {str(e)}" | |
| def main(): | |
| st.title("📂 مدیریت فایل پیشرفته") | |
| file_manager = FileManager() | |
| # Layout with two columns | |
| col1, col2 = st.columns([2, 1]) | |
| with col1: | |
| st.subheader("📤 آپلود فایل") | |
| uploaded_file = st.file_uploader( | |
| "فایل خود را اینجا قرار دهید یا برای انتخاب کلیک کنید", | |
| type=["jpg", "jpeg", "png", "gif", "txt"], | |
| accept_multiple_files=False | |
| ) | |
| if uploaded_file: | |
| result = file_manager.upload_file(uploaded_file) | |
| st.success(result) | |
| with col2: | |
| st.subheader("🔍 فیلتر فایلها") | |
| file_type = st.selectbox( | |
| "نمایش نوع فایل:", | |
| ["همه", ".jpg", ".jpeg", ".png", ".gif", ".txt"], | |
| index=0 | |
| ) | |
| # List of uploaded files | |
| st.subheader("📁 فایلهای آپلود شده") | |
| files = file_manager.list_files(None if file_type == "همه" else file_type) | |
| if not files: | |
| st.info("هنوز فایلی آپلود نشده است") | |
| else: | |
| for file in files: | |
| col1, col2, col3, col4 = st.columns([3, 1, 1, 1]) | |
| with col1: | |
| if st.button(f"👁️ پیشنمایش {file}"): | |
| preview = file_manager.preview_file(file) | |
| if isinstance(preview, str): | |
| st.text(preview) | |
| else: | |
| st.image(preview, use_column_width=True) | |
| with col2: | |
| if st.button(f"🗑️ حذف {file}"): | |
| status, message = file_manager.delete_file(file) | |
| if status == "success": | |
| st.success(message) | |
| else: | |
| st.error(message) | |
| with col3: | |
| with open(file_manager.root_path / file, 'rb') as f: | |
| st.download_button( | |
| label=f"⬇️ دانلود", | |
| data=f.read(), | |
| file_name=file | |
| ) | |
| # Compression section | |
| st.subheader("🗜️ فشردهسازی فایلها") | |
| selected_files = st.multiselect( | |
| "فایلهای مورد نظر برای فشردهسازی را انتخاب کنید", | |
| files | |
| ) | |
| if st.button("📦 فشردهسازی فایلهای انتخاب شده"): | |
| if selected_files: | |
| status, message = file_manager.compress_files(selected_files) | |
| if status == "success": | |
| st.success(message) | |
| else: | |
| st.error(message) | |
| else: | |
| st.warning("لطفاً فایلهایی برای فشردهسازی انتخاب کنید") | |
| if __name__ == "__main__": | |
| main() | |