ResumeIQ / ui /file_upload.py
pranav8tripathi@gmail.com
init
28f63ab
"""File upload UI components"""
import streamlit as st
from utils.file_uploader import BulkFileUploader
# Folder browser is not available in Docker/web environments
try:
from utils.folder_browser import FolderBrowser
FOLDER_BROWSER_AVAILABLE = True
except ImportError:
FOLDER_BROWSER_AVAILABLE = False
def render_file_upload():
"""Render file upload section and return uploaded files"""
st.subheader("πŸ“‚ Upload Resumes")
# Only show folder upload option if folder browser is available (local environment)
upload_options = ["Upload Multiple Files", "Upload ZIP Folder", "Google Drive Folder Link"]
if FOLDER_BROWSER_AVAILABLE:
upload_options.insert(1, "Bulk Upload from Folder")
upload_method = st.radio(
"Select upload method:",
upload_options,
horizontal=True
)
uploaded_files = []
if upload_method == "Upload Multiple Files":
uploaded_files = _upload_from_device()
elif upload_method == "Upload ZIP Folder":
uploaded_files = _upload_from_zip()
elif upload_method == "Bulk Upload from Folder":
uploaded_files = _upload_from_folder()
elif upload_method == "Google Drive Folder Link":
uploaded_files = _upload_from_google_drive()
return uploaded_files
def _upload_from_device():
"""Handle upload from device"""
if st.session_state.bulk_file_data:
st.session_state.bulk_file_data = []
# Instructions for bulk upload
with st.expander("πŸ’‘ How to upload multiple files at once", expanded=False):
st.markdown("""
**Option 1: Select Multiple Files**
- Click "Browse files" button
- Hold `Ctrl` (Windows/Linux) or `Cmd` (Mac) while clicking files
- Select all the resumes you want to upload
- Click "Open"
**Option 2: Drag & Drop**
- Select all resume files in your folder (Ctrl+A or Cmd+A)
- Drag them all together into the upload area below
- Drop to upload all at once
**Tip:** You can upload up to 200MB of files at once!
""")
uploaded_files = st.file_uploader(
"πŸ“€ Drag & drop multiple resumes here, or click to browse (PDF, DOCX, DOC)",
type=["pdf", "docx", "doc"],
accept_multiple_files=True,
help="You can select or drag multiple files at once. Hold Ctrl/Cmd to select multiple files."
)
if uploaded_files:
st.success(f"βœ… {len(uploaded_files)} file(s) uploaded successfully")
with st.expander("πŸ“‹ View uploaded files", expanded=False):
for idx, file in enumerate(uploaded_files, 1):
file_size = file.size / 1024 # Convert to KB
st.write(f"{idx}. **{file.name}** ({file_size:.1f} KB)")
return uploaded_files
def _upload_from_zip():
"""Handle upload from ZIP file"""
import zipfile
import io
st.info("πŸ’‘ **Tip:** Compress your resume folder into a ZIP file on your computer, then upload it here!")
with st.expander("πŸ“¦ How to create a ZIP file", expanded=False):
st.markdown("""
**Windows:**
1. Select all resume files in your folder
2. Right-click β†’ "Send to" β†’ "Compressed (zipped) folder"
3. Upload the created ZIP file below
**Mac:**
1. Select all resume files in your folder
2. Right-click β†’ "Compress Items"
3. Upload the created ZIP file below
**Linux:**
1. Right-click folder β†’ "Compress"
2. Choose ZIP format
3. Upload the created ZIP file below
""")
zip_file = st.file_uploader(
"πŸ“¦ Upload ZIP file containing resumes",
type=["zip"],
help="Upload a ZIP file containing PDF, DOCX, or DOC files"
)
if zip_file:
try:
with st.spinner("Extracting files from ZIP..."):
# Read ZIP file
zip_bytes = io.BytesIO(zip_file.read())
extracted_files = []
with zipfile.ZipFile(zip_bytes, 'r') as zip_ref:
# Get list of files in ZIP
file_list = zip_ref.namelist()
for file_name in file_list:
# Skip directories and hidden files
if file_name.endswith('/') or file_name.startswith('__MACOSX') or '/._ ' in file_name:
continue
# Check if file has supported extension
if file_name.lower().endswith(('.pdf', '.docx', '.doc')):
# Extract file content
file_content = zip_ref.read(file_name)
# Create a file-like object
file_obj = io.BytesIO(file_content)
file_obj.name = file_name.split('/')[-1] # Get just the filename
file_obj.seek(0)
extracted_files.append(file_obj)
if extracted_files:
st.success(f"βœ… Extracted {len(extracted_files)} resume(s) from ZIP file")
with st.expander("πŸ“‹ View extracted files", expanded=False):
for idx, file in enumerate(extracted_files, 1):
st.write(f"{idx}. **{file.name}**")
return extracted_files
else:
st.warning("⚠️ No supported resume files (PDF, DOCX, DOC) found in ZIP file")
return []
except zipfile.BadZipFile:
st.error("❌ Invalid ZIP file. Please upload a valid ZIP archive.")
return []
except Exception as e:
st.error(f"❌ Error extracting ZIP file: {str(e)}")
return []
return []
def _upload_from_folder():
"""Handle bulk upload from folder"""
if not FOLDER_BROWSER_AVAILABLE:
st.warning("⚠️ Folder browsing is not available in web deployment. Please use 'Upload from Device' instead.")
return []
col1, col2 = st.columns([3, 1])
with col1:
folder_path = st.text_input(
"Folder path containing resumes (PDF, DOCX, DOC):",
key="folder_path_input"
)
with col2:
st.write("")
st.write("")
if st.button("πŸ“ Browse", key="browse_folder_btn"):
selected_path = FolderBrowser.browse_folder()
if selected_path:
st.session_state.selected_folder_path = selected_path
st.rerun()
if 'selected_folder_path' in st.session_state and st.session_state.selected_folder_path:
folder_path = st.session_state.selected_folder_path
st.info(f"πŸ“‚ Selected: {folder_path}")
if folder_path and st.button("Load Files from Folder", key="load_folder_btn"):
with st.spinner("Loading files from folder..."):
file_data_list = BulkFileUploader.load_from_folder(folder_path)
if file_data_list:
st.session_state.bulk_file_data = file_data_list
st.success(f"βœ… Loaded {len(file_data_list)} files from folder")
if 'selected_folder_path' in st.session_state:
del st.session_state.selected_folder_path
else:
st.error("❌ No supported document files found in the specified folder")
if st.session_state.bulk_file_data:
uploaded_files = [BulkFileUploader.create_file_object(fd) for fd in st.session_state.bulk_file_data]
st.info(f"πŸ“ {len(uploaded_files)} file(s) loaded and ready for analysis")
return uploaded_files
return []
def _upload_from_google_drive():
"""Handle upload from Google Drive"""
drive_link = st.text_input("Enter Google Drive folder link:")
st.info("πŸ“Œ Note: You need to provide GOOGLE_DRIVE_API_KEY.")
if drive_link and st.button("Load Files from Google Drive"):
with st.spinner("Loading files from Google Drive..."):
file_data_list = BulkFileUploader.load_from_google_drive(drive_link)
if file_data_list:
st.session_state.bulk_file_data = file_data_list
st.success(f"βœ… Loaded {len(file_data_list)} files from Google Drive")
else:
st.error("❌ Could not load files from Google Drive. Check the link and API key.")
if st.session_state.bulk_file_data:
uploaded_files = [BulkFileUploader.create_file_object(fd) for fd in st.session_state.bulk_file_data]
st.info(f"πŸ“ {len(uploaded_files)} file(s) loaded and ready for analysis")
return uploaded_files
return []