yamanavijayavardhan commited on
Commit
8efbae1
·
1 Parent(s): 750ccee
Files changed (2) hide show
  1. main.py +40 -29
  2. templates/index.html +65 -27
main.py CHANGED
@@ -280,26 +280,41 @@ def compute_marks():
280
  processed_answers.append(ans)
281
  answers = processed_answers
282
 
283
- # Initialize data structure and parent folder
 
 
 
 
 
 
284
  data = {}
285
- parent_folder = ans_image_dir # Use the temp directory path defined earlier
286
-
287
- # Check if answers exist
288
- if not answers:
289
- log_print("No answers found", "ERROR")
290
- return jsonify({"error": "Missing required files"}), 400
291
-
292
- # Process student folders and images
293
- for student_folder in os.listdir(parent_folder):
294
- student_path = os.path.join(parent_folder, student_folder)
295
- if os.path.isdir(student_path):
296
- for image_file in os.listdir(student_path):
297
- if image_file.endswith('.jpg'): # Correct syntax for single extension
298
- full_path = os.path.join(student_path, image_file).replace("\\", "/")
299
- if student_folder in data:
300
- data[student_folder].append(full_path)
301
- else:
302
- data[student_folder] = [full_path]
 
 
 
 
 
 
 
 
 
303
 
304
  # Initialize vectors for answers
305
  sen_vec_answers = []
@@ -315,10 +330,10 @@ def compute_marks():
315
 
316
  # Calculate marks
317
  s_marks = {}
318
- for student_folder in data:
319
  s_marks[student_folder] = []
320
  count = 0
321
- for image_path in data[student_folder]:
322
  try:
323
  s_answer = extract_text_from_image(image_path)
324
  log_print(f"\nProcessing {student_folder}/{os.path.basename(image_path)}:")
@@ -344,18 +359,14 @@ def compute_marks():
344
  log_print(f"Error processing {image_path}: {str(e)}", "ERROR")
345
  s_marks[student_folder].append(0)
346
 
 
 
 
 
347
  log_print("\nFinal Results:")
348
  for student, marks_list in s_marks.items():
349
  log_print(f"{student}: {marks_list}")
350
 
351
- # Add cleanup at the end
352
- try:
353
- import shutil
354
- shutil.rmtree(ans_image_dir)
355
- os.makedirs(ans_image_dir, exist_ok=True)
356
- except Exception as e:
357
- log_print(f"Warning: Could not clean up ans_image directory: {e}", "WARNING")
358
-
359
  return jsonify({"message": s_marks}), 200
360
 
361
  except Exception as e:
 
280
  processed_answers.append(ans)
281
  answers = processed_answers
282
 
283
+ # Get files from the request
284
+ files = request.files.getlist('files[]')
285
+ if not files:
286
+ log_print("No files were uploaded", "ERROR")
287
+ return jsonify({"error": "No files were uploaded"}), 400
288
+
289
+ # Create student folders and save files
290
  data = {}
291
+ for file in files:
292
+ if file and is_valid_image_file(file.filename):
293
+ # Extract student folder from the path
294
+ path_parts = file.filename.split('/')
295
+ if len(path_parts) >= 2:
296
+ student_folder = path_parts[-2] # Get the parent folder name
297
+ filename = path_parts[-1] # Get the actual filename
298
+
299
+ # Create student directory if it doesn't exist
300
+ student_dir = os.path.join(ans_image_dir, student_folder)
301
+ os.makedirs(student_dir, exist_ok=True)
302
+
303
+ # Save the file
304
+ filepath = os.path.join(student_dir, filename)
305
+ file.save(filepath)
306
+
307
+ # Add to data structure
308
+ if student_folder not in data:
309
+ data[student_folder] = []
310
+ data[student_folder].append(filepath.replace("\\", "/"))
311
+ log_print(f"Saved file: {filepath}")
312
+
313
+ if not data:
314
+ log_print("No valid image files were found in the upload", "ERROR")
315
+ return jsonify({"error": "No valid image files were found"}), 400
316
+
317
+ log_print(f"Processed files structure: {data}")
318
 
319
  # Initialize vectors for answers
320
  sen_vec_answers = []
 
330
 
331
  # Calculate marks
332
  s_marks = {}
333
+ for student_folder, file_paths in data.items():
334
  s_marks[student_folder] = []
335
  count = 0
336
+ for image_path in file_paths:
337
  try:
338
  s_answer = extract_text_from_image(image_path)
339
  log_print(f"\nProcessing {student_folder}/{os.path.basename(image_path)}:")
 
359
  log_print(f"Error processing {image_path}: {str(e)}", "ERROR")
360
  s_marks[student_folder].append(0)
361
 
362
+ if not s_marks:
363
+ log_print("No marks were computed", "ERROR")
364
+ return jsonify({"error": "No marks were computed. Please check your input files and answers."}), 400
365
+
366
  log_print("\nFinal Results:")
367
  for student, marks_list in s_marks.items():
368
  log_print(f"{student}: {marks_list}")
369
 
 
 
 
 
 
 
 
 
370
  return jsonify({"message": s_marks}), 200
371
 
372
  except Exception as e:
templates/index.html CHANGED
@@ -499,6 +499,39 @@
499
  margin-top: 0;
500
  color: #4361ee;
501
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
502
  </style>
503
  </head>
504
  <body>
@@ -570,6 +603,13 @@
570
  </div>
571
  </div>
572
 
 
 
 
 
 
 
 
573
  <script>
574
  document.addEventListener('DOMContentLoaded', function() {
575
  const fileTypeSelect = document.getElementById('file-type');
@@ -613,8 +653,17 @@
613
  handleFileTypeChange();
614
  });
615
 
 
 
 
 
 
 
 
 
616
  async function computeAnswers() {
617
  try {
 
618
  const fileType = document.getElementById('file-type').value;
619
  const queryfile = document.getElementById('query-file').files[0];
620
  const anscsvFile = document.getElementById('csv-file').files[0];
@@ -622,6 +671,7 @@
622
 
623
  if (!queryfile) {
624
  alert("Please upload a query file first!");
 
625
  return;
626
  }
627
 
@@ -632,20 +682,22 @@
632
  if (fileType === 'csv') {
633
  if (!anscsvFile) {
634
  alert("Please upload a CSV file for answers!");
 
635
  return;
636
  }
637
  formData.append('ans_csv_file', anscsvFile);
638
  } else if (fileType === 'pdf') {
639
  if (!pdfFiles || pdfFiles.length < 2) {
640
  alert("Please upload at least 2 PDF files!");
 
641
  return;
642
  }
643
- // PDF files will be handled by the backend
 
 
644
  }
645
 
646
- // Show loading state
647
  const computeBtn = document.getElementById('compute-btn');
648
- computeBtn.textContent = 'Processing...';
649
  computeBtn.disabled = true;
650
 
651
  const response = await fetch('/compute_answers', {
@@ -668,17 +720,12 @@
668
  throw new Error('No answers received from server');
669
  }
670
 
671
- // Reset button state
672
- computeBtn.textContent = 'Compute Answers';
673
- computeBtn.disabled = false;
674
-
675
  } catch (error) {
676
  console.error('Error:', error);
677
  alert('Error: ' + error.message);
678
-
679
- // Reset button state on error
680
  const computeBtn = document.getElementById('compute-btn');
681
- computeBtn.textContent = 'Compute Answers';
682
  computeBtn.disabled = false;
683
  }
684
  }
@@ -896,37 +943,34 @@
896
 
897
  async function computeMarks() {
898
  try {
 
899
  const answerBoxes = document.querySelectorAll('.answer-box');
900
  if (answerBoxes.length === 0) {
901
  alert("Please generate answers first!");
 
902
  return;
903
  }
904
 
905
- // Validate that answers are not empty
906
  const answerValues = Array.from(answerBoxes).map(box => box.value.trim());
907
  if (answerValues.some(answer => !answer)) {
908
  alert("Please ensure all answer boxes are filled!");
 
909
  return;
910
  }
911
 
912
  if (selectedFiles.size === 0) {
913
  alert("Please upload student answer files!");
 
914
  return;
915
  }
916
 
917
- // Show loading state
918
  const computeBtn = document.getElementById('compute-marks-btn');
919
- computeBtn.textContent = 'Processing...';
920
  computeBtn.disabled = true;
921
 
922
- // Get answers from textboxes
923
- const answers = Array.from(answerBoxes).map(box => box.value);
924
- console.log("Sending answers:", answers);
925
-
926
  const formData = new FormData();
927
- formData.append('answers', JSON.stringify(answers));
928
 
929
- // Add files with their paths and validate file types
930
  let validFiles = 0;
931
  selectedFiles.forEach((fileInfo, path) => {
932
  if (fileInfo.file.type.startsWith('image/')) {
@@ -950,8 +994,6 @@
950
  }
951
 
952
  const result = await response.json();
953
- console.log("Received result:", result);
954
-
955
  if (result.error) {
956
  throw new Error(result.error);
957
  }
@@ -962,16 +1004,12 @@
962
 
963
  displayMarks(result.message);
964
 
965
- // Reset button
966
- computeBtn.textContent = 'Compute Marks';
967
- computeBtn.disabled = false;
968
-
969
  } catch (error) {
970
  console.error('Error:', error);
971
  alert('Error computing marks: ' + error.message);
972
-
 
973
  const computeBtn = document.getElementById('compute-marks-btn');
974
- computeBtn.textContent = 'Compute Marks';
975
  computeBtn.disabled = false;
976
  }
977
  }
 
499
  margin-top: 0;
500
  color: #4361ee;
501
  }
502
+
503
+ .loading-overlay {
504
+ position: fixed;
505
+ top: 0;
506
+ left: 0;
507
+ width: 100%;
508
+ height: 100%;
509
+ background: rgba(0, 0, 0, 0.7);
510
+ display: none;
511
+ justify-content: center;
512
+ align-items: center;
513
+ z-index: 1000;
514
+ }
515
+
516
+ .loading-spinner {
517
+ width: 50px;
518
+ height: 50px;
519
+ border: 5px solid #f3f3f3;
520
+ border-top: 5px solid #4361ee;
521
+ border-radius: 50%;
522
+ animation: spin 1s linear infinite;
523
+ }
524
+
525
+ .loading-text {
526
+ color: white;
527
+ margin-top: 20px;
528
+ font-size: 18px;
529
+ }
530
+
531
+ @keyframes spin {
532
+ 0% { transform: rotate(0deg); }
533
+ 100% { transform: rotate(360deg); }
534
+ }
535
  </style>
536
  </head>
537
  <body>
 
603
  </div>
604
  </div>
605
 
606
+ <div class="loading-overlay" id="loading-overlay">
607
+ <div style="text-align: center;">
608
+ <div class="loading-spinner"></div>
609
+ <div class="loading-text">Processing... This may take a few minutes.</div>
610
+ </div>
611
+ </div>
612
+
613
  <script>
614
  document.addEventListener('DOMContentLoaded', function() {
615
  const fileTypeSelect = document.getElementById('file-type');
 
653
  handleFileTypeChange();
654
  });
655
 
656
+ function showLoading() {
657
+ document.getElementById('loading-overlay').style.display = 'flex';
658
+ }
659
+
660
+ function hideLoading() {
661
+ document.getElementById('loading-overlay').style.display = 'none';
662
+ }
663
+
664
  async function computeAnswers() {
665
  try {
666
+ showLoading();
667
  const fileType = document.getElementById('file-type').value;
668
  const queryfile = document.getElementById('query-file').files[0];
669
  const anscsvFile = document.getElementById('csv-file').files[0];
 
671
 
672
  if (!queryfile) {
673
  alert("Please upload a query file first!");
674
+ hideLoading();
675
  return;
676
  }
677
 
 
682
  if (fileType === 'csv') {
683
  if (!anscsvFile) {
684
  alert("Please upload a CSV file for answers!");
685
+ hideLoading();
686
  return;
687
  }
688
  formData.append('ans_csv_file', anscsvFile);
689
  } else if (fileType === 'pdf') {
690
  if (!pdfFiles || pdfFiles.length < 2) {
691
  alert("Please upload at least 2 PDF files!");
692
+ hideLoading();
693
  return;
694
  }
695
+ for (let file of pdfFiles) {
696
+ formData.append('pdf_files[]', file);
697
+ }
698
  }
699
 
 
700
  const computeBtn = document.getElementById('compute-btn');
 
701
  computeBtn.disabled = true;
702
 
703
  const response = await fetch('/compute_answers', {
 
720
  throw new Error('No answers received from server');
721
  }
722
 
 
 
 
 
723
  } catch (error) {
724
  console.error('Error:', error);
725
  alert('Error: ' + error.message);
726
+ } finally {
727
+ hideLoading();
728
  const computeBtn = document.getElementById('compute-btn');
 
729
  computeBtn.disabled = false;
730
  }
731
  }
 
943
 
944
  async function computeMarks() {
945
  try {
946
+ showLoading();
947
  const answerBoxes = document.querySelectorAll('.answer-box');
948
  if (answerBoxes.length === 0) {
949
  alert("Please generate answers first!");
950
+ hideLoading();
951
  return;
952
  }
953
 
 
954
  const answerValues = Array.from(answerBoxes).map(box => box.value.trim());
955
  if (answerValues.some(answer => !answer)) {
956
  alert("Please ensure all answer boxes are filled!");
957
+ hideLoading();
958
  return;
959
  }
960
 
961
  if (selectedFiles.size === 0) {
962
  alert("Please upload student answer files!");
963
+ hideLoading();
964
  return;
965
  }
966
 
 
967
  const computeBtn = document.getElementById('compute-marks-btn');
 
968
  computeBtn.disabled = true;
969
 
 
 
 
 
970
  const formData = new FormData();
971
+ formData.append('answers', JSON.stringify(answerValues));
972
 
973
+ // Add files with their paths
974
  let validFiles = 0;
975
  selectedFiles.forEach((fileInfo, path) => {
976
  if (fileInfo.file.type.startsWith('image/')) {
 
994
  }
995
 
996
  const result = await response.json();
 
 
997
  if (result.error) {
998
  throw new Error(result.error);
999
  }
 
1004
 
1005
  displayMarks(result.message);
1006
 
 
 
 
 
1007
  } catch (error) {
1008
  console.error('Error:', error);
1009
  alert('Error computing marks: ' + error.message);
1010
+ } finally {
1011
+ hideLoading();
1012
  const computeBtn = document.getElementById('compute-marks-btn');
 
1013
  computeBtn.disabled = false;
1014
  }
1015
  }