ruilongli's picture
Update app.py
0a105dc verified
import gradio as gr, os, shutil, glob
from huggingface_hub import upload_file
# ---------- CONFIG -------------------------------------------------
DATASET_REPO = "ruilongli/capture-data"
PENDING_DIR = "pending"
APPROVED_DIR = "approved"
ADMIN_KEY = os.getenv("ADMIN_KEY") # set in Space secrets
HF_TOKEN = os.getenv("HF_TOKEN")
for d in (PENDING_DIR, APPROVED_DIR):
os.makedirs(d, exist_ok=True)
# -------------------------------------------------------------------
# -------- HELPERS --------------------------------------------------
def list_pending(): # paths to files awaiting review
return sorted(glob.glob(f"{PENDING_DIR}/*"))
# -------- PUBLIC UPLOAD HANDLER -----------------------------------
def handle_upload(tmp_path):
if not tmp_path:
return "❌ No file received."
fname = os.path.basename(tmp_path)
shutil.copy(tmp_path, os.path.join(PENDING_DIR, fname))
return f"✅ `{fname}` uploaded for review!"
# -------- ADMIN ACTIONS -------------------------------------------
def approve_files(_, selected_items): # no pw needed after login
if not selected_items:
return "⚠️ Nothing selected.", list_pending()
log_lines = []
for item in selected_items:
file_path = item[0] if isinstance(item, (tuple, list)) else item
fname = os.path.basename(file_path)
upload_file( # 1) push to dataset repo
path_or_fileobj=file_path,
path_in_repo=f"images/{fname}",
repo_id=DATASET_REPO,
repo_type="dataset",
token=HF_TOKEN,
)
shutil.move(file_path, os.path.join(APPROVED_DIR, fname)) # 2) move
log_lines.append(f"✅ {fname}")
return "\n".join(log_lines), list_pending()
def refresh_files(_): # simply reload folder
return "🔁 List refreshed.", list_pending()
# -------- ADMIN LOGIN ---------------------------------------------
def admin_login(pw):
if pw != ADMIN_KEY:
return "🔒 Wrong key!", gr.update(visible=False)
return "✅ Logged in.", gr.update(visible=True) # show admin group
# -------------------- UI ------------------------------------------
with gr.Blocks() as demo:
# -------- public uploader ----------
gr.Markdown("## 🖼️ Anonymous Image Upload")
with gr.Row():
up_comp = gr.File(type="filepath", file_types=["image"])
up_msg = gr.Textbox(label="Status")
up_comp.upload(handle_upload, up_comp, up_msg)
# -------- admin login widgets -------
with gr.Accordion("Admin login", open=False):
login_pw = gr.Textbox(label="Admin key", type="password")
login_btn = gr.Button("Log in")
login_msg = gr.Textbox(label="Login status", interactive=False)
# -------- admin panel (initially hidden) -----
admin_panel = gr.Column(visible=False)
with admin_panel:
gr.Markdown("## 🔍 Admin review panel")
gallery = gr.Gallery(
label="Pending images",
value=list_pending(),
columns=[4],
height="auto",
interactive=False,
# selectable="multiple"
)
with gr.Row():
approve_btn = gr.Button("Approve & publish", variant="primary")
refresh_btn = gr.Button("🔄 Refresh list", variant="secondary")
review_log = gr.Textbox(label="Log / Result", lines=6)
# ---- wiring ----
login_btn.click(admin_login, login_pw, [login_msg, admin_panel])
approve_btn.click(
fn=approve_files,
inputs=[login_pw, gallery], # pw unused but keeps signature
outputs=[review_log, gallery]
)
refresh_btn.click(
fn=refresh_files,
inputs=[login_pw],
outputs=[review_log, gallery]
)
demo.queue().launch()