Spaces:
Sleeping
Sleeping
| """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 [] | |