rahul7star commited on
Commit
ffe7caa
·
verified ·
1 Parent(s): 15b177f

stable base

Browse files

stable version to show images

Files changed (1) hide show
  1. app.py +231 -130
app.py CHANGED
@@ -1,192 +1,293 @@
1
  import os
 
 
2
  import tempfile
3
- from functools import lru_cache
4
- from huggingface_hub import HfApi, hf_hub_download
5
  import gradio as gr
 
 
 
 
 
 
 
 
6
 
7
  HF_TOKEN = os.getenv("HF_TOKEN")
 
8
 
9
- DEFAULT_REPO = "rahul7star/WAN22-Feb-2026"
10
- IMAGES_PER_PAGE = 6
 
 
11
 
12
- api = HfApi(token=HF_TOKEN)
 
13
 
 
 
14
 
15
- # -------------------------------------------------
16
- # Helpers
17
- # -------------------------------------------------
 
 
 
18
 
19
- def list_date_folders(repo_id):
20
- files = api.list_repo_files(repo_id=repo_id)
21
- return sorted(
22
- {f.split("/")[0] for f in files if "/" in f},
23
- reverse=True
24
- )
25
 
 
 
26
 
27
- def list_image_folders(repo_id, date):
28
- files = api.list_repo_files(repo_id=repo_id)
29
- return sorted(
30
- {
31
- "/".join(f.split("/")[:2])
32
- for f in files
33
- if f.startswith(date + "/") and f.count("/") >= 1
34
- }
35
- )
36
 
 
37
 
38
- def find_image_file(repo_id, folder):
39
- files = api.list_repo_files(repo_id=repo_id)
40
- for f in files:
41
- if f.startswith(folder) and f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")):
42
- return f
43
- return None
44
 
 
45
 
46
- def find_summary_file(repo_id, folder):
47
- files = api.list_repo_files(repo_id=repo_id)
48
- for f in files:
49
- if f.startswith(folder) and f.endswith("summary.txt"):
50
- return f
51
- return None
52
 
53
 
54
- def download_file(repo_id, path):
55
- return hf_hub_download(
56
- repo_id=repo_id,
57
- filename=path,
58
- token=HF_TOKEN,
59
- cache_dir=tempfile.mkdtemp()
60
  )
 
61
 
62
 
63
- # -------------------------------------------------
64
- # Cache (refreshed per repo + date)
65
- # -------------------------------------------------
 
66
 
67
- @lru_cache(maxsize=32)
68
- def load_date(repo_id, date):
69
- items = []
70
 
71
- for folder in list_image_folders(repo_id, date):
72
- img_path = find_image_file(repo_id, folder)
73
- if not img_path:
 
74
  continue
75
 
76
- local_img = download_file(repo_id, img_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- summary_path = find_summary_file(repo_id, folder)
79
- summary_text = ""
80
- if summary_path:
81
- local_summary = download_file(repo_id, summary_path)
82
- with open(local_summary, "r", encoding="utf-8") as f:
83
- summary_text = f.read().strip()
84
 
85
- items.append((local_img, summary_text))
 
86
 
87
- return items
88
 
 
 
 
89
 
90
- def render_page(repo_id, date, page):
91
- all_items = load_date(repo_id, date)
92
- total_pages = max(1, (len(all_items) + IMAGES_PER_PAGE - 1) // IMAGES_PER_PAGE)
93
 
94
- page = max(0, min(page, total_pages - 1))
95
- start = page * IMAGES_PER_PAGE
96
- end = start + IMAGES_PER_PAGE
 
 
 
97
 
98
- return all_items[start:end], page, total_pages
99
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- def nav(delta, repo_id, date, page):
102
- return (*render_page(repo_id, date, page + delta),)
103
 
 
104
 
105
- def refresh(repo_id, date):
106
- load_date.cache_clear()
107
- return render_page(repo_id, date, 0)
 
 
 
 
 
108
 
109
 
110
- # -------------------------------------------------
111
- # UI
112
- # -------------------------------------------------
113
-
114
- with gr.Blocks(css="""
115
- footer {visibility: hidden;}
116
- #copyright {
117
- text-align: center;
118
- font-size: 12px;
119
- color: #888;
120
- margin-top: 12px;
 
 
 
121
  }
122
- """) as demo:
123
 
124
- gr.Markdown("## 📸 Image Browser (Private HF Repo)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
- with gr.Row():
127
  repo_input = gr.Textbox(
128
  value=DEFAULT_REPO,
129
- label="Repository ID"
130
  )
131
- date_dd = gr.Dropdown(
132
- choices=list_date_folders(DEFAULT_REPO),
133
- label="Date"
 
 
134
  )
135
 
136
- gallery = gr.Gallery(
137
- label="Images",
138
- columns=3,
139
- height="auto",
140
- show_label=True
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  )
142
 
143
- page_state = gr.State(0)
144
- page_info = gr.Markdown()
145
-
146
- with gr.Row():
147
- prev_btn = gr.Button("⬅ Prev")
148
- next_btn = gr.Button("Next ➡")
149
- refresh_btn = gr.Button("🔄 Refresh")
 
 
 
 
 
 
 
 
150
 
151
- gr.HTML("<div id='copyright'>© OhamLab</div>")
 
 
 
 
 
 
 
 
152
 
153
- # Initial load
154
- demo.load(
155
- lambda r, d: render_page(r, d, 0),
156
- inputs=[repo_input, date_dd],
157
- outputs=[gallery, page_state, page_info]
 
 
 
158
  )
159
 
160
- # Navigation
161
  prev_btn.click(
162
  lambda r, d, p: nav(-1, r, d, p),
163
- inputs=[repo_input, date_dd, page_state],
164
- outputs=[gallery, page_state, page_info]
165
  )
166
 
167
  next_btn.click(
168
  lambda r, d, p: nav(1, r, d, p),
169
- inputs=[repo_input, date_dd, page_state],
170
- outputs=[gallery, page_state, page_info]
171
- )
172
-
173
- refresh_btn.click(
174
- refresh,
175
- inputs=[repo_input, date_dd],
176
- outputs=[gallery, page_state, page_info]
177
- )
178
-
179
- # Change date or repo → refresh cache
180
- date_dd.change(
181
- refresh,
182
- inputs=[repo_input, date_dd],
183
- outputs=[gallery, page_state, page_info]
184
  )
185
 
186
- repo_input.change(
187
- lambda r: gr.Dropdown(choices=list_date_folders(r)),
188
- inputs=repo_input,
189
- outputs=date_dd
190
- )
191
 
192
  demo.launch()
 
1
  import os
2
+ import math
3
+ import random
4
  import tempfile
 
 
5
  import gradio as gr
6
+ from huggingface_hub import HfApi, hf_hub_download
7
+
8
+ # ======================================================
9
+ # CONFIG
10
+ # ======================================================
11
+ DEFAULT_REPO = "rahul7star/WAN22-Mar-2026"
12
+ FREE_REPO = "rahul7star/ohamlab"
13
+ FREE_IMAGE_DIR = "showcase/image"
14
 
15
  HF_TOKEN = os.getenv("HF_TOKEN")
16
+ APP_PASSWORD = os.getenv("APP_PASSWORD")
17
 
18
+ if not HF_TOKEN:
19
+ raise RuntimeError("HF_TOKEN not set")
20
+ if not APP_PASSWORD:
21
+ raise RuntimeError("APP_PASSWORD not set")
22
 
23
+ api = HfApi()
24
+ PAGE_SIZE = 6
25
 
26
+ tmp_dir = tempfile.mkdtemp()
27
+ images_cache = {} # (repo, date) -> images
28
 
29
+ # ======================================================
30
+ # FREE PREVIEW
31
+ # ======================================================
32
+ def load_free_images():
33
+ tmp = tempfile.mkdtemp()
34
+ files = api.list_repo_files(FREE_REPO, token=HF_TOKEN)
35
 
36
+ imgs = [
37
+ f for f in files
38
+ if f.startswith(FREE_IMAGE_DIR)
39
+ and f.lower().endswith((".png", ".jpg", ".jpeg", ".webp"))
40
+ ]
 
41
 
42
+ random.shuffle(imgs)
43
+ imgs = imgs[:5]
44
 
45
+ out = []
46
+ for f in imgs:
47
+ try:
48
+ out.append(hf_hub_download(FREE_REPO, f, token=HF_TOKEN, local_dir=tmp))
49
+ except Exception as e:
50
+ print("[FREE IMG ERROR]", e)
 
 
 
51
 
52
+ return out
53
 
 
 
 
 
 
 
54
 
55
+ FREE_IMAGES = load_free_images()
56
 
57
+ # ======================================================
58
+ # HELPERS
59
+ # ======================================================
60
+ def clear_cache():
61
+ images_cache.clear()
62
+ print("[CACHE] cleared all")
63
 
64
 
65
+ def list_date_folders(repo, last_n=20):
66
+ files = api.list_repo_files(repo, token=HF_TOKEN)
67
+ dates = sorted(
68
+ {f.split("/")[0] for f in files if "/" in f},
69
+ reverse=True
 
70
  )
71
+ return dates[:last_n]
72
 
73
 
74
+ def download_images(repo, date):
75
+ key = (repo, date)
76
+ if key in images_cache:
77
+ return images_cache[key]
78
 
79
+ files = api.list_repo_files(repo, token=HF_TOKEN)
80
+ local = []
 
81
 
82
+ for f in files:
83
+ if not f.startswith(date + "/"):
84
+ continue
85
+ if not f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")):
86
  continue
87
 
88
+ dst = os.path.join(tmp_dir, repo.replace("/", "_"), f)
89
+ os.makedirs(os.path.dirname(dst), exist_ok=True)
90
+
91
+ try:
92
+ path = hf_hub_download(
93
+ repo,
94
+ f,
95
+ token=HF_TOKEN,
96
+ local_dir=os.path.dirname(dst),
97
+ )
98
+ local.append(path)
99
+ print("[DOWNLOAD]", repo, f)
100
+ except Exception as e:
101
+ print("[DOWNLOAD ERROR]", f, e)
102
+
103
+ images_cache[key] = local
104
+ print(f"[INFO] {repo} {date}: {len(local)} images")
105
+ return local
106
+
107
+
108
+ # ======================================================
109
+ # PAGINATION
110
+ # ======================================================
111
+ def render_page(repo, date, page):
112
+ images = download_images(repo, date)
113
+ total_pages = max(1, math.ceil(len(images) / PAGE_SIZE))
114
+
115
+ page = max(0, min(int(page), total_pages - 1))
116
+ start = page * PAGE_SIZE
117
+ end = start + PAGE_SIZE
118
+
119
+ return (
120
+ images[start:end],
121
+ page,
122
+ f"Page {page+1} / {total_pages}",
123
+ )
124
 
 
 
 
 
 
 
125
 
126
+ def nav(delta, repo, date, page):
127
+ return render_page(repo, date, page + delta)
128
 
 
129
 
130
+ def change_date(repo, date):
131
+ clear_cache()
132
+ return render_page(repo, date, 0)
133
 
 
 
 
134
 
135
+ def change_repo(repo):
136
+ clear_cache()
137
+ dates = list_date_folders(repo)
138
+ first = dates[0] if dates else ""
139
+ imgs, page, info = render_page(repo, first, 0)
140
+ return dates, imgs, page, first, info
141
 
 
142
 
143
+ # ======================================================
144
+ # AUTH
145
+ # ======================================================
146
+ def check_password(pwd):
147
+ if pwd != APP_PASSWORD:
148
+ return (
149
+ gr.update(visible=True),
150
+ gr.update(visible=False),
151
+ [],
152
+ 0,
153
+ "",
154
+ "❌ Wrong password",
155
+ )
156
 
157
+ dates = list_date_folders(DEFAULT_REPO)
158
+ latest = dates[0]
159
 
160
+ imgs, page, info = render_page(DEFAULT_REPO, latest, 0)
161
 
162
+ return (
163
+ gr.update(visible=False),
164
+ gr.update(visible=True),
165
+ imgs,
166
+ page,
167
+ latest,
168
+ info,
169
+ )
170
 
171
 
172
+ # ======================================================
173
+ # CSS
174
+ # ======================================================
175
+ css = """
176
+ footer, .gradio-footer { display:none!important; }
177
+ #ohamlab-footer {
178
+ position:fixed;
179
+ bottom:0;
180
+ width:100%;
181
+ background:#f8f9fb;
182
+ font-size:12px;
183
+ padding:8px;
184
+ border-top:1px solid #e5e7eb;
185
+ text-align:center;
186
  }
187
+ """
188
 
189
+ # ======================================================
190
+ # UI
191
+ # ======================================================
192
+ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
193
+ gr.Markdown("# 🔐 OhamLab Image Showcase (PRO)")
194
+
195
+ # ---------- LOGIN ----------
196
+ with gr.Column(visible=True) as login_box:
197
+ pwd = gr.Textbox(type="password", label="Password")
198
+ login_btn = gr.Button("Unlock")
199
+
200
+ gr.Markdown("### 🎁 Free Preview")
201
+ with gr.Row():
202
+ for img in FREE_IMAGES:
203
+ gr.Image(img, show_label=False)
204
+
205
+ # ---------- APP ----------
206
+ with gr.Column(visible=False) as app:
207
+ repo_state = gr.State(DEFAULT_REPO)
208
+ date_state = gr.State("")
209
+ page_state = gr.State(0)
210
 
 
211
  repo_input = gr.Textbox(
212
  value=DEFAULT_REPO,
213
+ label="Base HuggingFace Repo",
214
  )
215
+
216
+ date_dropdown = gr.Dropdown(label="Select Date")
217
+
218
+ manual_date = gr.Textbox(
219
+ label="Or enter date manually (YYYY-MM-DD)"
220
  )
221
 
222
+ gallery = gr.Gallery(columns=3, height="auto")
223
+ page_info = gr.Markdown()
224
+
225
+ with gr.Row():
226
+ prev_btn = gr.Button("⬅ Previous")
227
+ next_btn = gr.Button("Next ➡")
228
+
229
+ # ---------- EVENTS ----------
230
+ login_btn.click(
231
+ check_password,
232
+ inputs=pwd,
233
+ outputs=[
234
+ login_box,
235
+ app,
236
+ gallery,
237
+ page_state,
238
+ date_state,
239
+ page_info,
240
+ ],
241
  )
242
 
243
+ repo_input.change(
244
+ change_repo,
245
+ inputs=repo_input,
246
+ outputs=[
247
+ date_dropdown,
248
+ gallery,
249
+ page_state,
250
+ date_state,
251
+ page_info,
252
+ ],
253
+ ).then(
254
+ lambda r: r,
255
+ inputs=repo_input,
256
+ outputs=repo_state,
257
+ )
258
 
259
+ date_dropdown.change(
260
+ lambda r, d: change_date(r, d),
261
+ inputs=[repo_state, date_dropdown],
262
+ outputs=[gallery, page_state, page_info],
263
+ ).then(
264
+ lambda d: d,
265
+ inputs=date_dropdown,
266
+ outputs=date_state,
267
+ )
268
 
269
+ manual_date.submit(
270
+ lambda r, d: change_date(r, d),
271
+ inputs=[repo_state, manual_date],
272
+ outputs=[gallery, page_state, page_info],
273
+ ).then(
274
+ lambda d: d,
275
+ inputs=manual_date,
276
+ outputs=date_state,
277
  )
278
 
 
279
  prev_btn.click(
280
  lambda r, d, p: nav(-1, r, d, p),
281
+ inputs=[repo_state, date_state, page_state],
282
+ outputs=[gallery, page_state, page_info],
283
  )
284
 
285
  next_btn.click(
286
  lambda r, d, p: nav(1, r, d, p),
287
+ inputs=[repo_state, date_state, page_state],
288
+ outputs=[gallery, page_state, page_info],
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  )
290
 
291
+ gr.HTML("<div id='ohamlab-footer'>© OhamLab Copyright</div>")
 
 
 
 
292
 
293
  demo.launch()