Miscs
This commit is contained in:
+90
-23
@@ -1,4 +1,6 @@
|
||||
import shlex
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
@@ -7,7 +9,9 @@ from typing import List
|
||||
from google import genai
|
||||
from google.genai import types
|
||||
|
||||
MODEL_ID = "gemini-3-flash-preview"
|
||||
# Bug : l'output est limité à 8k token…
|
||||
# MODEL_ID = "gemini-3-flash-preview"
|
||||
MODEL_ID = "gemini-3.1-flash-lite"
|
||||
api_key = os.environ.get("GEMINI_API_KEY")
|
||||
|
||||
class QuestionItem(BaseModel):
|
||||
@@ -84,14 +88,25 @@ def process_exam(folder_path: str):
|
||||
response_json_schema=ExamExtraction.model_json_schema(),
|
||||
)
|
||||
|
||||
print("Sending request to Gemini...")
|
||||
response = client.models.generate_content(
|
||||
model=MODEL_ID,
|
||||
contents=contents,
|
||||
config=config
|
||||
)
|
||||
cache_file = folder / "gemini_response.json"
|
||||
|
||||
extracted_data = ExamExtraction.model_validate_json(response.text)
|
||||
if cache_file.is_file():
|
||||
print("Loading cached response from gemini_response.json...")
|
||||
response_text = cache_file.read_text(encoding="utf-8")
|
||||
else:
|
||||
print("Sending request to Gemini...")
|
||||
response = client.models.generate_content(
|
||||
model=MODEL_ID,
|
||||
contents=contents,
|
||||
config=config
|
||||
)
|
||||
response_text = response.text
|
||||
|
||||
print("Saving response to cache...")
|
||||
cache_file.write_text(response_text, encoding="utf-8")
|
||||
|
||||
# Validate from the text variable (cached or fresh)
|
||||
extracted_data = ExamExtraction.model_validate_json(response_text)
|
||||
|
||||
# 2. Setup output directories
|
||||
text_dir = folder / "Text"
|
||||
@@ -101,28 +116,80 @@ def process_exam(folder_path: str):
|
||||
|
||||
labels_file = folder / "labels"
|
||||
|
||||
print("Writing files...")
|
||||
# Step 1: Write initial labels
|
||||
print("Writing initial labels file...")
|
||||
with open(labels_file, "w", encoding="utf-8") as flabels:
|
||||
for q in extracted_data.questions:
|
||||
# Sanitize label for filesystem (prevent directory traversal if label contains '/')
|
||||
safe_label = q.label.replace("/", "_")
|
||||
flabels.write(f"{q.label}\n")
|
||||
|
||||
flabels.write(f"{safe_label}\n")
|
||||
# Step 2: Open labels file for user editing
|
||||
print("Opening labels file for editing...")
|
||||
editor = os.environ.get("EDITOR")
|
||||
try:
|
||||
if editor:
|
||||
subprocess.run(shlex.split(editor) + [str(labels_file)])
|
||||
else:
|
||||
# Fallbacks if $EDITOR is not set
|
||||
if sys.platform.startswith("linux"):
|
||||
subprocess.Popen(["xdg-open", str(labels_file)])
|
||||
elif sys.platform == "darwin":
|
||||
subprocess.Popen(["open", str(labels_file)])
|
||||
else:
|
||||
os.startfile(str(labels_file))
|
||||
|
||||
# Fix double-escaped newlines
|
||||
q_content = q.question_content.replace("\\n", "\n")
|
||||
s_content = q.solution_content.replace("\\n", "\n")
|
||||
|
||||
# xdg-open/open usually do not block, so we wait for user confirmation
|
||||
input("Press ENTER here once you have saved and closed the labels file...")
|
||||
except Exception:
|
||||
print("Error running editor, using labels as given.")
|
||||
|
||||
# Write Text/label
|
||||
with open(text_dir / safe_label, "w", encoding="utf-8") as f:
|
||||
f.write(f"{q.label}\n{q.question_content}")
|
||||
# Step 3 & 4: Read the edited file back and create a mapping
|
||||
with open(labels_file, "r", encoding="utf-8") as flabels:
|
||||
edited_lines = [line.strip() for line in flabels if line.strip()]
|
||||
|
||||
# Write Sol/label
|
||||
with open(sol_dir / safe_label, "w", encoding="utf-8") as f:
|
||||
f.write(f"{q.label}\n{q.solution_content}")
|
||||
mapping = []
|
||||
final_labels = []
|
||||
orig_idx = 0
|
||||
|
||||
print(f"Success! Processed {len(extracted_data.questions)} questions.")
|
||||
for line in edited_lines:
|
||||
if line.startswith("+"):
|
||||
new_label = line[1:].lstrip()
|
||||
final_labels.append(new_label)
|
||||
# New label, no source content
|
||||
mapping.append((new_label, None))
|
||||
else:
|
||||
new_label = line
|
||||
final_labels.append(new_label)
|
||||
# Map to initial order, advancing index only for non-'+' items
|
||||
q_item = extracted_data.questions[orig_idx] if orig_idx < len(extracted_data.questions) else None
|
||||
mapping.append((new_label, q_item))
|
||||
orig_idx += 1
|
||||
|
||||
# Rewrite the labels file cleanly (removing '+' prefixes)
|
||||
with open(labels_file, "w", encoding="utf-8") as flabels:
|
||||
for lbl in final_labels:
|
||||
flabels.write(f"{lbl}\n")
|
||||
|
||||
# Step 5: Write the final question and solution files
|
||||
print("Writing question and solution files...")
|
||||
for new_label, q_item in mapping:
|
||||
safe_label = new_label.replace("/", "_")
|
||||
|
||||
if q_item:
|
||||
q_content = q_item.question_content.replace("\\n", "\n")
|
||||
s_content = q_item.solution_content.replace("\\n", "\n")
|
||||
else:
|
||||
q_content = ""
|
||||
s_content = ""
|
||||
|
||||
# Write Text/label
|
||||
with open(text_dir / safe_label, "w", encoding="utf-8") as f:
|
||||
f.write(f"{new_label}\n{q_content}")
|
||||
|
||||
# Write Sol/label
|
||||
with open(sol_dir / safe_label, "w", encoding="utf-8") as f:
|
||||
f.write(f"{new_label}\n{s_content}")
|
||||
|
||||
print(f"Success! Processed {len(mapping)} labels.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
if not api_key:
|
||||
|
||||
Reference in New Issue
Block a user