Skip to content

Instantly share code, notes, and snippets.

@Dev-iL
Forked from dormeir999/Streamlit_Files_explorer.py
Last active June 19, 2024 12:09
Show Gist options
  • Save Dev-iL/87208918f18043747d294a4de5a6cfe1 to your computer and use it in GitHub Desktop.
Save Dev-iL/87208918f18043747d294a4de5a6cfe1 to your computer and use it in GitHub Desktop.
Streamlit_Files_explorer.py
import os
import shutil
import sys
from pathlib import Path
import streamlit as st
from streamlit import session_state as state
_TEE: str = "├── "
_BRANCH: str = "│ "
_LAST: str = "└── "
_SPACE: str = " "
configs: dict[str, str] = {
"APP_BASE_DIR": "<PUT SOMETHING HERE>",
"MODELS_DIR": "<PUT SOMETHING HERE>",
"CURRNET_FOLDER_STR": "Current folder",
"CREATE_FOLDER_STR": "Create new folder",
"DELETE_FOLDER_STR": "Delete folder",
}
def tree(dir_path: Path, prefix: str = ""):
"""Construct a visual tree of the contents of the provided folder.
A recursive generator, given a directory Path object will yield a visual tree structure line by line with each line
prefixed by the same characters.
"""
contents = list(dir_path.iterdir())
# contents each get pointers that are ├── with a final └── :
pointers = [_TEE] * (len(contents) - 1) + [_LAST]
for pointer, path in zip(pointers, contents):
yield prefix + pointer + path.name
if path.is_dir(): # extend the prefix and recurse:
extension = _BRANCH if pointer == _TEE else _SPACE
# i.e. space because last, └── , above so no more |
yield from tree(path, prefix=prefix + extension)
def get_dirs_inside_dir(folder, dirs_to_ignore=("__pycache__", ".ipynb_checkpoints", ".mypy_cache", ".notion")):
"""Get all directories inside a folder sorted by modification date, descending"""
return [
my_dir
for my_dir in map(
lambda x: os.path.basename(x), sorted(Path(folder).iterdir(), key=os.path.getmtime, reverse=True)
)
if os.path.isdir(os.path.join(folder, my_dir)) and my_dir not in dirs_to_ignore
]
def list_folders_in_folder(folder):
"""List all folders in a folder"""
return [file for file in os.listdir(folder) if os.path.isdir(os.path.join(folder, file))]
def show_dir_tree(folder):
"""Show the directory tree of a folder in a streamlit expander"""
folder_structure: str = "\n".join((line for line in tree(Path.home() / folder)))
with st.expander(f"Show {os.path.basename(folder)} folder tree"):
st.code(folder_structure, language="text")
def delete_folder(folder, ask=True):
"""Delete a folder and its contents."""
if not ask:
shutil.rmtree(folder)
else:
folder_basename = os.path.basename(folder)
if len(os.listdir(folder)) > 0:
st.warning(f"**{folder_basename} is not empty. Are you sure you want to delete it?**")
show_dir_tree(folder)
if st.button("Yes"):
try:
shutil.rmtree(folder)
except OSError:
st.error(f"Couldn't delete {folder_basename}:")
e = sys.exc_info()
st.error(e)
else:
st.write(f"**Are you sure you want to delete {folder_basename}?**")
if st.button("Yes"):
try:
shutil.rmtree(folder)
except OSError:
st.error(f"Couldn't delete {folder_basename}:")
e = sys.exc_info()
st.error(e)
def main():
models_abs_dir = os.path.join(configs["APP_BASE_DIR"], configs["MODELS_DIR"])
temp = []
i = 0
while temp != configs["CURRNET_FOLDER_STR"] and temp != configs["CREATE_FOLDER_STR"]:
i += 1
state.files_to_show = get_dirs_inside_dir(models_abs_dir)
temp = st.selectbox(
"Models' folder" + f": level {i}",
options=[configs["CURRNET_FOLDER_STR"]]
+ state.files_to_show
+ [configs["CREATE_FOLDER_STR"]]
+ [configs["DELETE_FOLDER_STR"]],
key=models_abs_dir,
)
if temp == configs["CREATE_FOLDER_STR"]:
new_folder = st.text_input(
label="New folder name",
value=str(state.dataset_name) + "_" + str(state.model) + "_models",
key="new_folder",
)
new_folder = os.path.join(models_abs_dir, new_folder)
if st.button("Create new folder"):
os.mkdir(new_folder)
state.files_to_show = get_dirs_inside_dir(models_abs_dir)
elif temp == configs["DELETE_FOLDER_STR"]:
if list_folders_in_folder(models_abs_dir):
chosen_delete_folder = st.selectbox(
label="Folder to delete", options=list_folders_in_folder(models_abs_dir), key="delete_folders"
)
chosen_delete_folder = os.path.join(models_abs_dir, chosen_delete_folder)
delete_folder(chosen_delete_folder)
state.files_to_show = get_dirs_inside_dir(models_abs_dir)
else:
st.info("No folders found")
elif not temp == configs["CURRNET_FOLDER_STR"]:
models_abs_dir = os.path.join(models_abs_dir, temp)
try:
show_dir_tree(models_abs_dir)
except FileNotFoundError:
pass
if __name__ == "__main__":
import streamlit.web.bootstrap
if "__streamlitmagic__" not in locals():
streamlit.web.bootstrap.run(__file__, False, [], {})
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment