|
1
|
"""Standardized output directory structure and manifest I/O for PlanOpticon.""" |
|
2
|
|
|
3
|
import logging |
|
4
|
from pathlib import Path |
|
5
|
from typing import Dict |
|
6
|
|
|
7
|
from video_processor.models import BatchManifest, VideoManifest |
|
8
|
|
|
9
|
logger = logging.getLogger(__name__) |
|
10
|
|
|
11
|
|
|
12
|
def create_video_output_dirs(output_dir: str | Path, video_name: str) -> Dict[str, Path]: |
|
13
|
""" |
|
14
|
Create standardized single-video output directory structure. |
|
15
|
|
|
16
|
Layout: |
|
17
|
output_dir/ |
|
18
|
manifest.json |
|
19
|
transcript/ |
|
20
|
transcript.json, .txt, .srt |
|
21
|
frames/ |
|
22
|
frame_0000.jpg ... |
|
23
|
diagrams/ |
|
24
|
diagram_0.json, .jpg, .mermaid, .svg, .png |
|
25
|
captures/ |
|
26
|
capture_0.jpg, capture_0.json |
|
27
|
results/ |
|
28
|
analysis.md, .html, .pdf |
|
29
|
knowledge_graph.db (primary, SQLite) |
|
30
|
knowledge_graph.json (export copy) |
|
31
|
key_points.json |
|
32
|
action_items.json |
|
33
|
cache/ |
|
34
|
|
|
35
|
Returns dict mapping directory names to Path objects. |
|
36
|
""" |
|
37
|
base = Path(output_dir) |
|
38
|
dirs = { |
|
39
|
"root": base, |
|
40
|
"transcript": base / "transcript", |
|
41
|
"frames": base / "frames", |
|
42
|
"diagrams": base / "diagrams", |
|
43
|
"captures": base / "captures", |
|
44
|
"results": base / "results", |
|
45
|
"cache": base / "cache", |
|
46
|
} |
|
47
|
for d in dirs.values(): |
|
48
|
d.mkdir(parents=True, exist_ok=True) |
|
49
|
logger.info(f"Created output structure for '{video_name}' at {base}") |
|
50
|
return dirs |
|
51
|
|
|
52
|
|
|
53
|
def create_batch_output_dirs(output_dir: str | Path, batch_name: str) -> Dict[str, Path]: |
|
54
|
""" |
|
55
|
Create standardized batch output directory structure. |
|
56
|
|
|
57
|
Layout: |
|
58
|
output_dir/ |
|
59
|
manifest.json |
|
60
|
batch_summary.md |
|
61
|
knowledge_graph.db (primary, SQLite) |
|
62
|
knowledge_graph.json (export copy) (when falkordblite installed) |
|
63
|
videos/ |
|
64
|
video_1/manifest.json |
|
65
|
video_2/manifest.json |
|
66
|
... |
|
67
|
|
|
68
|
Returns dict mapping directory names to Path objects. |
|
69
|
""" |
|
70
|
base = Path(output_dir) |
|
71
|
dirs = { |
|
72
|
"root": base, |
|
73
|
"videos": base / "videos", |
|
74
|
} |
|
75
|
for d in dirs.values(): |
|
76
|
d.mkdir(parents=True, exist_ok=True) |
|
77
|
logger.info(f"Created batch output structure for '{batch_name}' at {base}") |
|
78
|
return dirs |
|
79
|
|
|
80
|
|
|
81
|
# --- Manifest I/O --- |
|
82
|
|
|
83
|
|
|
84
|
def write_video_manifest(manifest: VideoManifest, output_dir: str | Path) -> Path: |
|
85
|
"""Write a VideoManifest to output_dir/manifest.json.""" |
|
86
|
path = Path(output_dir) / "manifest.json" |
|
87
|
path.parent.mkdir(parents=True, exist_ok=True) |
|
88
|
path.write_text(manifest.model_dump_json(indent=2)) |
|
89
|
logger.info(f"Wrote video manifest to {path}") |
|
90
|
return path |
|
91
|
|
|
92
|
|
|
93
|
def read_video_manifest(output_dir: str | Path) -> VideoManifest: |
|
94
|
"""Read a VideoManifest from output_dir/manifest.json.""" |
|
95
|
path = Path(output_dir) / "manifest.json" |
|
96
|
return VideoManifest.model_validate_json(path.read_text()) |
|
97
|
|
|
98
|
|
|
99
|
def write_batch_manifest(manifest: BatchManifest, output_dir: str | Path) -> Path: |
|
100
|
"""Write a BatchManifest to output_dir/manifest.json.""" |
|
101
|
path = Path(output_dir) / "manifest.json" |
|
102
|
path.parent.mkdir(parents=True, exist_ok=True) |
|
103
|
path.write_text(manifest.model_dump_json(indent=2)) |
|
104
|
logger.info(f"Wrote batch manifest to {path}") |
|
105
|
return path |
|
106
|
|
|
107
|
|
|
108
|
def read_batch_manifest(output_dir: str | Path) -> BatchManifest: |
|
109
|
"""Read a BatchManifest from output_dir/manifest.json.""" |
|
110
|
path = Path(output_dir) / "manifest.json" |
|
111
|
return BatchManifest.model_validate_json(path.read_text()) |
|
112
|
|