refactor: Improve directory processing UI with session state and rerun

This commit is contained in:
Bobby Abellana (aider) 2025-02-11 09:58:00 -08:00
parent 79b2bb0835
commit 6b5c851a00

View File

@ -207,118 +207,121 @@ if uploaded_files:
mime="application/zip", mime="application/zip",
) )
else: # Directory Processing else: # Directory Processing
st.header("Directory Processing") st.header("Directory Processing")
col1, col2 = st.columns(2) col1, col2 = st.columns(2)
with col1: with col1:
source_dir = st.text_input("Source Directory Path", source_dir = st.text_input("Source Directory Path",
help="Enter the full path to the directory containing files to process") help="Enter the full path to the directory containing files to process",
source_browse = st.button("Browse Source Directory") value=st.session_state.get('source_dir', ''))
if source_browse: source_browse = st.button("Browse Source Directory")
path = get_directory_path("Select Source Directory") if source_browse:
if path: path = get_directory_path("Select Source Directory")
source_dir = path if path:
st.session_state['source_dir'] = path # Persist the selection st.session_state['source_dir'] = path
st.experimental_rerun()
dest_dir = st.text_input("Destination Directory Path", dest_dir = st.text_input("Destination Directory Path",
help="Enter the full path where processed files will be saved") help="Enter the full path where processed files will be saved",
dest_browse = st.button("Browse Destination Directory") value=st.session_state.get('dest_dir', ''))
if dest_browse: dest_browse = st.button("Browse Destination Directory")
path = get_directory_path("Select Destination Directory") if dest_browse:
if path: path = get_directory_path("Select Destination Directory")
dest_dir = path if path:
st.session_state['dest_dir'] = path # Persist the selection st.session_state['dest_dir'] = path
st.experimental_rerun()
with col2: with col2:
if file_type == "Excel":
password_option = st.radio(
"Password Option:",
("No Password", "Password File")
)
passwords = []
if password_option == "Password File":
password_path = st.text_input("Password File Path",
help="Enter the full path to the text file containing passwords",
value=st.session_state.get('password_path', ''))
password_browse = st.button("Browse Password File")
if password_browse:
try:
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(
title="Select Password File",
filetypes=[("Text Files", "*.txt")]
)
if file_path:
st.session_state['password_path'] = file_path
st.experimental_rerun()
except Exception as e:
st.error(f"Error opening file dialog: {str(e)}")
if password_path and os.path.exists(password_path):
with open(password_path, 'r', encoding='utf-8') as pf:
passwords = [line.strip() for line in pf if line.strip()]
st.info(f"Loaded {len(passwords)} passwords from file")
if source_dir and dest_dir and st.button("Process Directory", type="primary"):
if not os.path.exists(source_dir):
st.error(f"Source directory does not exist: {source_dir}")
elif not os.path.exists(os.path.dirname(dest_dir)):
st.error(f"Parent of destination directory does not exist: {os.path.dirname(dest_dir)}")
else:
os.makedirs(dest_dir, exist_ok=True)
# Get all files recursively
if file_type == "Excel": if file_type == "Excel":
password_option = st.radio( files = glob.glob(os.path.join(source_dir, "**/*.xlsx"), recursive=True)
"Password Option:", files.extend(glob.glob(os.path.join(source_dir, "**/*.xlsm"), recursive=True))
("No Password", "Password File") else: # Word
) files = glob.glob(os.path.join(source_dir, "**/*.docx"), recursive=True)
files.extend(glob.glob(os.path.join(source_dir, "**/*.docm"), recursive=True))
passwords = [] if not files:
if password_option == "Password File": st.warning(f"No {file_type} files found in the source directory")
password_path = st.text_input("Password File Path",
help="Enter the full path to the text file containing passwords")
password_browse = st.button("Browse Password File")
if password_browse:
try:
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename(
title="Select Password File",
filetypes=[("Text Files", "*.txt")]
)
if file_path:
password_path = file_path
st.session_state['password_path'] = file_path
except Exception as e:
st.error(f"Error opening file dialog: {str(e)}")
if password_path and os.path.exists(password_path):
with open(password_path, 'r', encoding='utf-8') as pf:
passwords = [line.strip() for line in pf if line.strip()]
st.info(f"Loaded {len(passwords)} passwords from file")
if source_dir and dest_dir and st.button("Process Directory", type="primary"):
if not os.path.exists(source_dir):
st.error(f"Source directory does not exist: {source_dir}")
elif not os.path.exists(os.path.dirname(dest_dir)):
st.error(f"Parent of destination directory does not exist: {os.path.dirname(dest_dir)}")
else: else:
os.makedirs(dest_dir, exist_ok=True) progress_bar = st.progress(0)
status_text = st.empty()
# Get all files recursively for idx, source_path in enumerate(files):
if file_type == "Excel": try:
files = glob.glob(os.path.join(source_dir, "**/*.xlsx"), recursive=True) # Create a container for each file
files.extend(glob.glob(os.path.join(source_dir, "**/*.xlsm"), recursive=True)) relative_path = os.path.relpath(source_path, source_dir)
else: # Word dest_path = os.path.join(dest_dir, relative_path)
files = glob.glob(os.path.join(source_dir, "**/*.docx"), recursive=True)
files.extend(glob.glob(os.path.join(source_dir, "**/*.docm"), recursive=True))
if not files: with st.expander(f"Processing {relative_path}", expanded=True):
st.warning(f"No {file_type} files found in the source directory") st.write(f"📝 Processing {relative_path}...")
else:
progress_bar = st.progress(0)
status_text = st.empty()
for idx, source_path in enumerate(files): # Create destination directory if needed
try: os.makedirs(os.path.dirname(dest_path), exist_ok=True)
# Create a container for each file
relative_path = os.path.relpath(source_path, source_dir)
dest_path = os.path.join(dest_dir, relative_path)
with st.expander(f"Processing {relative_path}", expanded=True): # Process based on file type
st.write(f"📝 Processing {relative_path}...") if file_type == "Excel":
copy_excel_file(source_path, dest_path, passwords)
else: # Word
remove_all_protection_tags(source_path, dest_path)
# Create destination directory if needed st.success("✅ Processing complete!")
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
# Process based on file type # Update progress
if file_type == "Excel": progress = (idx + 1) / len(files)
copy_excel_file(source_path, dest_path, passwords) progress_bar.progress(progress)
else: # Word status_text.text(f"Processed {idx + 1} of {len(files)} files")
remove_all_protection_tags(source_path, dest_path)
st.success("✅ Processing complete!") except Exception as e:
st.error(f"❌ Error processing {relative_path}: {str(e)}")
# Update progress progress_bar.empty()
progress = (idx + 1) / len(files) status_text.text("✨ All processing complete!")
progress_bar.progress(progress)
status_text.text(f"Processed {idx + 1} of {len(files)} files")
except Exception as e: # Show the output directory
st.error(f"❌ Error processing {relative_path}: {str(e)}") st.success(f"Processed files are saved in: {dest_dir}")
progress_bar.empty()
status_text.text("✨ All processing complete!")
# Show the output directory
st.success(f"Processed files are saved in: {dest_dir}")
# Footer # Footer
st.sidebar.markdown("---") st.sidebar.markdown("---")