Commit
·
a3d1bae
1
Parent(s):
8a0e8d8
solving some error and try to print it in front end
Browse files- main.py +17 -3
- templates/index.html +49 -3
main.py
CHANGED
@@ -368,10 +368,14 @@ def notifications():
|
|
368 |
@app.route('/compute_marks', methods=['POST'])
|
369 |
def compute_marks():
|
370 |
try:
|
|
|
|
|
371 |
# Wait for initialization to complete
|
372 |
if not initialization_complete.is_set():
|
|
|
373 |
wait_for_initialization()
|
374 |
if not initialization_complete.is_set():
|
|
|
375 |
return jsonify({
|
376 |
"error": "Server initialization",
|
377 |
"message": "Server is still initializing. Please try again in a moment."
|
@@ -379,6 +383,7 @@ def compute_marks():
|
|
379 |
|
380 |
# Check content type
|
381 |
if not request.is_json and not request.form:
|
|
|
382 |
return jsonify({
|
383 |
"error": "Invalid request format",
|
384 |
"message": "Request must be either JSON or form data"
|
@@ -387,15 +392,17 @@ def compute_marks():
|
|
387 |
# Get correct answers
|
388 |
correct_answers = request.form.getlist('correct_answers[]')
|
389 |
if not correct_answers:
|
|
|
390 |
return jsonify({
|
391 |
"error": "Missing data",
|
392 |
"message": "No correct answers provided"
|
393 |
}), 400
|
394 |
|
395 |
-
log_print(f"Received correct answers
|
396 |
|
397 |
# Create TFIDF values for correct answers
|
398 |
try:
|
|
|
399 |
max_tfidf = create_tfidf_values(correct_answers)
|
400 |
log_print("Created TFIDF values successfully")
|
401 |
except Exception as e:
|
@@ -408,6 +415,7 @@ def compute_marks():
|
|
408 |
# Get all uploaded files
|
409 |
files = request.files.getlist('file')
|
410 |
if not files:
|
|
|
411 |
return jsonify({
|
412 |
"error": "Missing data",
|
413 |
"message": "No files uploaded"
|
@@ -422,6 +430,7 @@ def compute_marks():
|
|
422 |
|
423 |
max_size = 15 * 1024 * 1024 # 15MB
|
424 |
if total_size > max_size:
|
|
|
425 |
return jsonify({
|
426 |
"error": "File size limit exceeded",
|
427 |
"message": f"Total file size must be less than 15MB (current size: {total_size / 1024 / 1024:.1f}MB)"
|
@@ -457,6 +466,8 @@ def compute_marks():
|
|
457 |
processed_count = 0
|
458 |
total_files = len(files)
|
459 |
|
|
|
|
|
460 |
try:
|
461 |
# Process each file
|
462 |
for file in files:
|
@@ -507,6 +518,7 @@ def compute_marks():
|
|
507 |
log_print(f"Saved file to: {filepath}")
|
508 |
|
509 |
# Extract text
|
|
|
510 |
extracted_text = extract_text_from_image(filepath)
|
511 |
|
512 |
# Clean up the file immediately after processing
|
@@ -550,6 +562,7 @@ def compute_marks():
|
|
550 |
clean_correct_answer = correct_answer.encode('ascii', 'ignore').decode('ascii')
|
551 |
|
552 |
# Calculate similarity scores
|
|
|
553 |
semantic_score = question_vector_sentence(extracted_text, clean_correct_answer)
|
554 |
word_score = question_vector_word(extracted_text, clean_correct_answer)
|
555 |
tfidf_score = tfidf_answer_score(extracted_text, clean_correct_answer, max_tfidf)
|
@@ -592,6 +605,7 @@ def compute_marks():
|
|
592 |
"current_file": filename
|
593 |
}
|
594 |
notification_queue.put(progress_data)
|
|
|
595 |
|
596 |
except Exception as e:
|
597 |
error_msg = str(e).encode('ascii', 'ignore').decode('ascii')
|
@@ -650,10 +664,10 @@ def compute_marks():
|
|
650 |
}
|
651 |
}
|
652 |
|
653 |
-
log_print(
|
654 |
-
|
655 |
response = jsonify(response_data)
|
656 |
response.headers['Content-Type'] = 'application/json'
|
|
|
657 |
return response
|
658 |
|
659 |
except Exception as e:
|
|
|
368 |
@app.route('/compute_marks', methods=['POST'])
|
369 |
def compute_marks():
|
370 |
try:
|
371 |
+
log_print("\n=== Starting Compute Marks Process ===")
|
372 |
+
|
373 |
# Wait for initialization to complete
|
374 |
if not initialization_complete.is_set():
|
375 |
+
log_print("Waiting for initialization...")
|
376 |
wait_for_initialization()
|
377 |
if not initialization_complete.is_set():
|
378 |
+
log_print("Initialization timeout", "ERROR")
|
379 |
return jsonify({
|
380 |
"error": "Server initialization",
|
381 |
"message": "Server is still initializing. Please try again in a moment."
|
|
|
383 |
|
384 |
# Check content type
|
385 |
if not request.is_json and not request.form:
|
386 |
+
log_print("Invalid request format", "ERROR")
|
387 |
return jsonify({
|
388 |
"error": "Invalid request format",
|
389 |
"message": "Request must be either JSON or form data"
|
|
|
392 |
# Get correct answers
|
393 |
correct_answers = request.form.getlist('correct_answers[]')
|
394 |
if not correct_answers:
|
395 |
+
log_print("No correct answers provided", "ERROR")
|
396 |
return jsonify({
|
397 |
"error": "Missing data",
|
398 |
"message": "No correct answers provided"
|
399 |
}), 400
|
400 |
|
401 |
+
log_print(f"Received {len(correct_answers)} correct answers")
|
402 |
|
403 |
# Create TFIDF values for correct answers
|
404 |
try:
|
405 |
+
log_print("Creating TFIDF values...")
|
406 |
max_tfidf = create_tfidf_values(correct_answers)
|
407 |
log_print("Created TFIDF values successfully")
|
408 |
except Exception as e:
|
|
|
415 |
# Get all uploaded files
|
416 |
files = request.files.getlist('file')
|
417 |
if not files:
|
418 |
+
log_print("No files uploaded", "ERROR")
|
419 |
return jsonify({
|
420 |
"error": "Missing data",
|
421 |
"message": "No files uploaded"
|
|
|
430 |
|
431 |
max_size = 15 * 1024 * 1024 # 15MB
|
432 |
if total_size > max_size:
|
433 |
+
log_print(f"File size limit exceeded: {total_size / 1024 / 1024:.1f}MB", "ERROR")
|
434 |
return jsonify({
|
435 |
"error": "File size limit exceeded",
|
436 |
"message": f"Total file size must be less than 15MB (current size: {total_size / 1024 / 1024:.1f}MB)"
|
|
|
466 |
processed_count = 0
|
467 |
total_files = len(files)
|
468 |
|
469 |
+
log_print(f"Starting to process {total_files} files...")
|
470 |
+
|
471 |
try:
|
472 |
# Process each file
|
473 |
for file in files:
|
|
|
518 |
log_print(f"Saved file to: {filepath}")
|
519 |
|
520 |
# Extract text
|
521 |
+
log_print(f"Extracting text from: {filepath}")
|
522 |
extracted_text = extract_text_from_image(filepath)
|
523 |
|
524 |
# Clean up the file immediately after processing
|
|
|
562 |
clean_correct_answer = correct_answer.encode('ascii', 'ignore').decode('ascii')
|
563 |
|
564 |
# Calculate similarity scores
|
565 |
+
log_print(f"Calculating scores for answer {i+1}...")
|
566 |
semantic_score = question_vector_sentence(extracted_text, clean_correct_answer)
|
567 |
word_score = question_vector_word(extracted_text, clean_correct_answer)
|
568 |
tfidf_score = tfidf_answer_score(extracted_text, clean_correct_answer, max_tfidf)
|
|
|
605 |
"current_file": filename
|
606 |
}
|
607 |
notification_queue.put(progress_data)
|
608 |
+
log_print(f"Progress update: {processed_count}/{total_files} files processed")
|
609 |
|
610 |
except Exception as e:
|
611 |
error_msg = str(e).encode('ascii', 'ignore').decode('ascii')
|
|
|
664 |
}
|
665 |
}
|
666 |
|
667 |
+
log_print("Sending response...")
|
|
|
668 |
response = jsonify(response_data)
|
669 |
response.headers['Content-Type'] = 'application/json'
|
670 |
+
log_print("=== Compute Marks Process Completed ===")
|
671 |
return response
|
672 |
|
673 |
except Exception as e:
|
templates/index.html
CHANGED
@@ -1225,24 +1225,29 @@
|
|
1225 |
|
1226 |
async function computeMarks() {
|
1227 |
try {
|
|
|
1228 |
showLoading();
|
1229 |
const answerBoxes = document.querySelectorAll('.answer-box');
|
1230 |
|
1231 |
if (answerBoxes.length === 0) {
|
|
|
1232 |
notificationSystem.error("Please generate answers first!");
|
1233 |
hideLoading();
|
1234 |
return;
|
1235 |
}
|
1236 |
|
1237 |
const answerValues = Array.from(answerBoxes).map(box => box.value.trim());
|
|
|
1238 |
|
1239 |
if (answerValues.some(answer => !answer)) {
|
|
|
1240 |
notificationSystem.error("Please ensure all answer boxes are filled!");
|
1241 |
hideLoading();
|
1242 |
return;
|
1243 |
}
|
1244 |
|
1245 |
if (selectedFiles.size === 0) {
|
|
|
1246 |
notificationSystem.error("Please upload student answer files!");
|
1247 |
hideLoading();
|
1248 |
return;
|
@@ -1257,6 +1262,8 @@
|
|
1257 |
throw new Error(`Total file size exceeds 15MB limit. Please reduce the number of files.`);
|
1258 |
}
|
1259 |
}
|
|
|
|
|
1260 |
|
1261 |
notificationSystem.info(`Processing ${selectedFiles.size} student files. This may take several minutes...`);
|
1262 |
|
@@ -1269,6 +1276,8 @@
|
|
1269 |
answerValues.forEach((answer, index) => {
|
1270 |
formData.append('correct_answers[]', answer);
|
1271 |
});
|
|
|
|
|
1272 |
|
1273 |
// Add files with their folder structure
|
1274 |
let validFiles = 0;
|
@@ -1278,12 +1287,14 @@
|
|
1278 |
validFiles++;
|
1279 |
}
|
1280 |
});
|
|
|
|
|
1281 |
|
1282 |
if (validFiles === 0) {
|
1283 |
throw new Error("No valid image files found in the uploaded folder");
|
1284 |
}
|
1285 |
|
1286 |
-
notificationSystem.info(`
|
1287 |
|
1288 |
// Update loading message with more detailed progress
|
1289 |
const loadingText = document.querySelector('.loading-text');
|
@@ -1294,20 +1305,29 @@
|
|
1294 |
<small>Progress: 0/${validFiles} files processed</small>
|
1295 |
`;
|
1296 |
|
|
|
|
|
|
|
1297 |
try {
|
1298 |
const response = await fetch('/compute_marks', {
|
1299 |
method: 'POST',
|
1300 |
body: formData,
|
1301 |
keepalive: true
|
1302 |
});
|
|
|
|
|
1303 |
|
1304 |
// Set up event source for real-time notifications
|
|
|
|
|
|
|
1305 |
const eventSource = new EventSource('/notifications');
|
1306 |
let errorCount = 0;
|
1307 |
const maxErrors = 3;
|
1308 |
|
1309 |
eventSource.onmessage = function(event) {
|
1310 |
try {
|
|
|
1311 |
const data = JSON.parse(event.data);
|
1312 |
if (!data || typeof data !== 'object') {
|
1313 |
console.warn('Received invalid notification data:', event.data);
|
@@ -1315,8 +1335,10 @@
|
|
1315 |
}
|
1316 |
|
1317 |
if (data.type === 'extracted_text') {
|
|
|
1318 |
notificationSystem.info(`Extracted text from ${data.filename}:\n${data.text}`, 8000);
|
1319 |
} else if (data.type === 'progress') {
|
|
|
1320 |
// Update progress in loading text
|
1321 |
const loadingText = document.querySelector('.loading-text');
|
1322 |
if (loadingText) {
|
@@ -1328,10 +1350,13 @@
|
|
1328 |
Current file: ${data.current_file}</small>
|
1329 |
`;
|
1330 |
}
|
|
|
|
|
1331 |
// Reset error count on successful progress update
|
1332 |
errorCount = 0;
|
1333 |
} else if (data.type === 'error') {
|
1334 |
console.error('Server notification error:', data.message);
|
|
|
1335 |
errorCount++;
|
1336 |
if (errorCount >= maxErrors) {
|
1337 |
eventSource.close();
|
@@ -1340,6 +1365,7 @@
|
|
1340 |
}
|
1341 |
} catch (e) {
|
1342 |
console.error('Error parsing notification data:', e);
|
|
|
1343 |
errorCount++;
|
1344 |
if (errorCount >= maxErrors) {
|
1345 |
eventSource.close();
|
@@ -1350,37 +1376,54 @@
|
|
1350 |
|
1351 |
eventSource.onerror = function(error) {
|
1352 |
console.error('EventSource error:', error);
|
1353 |
-
eventSource.close();
|
1354 |
notificationSystem.error('Lost connection to server. Please refresh the page.');
|
|
|
1355 |
};
|
1356 |
|
1357 |
let result;
|
1358 |
const contentType = response.headers.get('content-type');
|
|
|
|
|
|
|
1359 |
if (contentType && contentType.includes('application/json')) {
|
1360 |
result = await response.json();
|
|
|
|
|
1361 |
} else {
|
|
|
|
|
1362 |
throw new Error('Server returned non-JSON response');
|
1363 |
}
|
1364 |
|
1365 |
// Close event source after getting final response
|
1366 |
eventSource.close();
|
|
|
|
|
1367 |
|
1368 |
if (!response.ok) {
|
|
|
|
|
1369 |
throw new Error(result.message || result.error || `Server error: ${response.status}`);
|
1370 |
}
|
1371 |
|
1372 |
if (result.status === 'error') {
|
|
|
|
|
1373 |
throw new Error(result.message || result.error);
|
1374 |
}
|
1375 |
|
1376 |
if (!result.results) {
|
|
|
|
|
1377 |
throw new Error('No results found in server response');
|
1378 |
}
|
1379 |
|
1380 |
-
|
1381 |
notificationSystem.success("Successfully computed marks!");
|
|
|
1382 |
|
1383 |
if (result.failed_files && result.failed_files.length > 0) {
|
|
|
1384 |
const failedMessage = result.failed_files
|
1385 |
.map(f => `${f.file}: ${f.error}`)
|
1386 |
.join('\n');
|
@@ -1389,6 +1432,7 @@
|
|
1389 |
|
1390 |
} catch (fetchError) {
|
1391 |
console.error('Fetch error:', fetchError);
|
|
|
1392 |
if (!navigator.onLine) {
|
1393 |
throw new Error('No internet connection. Please check your connection and try again.');
|
1394 |
} else {
|
@@ -1400,6 +1444,8 @@
|
|
1400 |
console.error('Error details:', error);
|
1401 |
notificationSystem.error(error.message || 'Error computing marks. Please try again.');
|
1402 |
} finally {
|
|
|
|
|
1403 |
hideLoading();
|
1404 |
const computeBtn = document.getElementById('compute-marks-btn');
|
1405 |
computeBtn.disabled = false;
|
|
|
1225 |
|
1226 |
async function computeMarks() {
|
1227 |
try {
|
1228 |
+
console.log("=== Starting Compute Marks Process ===");
|
1229 |
showLoading();
|
1230 |
const answerBoxes = document.querySelectorAll('.answer-box');
|
1231 |
|
1232 |
if (answerBoxes.length === 0) {
|
1233 |
+
console.error("No answer boxes found");
|
1234 |
notificationSystem.error("Please generate answers first!");
|
1235 |
hideLoading();
|
1236 |
return;
|
1237 |
}
|
1238 |
|
1239 |
const answerValues = Array.from(answerBoxes).map(box => box.value.trim());
|
1240 |
+
console.log(`Found ${answerValues.length} answer boxes`);
|
1241 |
|
1242 |
if (answerValues.some(answer => !answer)) {
|
1243 |
+
console.error("Empty answer boxes found");
|
1244 |
notificationSystem.error("Please ensure all answer boxes are filled!");
|
1245 |
hideLoading();
|
1246 |
return;
|
1247 |
}
|
1248 |
|
1249 |
if (selectedFiles.size === 0) {
|
1250 |
+
console.error("No files selected");
|
1251 |
notificationSystem.error("Please upload student answer files!");
|
1252 |
hideLoading();
|
1253 |
return;
|
|
|
1262 |
throw new Error(`Total file size exceeds 15MB limit. Please reduce the number of files.`);
|
1263 |
}
|
1264 |
}
|
1265 |
+
console.log(`Total file size: ${(totalSize / 1024 / 1024).toFixed(2)}MB`);
|
1266 |
+
notificationSystem.info(`Total file size: ${(totalSize / 1024 / 1024).toFixed(2)}MB`);
|
1267 |
|
1268 |
notificationSystem.info(`Processing ${selectedFiles.size} student files. This may take several minutes...`);
|
1269 |
|
|
|
1276 |
answerValues.forEach((answer, index) => {
|
1277 |
formData.append('correct_answers[]', answer);
|
1278 |
});
|
1279 |
+
console.log(`Added ${answerValues.length} correct answers to form data`);
|
1280 |
+
notificationSystem.info(`Processing ${answerValues.length} correct answers...`);
|
1281 |
|
1282 |
// Add files with their folder structure
|
1283 |
let validFiles = 0;
|
|
|
1287 |
validFiles++;
|
1288 |
}
|
1289 |
});
|
1290 |
+
console.log(`Added ${validFiles} valid image files to form data`);
|
1291 |
+
notificationSystem.info(`Found ${validFiles} valid image files to process`);
|
1292 |
|
1293 |
if (validFiles === 0) {
|
1294 |
throw new Error("No valid image files found in the uploaded folder");
|
1295 |
}
|
1296 |
|
1297 |
+
notificationSystem.info(`Starting to process ${validFiles} files. Please be patient...`);
|
1298 |
|
1299 |
// Update loading message with more detailed progress
|
1300 |
const loadingText = document.querySelector('.loading-text');
|
|
|
1305 |
<small>Progress: 0/${validFiles} files processed</small>
|
1306 |
`;
|
1307 |
|
1308 |
+
console.log("Sending request to server...");
|
1309 |
+
notificationSystem.info("Sending request to server...");
|
1310 |
+
|
1311 |
try {
|
1312 |
const response = await fetch('/compute_marks', {
|
1313 |
method: 'POST',
|
1314 |
body: formData,
|
1315 |
keepalive: true
|
1316 |
});
|
1317 |
+
console.log(`Server response status: ${response.status}`);
|
1318 |
+
notificationSystem.info(`Server response status: ${response.status}`);
|
1319 |
|
1320 |
// Set up event source for real-time notifications
|
1321 |
+
console.log("Setting up EventSource connection...");
|
1322 |
+
notificationSystem.info("Setting up real-time progress updates...");
|
1323 |
+
|
1324 |
const eventSource = new EventSource('/notifications');
|
1325 |
let errorCount = 0;
|
1326 |
const maxErrors = 3;
|
1327 |
|
1328 |
eventSource.onmessage = function(event) {
|
1329 |
try {
|
1330 |
+
console.log("Received notification:", event.data);
|
1331 |
const data = JSON.parse(event.data);
|
1332 |
if (!data || typeof data !== 'object') {
|
1333 |
console.warn('Received invalid notification data:', event.data);
|
|
|
1335 |
}
|
1336 |
|
1337 |
if (data.type === 'extracted_text') {
|
1338 |
+
console.log(`Extracted text from ${data.filename}`);
|
1339 |
notificationSystem.info(`Extracted text from ${data.filename}:\n${data.text}`, 8000);
|
1340 |
} else if (data.type === 'progress') {
|
1341 |
+
console.log(`Progress update: ${data.processed}/${data.total} files`);
|
1342 |
// Update progress in loading text
|
1343 |
const loadingText = document.querySelector('.loading-text');
|
1344 |
if (loadingText) {
|
|
|
1350 |
Current file: ${data.current_file}</small>
|
1351 |
`;
|
1352 |
}
|
1353 |
+
// Show progress notification
|
1354 |
+
notificationSystem.info(`Progress: ${data.processed}/${data.total} files processed\nCurrent file: ${data.current_file}`, 5000);
|
1355 |
// Reset error count on successful progress update
|
1356 |
errorCount = 0;
|
1357 |
} else if (data.type === 'error') {
|
1358 |
console.error('Server notification error:', data.message);
|
1359 |
+
notificationSystem.error(`Server error: ${data.message}`);
|
1360 |
errorCount++;
|
1361 |
if (errorCount >= maxErrors) {
|
1362 |
eventSource.close();
|
|
|
1365 |
}
|
1366 |
} catch (e) {
|
1367 |
console.error('Error parsing notification data:', e);
|
1368 |
+
notificationSystem.error(`Error processing server update: ${e.message}`);
|
1369 |
errorCount++;
|
1370 |
if (errorCount >= maxErrors) {
|
1371 |
eventSource.close();
|
|
|
1376 |
|
1377 |
eventSource.onerror = function(error) {
|
1378 |
console.error('EventSource error:', error);
|
|
|
1379 |
notificationSystem.error('Lost connection to server. Please refresh the page.');
|
1380 |
+
eventSource.close();
|
1381 |
};
|
1382 |
|
1383 |
let result;
|
1384 |
const contentType = response.headers.get('content-type');
|
1385 |
+
console.log(`Response content type: ${contentType}`);
|
1386 |
+
notificationSystem.info(`Response content type: ${contentType}`);
|
1387 |
+
|
1388 |
if (contentType && contentType.includes('application/json')) {
|
1389 |
result = await response.json();
|
1390 |
+
console.log("Successfully parsed JSON response");
|
1391 |
+
notificationSystem.info("Successfully received server response");
|
1392 |
} else {
|
1393 |
+
console.error(`Invalid content type: ${contentType}`);
|
1394 |
+
notificationSystem.error(`Invalid response type: ${contentType}`);
|
1395 |
throw new Error('Server returned non-JSON response');
|
1396 |
}
|
1397 |
|
1398 |
// Close event source after getting final response
|
1399 |
eventSource.close();
|
1400 |
+
console.log("Closed EventSource connection");
|
1401 |
+
notificationSystem.info("Completed processing all files");
|
1402 |
|
1403 |
if (!response.ok) {
|
1404 |
+
console.error(`Server error: ${response.status}`);
|
1405 |
+
notificationSystem.error(`Server error: ${response.status}`);
|
1406 |
throw new Error(result.message || result.error || `Server error: ${response.status}`);
|
1407 |
}
|
1408 |
|
1409 |
if (result.status === 'error') {
|
1410 |
+
console.error(`Server returned error: ${result.message || result.error}`);
|
1411 |
+
notificationSystem.error(`Server error: ${result.message || result.error}`);
|
1412 |
throw new Error(result.message || result.error);
|
1413 |
}
|
1414 |
|
1415 |
if (!result.results) {
|
1416 |
+
console.error("No results in response");
|
1417 |
+
notificationSystem.error("No results received from server");
|
1418 |
throw new Error('No results found in server response');
|
1419 |
}
|
1420 |
|
1421 |
+
console.log("Successfully received results");
|
1422 |
notificationSystem.success("Successfully computed marks!");
|
1423 |
+
displayMarks(result.results);
|
1424 |
|
1425 |
if (result.failed_files && result.failed_files.length > 0) {
|
1426 |
+
console.warn(`Some files failed to process: ${result.failed_files.length} files`);
|
1427 |
const failedMessage = result.failed_files
|
1428 |
.map(f => `${f.file}: ${f.error}`)
|
1429 |
.join('\n');
|
|
|
1432 |
|
1433 |
} catch (fetchError) {
|
1434 |
console.error('Fetch error:', fetchError);
|
1435 |
+
notificationSystem.error(`Fetch error: ${fetchError.message}`);
|
1436 |
if (!navigator.onLine) {
|
1437 |
throw new Error('No internet connection. Please check your connection and try again.');
|
1438 |
} else {
|
|
|
1444 |
console.error('Error details:', error);
|
1445 |
notificationSystem.error(error.message || 'Error computing marks. Please try again.');
|
1446 |
} finally {
|
1447 |
+
console.log("=== Compute Marks Process Completed ===");
|
1448 |
+
notificationSystem.info("Process completed");
|
1449 |
hideLoading();
|
1450 |
const computeBtn = document.getElementById('compute-marks-btn');
|
1451 |
computeBtn.disabled = false;
|