mertunsall commited on
Commit
bb469a5
·
1 Parent(s): 3322b77
Files changed (1) hide show
  1. app.py +455 -36
app.py CHANGED
@@ -108,6 +108,35 @@ def _load_traj_entries(repo_id: str, directory: str) -> list:
108
  return entries
109
 
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  def _format_annotation(index: int, annotation) -> str:
112
  prefix = f"Step {index + 1}"
113
  if isinstance(annotation, str):
@@ -122,10 +151,14 @@ def _format_annotation(index: int, annotation) -> str:
122
 
123
  def _prepare_gallery_items(
124
  repo_id: str, directory: Optional[str]
125
- ) -> tuple[list[tuple[str, str]], list[str]]:
126
- """Prepare gallery items and status messages for a directory."""
127
  if not directory:
128
- return [], ["Select a fourth-level folder to view screenshots."]
 
 
 
 
129
 
130
  prefix = f"{directory}/"
131
  files = [path for path in _list_repo_files(repo_id) if path.startswith(prefix)]
@@ -170,6 +203,55 @@ def _prepare_gallery_items(
170
  "⚠️ Mismatch between images and annotations; displaying available pairs."
171
  )
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  gallery_items: list[tuple[str, str]] = []
174
  for idx, url in enumerate(image_urls):
175
  caption = "No annotation available"
@@ -177,7 +259,7 @@ def _prepare_gallery_items(
177
  caption = _format_annotation(idx, annotations[idx])
178
  gallery_items.append((url, caption))
179
 
180
- return gallery_items, status_lines
181
 
182
 
183
  def _dropdown_update(
@@ -209,6 +291,8 @@ def refresh_repo(repo_id: str):
209
  gr.update(choices=[], value=None, interactive=False),
210
  gr.update(choices=[], value=None, interactive=False),
211
  gr.update(choices=[], value=None, interactive=False),
 
 
212
  gr.update(value=[]),
213
  gr.update(value=""),
214
  gr.update(value=f"❌ Unable to load repo `{repo_id}`: {error}"),
@@ -221,6 +305,8 @@ def refresh_repo(repo_id: str):
221
  gr.update(choices=[], value=None, interactive=False),
222
  gr.update(choices=[], value=None, interactive=False),
223
  gr.update(choices=[], value=None, interactive=False),
 
 
224
  gr.update(value=[]),
225
  gr.update(value=""),
226
  gr.update(value=f"❌ Unexpected error loading `{repo_id}`: {error}"),
@@ -255,12 +341,29 @@ def refresh_repo(repo_id: str):
255
  )
256
  fourth_value = fourth_dirs[0] if fourth_dirs else None
257
 
258
- target_directory = (
259
- _build_path(top_value, second_value, third_value, fourth_value)
 
 
260
  if fourth_value
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  else None
262
  )
263
- gallery_items, gallery_status = _prepare_gallery_items(repo_id, target_directory)
 
 
264
 
265
  first_dropdown_update = _dropdown_update(
266
  choices=top_dirs,
@@ -294,17 +397,29 @@ def refresh_repo(repo_id: str):
294
  empty_info="No fourth-level folders under the selection",
295
  )
296
 
 
 
 
 
 
 
 
 
 
297
  gallery_update = gr.update(value=gallery_items)
298
  annotation_update = gr.update(value="\n".join(gallery_status))
 
299
 
300
  return (
301
  first_dropdown_update,
302
  second_dropdown_update,
303
  third_dropdown_update,
304
  fourth_dropdown_update,
 
 
305
  gallery_update,
306
  annotation_update,
307
- gr.update(value="\n".join(status_lines)),
308
  )
309
 
310
 
@@ -333,10 +448,29 @@ def update_second_dropdown(repo_id: str, top_level_dir: str):
333
  filled_info="Choose a fourth-level folder",
334
  empty_info="Select a higher-level folder first",
335
  )
 
 
 
 
 
 
 
 
 
 
 
336
  annotation_update = gr.update(
337
  value="Select a top-level folder to load screenshots and annotations."
338
  )
339
- return empty_second, empty_third, empty_fourth, gr.update(value=[]), annotation_update
 
 
 
 
 
 
 
 
340
 
341
  second_dirs = _get_subdirectories(repo_id, top_level_dir)
342
  second_value = second_dirs[0] if second_dirs else None
@@ -349,18 +483,40 @@ def update_second_dropdown(repo_id: str, top_level_dir: str):
349
  third_value = third_dirs[0] if third_dirs else None
350
 
351
  fourth_dirs = (
352
- _get_subdirectories(repo_id, _build_path(top_level_dir, second_value, third_value))
 
 
353
  if third_value
354
  else []
355
  )
356
  fourth_value = fourth_dirs[0] if fourth_dirs else None
357
 
358
- target_directory = (
359
- _build_path(top_level_dir, second_value, third_value, fourth_value)
 
 
 
360
  if fourth_value
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  else None
362
  )
363
- gallery_items, gallery_status = _prepare_gallery_items(repo_id, target_directory)
 
 
 
 
364
 
365
  return (
366
  _dropdown_update(
@@ -384,6 +540,14 @@ def update_second_dropdown(repo_id: str, top_level_dir: str):
384
  filled_info="Choose a fourth-level folder",
385
  empty_info="No fourth-level folders under the selection",
386
  ),
 
 
 
 
 
 
 
 
387
  gr.update(value=gallery_items),
388
  gr.update(value="\n".join(gallery_status)),
389
  )
@@ -411,10 +575,19 @@ def update_second_dropdown(repo_id: str, top_level_dir: str):
411
  filled_info="Choose a fourth-level folder",
412
  empty_info="Unable to load subdirectories",
413
  )
 
 
 
 
 
 
 
414
  return (
415
  empty_second,
416
  empty_third,
417
  empty_fourth,
 
 
418
  gr.update(value=[]),
419
  gr.update(value="Unable to load screenshots or annotations."),
420
  )
@@ -438,10 +611,28 @@ def update_third_dropdown(repo_id: str, top_level_dir: str, second_level_dir: st
438
  filled_info="Choose a fourth-level folder",
439
  empty_info="Select higher-level folders first",
440
  )
 
 
 
 
 
 
 
 
 
 
 
441
  annotation_update = gr.update(
442
  value="Select higher-level folders to load screenshots and annotations."
443
  )
444
- return empty_third, empty_fourth, gr.update(value=[]), annotation_update
 
 
 
 
 
 
 
445
 
446
  third_dirs = _get_subdirectories(
447
  repo_id, _build_path(top_level_dir, second_level_dir)
@@ -457,12 +648,32 @@ def update_third_dropdown(repo_id: str, top_level_dir: str, second_level_dir: st
457
  )
458
  fourth_value = fourth_dirs[0] if fourth_dirs else None
459
 
460
- target_directory = (
461
- _build_path(top_level_dir, second_level_dir, third_value, fourth_value)
 
 
 
462
  if fourth_value
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  else None
464
  )
465
- gallery_items, gallery_status = _prepare_gallery_items(repo_id, target_directory)
 
 
 
 
466
 
467
  return (
468
  _dropdown_update(
@@ -479,6 +690,14 @@ def update_third_dropdown(repo_id: str, top_level_dir: str, second_level_dir: st
479
  filled_info="Choose a fourth-level folder",
480
  empty_info="No fourth-level folders under the selection",
481
  ),
 
 
 
 
 
 
 
 
482
  gr.update(value=gallery_items),
483
  gr.update(value="\n".join(gallery_status)),
484
  )
@@ -502,9 +721,18 @@ def update_third_dropdown(repo_id: str, top_level_dir: str, second_level_dir: st
502
  filled_info="Choose a fourth-level folder",
503
  empty_info="Unable to load subdirectories",
504
  )
 
 
 
 
 
 
 
505
  return (
506
  empty_third,
507
  empty_fourth,
 
 
508
  gr.update(value=[]),
509
  gr.update(value="Unable to load screenshots or annotations."),
510
  )
@@ -516,7 +744,7 @@ def update_fourth_dropdown(
516
  second_level_dir: str,
517
  third_level_dir: str,
518
  ):
519
- """Update the fourth dropdown and gallery when the third-level changes."""
520
  try:
521
  if not top_level_dir or not second_level_dir or not third_level_dir:
522
  empty_fourth = _dropdown_update(
@@ -526,10 +754,27 @@ def update_fourth_dropdown(
526
  filled_info="Choose a fourth-level folder",
527
  empty_info="Select higher-level folders first",
528
  )
 
 
 
 
 
 
 
 
 
 
 
529
  annotation_update = gr.update(
530
  value="Select higher-level folders to load screenshots and annotations."
531
  )
532
- return empty_fourth, gr.update(value=[]), annotation_update
 
 
 
 
 
 
533
 
534
  fourth_dirs = _get_subdirectories(
535
  repo_id,
@@ -537,17 +782,34 @@ def update_fourth_dropdown(
537
  )
538
  fourth_value = fourth_dirs[0] if fourth_dirs else None
539
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  target_directory = (
541
  _build_path(
542
  top_level_dir,
543
  second_level_dir,
544
  third_level_dir,
545
  fourth_value,
 
546
  )
547
- if fourth_value
548
  else None
549
  )
550
- gallery_items, gallery_status = _prepare_gallery_items(repo_id, target_directory)
 
 
 
 
551
 
552
  return (
553
  _dropdown_update(
@@ -557,6 +819,14 @@ def update_fourth_dropdown(
557
  filled_info="Choose a fourth-level folder",
558
  empty_info="No fourth-level folders under the selection",
559
  ),
 
 
 
 
 
 
 
 
560
  gr.update(value=gallery_items),
561
  gr.update(value="\n".join(gallery_status)),
562
  )
@@ -574,44 +844,163 @@ def update_fourth_dropdown(
574
  filled_info="Choose a fourth-level folder",
575
  empty_info="Unable to load subdirectories",
576
  )
 
 
 
 
 
 
 
577
  return (
578
  empty_fourth,
 
 
579
  gr.update(value=[]),
580
  gr.update(value="Unable to load screenshots or annotations."),
581
  )
582
 
583
 
584
- def update_gallery(
585
  repo_id: str,
586
  top_level_dir: str,
587
  second_level_dir: str,
588
  third_level_dir: str,
589
  fourth_level_dir: str,
590
  ):
591
- """Update the image gallery when the fourth-level selection changes."""
592
  try:
593
- if not all([top_level_dir, second_level_dir, third_level_dir, fourth_level_dir]):
 
 
 
 
 
 
 
 
 
 
 
 
 
594
  annotation_update = gr.update(
595
- value="Select all folder levels to load screenshots and annotations."
596
  )
597
- return gr.update(value=[]), annotation_update
598
 
599
- directory = _build_path(
600
- top_level_dir,
601
- second_level_dir,
602
- third_level_dir,
603
- fourth_level_dir,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
604
  )
605
- gallery_items, gallery_status = _prepare_gallery_items(repo_id, directory)
606
- return gr.update(value=gallery_items), gr.update(value="\n".join(gallery_status))
607
  except Exception as error:
608
  print(
609
- "[update_gallery] Error for "
610
  f"{repo_id}/{top_level_dir}/{second_level_dir}/{third_level_dir}/{fourth_level_dir}: {error}",
611
  flush=True,
612
  )
613
  print(traceback.format_exc(), flush=True)
614
- return gr.update(value=[]), gr.update(value="Unable to load screenshots or annotations.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
615
 
616
 
617
  with gr.Blocks(title="HF Dataset Explorer") as demo:
@@ -635,6 +1024,8 @@ Provide a dataset repository ID (e.g. `org/dataset`) to list its top-level folde
635
  second_level_dropdown = gr.Dropdown(label="Second-level folders", interactive=False)
636
  third_level_dropdown = gr.Dropdown(label="Third-level folders", interactive=False)
637
  fourth_level_dropdown = gr.Dropdown(label="Fourth-level folders", interactive=False)
 
 
638
  image_gallery = gr.Gallery(label="Images", columns=4)
639
  annotation_status = gr.Markdown()
640
 
@@ -646,6 +1037,8 @@ Provide a dataset repository ID (e.g. `org/dataset`) to list its top-level folde
646
  second_level_dropdown,
647
  third_level_dropdown,
648
  fourth_level_dropdown,
 
 
649
  image_gallery,
650
  annotation_status,
651
  status_display,
@@ -659,6 +1052,8 @@ Provide a dataset repository ID (e.g. `org/dataset`) to list its top-level folde
659
  second_level_dropdown,
660
  third_level_dropdown,
661
  fourth_level_dropdown,
 
 
662
  image_gallery,
663
  annotation_status,
664
  ],
@@ -670,6 +1065,8 @@ Provide a dataset repository ID (e.g. `org/dataset`) to list its top-level folde
670
  outputs=[
671
  third_level_dropdown,
672
  fourth_level_dropdown,
 
 
673
  image_gallery,
674
  annotation_status,
675
  ],
@@ -685,12 +1082,31 @@ Provide a dataset repository ID (e.g. `org/dataset`) to list its top-level folde
685
  ],
686
  outputs=[
687
  fourth_level_dropdown,
 
 
688
  image_gallery,
689
  annotation_status,
690
  ],
691
  )
692
 
693
  fourth_level_dropdown.change(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
  update_gallery,
695
  inputs=[
696
  repo_id_input,
@@ -698,8 +1114,9 @@ Provide a dataset repository ID (e.g. `org/dataset`) to list its top-level folde
698
  second_level_dropdown,
699
  third_level_dropdown,
700
  fourth_level_dropdown,
 
701
  ],
702
- outputs=[image_gallery, annotation_status],
703
  )
704
 
705
  demo.load(
@@ -710,6 +1127,8 @@ Provide a dataset repository ID (e.g. `org/dataset`) to list its top-level folde
710
  second_level_dropdown,
711
  third_level_dropdown,
712
  fourth_level_dropdown,
 
 
713
  image_gallery,
714
  annotation_status,
715
  status_display,
 
108
  return entries
109
 
110
 
111
+ def _load_instruction_file(repo_id: str, filepath: str) -> Optional[str]:
112
+ """Download a metadata JSON file and extract its instruction field."""
113
+ local_path = hf_hub_download(
114
+ repo_id=repo_id,
115
+ filename=filepath,
116
+ repo_type="dataset",
117
+ )
118
+
119
+ with open(local_path, "r", encoding="utf-8") as file:
120
+ data = json.load(file)
121
+
122
+ instruction: Optional[str] = None
123
+ if isinstance(data, dict):
124
+ instruction = data.get("instruction")
125
+ elif isinstance(data, list):
126
+ for entry in data:
127
+ if isinstance(entry, dict) and "instruction" in entry:
128
+ instruction = entry["instruction"]
129
+ break
130
+
131
+ if instruction is None:
132
+ return None
133
+
134
+ if isinstance(instruction, str):
135
+ return instruction.strip()
136
+
137
+ return str(instruction)
138
+
139
+
140
  def _format_annotation(index: int, annotation) -> str:
141
  prefix = f"Step {index + 1}"
142
  if isinstance(annotation, str):
 
151
 
152
  def _prepare_gallery_items(
153
  repo_id: str, directory: Optional[str]
154
+ ) -> tuple[list[tuple[str, str]], list[str], str]:
155
+ """Prepare gallery items, status messages, and instruction text for a directory."""
156
  if not directory:
157
+ return (
158
+ [],
159
+ ["Select a fifth-level folder to view screenshots."],
160
+ "ℹ️ Instruction will appear once a fifth-level folder is selected.",
161
+ )
162
 
163
  prefix = f"{directory}/"
164
  files = [path for path in _list_repo_files(repo_id) if path.startswith(prefix)]
 
203
  "⚠️ Mismatch between images and annotations; displaying available pairs."
204
  )
205
 
206
+ folder_name = directory.rsplit("/", 1)[-1]
207
+ metadata_files = [
208
+ path
209
+ for path in files
210
+ if "/" not in path[len(prefix) :]
211
+ and path.lower().endswith(".json")
212
+ and not path.lower().endswith(".jsonl")
213
+ ]
214
+
215
+ instruction_markdown = ""
216
+ if metadata_files:
217
+ metadata_files.sort(
218
+ key=lambda path: (
219
+ 0
220
+ if path.rsplit("/", 1)[-1].rsplit(".", 1)[0] == folder_name
221
+ else 1,
222
+ path.rsplit("/", 1)[-1].lower(),
223
+ )
224
+ )
225
+ metadata_path = metadata_files[0]
226
+ metadata_filename = metadata_path.rsplit("/", 1)[-1]
227
+ try:
228
+ instruction_value = _load_instruction_file(repo_id, metadata_path)
229
+ if instruction_value:
230
+ instruction_markdown = f"**Instruction:** {instruction_value}"
231
+ status_lines.append("📋 Instruction: loaded")
232
+ else:
233
+ instruction_markdown = (
234
+ f"⚠️ Instruction missing in `{metadata_filename}`."
235
+ )
236
+ status_lines.append("⚠️ Instruction: missing in metadata.")
237
+ except json.JSONDecodeError as error:
238
+ status_lines.append(
239
+ f"⚠️ Failed to parse `{metadata_filename}`: {error}"
240
+ )
241
+ instruction_markdown = (
242
+ f"⚠️ Unable to parse instruction from `{metadata_filename}`."
243
+ )
244
+ except Exception as error: # pragma: no cover - unexpected IO errors
245
+ status_lines.append(
246
+ f"⚠️ Error loading `{metadata_filename}`: {error}"
247
+ )
248
+ instruction_markdown = (
249
+ f"⚠️ Unable to load instruction from `{metadata_filename}`."
250
+ )
251
+ else:
252
+ instruction_markdown = "⚠️ Instruction file not found in this folder."
253
+ status_lines.append("⚠️ Instruction: file not found.")
254
+
255
  gallery_items: list[tuple[str, str]] = []
256
  for idx, url in enumerate(image_urls):
257
  caption = "No annotation available"
 
259
  caption = _format_annotation(idx, annotations[idx])
260
  gallery_items.append((url, caption))
261
 
262
+ return gallery_items, status_lines, instruction_markdown
263
 
264
 
265
  def _dropdown_update(
 
291
  gr.update(choices=[], value=None, interactive=False),
292
  gr.update(choices=[], value=None, interactive=False),
293
  gr.update(choices=[], value=None, interactive=False),
294
+ gr.update(choices=[], value=None, interactive=False),
295
+ gr.update(value=""),
296
  gr.update(value=[]),
297
  gr.update(value=""),
298
  gr.update(value=f"❌ Unable to load repo `{repo_id}`: {error}"),
 
305
  gr.update(choices=[], value=None, interactive=False),
306
  gr.update(choices=[], value=None, interactive=False),
307
  gr.update(choices=[], value=None, interactive=False),
308
+ gr.update(choices=[], value=None, interactive=False),
309
+ gr.update(value=""),
310
  gr.update(value=[]),
311
  gr.update(value=""),
312
  gr.update(value=f"❌ Unexpected error loading `{repo_id}`: {error}"),
 
341
  )
342
  fourth_value = fourth_dirs[0] if fourth_dirs else None
343
 
344
+ fifth_dirs = (
345
+ _get_subdirectories(
346
+ repo_id, _build_path(top_value, second_value, third_value, fourth_value)
347
+ )
348
  if fourth_value
349
+ else []
350
+ )
351
+ fifth_value = fifth_dirs[0] if fifth_dirs else None
352
+
353
+ target_directory = (
354
+ _build_path(
355
+ top_value,
356
+ second_value,
357
+ third_value,
358
+ fourth_value,
359
+ fifth_value,
360
+ )
361
+ if fifth_value
362
  else None
363
  )
364
+ gallery_items, gallery_status, instruction_markdown = _prepare_gallery_items(
365
+ repo_id, target_directory
366
+ )
367
 
368
  first_dropdown_update = _dropdown_update(
369
  choices=top_dirs,
 
397
  empty_info="No fourth-level folders under the selection",
398
  )
399
 
400
+ fifth_dropdown_update = _dropdown_update(
401
+ choices=fifth_dirs,
402
+ value=fifth_value,
403
+ label="Fifth-level folders",
404
+ filled_info="Choose a fifth-level folder",
405
+ empty_info="No fifth-level folders under the selection",
406
+ )
407
+
408
+ instruction_update = gr.update(value=instruction_markdown)
409
  gallery_update = gr.update(value=gallery_items)
410
  annotation_update = gr.update(value="\n".join(gallery_status))
411
+ status_update = gr.update(value="\n".join(status_lines))
412
 
413
  return (
414
  first_dropdown_update,
415
  second_dropdown_update,
416
  third_dropdown_update,
417
  fourth_dropdown_update,
418
+ fifth_dropdown_update,
419
+ instruction_update,
420
  gallery_update,
421
  annotation_update,
422
+ status_update,
423
  )
424
 
425
 
 
448
  filled_info="Choose a fourth-level folder",
449
  empty_info="Select a higher-level folder first",
450
  )
451
+ empty_fifth = _dropdown_update(
452
+ choices=[],
453
+ value=None,
454
+ label="Fifth-level folders",
455
+ filled_info="Choose a fifth-level folder",
456
+ empty_info="Select a higher-level folder first",
457
+ )
458
+ instruction_update = gr.update(
459
+ value="ℹ️ Select a top-level folder to display its instruction."
460
+ )
461
+ gallery_update = gr.update(value=[])
462
  annotation_update = gr.update(
463
  value="Select a top-level folder to load screenshots and annotations."
464
  )
465
+ return (
466
+ empty_second,
467
+ empty_third,
468
+ empty_fourth,
469
+ empty_fifth,
470
+ instruction_update,
471
+ gallery_update,
472
+ annotation_update,
473
+ )
474
 
475
  second_dirs = _get_subdirectories(repo_id, top_level_dir)
476
  second_value = second_dirs[0] if second_dirs else None
 
483
  third_value = third_dirs[0] if third_dirs else None
484
 
485
  fourth_dirs = (
486
+ _get_subdirectories(
487
+ repo_id, _build_path(top_level_dir, second_value, third_value)
488
+ )
489
  if third_value
490
  else []
491
  )
492
  fourth_value = fourth_dirs[0] if fourth_dirs else None
493
 
494
+ fifth_dirs = (
495
+ _get_subdirectories(
496
+ repo_id,
497
+ _build_path(top_level_dir, second_value, third_value, fourth_value),
498
+ )
499
  if fourth_value
500
+ else []
501
+ )
502
+ fifth_value = fifth_dirs[0] if fifth_dirs else None
503
+
504
+ target_directory = (
505
+ _build_path(
506
+ top_level_dir,
507
+ second_value,
508
+ third_value,
509
+ fourth_value,
510
+ fifth_value,
511
+ )
512
+ if fifth_value
513
  else None
514
  )
515
+ (
516
+ gallery_items,
517
+ gallery_status,
518
+ instruction_markdown,
519
+ ) = _prepare_gallery_items(repo_id, target_directory)
520
 
521
  return (
522
  _dropdown_update(
 
540
  filled_info="Choose a fourth-level folder",
541
  empty_info="No fourth-level folders under the selection",
542
  ),
543
+ _dropdown_update(
544
+ choices=fifth_dirs,
545
+ value=fifth_value,
546
+ label="Fifth-level folders",
547
+ filled_info="Choose a fifth-level folder",
548
+ empty_info="No fifth-level folders under the selection",
549
+ ),
550
+ gr.update(value=instruction_markdown),
551
  gr.update(value=gallery_items),
552
  gr.update(value="\n".join(gallery_status)),
553
  )
 
575
  filled_info="Choose a fourth-level folder",
576
  empty_info="Unable to load subdirectories",
577
  )
578
+ empty_fifth = _dropdown_update(
579
+ choices=[],
580
+ value=None,
581
+ label="Fifth-level folders",
582
+ filled_info="Choose a fifth-level folder",
583
+ empty_info="Unable to load subdirectories",
584
+ )
585
  return (
586
  empty_second,
587
  empty_third,
588
  empty_fourth,
589
+ empty_fifth,
590
+ gr.update(value="Unable to load instruction."),
591
  gr.update(value=[]),
592
  gr.update(value="Unable to load screenshots or annotations."),
593
  )
 
611
  filled_info="Choose a fourth-level folder",
612
  empty_info="Select higher-level folders first",
613
  )
614
+ empty_fifth = _dropdown_update(
615
+ choices=[],
616
+ value=None,
617
+ label="Fifth-level folders",
618
+ filled_info="Choose a fifth-level folder",
619
+ empty_info="Select higher-level folders first",
620
+ )
621
+ instruction_update = gr.update(
622
+ value="ℹ️ Select higher-level folders to display the instruction."
623
+ )
624
+ gallery_update = gr.update(value=[])
625
  annotation_update = gr.update(
626
  value="Select higher-level folders to load screenshots and annotations."
627
  )
628
+ return (
629
+ empty_third,
630
+ empty_fourth,
631
+ empty_fifth,
632
+ instruction_update,
633
+ gallery_update,
634
+ annotation_update,
635
+ )
636
 
637
  third_dirs = _get_subdirectories(
638
  repo_id, _build_path(top_level_dir, second_level_dir)
 
648
  )
649
  fourth_value = fourth_dirs[0] if fourth_dirs else None
650
 
651
+ fifth_dirs = (
652
+ _get_subdirectories(
653
+ repo_id,
654
+ _build_path(top_level_dir, second_level_dir, third_value, fourth_value),
655
+ )
656
  if fourth_value
657
+ else []
658
+ )
659
+ fifth_value = fifth_dirs[0] if fifth_dirs else None
660
+
661
+ target_directory = (
662
+ _build_path(
663
+ top_level_dir,
664
+ second_level_dir,
665
+ third_value,
666
+ fourth_value,
667
+ fifth_value,
668
+ )
669
+ if fifth_value
670
  else None
671
  )
672
+ (
673
+ gallery_items,
674
+ gallery_status,
675
+ instruction_markdown,
676
+ ) = _prepare_gallery_items(repo_id, target_directory)
677
 
678
  return (
679
  _dropdown_update(
 
690
  filled_info="Choose a fourth-level folder",
691
  empty_info="No fourth-level folders under the selection",
692
  ),
693
+ _dropdown_update(
694
+ choices=fifth_dirs,
695
+ value=fifth_value,
696
+ label="Fifth-level folders",
697
+ filled_info="Choose a fifth-level folder",
698
+ empty_info="No fifth-level folders under the selection",
699
+ ),
700
+ gr.update(value=instruction_markdown),
701
  gr.update(value=gallery_items),
702
  gr.update(value="\n".join(gallery_status)),
703
  )
 
721
  filled_info="Choose a fourth-level folder",
722
  empty_info="Unable to load subdirectories",
723
  )
724
+ empty_fifth = _dropdown_update(
725
+ choices=[],
726
+ value=None,
727
+ label="Fifth-level folders",
728
+ filled_info="Choose a fifth-level folder",
729
+ empty_info="Unable to load subdirectories",
730
+ )
731
  return (
732
  empty_third,
733
  empty_fourth,
734
+ empty_fifth,
735
+ gr.update(value="Unable to load instruction."),
736
  gr.update(value=[]),
737
  gr.update(value="Unable to load screenshots or annotations."),
738
  )
 
744
  second_level_dir: str,
745
  third_level_dir: str,
746
  ):
747
+ """Update the fourth and fifth dropdowns when the third-level changes."""
748
  try:
749
  if not top_level_dir or not second_level_dir or not third_level_dir:
750
  empty_fourth = _dropdown_update(
 
754
  filled_info="Choose a fourth-level folder",
755
  empty_info="Select higher-level folders first",
756
  )
757
+ empty_fifth = _dropdown_update(
758
+ choices=[],
759
+ value=None,
760
+ label="Fifth-level folders",
761
+ filled_info="Choose a fifth-level folder",
762
+ empty_info="Select higher-level folders first",
763
+ )
764
+ instruction_update = gr.update(
765
+ value="ℹ️ Select higher-level folders to display the instruction."
766
+ )
767
+ gallery_update = gr.update(value=[])
768
  annotation_update = gr.update(
769
  value="Select higher-level folders to load screenshots and annotations."
770
  )
771
+ return (
772
+ empty_fourth,
773
+ empty_fifth,
774
+ instruction_update,
775
+ gallery_update,
776
+ annotation_update,
777
+ )
778
 
779
  fourth_dirs = _get_subdirectories(
780
  repo_id,
 
782
  )
783
  fourth_value = fourth_dirs[0] if fourth_dirs else None
784
 
785
+ fifth_dirs = (
786
+ _get_subdirectories(
787
+ repo_id,
788
+ _build_path(
789
+ top_level_dir, second_level_dir, third_level_dir, fourth_value
790
+ ),
791
+ )
792
+ if fourth_value
793
+ else []
794
+ )
795
+ fifth_value = fifth_dirs[0] if fifth_dirs else None
796
+
797
  target_directory = (
798
  _build_path(
799
  top_level_dir,
800
  second_level_dir,
801
  third_level_dir,
802
  fourth_value,
803
+ fifth_value,
804
  )
805
+ if fifth_value
806
  else None
807
  )
808
+ (
809
+ gallery_items,
810
+ gallery_status,
811
+ instruction_markdown,
812
+ ) = _prepare_gallery_items(repo_id, target_directory)
813
 
814
  return (
815
  _dropdown_update(
 
819
  filled_info="Choose a fourth-level folder",
820
  empty_info="No fourth-level folders under the selection",
821
  ),
822
+ _dropdown_update(
823
+ choices=fifth_dirs,
824
+ value=fifth_value,
825
+ label="Fifth-level folders",
826
+ filled_info="Choose a fifth-level folder",
827
+ empty_info="No fifth-level folders under the selection",
828
+ ),
829
+ gr.update(value=instruction_markdown),
830
  gr.update(value=gallery_items),
831
  gr.update(value="\n".join(gallery_status)),
832
  )
 
844
  filled_info="Choose a fourth-level folder",
845
  empty_info="Unable to load subdirectories",
846
  )
847
+ empty_fifth = _dropdown_update(
848
+ choices=[],
849
+ value=None,
850
+ label="Fifth-level folders",
851
+ filled_info="Choose a fifth-level folder",
852
+ empty_info="Unable to load subdirectories",
853
+ )
854
  return (
855
  empty_fourth,
856
+ empty_fifth,
857
+ gr.update(value="Unable to load instruction."),
858
  gr.update(value=[]),
859
  gr.update(value="Unable to load screenshots or annotations."),
860
  )
861
 
862
 
863
+ def update_fifth_dropdown(
864
  repo_id: str,
865
  top_level_dir: str,
866
  second_level_dir: str,
867
  third_level_dir: str,
868
  fourth_level_dir: str,
869
  ):
870
+ """Update the fifth dropdown and gallery when the fourth-level changes."""
871
  try:
872
+ if not all(
873
+ [top_level_dir, second_level_dir, third_level_dir, fourth_level_dir]
874
+ ):
875
+ empty_fifth = _dropdown_update(
876
+ choices=[],
877
+ value=None,
878
+ label="Fifth-level folders",
879
+ filled_info="Choose a fifth-level folder",
880
+ empty_info="Select higher-level folders first",
881
+ )
882
+ instruction_update = gr.update(
883
+ value="ℹ️ Select higher-level folders to display the instruction."
884
+ )
885
+ gallery_update = gr.update(value=[])
886
  annotation_update = gr.update(
887
+ value="Select higher-level folders to load screenshots and annotations."
888
  )
889
+ return empty_fifth, instruction_update, gallery_update, annotation_update
890
 
891
+ fifth_dirs = _get_subdirectories(
892
+ repo_id,
893
+ _build_path(
894
+ top_level_dir,
895
+ second_level_dir,
896
+ third_level_dir,
897
+ fourth_level_dir,
898
+ ),
899
+ )
900
+ fifth_value = fifth_dirs[0] if fifth_dirs else None
901
+
902
+ target_directory = (
903
+ _build_path(
904
+ top_level_dir,
905
+ second_level_dir,
906
+ third_level_dir,
907
+ fourth_level_dir,
908
+ fifth_value,
909
+ )
910
+ if fifth_value
911
+ else None
912
+ )
913
+ (
914
+ gallery_items,
915
+ gallery_status,
916
+ instruction_markdown,
917
+ ) = _prepare_gallery_items(repo_id, target_directory)
918
+
919
+ return (
920
+ _dropdown_update(
921
+ choices=fifth_dirs,
922
+ value=fifth_value,
923
+ label="Fifth-level folders",
924
+ filled_info="Choose a fifth-level folder",
925
+ empty_info="No fifth-level folders under the selection",
926
+ ),
927
+ gr.update(value=instruction_markdown),
928
+ gr.update(value=gallery_items),
929
+ gr.update(value="\n".join(gallery_status)),
930
  )
 
 
931
  except Exception as error:
932
  print(
933
+ "[update_fifth_dropdown] Error for "
934
  f"{repo_id}/{top_level_dir}/{second_level_dir}/{third_level_dir}/{fourth_level_dir}: {error}",
935
  flush=True,
936
  )
937
  print(traceback.format_exc(), flush=True)
938
+ empty_fifth = _dropdown_update(
939
+ choices=[],
940
+ value=None,
941
+ label="Fifth-level folders",
942
+ filled_info="Choose a fifth-level folder",
943
+ empty_info="Unable to load subdirectories",
944
+ )
945
+ return (
946
+ empty_fifth,
947
+ gr.update(value="Unable to load instruction."),
948
+ gr.update(value=[]),
949
+ gr.update(value="Unable to load screenshots or annotations."),
950
+ )
951
+
952
+
953
+ def update_gallery(
954
+ repo_id: str,
955
+ top_level_dir: str,
956
+ second_level_dir: str,
957
+ third_level_dir: str,
958
+ fourth_level_dir: str,
959
+ fifth_level_dir: str,
960
+ ):
961
+ """Update the image gallery when the fifth-level selection changes."""
962
+ try:
963
+ directory = (
964
+ _build_path(
965
+ top_level_dir,
966
+ second_level_dir,
967
+ third_level_dir,
968
+ fourth_level_dir,
969
+ fifth_level_dir,
970
+ )
971
+ if all(
972
+ [
973
+ top_level_dir,
974
+ second_level_dir,
975
+ third_level_dir,
976
+ fourth_level_dir,
977
+ fifth_level_dir,
978
+ ]
979
+ )
980
+ else None
981
+ )
982
+ (
983
+ gallery_items,
984
+ gallery_status,
985
+ instruction_markdown,
986
+ ) = _prepare_gallery_items(repo_id, directory)
987
+ return (
988
+ gr.update(value=instruction_markdown),
989
+ gr.update(value=gallery_items),
990
+ gr.update(value="\n".join(gallery_status)),
991
+ )
992
+ except Exception as error:
993
+ print(
994
+ "[update_gallery] Error for "
995
+ f"{repo_id}/{top_level_dir}/{second_level_dir}/{third_level_dir}/{fourth_level_dir}/{fifth_level_dir}: {error}",
996
+ flush=True,
997
+ )
998
+ print(traceback.format_exc(), flush=True)
999
+ return (
1000
+ gr.update(value="Unable to load instruction."),
1001
+ gr.update(value=[]),
1002
+ gr.update(value="Unable to load screenshots or annotations."),
1003
+ )
1004
 
1005
 
1006
  with gr.Blocks(title="HF Dataset Explorer") as demo:
 
1024
  second_level_dropdown = gr.Dropdown(label="Second-level folders", interactive=False)
1025
  third_level_dropdown = gr.Dropdown(label="Third-level folders", interactive=False)
1026
  fourth_level_dropdown = gr.Dropdown(label="Fourth-level folders", interactive=False)
1027
+ fifth_level_dropdown = gr.Dropdown(label="Fifth-level folders", interactive=False)
1028
+ instruction_display = gr.Markdown()
1029
  image_gallery = gr.Gallery(label="Images", columns=4)
1030
  annotation_status = gr.Markdown()
1031
 
 
1037
  second_level_dropdown,
1038
  third_level_dropdown,
1039
  fourth_level_dropdown,
1040
+ fifth_level_dropdown,
1041
+ instruction_display,
1042
  image_gallery,
1043
  annotation_status,
1044
  status_display,
 
1052
  second_level_dropdown,
1053
  third_level_dropdown,
1054
  fourth_level_dropdown,
1055
+ fifth_level_dropdown,
1056
+ instruction_display,
1057
  image_gallery,
1058
  annotation_status,
1059
  ],
 
1065
  outputs=[
1066
  third_level_dropdown,
1067
  fourth_level_dropdown,
1068
+ fifth_level_dropdown,
1069
+ instruction_display,
1070
  image_gallery,
1071
  annotation_status,
1072
  ],
 
1082
  ],
1083
  outputs=[
1084
  fourth_level_dropdown,
1085
+ fifth_level_dropdown,
1086
+ instruction_display,
1087
  image_gallery,
1088
  annotation_status,
1089
  ],
1090
  )
1091
 
1092
  fourth_level_dropdown.change(
1093
+ update_fifth_dropdown,
1094
+ inputs=[
1095
+ repo_id_input,
1096
+ folder_dropdown,
1097
+ second_level_dropdown,
1098
+ third_level_dropdown,
1099
+ fourth_level_dropdown,
1100
+ ],
1101
+ outputs=[
1102
+ fifth_level_dropdown,
1103
+ instruction_display,
1104
+ image_gallery,
1105
+ annotation_status,
1106
+ ],
1107
+ )
1108
+
1109
+ fifth_level_dropdown.change(
1110
  update_gallery,
1111
  inputs=[
1112
  repo_id_input,
 
1114
  second_level_dropdown,
1115
  third_level_dropdown,
1116
  fourth_level_dropdown,
1117
+ fifth_level_dropdown,
1118
  ],
1119
+ outputs=[instruction_display, image_gallery, annotation_status],
1120
  )
1121
 
1122
  demo.load(
 
1127
  second_level_dropdown,
1128
  third_level_dropdown,
1129
  fourth_level_dropdown,
1130
+ fifth_level_dropdown,
1131
+ instruction_display,
1132
  image_gallery,
1133
  annotation_status,
1134
  status_display,