summaryrefslogtreecommitdiff
path: root/highlight.py
diff options
context:
space:
mode:
Diffstat (limited to 'highlight.py')
-rw-r--r--highlight.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/highlight.py b/highlight.py
new file mode 100644
index 0000000..361a0d2
--- /dev/null
+++ b/highlight.py
@@ -0,0 +1,118 @@
1import sys
2import json
3import re
4from datetime import timedelta
5
6# ANSI escape codes for terminal colors
7class Colors:
8 GREEN = '\033[92m' # Highlight for valid ad text
9 RED = '\033[91m' # Highlight for invalid target ranges
10 BLUE = '\033[94m' # Header color
11 RESET = '\033[0m' # Reset to default color
12
13def timestamp_to_seconds(ts_str: str) -> float:
14 """Converts HH:MM:SS.mmm string to total seconds. Returns -1.0 on failure."""
15 try:
16 parts = ts_str.split(':')
17 h, m = int(parts[0]), int(parts[1])
18 s_ms = parts[2].split('.')
19 s, ms = int(s_ms[0]), int(s_ms[1])
20 return h * 3600 + m * 60 + s + ms / 1000.0
21 except (ValueError, IndexError):
22 return -1.0
23
24def visualize_entry(entry: dict):
25 """Parses and prints a single entry from the jsonl file with highlighting."""
26 entry_id = entry.get("id", "N/A")
27 full_text = entry.get("text", "")
28 target_str = entry.get("target", "")
29
30 print(f"{Colors.BLUE}{'='*80}\nID: {entry_id}{Colors.RESET}")
31
32 # --- 1. Parse the transcript from the 'text' field ---
33 transcript_lines = []
34 # Regex to find the start of the actual transcript text
35 transcript_match = re.search(r"Transcript:\n(.*)", full_text, re.DOTALL)
36 if not transcript_match:
37 print(f"{Colors.RED}Could not find transcript text in entry.{Colors.RESET}")
38 return
39
40 raw_transcript = transcript_match.group(1).strip()
41 line_pattern = re.compile(r"\[(\d{2}:\d{2}:\d{2}\.\d{3}) --> (\d{2}:\d{2}:\d{2}\.\d{3})\](.*)")
42
43 min_transcript_time, max_transcript_time = float('inf'), float('-inf')
44
45 for line in raw_transcript.split('\n'):
46 match = line_pattern.match(line)
47 if match:
48 start_str, end_str, text = match.groups()
49 start_sec = timestamp_to_seconds(start_str)
50 end_sec = timestamp_to_seconds(end_str)
51 transcript_lines.append({"start": start_sec, "end": end_sec, "line": line})
52 min_transcript_time = min(min_transcript_time, start_sec)
53 max_transcript_time = max(max_transcript_time, end_sec)
54
55 # --- 2. Parse and validate the target ranges ---
56 valid_target_ranges = []
57 has_invalid_target = False
58
59 if target_str:
60 for target_line in target_str.strip().split('\n'):
61 if '-' not in target_line:
62 has_invalid_target = True
63 continue
64
65 start_target_str, end_target_str = target_line.split('-', 1)
66 start_target_sec = timestamp_to_seconds(start_target_str.strip())
67 end_target_sec = timestamp_to_seconds(end_target_str.strip())
68
69 # Validation checks
70 is_valid_format = start_target_sec != -1.0 and end_target_sec != -1.0
71 is_valid_range = is_valid_format and start_target_sec < end_target_sec
72 # Check if the target overlaps with the transcript's time frame at all
73 is_overlapping = is_valid_range and start_target_sec < max_transcript_time and end_target_sec > min_transcript_time
74
75 if is_overlapping:
76 valid_target_ranges.append({"start": start_target_sec, "end": end_target_sec})
77 else:
78 has_invalid_target = True
79
80 # --- 3. Print results with highlighting ---
81 print(f"TARGET: ", end="")
82 if has_invalid_target:
83 print(f"{Colors.RED}{target_str or 'EMPTY'}{Colors.RESET}")
84 else:
85 print(f"{Colors.GREEN}{target_str or 'EMPTY'}{Colors.RESET}")
86 print("-" * 30)
87
88 for line_info in transcript_lines:
89 is_ad_line = False
90 for target_range in valid_target_ranges:
91 # Check for overlap between the line's time and the target's time
92 if line_info['start'] < target_range['end'] and line_info['end'] > target_range['start']:
93 is_ad_line = True
94 break
95
96 if is_ad_line:
97 print(f"{Colors.GREEN}{line_info['line']}{Colors.RESET}")
98 else:
99 print(line_info['line'])
100
101def main(filepath: str):
102 try:
103 with open(filepath, 'r', encoding='utf-8') as f:
104 for line in f:
105 try:
106 entry = json.loads(line)
107 visualize_entry(entry)
108 except json.JSONDecodeError:
109 print(f"{Colors.RED}Error: Could not decode JSON line: {line.strip()}{Colors.RESET}")
110 except FileNotFoundError:
111 print(f"{Colors.RED}Error: File not found at {filepath}{Colors.RESET}")
112
113if __name__ == "__main__":
114 if len(sys.argv) < 2:
115 print("Usage: python highlight.py <path_to_labels.jsonl>")
116 sys.exit(1)
117
118 main(sys.argv[1])