Repository navigation
Expand file tree
/
Copy pathmark_sc.py
More file actions
147 lines (122 loc) · 5.17 KB
/
Copy pathmark_sc.py
File metadata and controls
147 lines (122 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
from fastapi import FastAPI
import fitz
import re
import requests
import os
from dotenv import load_dotenv
load_dotenv()
SUPABASE_URL = os.getenv("SUPABASE_URL")
SUPABASE_KEY = os.getenv("SUPABASE_KEY")
MARK_SCHEME_BUCKET_NAME = os.getenv("MARK_SCHEME_BUCKET_NAME")
PAPER_DIR = "answers"
app = FastAPI()
# -------------------------------
# Upload to Supabase
# -------------------------------
def upload_to_supabase_storage(image_bytes, filename, bucket_name):
headers = {
"apikey": SUPABASE_KEY,
"Authorization": f"Bearer {SUPABASE_KEY}",
"Content-Type": "application/octet-stream"
}
upload_url = f"{SUPABASE_URL}/storage/v1/object/{bucket_name}/{filename}"
r = requests.put(upload_url, headers=headers, data=image_bytes)
if r.status_code != 200:
print(f"❌ Upload failed for {filename}: {r.text}")
return None
return f"{SUPABASE_URL}/storage/v1/object/public/{bucket_name}/{filename}"
# -------------------------------
# Update Supabase DB
# -------------------------------
def update_question_with_mark_scheme(metadata):
headers = {
"apikey": SUPABASE_KEY,
"Authorization": f"Bearer {SUPABASE_KEY}",
"Content-Type": "application/json",
"Prefer": "return=representation"
}
query = "&".join([
f"question_number=eq.{metadata['question_number']}",
f"paper_code=eq.{metadata['paper_code']}",
f"paper_year=eq.{metadata['paper_year']}",
f"session=eq.{metadata['session']}",
f"component=eq.{metadata['component']}"
])
url = f"{SUPABASE_URL}/rest/v1/alevel_math_questions?{query}"
r = requests.patch(url, headers=headers, json={"answer_img": metadata["answer_img"]})
if r.status_code in [200, 204]:
print(f"✅ Updated mark scheme for Q{metadata['question_number']}")
else:
print(f"❌ Failed to update DB for Q{metadata['question_number']}: {r.text}")
# -------------------------------
# Process PDF
# -------------------------------
@app.get("/upload-mark-scheme")
def upload_mark_scheme_pdf():
filename = "9709_S24_ms_32.pdf" # example
filepath = os.path.join(PAPER_DIR, filename)
doc = fitz.open(filepath)
print(f"\n📄 Processing: {filename} | Total pages: {doc.page_count}")
# Parse filename metadata
match = re.match(r"9709_([msw])(\d\d)_ms_(\d)(\d)\.pdf", filename, re.IGNORECASE)
if not match:
print(f"❌ Bad filename format: {filename}")
return {"message": "Bad filename format"}
session_code, year_suffix, component_code, paper_code = match.groups()
session = {"m": "Feb/March", "s": "May/June", "w": "Oct/Nov"}.get(session_code.lower(), "Unknown")
year = f"20{year_suffix}"
component = {
"1": "Pure 1",
"2": "Pure 2",
"3": "Pure 3",
"4": "Mechanics",
"5": "Stats 1",
"6": "Stats 2"
}.get(component_code, "Unknown")
# Track questions
question_map = {}
current_question = None
# -------------------------------
# Iterate over pages
# -------------------------------
for page_num in range(5, doc.page_count): # start from page 5
page = doc.load_page(page_num)
text = page.get_text("text")
# Simplified regex to find a question number at the beginning of the text
# This reliably detects both "Question 1" and just "1" at the start of a page
question_match = re.search(r"^\s*Question\s*(\d{1,2})|\b(\d{1,2})\s*\(?[a-zA-Z]\)?", text, re.IGNORECASE)
if question_match:
# Use the most specific match group
if question_match.group(1):
current_question = question_match.group(1)
else:
current_question = question_match.group(2)
# -------------------------------
# Build filename
# -------------------------------
# The filename now relies on the page number to ensure uniqueness
if current_question:
filename_img = f"MS_{component}_{session}_{year}_{paper_code}_{current_question}_page{page_num+1}.png"
# -------------------------------
# Save & upload
# -------------------------------
pix = page.get_pixmap(dpi=150)
img_bytes = pix.tobytes("png")
public_url = upload_to_supabase_storage(img_bytes, filename_img, MARK_SCHEME_BUCKET_NAME)
if public_url:
question_map.setdefault(current_question, []).append(public_url)
print(f"📄 Page {page_num+1} → {filename_img}")
# -------------------------------
# Push to Supabase
# -------------------------------
for q_num, img_links in question_map.items():
metadata = {
"question_number": q_num,
"paper_code": paper_code,
"paper_year": year,
"session": session,
"component": component,
"answer_img": img_links
}
update_question_with_mark_scheme(metadata)
return {"message": "✅ Mark scheme processed successfully"}