import gradio as gr import os import shutil import pandas as pd from datetime import datetime # --- Configuration --- UPLOAD_DIR = "shared_files" MAX_STORAGE_GB = 1 MAX_STORAGE_BYTES = MAX_STORAGE_GB * 1024 * 1024 * 1024 OWNER_PASSWORD = os.environ.get("OWNER_PASSWORD") USER_PASSWORD = os.environ.get("USER_PASSWORD") os.makedirs(UPLOAD_DIR, exist_ok=True) def get_dir_size(path): total_size = 0 for dirpath, _, filenames in os.walk(path): for f in filenames: total_size += os.path.getsize(os.path.join(dirpath, f)) return total_size def get_file_info(): file_data = [] file_list_for_dropdown = [] for f in os.listdir(UPLOAD_DIR): path = os.path.join(UPLOAD_DIR, f) if os.path.isfile(path): stats = os.stat(path) dt_object = datetime.fromtimestamp(stats.st_mtime) # --- PARSING LOGIC --- # Format: Timestamp_UserName_OriginalName.ext parts = f.split("_", 2) if len(parts) == 3: user_name = parts[1] display_name = parts[2] else: user_name = "Anonymous" display_name = parts[1] if len(parts) > 1 else f file_data.append({ "Filename": display_name, "Uploaded By": user_name, "Date": dt_object.strftime("%Y-%m-%d"), "Time": dt_object.strftime("%H:%M:%S"), "Size (MB)": round(stats.st_size / (1024 * 1024), 2), "mtime": stats.st_mtime }) file_list_for_dropdown.append(f) df = pd.DataFrame(file_data) current_bytes = get_dir_size(UPLOAD_DIR) usage_pct = (current_bytes / MAX_STORAGE_BYTES) * 100 status_msg = f"📊 Storage Usage: {round(current_bytes/(1024**3), 3)}GB / {MAX_STORAGE_GB}GB ({round(usage_pct, 1)}%)" if df.empty: return pd.DataFrame(columns=["Filename", "Uploaded By", "Date", "Time", "Size (MB)"]), status_msg, [] sorted_df = df.sort_values(by="mtime", ascending=False).drop(columns=['mtime']) return sorted_df, status_msg, file_list_for_dropdown def upload_and_refresh(uploaded_files, user_name): if not user_name or user_name.strip() == "": user_name = "Anonymous" # Clean user name to prevent filename errors user_name = "".join(x for x in user_name if x.isalnum()) if uploaded_files: if not isinstance(uploaded_files, list): uploaded_files = [uploaded_files] for file in uploaded_files: file_size = os.stat(file.name).st_size # Janitor to maintain 1GB limit while get_dir_size(UPLOAD_DIR) + file_size > MAX_STORAGE_BYTES: oldest_files = sorted([os.path.join(UPLOAD_DIR, f) for f in os.listdir(UPLOAD_DIR)], key=os.path.getmtime) if not oldest_files: break os.remove(oldest_files[0]) timestamp = datetime.now().strftime("%H%M%S") # New format: Time_User_Filename safe_filename = f"{timestamp}_{user_name}_{os.path.basename(file.name)}" shutil.copy(file.name, os.path.join(UPLOAD_DIR, safe_filename)) df, status, files = get_file_info() # Returns None for file_input and empty string for name_input to clear them return None, "", df, status, gr.update(choices=files) def delete_selected_files(password, files_to_delete): if password != OWNER_PASSWORD: return "❌ Incorrect Password." if not files_to_delete: return "⚠️ No files selected." for f in files_to_delete: path = os.path.join(UPLOAD_DIR, f) if os.path.exists(path): os.remove(path) return f"✅ Deleted {len(files_to_delete)} file(s)." with gr.Blocks(title="File Exchange") as demo: gr.Markdown("# 🚀 File Exchange") storage_label = gr.Markdown("📊 Storage Usage: Calculating...") with gr.Row(): with gr.Column(scale=1): name_input = gr.Textbox(label="Your Name (Optional)") file_input = gr.File(label="Select Files", file_count="multiple", type="filepath") upload_btn = gr.Button("Upload & Share", variant="primary") with gr.Accordion("Owner Controls", open=False): pass_input = gr.Textbox(label="Owner Password", type="password") delete_dropdown = gr.Dropdown(label="Select Files to Delete", choices=[], multiselect=True) delete_btn = gr.Button("🗑 Delete Selected", variant="stop") admin_status = gr.Markdown("") with gr.Column(scale=2): file_table = gr.Dataframe(label="Current Files", interactive=False) download_manager = gr.File(label="Download List", file_count="multiple", interactive=False) refresh_btn = gr.Button("🔄 Refresh List") def full_refresh(): df, status, files = get_file_info() paths = [os.path.join(UPLOAD_DIR, f) for f in files] return df, status, gr.update(choices=files), paths demo.load(fn=full_refresh, outputs=[file_table, storage_label, delete_dropdown, download_manager]) upload_btn.click( fn=upload_and_refresh, inputs=[file_input, name_input], outputs=[file_input, name_input, file_table, storage_label, delete_dropdown] ).then(fn=lambda: [os.path.join(UPLOAD_DIR, f) for f in os.listdir(UPLOAD_DIR)], outputs=download_manager) delete_btn.click( fn=delete_selected_files, inputs=[pass_input, delete_dropdown], outputs=admin_status ).then(fn=full_refresh, outputs=[file_table, storage_label, delete_dropdown, download_manager]) refresh_btn.click(fn=full_refresh, outputs=[file_table, storage_label, delete_dropdown, download_manager]) demo.launch(auth=(USER_PASSWORD,USER_PASSWORD))