File size: 3,882 Bytes
53168be
9592f2d
f29b7af
9592f2d
53168be
9592f2d
 
53168be
9592f2d
f29b7af
9592f2d
 
 
 
53168be
 
 
 
 
 
9592f2d
bd7eee1
9592f2d
53168be
9592f2d
 
53168be
 
c568469
 
51a527c
c568469
 
 
53168be
c568469
53168be
9592f2d
53168be
9592f2d
 
 
 
53168be
 
c568469
 
f29b7af
53168be
 
534aef6
53168be
 
 
 
 
534aef6
9592f2d
f29b7af
53168be
9592f2d
 
53168be
 
9592f2d
 
53168be
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a105dc
53168be
 
 
 
 
9592f2d
53168be
 
9592f2d
 
 
53168be
 
 
 
 
 
 
18a61d5
f29b7af
18a61d5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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()