Spaces:
Running
Running
File size: 6,181 Bytes
91a7855 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import gradio as gr
import os
import shutil
# --- Configuration ---
INITIAL_PATH = os.getcwd() # Start in the current working directory
ALLOWED_EXTENSIONS_UPLOAD = None # Allow all file types for upload initially, or set a list like ['.txt', '.pdf']
ALLOWED_EXTENSIONS_DOWNLOAD = None # Allow all for download, or restrict if needed
# --- Helper Functions ---
def list_files_and_folders(path):
"""Lists files and folders in a given directory."""
try:
items = os.listdir(path)
files = []
folders = []
for item in items:
item_path = os.path.join(path, item)
if os.path.isfile(item_path):
files.append(item)
elif os.path.isdir(item_path):
folders.append(item)
return folders, files, path, None # Return folders, files, current path, and no error
except Exception as e:
return [], [], path, str(e) # Return empty lists and error message
def change_directory(path, current_path, direction):
"""Changes the current directory (up or into a folder)."""
new_path = current_path
if direction == "up":
new_path = os.path.dirname(current_path)
elif direction == "enter":
new_path = os.path.join(current_path, path) # Path here is the selected folder
elif direction == "refresh":
new_path = current_path # Just refresh current
if not os.path.exists(new_path) or not os.path.isdir(new_path):
return [], [], current_path, "Invalid directory path."
return list_files_and_folders(new_path)
def upload_file(files, current_path):
"""Uploads files to the current directory."""
if not files:
return [], [], current_path, "No files uploaded."
uploaded_filenames = []
for file in files:
try:
filename = os.path.basename(file.name) # Get original filename
destination_path = os.path.join(current_path, filename)
if ALLOWED_EXTENSIONS_UPLOAD: # Check allowed extensions if specified
file_extension = os.path.splitext(filename)[1].lower()
if file_extension not in ALLOWED_EXTENSIONS_UPLOAD:
return [], [], current_path, f"File type '{file_extension}' not allowed for upload."
shutil.copyfile(file.name, destination_path) # Copy uploaded file
uploaded_filenames.append(filename)
except Exception as e:
return [], [], current_path, f"Error uploading file '{filename}': {str(e)}"
# Refresh file list after upload
return list_files_and_folders(current_path)
def download_file(file_path, current_path):
"""Returns the file path for download."""
full_file_path = os.path.join(current_path, file_path) # Construct full path
if not os.path.isfile(full_file_path):
return None, "File not found for download."
if ALLOWED_EXTENSIONS_DOWNLOAD: # Check allowed extensions if specified
file_extension = os.path.splitext(full_file_path)[1].lower()
if file_extension not in ALLOWED_EXTENSIONS_DOWNLOAD:
return None, f"File type '{file_extension}' not allowed for download."
return full_file_path, None
# --- Gradio Interface ---
with gr.Blocks() as demo:
current_directory = gr.State(INITIAL_PATH)
with gr.Row():
current_path_display = gr.Textbox(value=INITIAL_PATH, label="Current Path", interactive=False, scale=4)
refresh_button = gr.Button("Refresh", scale=1)
up_button = gr.Button("Up", scale=1)
with gr.Row():
with gr.Column(scale=1):
folder_output = gr.List([], headers=["Folders"], label="Folders", elem_id="folder-list", interactive=False) # Removed type="value"
file_output = gr.List([], headers=["Files"], label="Files", elem_id="file-list", interactive=False) # Removed type="value"
with gr.Column(scale=2):
upload_component = gr.File(label="Upload Files", file_count="multiple") # Allows multiple file uploads
download_button = gr.File(label="Download Selected File")
error_output = gr.Markdown(label="Status")
# --- Functionality ---
def update_file_list(current_path):
folders, files, updated_path, error = list_files_and_folders(current_path)
return folders, files, updated_path, updated_path, error
def on_folder_select(folder_name, current_path_state):
return change_directory(folder_name, folder_output.value, "enter") # Corrected: use folder_output.value not folder_name directly
def on_up_button_click(current_path_state):
return change_directory("", current_path_state, "up") # Path is empty for "up"
def on_refresh_button_click(current_path_state):
return change_directory("", current_path_state, "refresh") # Path is empty for "refresh"
def on_file_upload(uploaded_files, current_path_state):
return upload_file(uploaded_files, current_path_state)
def on_file_select_for_download(file_name, current_path_state):
return download_file(file_name, current_path_state)
# --- Event Handlers ---
demo.load(update_file_list, inputs=current_directory, outputs=[folder_output, file_output, current_directory, current_path_display, error_output])
folder_output.select(on_folder_select, [folder_output, current_directory], [folder_output, file_output, current_directory, current_path_display, error_output])
up_button.click(on_up_button_click, inputs=current_directory, outputs=[folder_output, file_output, current_directory, current_path_display, error_output])
refresh_button.click(on_refresh_button_click, inputs=current_directory, outputs=[folder_output, file_output, current_directory, current_path_display, error_output])
upload_component.upload(on_file_upload, [upload_component, current_directory], [folder_output, file_output, current_directory, current_path_display, error_output] ) # clear_value=True to reset upload after submission
file_output.select(on_file_select_for_download, [file_output, current_directory], [download_button, error_output])
if __name__ == "__main__":
demo.launch(share=True,server_port=1337) |