rahul7star commited on
Commit
6bd2d6f
·
verified ·
1 Parent(s): d2f2085

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -24
app.py CHANGED
@@ -3,6 +3,7 @@ import math
3
  import time
4
  import random
5
  import tempfile
 
6
  import gradio as gr
7
  import pandas as pd
8
  from datasets import load_dataset
@@ -12,7 +13,7 @@ from huggingface_hub import snapshot_download
12
  # QUOTA CONFIG
13
  # ======================================================
14
  LIMIT = 3
15
- WINDOW = 86400
16
  usage = {}
17
 
18
 
@@ -22,6 +23,7 @@ def quota_guard(fn):
22
  now = time.time()
23
 
24
  count, start = usage.get(session, (0, now))
 
25
  if now - start > WINDOW:
26
  count = 0
27
  start = now
@@ -46,46 +48,60 @@ APP_PASSWORD = os.getenv("APP_PASSWORD")
46
  if not APP_PASSWORD:
47
  raise RuntimeError("APP_PASSWORD environment variable not set")
48
 
 
49
  PRO_DATASET = "rahul7star/Wan-video"
 
 
 
 
 
50
  FREE_VIDEO_REPO = "rahul7star/ohamlab"
51
  FREE_VIDEO_FOLDER = "video"
 
52
 
53
 
54
  # ======================================================
55
- # LOAD FREE VIDEOS FROM HF REPO
56
  # ======================================================
57
  def load_free_videos():
58
  local_dir = snapshot_download(
59
  repo_id=FREE_VIDEO_REPO,
60
- allow_patterns=[f"{FREE_VIDEO_FOLDER}/*"],
61
  local_dir=tempfile.mkdtemp(),
62
- repo_type="model",
63
  )
64
 
65
  video_dir = os.path.join(local_dir, FREE_VIDEO_FOLDER)
 
 
 
 
 
66
  videos = [
67
  os.path.join(video_dir, f)
68
  for f in os.listdir(video_dir)
69
  if f.lower().endswith((".mp4", ".webm", ".mov"))
70
  ]
71
 
 
72
  return videos
73
 
74
 
75
  FREE_VIDEOS = load_free_videos()
76
 
77
 
78
- def pick_free_videos(max_count=5):
79
  if not FREE_VIDEOS:
80
  return []
81
 
82
  if len(FREE_VIDEOS) >= max_count:
83
  return random.sample(FREE_VIDEOS, max_count)
84
 
85
- # repeat if less than max_count
86
  result = []
87
  while len(result) < max_count:
88
  result.extend(FREE_VIDEOS)
 
89
  return result[:max_count]
90
 
91
 
@@ -93,34 +109,47 @@ def pick_free_videos(max_count=5):
93
  # LOAD PRO DATASET
94
  # ======================================================
95
  dataset = load_dataset(PRO_DATASET, split="test")
96
- df = dataset.to_pandas()[["video", "text", "date"]].dropna().reset_index(drop=True)
 
97
 
98
 
99
  # ======================================================
100
- # PAGINATION
101
  # ======================================================
102
  def render_grid(page, page_size):
103
  page = int(page)
104
  page_size = int(page_size)
105
 
106
- total_pages = max(1, math.ceil(len(df) / page_size))
 
107
  page = max(0, min(page, total_pages - 1))
108
 
109
- batch = df.iloc[page * page_size:(page + 1) * page_size]
 
 
110
 
111
  cards = []
112
  for _, row in batch.iterrows():
113
  cards.append(f"""
114
  <div class="card">
115
- <video src="{row['video']}" controls></video>
116
  <div class="meta">
117
- <div class="date">{row['date']}</div>
118
- <div class="caption">{row['text']}</div>
119
  </div>
120
  </div>
121
  """)
122
 
123
- return f"<div class='grid'>{''.join(cards)}</div>", page
 
 
 
 
 
 
 
 
 
124
 
125
 
126
  def next_page(page, page_size):
@@ -136,14 +165,14 @@ def reset_page(page_size):
136
 
137
 
138
  # ======================================================
139
- # AUTH
140
  # ======================================================
141
  @quota_guard
142
  def check_password(user_password, request: gr.Request):
143
  if user_password == APP_PASSWORD:
144
  html, page = render_grid(0, 5)
145
  return (
146
- gr.update(visible=False), # login
147
  gr.update(visible=False), # free preview
148
  gr.update(visible=True), # pro content
149
  html,
@@ -203,23 +232,30 @@ footer, .gradio-footer {
203
  # UI
204
  # ======================================================
205
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
206
- gr.Markdown("# 🔐 OhamLab Video Showcase - For PRO Users 18+")
207
 
208
- # ---------- LOGIN ----------
209
  with gr.Column(visible=True) as login_box:
210
  password_input = gr.Textbox(type="password", label="Password")
211
  login_btn = gr.Button("Unlock")
212
  login_status = gr.Markdown()
213
 
214
- # ---------- FREE PREVIEW ----------
215
  with gr.Column(visible=True) as free_preview:
216
  gr.Markdown("### 🎬 Free Preview")
217
- free_videos = pick_free_videos(5)
 
 
218
  with gr.Row():
219
  for v in free_videos:
220
- gr.Video(v, autoplay=False)
221
-
222
- # ---------- PRO CONTENT ----------
 
 
 
 
 
223
  with gr.Column(visible=False) as app_content:
224
  with gr.Row():
225
  page_size = gr.Dropdown([1, 5, 10], value=5)
@@ -235,7 +271,7 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
235
  next_btn.click(next_page, [page_state, page_size], [gallery, page_state])
236
  page_size.change(reset_page, [page_size], [gallery, page_state])
237
 
238
- # ---------- EVENTS ----------
239
  login_btn.click(
240
  check_password,
241
  inputs=password_input,
 
3
  import time
4
  import random
5
  import tempfile
6
+
7
  import gradio as gr
8
  import pandas as pd
9
  from datasets import load_dataset
 
13
  # QUOTA CONFIG
14
  # ======================================================
15
  LIMIT = 3
16
+ WINDOW = 86400 # 24 hours
17
  usage = {}
18
 
19
 
 
23
  now = time.time()
24
 
25
  count, start = usage.get(session, (0, now))
26
+
27
  if now - start > WINDOW:
28
  count = 0
29
  start = now
 
48
  if not APP_PASSWORD:
49
  raise RuntimeError("APP_PASSWORD environment variable not set")
50
 
51
+ # PRO CONTENT
52
  PRO_DATASET = "rahul7star/Wan-video"
53
+ VIDEO_COL = "video"
54
+ TEXT_COL = "text"
55
+ DATE_COL = "date"
56
+
57
+ # FREE PREVIEW (MODEL REPO)
58
  FREE_VIDEO_REPO = "rahul7star/ohamlab"
59
  FREE_VIDEO_FOLDER = "video"
60
+ MAX_FREE_VIDEOS = 5
61
 
62
 
63
  # ======================================================
64
+ # LOAD FREE VIDEOS (MODEL REPO – SAFE)
65
  # ======================================================
66
  def load_free_videos():
67
  local_dir = snapshot_download(
68
  repo_id=FREE_VIDEO_REPO,
69
+ repo_type="model", # ✅ IMPORTANT
70
  local_dir=tempfile.mkdtemp(),
71
+ local_dir_use_symlinks=False,
72
  )
73
 
74
  video_dir = os.path.join(local_dir, FREE_VIDEO_FOLDER)
75
+
76
+ if not os.path.isdir(video_dir):
77
+ print(f"[WARN] Free video folder not found: {video_dir}")
78
+ return []
79
+
80
  videos = [
81
  os.path.join(video_dir, f)
82
  for f in os.listdir(video_dir)
83
  if f.lower().endswith((".mp4", ".webm", ".mov"))
84
  ]
85
 
86
+ print(f"[INFO] Loaded {len(videos)} free videos")
87
  return videos
88
 
89
 
90
  FREE_VIDEOS = load_free_videos()
91
 
92
 
93
+ def pick_free_videos(max_count=MAX_FREE_VIDEOS):
94
  if not FREE_VIDEOS:
95
  return []
96
 
97
  if len(FREE_VIDEOS) >= max_count:
98
  return random.sample(FREE_VIDEOS, max_count)
99
 
100
+ # repeat videos if fewer than required
101
  result = []
102
  while len(result) < max_count:
103
  result.extend(FREE_VIDEOS)
104
+
105
  return result[:max_count]
106
 
107
 
 
109
  # LOAD PRO DATASET
110
  # ======================================================
111
  dataset = load_dataset(PRO_DATASET, split="test")
112
+ df = dataset.to_pandas()
113
+ df = df[[VIDEO_COL, TEXT_COL, DATE_COL]].dropna().reset_index(drop=True)
114
 
115
 
116
  # ======================================================
117
+ # PAGINATION LOGIC
118
  # ======================================================
119
  def render_grid(page, page_size):
120
  page = int(page)
121
  page_size = int(page_size)
122
 
123
+ total_items = len(df)
124
+ total_pages = max(1, math.ceil(total_items / page_size))
125
  page = max(0, min(page, total_pages - 1))
126
 
127
+ start = page * page_size
128
+ end = start + page_size
129
+ batch = df.iloc[start:end]
130
 
131
  cards = []
132
  for _, row in batch.iterrows():
133
  cards.append(f"""
134
  <div class="card">
135
+ <video src="{row[VIDEO_COL]}" controls preload="metadata"></video>
136
  <div class="meta">
137
+ <div class="date">{row[DATE_COL]}</div>
138
+ <div class="caption">{row[TEXT_COL]}</div>
139
  </div>
140
  </div>
141
  """)
142
 
143
+ html = f"""
144
+ <div class="grid">
145
+ {''.join(cards)}
146
+ </div>
147
+ <div class="page-info">
148
+ Page {page + 1} / {total_pages}
149
+ </div>
150
+ """
151
+
152
+ return html, page
153
 
154
 
155
  def next_page(page, page_size):
 
165
 
166
 
167
  # ======================================================
168
+ # AUTH GATE
169
  # ======================================================
170
  @quota_guard
171
  def check_password(user_password, request: gr.Request):
172
  if user_password == APP_PASSWORD:
173
  html, page = render_grid(0, 5)
174
  return (
175
+ gr.update(visible=False), # login box
176
  gr.update(visible=False), # free preview
177
  gr.update(visible=True), # pro content
178
  html,
 
232
  # UI
233
  # ======================================================
234
  with gr.Blocks(theme=gr.themes.Soft(), css=css) as demo:
235
+ gr.Markdown("# 🔐 OhamLab Video Showcase")
236
 
237
+ # -------- LOGIN --------
238
  with gr.Column(visible=True) as login_box:
239
  password_input = gr.Textbox(type="password", label="Password")
240
  login_btn = gr.Button("Unlock")
241
  login_status = gr.Markdown()
242
 
243
+ # -------- FREE PREVIEW --------
244
  with gr.Column(visible=True) as free_preview:
245
  gr.Markdown("### 🎬 Free Preview")
246
+
247
+ free_videos = pick_free_videos()
248
+
249
  with gr.Row():
250
  for v in free_videos:
251
+ gr.Video(
252
+ value=v,
253
+ autoplay=False,
254
+ loop=False,
255
+ show_download_button=False
256
+ )
257
+
258
+ # -------- PRO CONTENT --------
259
  with gr.Column(visible=False) as app_content:
260
  with gr.Row():
261
  page_size = gr.Dropdown([1, 5, 10], value=5)
 
271
  next_btn.click(next_page, [page_state, page_size], [gallery, page_state])
272
  page_size.change(reset_page, [page_size], [gallery, page_state])
273
 
274
+ # -------- EVENTS --------
275
  login_btn.click(
276
  check_password,
277
  inputs=password_input,