share / app.py
myyim's picture
Update app.py
ed0689c verified
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))