Render a live progress display of in-flight scenes until stop_event is set. Counts entries marked "done" toward overall completion; everything else is shown as an in-progress task with a spinner and elapsed time.
(
status_dict, total: int, stop_event: threading.Event
)
| 213 | |
| 214 | |
| 215 | def _run_progress_monitor( |
| 216 | status_dict, total: int, stop_event: threading.Event |
| 217 | ) -> None: |
| 218 | """Render a live progress display of in-flight scenes until stop_event is |
| 219 | set. Counts entries marked "done" toward overall completion; everything |
| 220 | else is shown as an in-progress task with a spinner and elapsed time.""" |
| 221 | from rich.console import Group |
| 222 | from rich.live import Live |
| 223 | from rich.progress import ( |
| 224 | BarColumn, |
| 225 | MofNCompleteColumn, |
| 226 | Progress, |
| 227 | SpinnerColumn, |
| 228 | TextColumn, |
| 229 | TimeElapsedColumn, |
| 230 | ) |
| 231 | |
| 232 | overall = Progress( |
| 233 | TextColumn("[bold]Scenes[/bold]"), |
| 234 | BarColumn(), |
| 235 | MofNCompleteColumn(), |
| 236 | TimeElapsedColumn(), |
| 237 | ) |
| 238 | scenes = Progress( |
| 239 | SpinnerColumn(), |
| 240 | TextColumn("{task.description}"), |
| 241 | TextColumn("[cyan]{task.fields[phase]:>14}[/cyan]"), |
| 242 | TimeElapsedColumn(), |
| 243 | ) |
| 244 | overall_task = overall.add_task("scenes", total=total) |
| 245 | scene_tasks: dict[str, int] = {} |
| 246 | |
| 247 | def refresh() -> None: |
| 248 | snapshot = dict(status_dict) |
| 249 | done = sum(1 for v in snapshot.values() if v == "finished") |
| 250 | overall.update(overall_task, completed=done) |
| 251 | in_progress = {k: v for k, v in snapshot.items() if v != "finished"} |
| 252 | for key in list(scene_tasks): |
| 253 | if key not in in_progress: |
| 254 | scenes.remove_task(scene_tasks.pop(key)) |
| 255 | for key, phase in in_progress.items(): |
| 256 | if key in scene_tasks: |
| 257 | scenes.update(scene_tasks[key], phase=phase) |
| 258 | else: |
| 259 | scene_tasks[key] = scenes.add_task(key, total=None, phase=phase) |
| 260 | |
| 261 | with Live(Group(overall, scenes), refresh_per_second=4): |
| 262 | while not stop_event.is_set(): |
| 263 | refresh() |
| 264 | stop_event.wait(0.5) |
| 265 | refresh() |
| 266 | |
| 267 | |
| 268 | def filter_smallest_scenes_per_category( |