import os import pandas as pd import gradio as gr from datetime import datetime from huggingface_hub import HfApi, hf_hub_download # --- CONFIGURATION --- # Replace with your Hugging Face username and the private dataset name you created DATASET_REPO_ID = "tayy786/my-user-database" DB_FILE_NAME = "user_database.csv" LOCAL_DIR = "local_data" os.makedirs(LOCAL_DIR, exist_ok=True) api = HfApi() # Get the Hugging Face token saved in the Space's Secrets HF_TOKEN = os.environ.get("HF_TOKEN") def sync_from_hf(): """Downloads the current database CSV from the private dataset repository.""" local_csv_path = os.path.join(LOCAL_DIR, DB_FILE_NAME) try: # Download file from dataset repo filepath = hf_hub_download( repo_id=DATASET_REPO_ID, filename=DB_FILE_NAME, repo_type="dataset", token=HF_TOKEN, local_dir=LOCAL_DIR ) return pd.read_csv(filepath) except Exception: # If file doesn't exist yet in the repository, create a fresh DataFrame df = pd.DataFrame(columns=["Name", "Address", "Cell Number", "Seat Number", "Password", "Image Repo Path", "Timestamp"]) df.to_csv(local_csv_path, index=False) return df def register_user(name, address, cell_num, seat_num, password, image_path): if not all([name, address, cell_num, seat_num, password]): return "⚠️ Error: All text fields are required!" if image_path is None: return "⚠️ Error: Please upload or take a picture!" if not HF_TOKEN: return "⚠️ Space Secret 'HF_TOKEN' is missing. Configuration required." try: # 1. Pull latest database state df = sync_from_hf() seat_num_str = str(seat_num).strip() if seat_num_str in df['Seat Number'].astype(str).values: return f"❌ Error: Seat Number {seat_num_str} is already registered!" # 2. Upload the profile picture directly to the private dataset repo_image_path = f"images/user_{seat_num_str}.png" api.upload_file( path_or_fileobj=image_path, path_in_repo=repo_image_path, repo_id=DATASET_REPO_ID, repo_type="dataset", token=HF_TOKEN ) # 3. Append metadata to CSV new_user = { "Name": name, "Address": address, "Cell Number": str(cell_num), "Seat Number": seat_num_str, "Password": password, # Note: For production systems, passwords should be hashed "Image Repo Path": repo_image_path, "Timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S") } df = pd.concat([df, pd.DataFrame([new_user])], ignore_index=True) local_csv_path = os.path.join(LOCAL_DIR, DB_FILE_NAME) df.to_csv(local_csv_path, index=False) # 4. Upload updated CSV back to HF Dataset api.upload_file( path_or_fileobj=local_csv_path, path_in_repo=DB_FILE_NAME, repo_id=DATASET_REPO_ID, repo_type="dataset", token=HF_TOKEN ) return f"✅ Success! {name} (Seat: {seat_num_str}) has been securely registered." except Exception as e: return f"❌ Registration failed: {str(e)}" def search_user(search_query): if not search_query: return "⚠️ Please enter a search term.", None, "" try: df = sync_from_hf() query = str(search_query).lower().strip() # Search match logic match = df[ df['Name'].astype(str).str.lower().str.contains(query) | df['Cell Number'].astype(str).str.contains(query) | df['Seat Number'].astype(str).str.lower().str.contains(query) ] if match.empty: return "🔍 No user found matching that criteria.", None, "" user_data = match.iloc[0] # Pull the matching profile image out of the private dataset container local_img_path = None repo_img_path = user_data['Image Repo Path'] try: local_img_path = hf_hub_download( repo_id=DATASET_REPO_ID, filename=repo_img_path, repo_type="dataset", token=HF_TOKEN, local_dir=LOCAL_DIR ) except Exception: pass # Handle image missing error gracefully details_text = f""" ### 👤 User Profile Found: * **Name:** {user_data['Name']} * **Seat Number:** {user_data['Seat Number']} * **Cell Number:** {user_data['Cell Number']} * **Address:** {user_data['Address']} * **Registered On:** {user_data['Timestamp']} """ return "✅ User Found!", local_img_path, details_text except Exception as e: return f"❌ Search failed: {str(e)}", None, "" # --- Gradio Frontend Interface --- with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.Markdown("# 📇 Persistent User Registration & Search System") with gr.Tabs(): # Registration Tab with gr.TabItem("📝 Registration"): gr.Markdown("### Enter credentials to store permanently in Private HF Dataset backend.") with gr.Row(): with gr.Column(): name_in = gr.Textbox(label="Full Name") cell_in = gr.Textbox(label="Cell Number") seat_in = gr.Textbox(label="Seat Number") pass_in = gr.Textbox(label="Password", type="password") addr_in = gr.Textbox(label="Address", lines=2) with gr.Column(): img_in = gr.Image(label="Profile Picture (Upload or Camera)", type="filepath") submit_btn = gr.Button("Register Securely", variant="primary") reg_output = gr.Textbox(label="System Status") submit_btn.click( fn=register_user, inputs=[name_in, addr_in, cell_in, seat_in, pass_in, img_in], outputs=reg_output ) # Search Tab with gr.TabItem("🔍 Search Profile"): gr.Markdown("### Lookup details using Name, Cell, or Seat Number.") with gr.Row(): with gr.Column(scale=2): search_input = gr.Textbox(label="Search String") search_btn = gr.Button("Find Record", variant="primary") status_output = gr.Textbox(label="Lookup Status") with gr.Column(scale=1): image_output = gr.Image(label="Retrieved Picture") details_output = gr.Markdown() search_btn.click( fn=search_user, inputs=search_input, outputs=[status_output, image_output, details_output] ) if __name__ == "__main__": demo.launch()