summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--highlight.py4
-rw-r--r--review.py121
2 files changed, 124 insertions, 1 deletions
diff --git a/highlight.py b/highlight.py
index 361a0d2..ffcdd2c 100644
--- a/highlight.py
+++ b/highlight.py
@@ -1,6 +1,7 @@
1import sys 1import sys
2import json 2import json
3import re 3import re
4import pathlib
4from datetime import timedelta 5from datetime import timedelta
5 6
6# ANSI escape codes for terminal colors 7# ANSI escape codes for terminal colors
@@ -100,7 +101,8 @@ def visualize_entry(entry: dict):
100 101
101def main(filepath: str): 102def main(filepath: str):
102 try: 103 try:
103 with open(filepath, 'r', encoding='utf-8') as f: 104 p = pathlib.Path(filepath)
105 with p.open('r', encoding='utf-8') as f:
104 for line in f: 106 for line in f:
105 try: 107 try:
106 entry = json.loads(line) 108 entry = json.loads(line)
diff --git a/review.py b/review.py
new file mode 100644
index 0000000..3c34eac
--- /dev/null
+++ b/review.py
@@ -0,0 +1,121 @@
1import sys
2import os
3import json
4import subprocess
5import re
6from datetime import timedelta
7
8# --- Configuration ---
9HIGHLIGHT_SCRIPT_NAME = "highlight.py"
10GOOD_DATASET_FILE = "dataset.jsonl"
11BAD_FILES_LOG = "errors.txt"
12PROGRESS_FILE = ".curation_progress.log"
13
14# --- Unbuffered Input (Cross-Platform) ---
15try:
16 # Unix-like systems (Linux, macOS)
17 import tty, termios
18 def getch():
19 fd = sys.stdin.fileno()
20 old_settings = termios.tcgetattr(fd)
21 try:
22 tty.setraw(sys.stdin.fileno())
23 ch = sys.stdin.read(1)
24 finally:
25 termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
26 return ch
27except ImportError:
28 # Windows
29 import msvcrt
30 def getch():
31 return msvcrt.getch().decode()
32
33# --- Main Curation Logic ---
34
35def review_files(file_paths: list[str]):
36 """
37 Iterates through files, displays them for review, and sorts them based on user input.
38 """
39 if not os.path.exists(HIGHLIGHT_SCRIPT_NAME):
40 print(f"Error: The visualization script '{HIGHLIGHT_SCRIPT_NAME}' was not found in this directory.")
41 sys.exit(1)
42
43 # Load the set of already processed files
44 processed_files = set()
45 if os.path.exists(PROGRESS_FILE):
46 with open(PROGRESS_FILE, 'r', encoding='utf-8') as f:
47 processed_files = {line.strip() for line in f}
48
49 total_files = len(file_paths)
50 for i, filepath in enumerate(file_paths):
51 if filepath in processed_files:
52 print(f"Skipping already processed file: {filepath}")
53 continue
54
55 print("-" * 80)
56 print(f"Reviewing file ({i + 1}/{total_files}): {filepath}")
57
58 # 1. Run highlight.py and pipe its output to the user's pager
59 try:
60 pager_cmd = os.environ.get("PAGER", "less").split()
61 highlight_process = subprocess.Popen(
62 ["python", HIGHLIGHT_SCRIPT_NAME, filepath],
63 stdout=subprocess.PIPE,
64 text=True,
65 encoding='utf-8'
66 )
67 pager_process = subprocess.Popen(pager_cmd, stdin=highlight_process.stdout)
68 highlight_process.stdout.close()
69 return_code = pager_process.wait()
70 if return_code != 0:
71 print(f"Warning: Pager exited with code {return_code}.")
72 except FileNotFoundError:
73 print(f"Error: Pager command not found. Is '{os.environ.get('PAGER', 'less')}' installed?")
74 continue
75 except Exception as e:
76 print(f"An error occurred while running the subprocess: {e}")
77 continue
78
79 # 2. Prompt for user decision
80 while True:
81 print("\nWas this file's labeling correct? (y/n): ", end="", flush=True)
82 choice = getch().lower()
83 print(choice)
84
85 if choice == 'y':
86 print(f" -> Appending {filepath} to {GOOD_DATASET_FILE}")
87 try:
88 with open(filepath, 'r', encoding='utf-8') as infile, \
89 open(GOOD_DATASET_FILE, 'a', encoding='utf-8') as outfile:
90 for line in infile:
91 outfile.write(line)
92 except Exception as e:
93 print(f"Error appending to dataset file: {e}")
94 break
95 elif choice == 'n':
96 print(f" -> Logging {filepath} to {BAD_FILES_LOG}")
97 try:
98 with open(BAD_FILES_LOG, 'a', encoding='utf-8') as errfile:
99 errfile.write(filepath + '\n')
100 except Exception as e:
101 print(f"Error writing to log file: {e}")
102 break
103 elif choice in ['\x03', 'q']: # Handle Ctrl+C or 'q' to quit
104 print("\nExiting review process.")
105 sys.exit(0)
106 else:
107 print("Invalid input. Please press 'y' for yes or 'n' for no.")
108
109 # Log the file as processed after a decision has been made
110 with open(PROGRESS_FILE, 'a', encoding='utf-8') as f:
111 f.write(filepath + '\n')
112
113if __name__ == "__main__":
114 if len(sys.argv) < 2:
115 print("Usage: python curate_dataset.py <file1.jsonl> <file2.jsonl> ...")
116 print("Or: python curate_dataset.py /path/to/*/*.jsonl")
117 sys.exit(1)
118
119 review_files(sys.argv[1:])
120 print("-" * 80)
121 print("Curation complete.") \ No newline at end of file