fix(dashboard): DPP tags properly dynamic based on user target exam

This commit is contained in:
2026-07-08 12:46:44 +05:30
parent c87b305646
commit 1a6168f724
28 changed files with 853 additions and 304 deletions

116
backend/fix_from_source.py Normal file
View File

@@ -0,0 +1,116 @@
import sys
sys.path.append('/app')
from sqlmodel import Session, select
from database import engine
import models
import glob
import os
import fitz
import re
def parse_pdf(filepath):
doc = fitz.open(filepath)
text = ""
for page in doc:
text += page.get_text() + "\n"
q_block = text.split("Questions\n")[-1].split("Answer Key\n")[0]
q_pattern = re.compile(r'^(\d+)\.\s+(.*?)(?=^\d+\.\s+|\Z)', re.DOTALL | re.MULTILINE)
questions_dict = {}
for match in q_pattern.finditer(q_block):
q_num = int(match.group(1))
if 1 <= q_num <= 15:
questions_dict[q_num] = match.group(2).strip()
answers_dict = {}
if "Answer Key\n" in text:
a_block = text.split("Answer Key\n")[-1]
a_pattern = re.compile(r'^(\d+)\s+(.*?)(?=^\d+\s+|\Z)', re.DOTALL | re.MULTILINE)
for match in a_pattern.finditer(a_block):
q_num = int(match.group(1))
if 1 <= q_num <= 15:
if q_num not in answers_dict:
answers_dict[q_num] = match.group(2).strip()
return questions_dict, answers_dict
def format_text(text):
if not text: return text
# Original targets
text = re.sub(r'\bsp3d2\b', r'$sp^3d^2$', text)
text = re.sub(r'\bsp3d\b', r'$sp^3d$', text)
text = re.sub(r'\bsp3\b', r'$sp^3$', text)
text = re.sub(r'\bsp2\b', r'$sp^2$', text)
def repl(m):
word = m.group(0)
if word.lower() in ["sp2", "sp3", "sp3d", "sp3d2", "3d", "a1", "b1", "c1"]:
return word
return '$' + re.sub(r'(\d+)', r'_\1', word) + '$'
text = re.sub(r'\b[A-Z][a-z]*[A-Z]*[a-z]*\d+[A-Za-z0-9]*\b', repl, text)
text = text.replace('z1 = 1 + i', '$z_1 = 1 + i$')
text = text.replace('z2 = 2 − i', '$z_2 = 2 - i$')
text = text.replace('z1\nz2', '$\\frac{z_1}{z_2}$')
text = text.replace('z−1\nz+1', '$\\frac{z-1}{z+1}$')
text = text.replace('z2 = ¯z', '$z^2 = \\bar{z}$')
text = text.replace('x2 − 3x + 5 = 0', '$x^2 - 3x + 5 = 0$')
text = text.replace('x2 + 2x + 5 = 0', '$x^2 + 2x + 5 = 0$')
text = text.replace('1+i\n1−i', '$\\frac{1+i}{1-i}$')
text = text.replace('z + 1\nz', '$\\frac{z+1}{z}$')
text = text.replace('z − 1\nz i', '$\\frac{z-1}{z i}$')
text = text.replace('30◦', '30°')
text = text.replace('⃗v = 3', '$\\vec{v} = 3$')
text = text.replace('σ bonds', '$\\sigma$ bonds')
text = text.replace('π bonds', '$\\pi$ bonds')
return text
def fix_all_from_source():
pdf_files = glob.glob('/app/pdfs_to_parse/*.pdf')
with Session(engine) as session:
for pdf_path in pdf_files:
filename = os.path.basename(pdf_path)
subject = "Physics"
topic = "General"
if "phy" in filename.lower():
subject = "Physics"
topic = "Laws of Motion"
elif "che" in filename.lower():
subject = "Chemistry"
topic = "Chemical Bonding"
elif "mth" in filename.lower():
subject = "Mathematics"
topic = "Calculus"
elif "bio" in filename.lower():
subject = "Biology"
topic = "Genetics"
q_dict, a_dict = parse_pdf(pdf_path)
# Find the test for this topic
test = session.exec(select(models.Test).where(models.Test.title == f"DPP: {subject} - {topic}")).first()
if not test:
continue
q_ids = test.sections.get("Section 1", {}).get("questions", [])
for i, q_id in enumerate(q_ids):
q_num = i + 1
if q_num in q_dict:
raw_text = q_dict[q_num].replace('\x00', '')
formatted = format_text(raw_text)
q = session.exec(select(models.Question).where(models.Question.id == q_id)).first()
if q:
q.question_text = formatted
session.add(q)
session.commit()
print("Successfully updated questions from source.")
if __name__ == "__main__":
fix_all_from_source()