kphfrepo commited on
Commit
bb1b6ec
·
verified ·
1 Parent(s): b5da50f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +76 -131
app.py CHANGED
@@ -4,13 +4,20 @@ from urllib.parse import quote
4
  import gradio as gr
5
 
6
  DEFAULT_DIR = "/bucket_data"
 
 
7
 
8
  # ----------------------------
9
- # FILE SCANNER (FIXED + SAFE)
10
  # ----------------------------
11
  def load_live_cctv_dashboard():
12
  try:
13
- print("\n⚡ Scanning filesystem...")
 
 
 
 
 
14
 
15
  image_exts = (".png", ".jpg", ".jpeg", ".webp", ".gif")
16
  video_exts = (".mp4", ".mkv", ".avi", ".mov", ".dav", ".ts")
@@ -19,26 +26,46 @@ def load_live_cctv_dashboard():
19
  video_count = 0
20
  image_count = 0
21
 
 
 
 
 
22
  for root, dirs, files in os.walk(DEFAULT_DIR):
 
 
 
 
 
 
 
 
23
 
24
- # 🔥 DEBUG (confirm traversal works)
25
- print("DIR:", root, "FILES:", len(files))
 
26
 
27
  for filename in files:
28
 
 
 
29
  full_path = os.path.join(root, filename)
30
  lower = filename.lower()
31
 
32
- # -------------------
33
  # skip junk safely
34
- # -------------------
35
  if lower == ".gitattributes":
 
36
  continue
 
37
  if lower.endswith(".7z"):
 
38
  continue
 
39
  if os.path.isdir(full_path):
 
40
  continue
41
 
 
 
42
  relative_path = os.path.relpath(full_path, DEFAULT_DIR)
43
  relative_path = relative_path.replace("\\", "/")
44
 
@@ -52,187 +79,100 @@ def load_live_cctv_dashboard():
52
 
53
  encoded_path = quote(relative_path, safe="/")
54
 
55
- # -------------------
56
- # VIDEO
57
- # -------------------
58
  if lower.endswith(video_exts):
59
  video_count += 1
60
- print("added video:", encoded_path)
61
 
62
  grouped_assets[folder_name]["videos"].append({
63
  "name": filename,
64
  "video_url": encoded_path,
65
  })
66
 
67
- # -------------------
68
- # IMAGE
69
- # -------------------
70
  elif lower.endswith(image_exts):
71
  image_count += 1
72
- print("added image:", encoded_path)
73
 
74
  grouped_assets[folder_name]["images"].append({
75
  "name": filename,
76
  "image_url": encoded_path,
77
  })
78
 
79
- print(f"✅ DONE: {video_count} videos + {image_count} images")
 
 
 
 
 
80
  return grouped_assets
81
 
82
  except Exception as e:
83
- print("❌ Scan error:", e)
84
  return {}
85
 
86
 
87
  # ----------------------------
88
- # JS: THUMBNAIL HOVER ENGINE
89
  # ----------------------------
90
- custom_js = """
91
- function initThumbStrip(placeholder) {
92
- if (placeholder.dataset.thumbInit === "1") return;
93
-
94
- const base = placeholder.dataset.thumbBase;
95
- if (!base) return;
96
-
97
- placeholder.dataset.thumbInit = "1";
98
- placeholder.style.position = "relative";
99
- placeholder.style.overflow = "hidden";
100
-
101
- let thumbImg = placeholder.querySelector(".native-thumb-poster");
102
-
103
- if (!thumbImg) {
104
- thumbImg = document.createElement("img");
105
- thumbImg.className = "native-thumb-poster";
106
- thumbImg.style.cssText = `
107
- position:absolute;
108
- inset:0;
109
- width:100%;
110
- height:100%;
111
- object-fit:cover;
112
- z-index:1;
113
- pointer-events:none;
114
- `;
115
- thumbImg.onerror = () => {
116
- thumbImg.style.display = "none";
117
- };
118
- placeholder.prepend(thumbImg);
119
- }
120
-
121
- placeholder.querySelectorAll("span").forEach(el => {
122
- el.style.position = "relative";
123
- el.style.zIndex = "2";
124
- });
125
-
126
- let frame = 1;
127
- thumbImg.src = `${base}/thumbnail1.webp`;
128
-
129
- const cache = [];
130
- for (let i = 1; i <= 5; i++) {
131
- const img = new Image();
132
- img.src = `${base}/thumbnail${i}.webp`;
133
- cache.push(img);
134
- }
135
-
136
- if (placeholder.cycleInterval)
137
- clearInterval(placeholder.cycleInterval);
138
-
139
- placeholder.cycleInterval = setInterval(() => {
140
- frame = frame % 5 + 1;
141
- thumbImg.src = `${base}/thumbnail${frame}.webp`;
142
- }, 2000);
143
- }
144
-
145
- const observer = new IntersectionObserver((entries) => {
146
- entries.forEach(entry => {
147
- const el = entry.target;
148
-
149
- if (entry.isIntersecting) {
150
- initThumbStrip(el);
151
- } else {
152
- if (el.cycleInterval) clearInterval(el.cycleInterval);
153
- el.dataset.thumbInit = "0";
154
- }
155
- });
156
- }, { threshold: 0.1, rootMargin: "200px" });
157
-
158
- function observe() {
159
- document.querySelectorAll(".video-placeholder").forEach(el => {
160
- observer.observe(el);
161
- });
162
- }
163
-
164
- if (document.readyState === "loading")
165
- document.addEventListener("DOMContentLoaded", observe);
166
- else
167
- observe();
168
-
169
- new MutationObserver(observe).observe(document.body, {
170
- childList: true,
171
- subtree: true
172
- });
173
- """
174
 
175
-
176
- # ----------------------------
177
- # GRADIO APP
178
- # ----------------------------
179
- with gr.Blocks(
180
- title="CCTV Ultimate Explorer",
181
- theme=gr.themes.Soft(),
182
- js=custom_js
183
- ) as demo:
184
-
185
- refresh_btn = gr.Button("🔄 Sync Latest Camera Footage", variant="primary")
186
 
187
  @gr.render(inputs=refresh_btn, triggers=[demo.load, refresh_btn.click])
188
  def render_ui():
189
 
190
- print("\n--- RENDER START ---")
 
 
191
 
192
  assets = load_live_cctv_dashboard()
193
 
 
 
194
  if not assets:
195
- gr.Markdown("### ❌ No media found")
196
  return
197
 
198
  html = []
199
 
200
- BASE_URL = "https://kphfrepo-webdav.hf.space"
201
-
202
  for folder, media in assets.items():
203
 
 
 
204
  html.append(f"""
205
- <div style="margin-top:25px;">
206
  <h2>📁 {folder}</h2>
207
  """)
208
 
209
  # ---------------- VIDEOS ----------------
210
  if media["videos"]:
211
- html.append("<div style='display:grid;gap:15px;'>")
212
 
213
  for v in media["videos"]:
214
 
215
  video_path = v["video_url"].lstrip("/")
216
- public_video_url = f"{BASE_URL}/{video_path}"
 
 
217
 
218
  thumb_base = os.path.splitext(video_path)[0]
219
- thumb_base_url = f"{BASE_URL}/{thumb_base}"
220
 
221
  html.append(f"""
222
- <div style="border:1px solid #ddd;padding:10px;border-radius:8px;">
223
-
224
- <div style="height:250px;position:relative;background:#000;">
225
 
226
  <div class="video-placeholder"
227
- data-video-url="{public_video_url}"
228
- data-thumb-base="{thumb_base_url}"
229
  style="width:100%;height:100%;
230
  display:flex;flex-direction:column;
231
  align-items:center;justify-content:center;
232
- background:#1e293b;color:white;cursor:pointer;">
233
 
234
- <span style="font-size:2.5rem;">▶️</span>
235
- <span style="font-size:12px;">Hover preview + Click play</span>
236
 
237
  </div>
238
 
@@ -244,14 +184,17 @@ with gr.Blocks(
244
 
245
  # ---------------- IMAGES ----------------
246
  if media["images"]:
247
- html.append("<div style='display:grid;grid-template-columns:repeat(auto-fill,150px);gap:10px;'>")
248
 
249
  for img in media["images"]:
 
250
  img_url = f"{BASE_URL}/{img['image_url'].lstrip('/')}"
251
 
 
 
252
  html.append(f"""
253
  <img src="{img_url}"
254
- style="width:150px;height:120px;object-fit:cover;border-radius:6px;" />
255
  """)
256
 
257
  html.append("</div>")
@@ -260,7 +203,9 @@ with gr.Blocks(
260
 
261
  gr.HTML("".join(html))
262
 
263
- print("--- RENDER END ---\n")
 
 
264
 
265
 
266
  if __name__ == "__main__":
 
4
  import gradio as gr
5
 
6
  DEFAULT_DIR = "/bucket_data"
7
+ BASE_URL = "https://kphfrepo-webdav.hf.space"
8
+
9
 
10
  # ----------------------------
11
+ # SCANNER (FULL DEBUG MODE)
12
  # ----------------------------
13
  def load_live_cctv_dashboard():
14
  try:
15
+ print("\n==============================")
16
+ print("⚡ SCANNER STARTED")
17
+ print("==============================")
18
+
19
+ print("STEP 1: DEFAULT_DIR =", DEFAULT_DIR)
20
+ print("STEP 2: EXISTS =", os.path.exists(DEFAULT_DIR))
21
 
22
  image_exts = (".png", ".jpg", ".jpeg", ".webp", ".gif")
23
  video_exts = (".mp4", ".mkv", ".avi", ".mov", ".dav", ".ts")
 
26
  video_count = 0
27
  image_count = 0
28
 
29
+ print("\nSTEP 3: ENTERING os.walk...")
30
+
31
+ walker_step = 0
32
+
33
  for root, dirs, files in os.walk(DEFAULT_DIR):
34
+ walker_step += 1
35
+
36
+ print("\n------------------------------")
37
+ print("WALK STEP:", walker_step)
38
+ print("ROOT:", root)
39
+ print("DIRS:", dirs)
40
+ print("FILES COUNT:", len(files))
41
+ print("------------------------------")
42
 
43
+ if walker_step > 50:
44
+ print("DEBUG LIMIT STOPPED WALK EARLY")
45
+ break
46
 
47
  for filename in files:
48
 
49
+ print(" FILE:", filename)
50
+
51
  full_path = os.path.join(root, filename)
52
  lower = filename.lower()
53
 
 
54
  # skip junk safely
 
55
  if lower == ".gitattributes":
56
+ print(" SKIP: gitattributes")
57
  continue
58
+
59
  if lower.endswith(".7z"):
60
+ print(" SKIP: 7z")
61
  continue
62
+
63
  if os.path.isdir(full_path):
64
+ print(" SKIP: isdir (unexpected)")
65
  continue
66
 
67
+ print(" PROCESSING:", filename)
68
+
69
  relative_path = os.path.relpath(full_path, DEFAULT_DIR)
70
  relative_path = relative_path.replace("\\", "/")
71
 
 
79
 
80
  encoded_path = quote(relative_path, safe="/")
81
 
82
+ # ---------------- VIDEO ----------------
 
 
83
  if lower.endswith(video_exts):
84
  video_count += 1
85
+ print(" 🎬 ADD VIDEO:", encoded_path)
86
 
87
  grouped_assets[folder_name]["videos"].append({
88
  "name": filename,
89
  "video_url": encoded_path,
90
  })
91
 
92
+ # ---------------- IMAGE ----------------
 
 
93
  elif lower.endswith(image_exts):
94
  image_count += 1
95
+ print(" 🖼 ADD IMAGE:", encoded_path)
96
 
97
  grouped_assets[folder_name]["images"].append({
98
  "name": filename,
99
  "image_url": encoded_path,
100
  })
101
 
102
+ print("\n==============================")
103
+ print("SCANNER FINISHED")
104
+ print("VIDEOS:", video_count)
105
+ print("IMAGES:", image_count)
106
+ print("==============================\n")
107
+
108
  return grouped_assets
109
 
110
  except Exception as e:
111
+ print("\n❌ SCANNER ERROR:", e)
112
  return {}
113
 
114
 
115
  # ----------------------------
116
+ # GRADIO UI
117
  # ----------------------------
118
+ with gr.Blocks(title="CCTV Debug Explorer") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
+ refresh_btn = gr.Button("🔄 Scan Bucket")
 
 
 
 
 
 
 
 
 
 
121
 
122
  @gr.render(inputs=refresh_btn, triggers=[demo.load, refresh_btn.click])
123
  def render_ui():
124
 
125
+ print("\n==============================")
126
+ print("⚡ RENDER START")
127
+ print("==============================")
128
 
129
  assets = load_live_cctv_dashboard()
130
 
131
+ print("RENDER RECEIVED ASSETS:", len(assets))
132
+
133
  if not assets:
134
+ gr.Markdown("### ❌ No assets found")
135
  return
136
 
137
  html = []
138
 
 
 
139
  for folder, media in assets.items():
140
 
141
+ print("RENDER FOLDER:", folder)
142
+
143
  html.append(f"""
144
+ <div style="margin:20px 0;">
145
  <h2>📁 {folder}</h2>
146
  """)
147
 
148
  # ---------------- VIDEOS ----------------
149
  if media["videos"]:
150
+ html.append("<div style='display:grid;gap:12px;'>")
151
 
152
  for v in media["videos"]:
153
 
154
  video_path = v["video_url"].lstrip("/")
155
+ video_url = f"{BASE_URL}/{video_path}"
156
+
157
+ print("RENDER VIDEO:", video_url)
158
 
159
  thumb_base = os.path.splitext(video_path)[0]
160
+ thumb_url = f"{BASE_URL}/{thumb_base}"
161
 
162
  html.append(f"""
163
+ <div style="border:1px solid #ccc;padding:10px;border-radius:8px;">
164
+ <div style="height:250px;background:#000;position:relative;">
 
165
 
166
  <div class="video-placeholder"
167
+ data-video-url="{video_url}"
168
+ data-thumb-base="{thumb_url}"
169
  style="width:100%;height:100%;
170
  display:flex;flex-direction:column;
171
  align-items:center;justify-content:center;
172
+ background:#111827;color:white;cursor:pointer;">
173
 
174
+ <span style="font-size:2rem;">▶️</span>
175
+ <span style="font-size:12px;">Video Ready</span>
176
 
177
  </div>
178
 
 
184
 
185
  # ---------------- IMAGES ----------------
186
  if media["images"]:
187
+ html.append("<div style='display:flex;gap:10px;flex-wrap:wrap;margin-top:10px;'>")
188
 
189
  for img in media["images"]:
190
+
191
  img_url = f"{BASE_URL}/{img['image_url'].lstrip('/')}"
192
 
193
+ print("RENDER IMAGE:", img_url)
194
+
195
  html.append(f"""
196
  <img src="{img_url}"
197
+ style="width:140px;height:110px;object-fit:cover;border-radius:6px;" />
198
  """)
199
 
200
  html.append("</div>")
 
203
 
204
  gr.HTML("".join(html))
205
 
206
+ print("==============================")
207
+ print("⚡ RENDER END")
208
+ print("==============================\n")
209
 
210
 
211
  if __name__ == "__main__":