rahul7star commited on
Commit
7cfa4ef
·
verified ·
1 Parent(s): 7a61d1c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -80
app.py CHANGED
@@ -6,39 +6,13 @@ import tempfile
6
  import gradio as gr
7
  from huggingface_hub import HfApi, hf_hub_download
8
 
9
- # ======================================================
10
- # QUOTA CONFIG
11
- # ======================================================
12
- LIMIT = int(os.getenv("APP_DAILY_LIMIT", "3"))
13
- WINDOW = 86400
14
- usage = {}
15
-
16
- def quota_guard(fn):
17
- def wrapper(*args, **kwargs):
18
- request: gr.Request | None = kwargs.get("request")
19
- session = request.session_hash if request else "global"
20
- now = time.time()
21
-
22
- count, start = usage.get(session, (0, now))
23
- if now - start > WINDOW:
24
- count, start = 0, now
25
-
26
- if count >= LIMIT:
27
- raise gr.Error(
28
- f"🚫 Daily demo limit reached.\n\n"
29
- f"Max {LIMIT} unlocks per day."
30
- )
31
-
32
- usage[session] = (count + 1, start)
33
- return fn(*args)
34
- return wrapper
35
-
36
  # ======================================================
37
  # CONFIG
38
  # ======================================================
39
  REPO_ID = "rahul7star/WAN22-Mar-2026"
40
  FREE_REPO = "rahul7star/ohamlab"
41
  FREE_IMAGE_DIR = "showcase/image"
 
42
  HF_TOKEN = os.getenv("HF_TOKEN")
43
  APP_PASSWORD = os.getenv("APP_PASSWORD")
44
 
@@ -48,7 +22,9 @@ if not APP_PASSWORD:
48
  raise RuntimeError("APP_PASSWORD not set")
49
 
50
  api = HfApi()
51
- TMP_ROOT = tempfile.mkdtemp()
 
 
52
  images_cache = {}
53
 
54
  # ======================================================
@@ -57,33 +33,45 @@ images_cache = {}
57
  def load_free_images():
58
  tmp = tempfile.mkdtemp()
59
  files = api.list_repo_files(FREE_REPO, token=HF_TOKEN)
 
60
  imgs = [
61
  f for f in files
62
- if f.startswith(FREE_IMAGE_DIR + "/")
63
  and f.lower().endswith((".png", ".jpg", ".jpeg", ".webp"))
64
  ]
 
65
  random.shuffle(imgs)
66
  imgs = imgs[:5]
67
 
68
  out = []
69
  for f in imgs:
70
- out.append(
71
- hf_hub_download(FREE_REPO, f, local_dir=tmp, token=HF_TOKEN)
72
- )
 
 
73
  return out
74
 
 
75
  FREE_IMAGES = load_free_images()
76
 
77
  # ======================================================
78
- # HELPERS
79
  # ======================================================
80
- def list_date_folders(last_n_days=20):
81
  files = api.list_repo_files(REPO_ID, token=HF_TOKEN)
82
  dates = sorted(
83
  {f.split("/")[0] for f in files if "/" in f},
84
  reverse=True
85
  )
86
- return dates[:last_n_days]
 
 
 
 
 
 
 
87
 
88
  def download_images_for_date(date):
89
  if date in images_cache:
@@ -93,42 +81,77 @@ def download_images_for_date(date):
93
  local = []
94
 
95
  for f in files:
96
- if f.startswith(date + "/") and f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")):
97
- local_path = hf_hub_download(
 
 
 
 
 
 
 
 
98
  REPO_ID,
99
  f,
100
- local_dir=TMP_ROOT,
101
- token=HF_TOKEN
102
  )
103
- local.append(local_path)
 
 
 
104
 
105
- images_cache[date] = sorted(local)
 
106
  return local
107
 
108
- def render_page(date, page, page_size):
 
 
 
 
109
  images = download_images_for_date(date)
110
- total_pages = max(1, math.ceil(len(images) / page_size))
111
- page = max(0, min(page, total_pages - 1))
112
- start = page * page_size
113
- end = start + page_size
114
- return images[start:end], page, total_pages
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
  # ======================================================
117
  # AUTH
118
  # ======================================================
119
- @quota_guard
120
  def check_password(pwd):
121
  if pwd != APP_PASSWORD:
122
  return (
123
  gr.update(visible=True),
124
  gr.update(visible=False),
125
  gr.update(visible=True),
126
- [], 0, "", "❌ Wrong password"
 
 
 
127
  )
128
 
129
  dates = list_date_folders()
130
  latest = dates[0]
131
- imgs, page, total = render_page(latest, 0, 6)
 
132
 
133
  return (
134
  gr.update(visible=False),
@@ -137,14 +160,17 @@ def check_password(pwd):
137
  imgs,
138
  page,
139
  latest,
140
- f"Page 1 / {total}"
 
141
  )
142
 
 
143
  # ======================================================
144
- # UI
145
  # ======================================================
146
  css = """
147
  footer, .gradio-footer { display:none!important; }
 
148
  #ohamlab-footer {
149
  position:fixed;
150
  bottom:0;
@@ -157,10 +183,13 @@ footer, .gradio-footer { display:none!important; }
157
  }
158
  """
159
 
 
 
 
160
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
161
- gr.Markdown("# 🔐 OhamLab Image Showcase")
162
 
163
- # LOGIN
164
  with gr.Column(visible=True) as login_box:
165
  pwd = gr.Textbox(type="password", label="Password")
166
  login_btn = gr.Button("Unlock")
@@ -171,57 +200,80 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
171
  for img in FREE_IMAGES:
172
  gr.Image(img, show_label=False)
173
 
174
- # APP
175
  with gr.Column(visible=False) as app:
176
  current_date = gr.State("")
177
  page_state = gr.State(0)
178
- page_size = gr.State(6)
179
 
180
  date_dropdown = gr.Dropdown(
181
  choices=list_date_folders(),
182
- label="Select Date"
 
 
 
 
 
 
 
 
 
 
183
  )
184
- manual_date = gr.Textbox(label="Or enter date (YYYY-MM-DD)")
185
 
186
- gallery = gr.Gallery(columns=3, height="auto")
187
  page_info = gr.Markdown()
188
 
189
  with gr.Row():
190
- prev_btn = gr.Button("⬅ Prev")
191
  next_btn = gr.Button("Next ➡")
192
 
193
- # EVENTS
194
  login_btn.click(
195
  check_password,
196
- pwd,
197
- [login_box, app, gallery, page_state, current_date, page_info]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
198
  )
199
 
200
- def change_date(date):
201
- imgs, page, total = render_page(date, 0, 6)
202
- return imgs, 0, date, f"Page 1 / {total}"
 
 
203
 
204
  date_dropdown.change(
205
  change_date,
206
- date_dropdown,
207
- [gallery, page_state, current_date, page_info]
 
 
 
 
208
  )
209
 
210
  manual_date.submit(
211
  change_date,
212
- manual_date,
213
- [gallery, page_state, current_date, page_info]
 
 
 
 
214
  )
215
 
216
- def nav(delta, date, page):
217
- imgs, page, total = render_page(date, page + delta, 6)
218
- return imgs, page, f"Page {page+1} / {total}"
219
-
220
- prev_btn.click( lambda d, p: nav(-1, d, p), inputs=[current_date, page_state], outputs=[gallery, page_state, page_info],)
221
-
222
- next_btn.click( lambda d, p: nav(1, d, p), inputs=[current_date, page_state], outputs=[gallery, page_state, page_info],)
223
-
224
-
225
- gr.HTML("<div id='ohamlab-footer'>© OhamLab</div>")
226
 
227
  demo.launch()
 
6
  import gradio as gr
7
  from huggingface_hub import HfApi, hf_hub_download
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  # ======================================================
10
  # CONFIG
11
  # ======================================================
12
  REPO_ID = "rahul7star/WAN22-Mar-2026"
13
  FREE_REPO = "rahul7star/ohamlab"
14
  FREE_IMAGE_DIR = "showcase/image"
15
+
16
  HF_TOKEN = os.getenv("HF_TOKEN")
17
  APP_PASSWORD = os.getenv("APP_PASSWORD")
18
 
 
22
  raise RuntimeError("APP_PASSWORD not set")
23
 
24
  api = HfApi()
25
+
26
+ PAGE_SIZE = 6
27
+ tmp_dir = tempfile.mkdtemp()
28
  images_cache = {}
29
 
30
  # ======================================================
 
33
  def load_free_images():
34
  tmp = tempfile.mkdtemp()
35
  files = api.list_repo_files(FREE_REPO, token=HF_TOKEN)
36
+
37
  imgs = [
38
  f for f in files
39
+ if f.startswith(FREE_IMAGE_DIR)
40
  and f.lower().endswith((".png", ".jpg", ".jpeg", ".webp"))
41
  ]
42
+
43
  random.shuffle(imgs)
44
  imgs = imgs[:5]
45
 
46
  out = []
47
  for f in imgs:
48
+ try:
49
+ out.append(hf_hub_download(FREE_REPO, f, token=HF_TOKEN, local_dir=tmp))
50
+ except Exception as e:
51
+ print("[FREE IMG ERROR]", e)
52
+
53
  return out
54
 
55
+
56
  FREE_IMAGES = load_free_images()
57
 
58
  # ======================================================
59
+ # DATE + CACHE HELPERS
60
  # ======================================================
61
+ def list_date_folders(last_n=20):
62
  files = api.list_repo_files(REPO_ID, token=HF_TOKEN)
63
  dates = sorted(
64
  {f.split("/")[0] for f in files if "/" in f},
65
  reverse=True
66
  )
67
+ return dates[:last_n]
68
+
69
+
70
+ def clear_date_cache(date):
71
+ if date in images_cache:
72
+ del images_cache[date]
73
+ print(f"[CACHE] cleared {date}")
74
+
75
 
76
  def download_images_for_date(date):
77
  if date in images_cache:
 
81
  local = []
82
 
83
  for f in files:
84
+ if not f.startswith(date + "/"):
85
+ continue
86
+ if not f.lower().endswith((".png", ".jpg", ".jpeg", ".webp")):
87
+ continue
88
+
89
+ dst_dir = os.path.join(tmp_dir, os.path.dirname(f))
90
+ os.makedirs(dst_dir, exist_ok=True)
91
+
92
+ try:
93
+ path = hf_hub_download(
94
  REPO_ID,
95
  f,
96
+ token=HF_TOKEN,
97
+ local_dir=dst_dir
98
  )
99
+ local.append(path)
100
+ print("[DOWNLOAD]", f, "->", path)
101
+ except Exception as e:
102
+ print("[DOWNLOAD ERROR]", f, e)
103
 
104
+ images_cache[date] = local
105
+ print(f"[INFO] {date} images:", len(local))
106
  return local
107
 
108
+
109
+ # ======================================================
110
+ # PAGINATION
111
+ # ======================================================
112
+ def render_page(date, page):
113
  images = download_images_for_date(date)
114
+
115
+ total_pages = max(1, math.ceil(len(images) / PAGE_SIZE))
116
+ page = max(0, min(int(page), total_pages - 1))
117
+
118
+ start = page * PAGE_SIZE
119
+ end = start + PAGE_SIZE
120
+ subset = images[start:end]
121
+
122
+ print(f"[RENDER] {date} page {page+1}/{total_pages}")
123
+
124
+ return subset, page, f"Page {page+1} / {total_pages}"
125
+
126
+
127
+ def nav(delta, date, page):
128
+ return render_page(date, page + delta)
129
+
130
+
131
+ def change_date(date):
132
+ clear_date_cache(date)
133
+ return render_page(date, 0)
134
+
135
 
136
  # ======================================================
137
  # AUTH
138
  # ======================================================
 
139
  def check_password(pwd):
140
  if pwd != APP_PASSWORD:
141
  return (
142
  gr.update(visible=True),
143
  gr.update(visible=False),
144
  gr.update(visible=True),
145
+ [],
146
+ 0,
147
+ "",
148
+ "❌ Wrong password",
149
  )
150
 
151
  dates = list_date_folders()
152
  latest = dates[0]
153
+
154
+ imgs, page, info = render_page(latest, 0)
155
 
156
  return (
157
  gr.update(visible=False),
 
160
  imgs,
161
  page,
162
  latest,
163
+ info,
164
+ "✅ Access granted",
165
  )
166
 
167
+
168
  # ======================================================
169
+ # CSS
170
  # ======================================================
171
  css = """
172
  footer, .gradio-footer { display:none!important; }
173
+
174
  #ohamlab-footer {
175
  position:fixed;
176
  bottom:0;
 
183
  }
184
  """
185
 
186
+ # ======================================================
187
+ # UI
188
+ # ======================================================
189
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
190
+ gr.Markdown("# 🔐 OhamLab Image Showcase (PRO)")
191
 
192
+ # -------- LOGIN --------
193
  with gr.Column(visible=True) as login_box:
194
  pwd = gr.Textbox(type="password", label="Password")
195
  login_btn = gr.Button("Unlock")
 
200
  for img in FREE_IMAGES:
201
  gr.Image(img, show_label=False)
202
 
203
+ # -------- APP --------
204
  with gr.Column(visible=False) as app:
205
  current_date = gr.State("")
206
  page_state = gr.State(0)
 
207
 
208
  date_dropdown = gr.Dropdown(
209
  choices=list_date_folders(),
210
+ label="Select date"
211
+ )
212
+
213
+ manual_date = gr.Textbox(
214
+ label="Or enter date manually (YYYY-MM-DD)"
215
+ )
216
+
217
+ gallery = gr.Gallery(
218
+ label="Images",
219
+ columns=3,
220
+ height="auto"
221
  )
 
222
 
 
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
+ login_box,
237
+ gallery,
238
+ page_state,
239
+ current_date,
240
+ page_info,
241
+ status,
242
+ ],
243
+ )
244
+
245
+ prev_btn.click(
246
+ lambda d, p: nav(-1, d, p),
247
+ inputs=[current_date, page_state],
248
+ outputs=[gallery, page_state, page_info],
249
  )
250
 
251
+ next_btn.click(
252
+ lambda d, p: nav(1, d, p),
253
+ inputs=[current_date, page_state],
254
+ outputs=[gallery, page_state, page_info],
255
+ )
256
 
257
  date_dropdown.change(
258
  change_date,
259
+ inputs=date_dropdown,
260
+ outputs=[gallery, page_state, page_info],
261
+ ).then(
262
+ lambda d: d,
263
+ inputs=date_dropdown,
264
+ outputs=current_date,
265
  )
266
 
267
  manual_date.submit(
268
  change_date,
269
+ inputs=manual_date,
270
+ outputs=[gallery, page_state, page_info],
271
+ ).then(
272
+ lambda d: d,
273
+ inputs=manual_date,
274
+ outputs=current_date,
275
  )
276
 
277
+ gr.HTML("<div id='ohamlab-footer'>© OhamLab Copyright</div>")
 
 
 
 
 
 
 
 
 
278
 
279
  demo.launch()