yamanavijayavardhan commited on
Commit
8a0e8d8
·
1 Parent(s): bd41193

adding count down 1 2 3 4 and removing the null return error

Browse files
Files changed (2) hide show
  1. main.py +38 -47
  2. templates/index.html +47 -7
main.py CHANGED
@@ -334,29 +334,34 @@ def validate_folder_structure(files):
334
  @app.route('/notifications')
335
  def notifications():
336
  def generate():
337
- start_time = time.time()
338
- timeout = 300 # 5 minutes timeout
339
 
340
  while True:
341
  try:
342
- # Check timeout
343
- if time.time() - start_time > timeout:
344
- yield "data: {\"type\": \"timeout\", \"message\": \"Connection timed out\"}\n\n"
345
- break
346
-
347
  # Get notification from queue (non-blocking)
348
  try:
349
  notification = notification_queue.get_nowait()
350
- yield f"data: {json.dumps(notification)}\n\n"
 
 
351
  except queue.Empty:
352
  # If no notification, yield empty to keep connection alive
353
- yield "data: {}\n\n"
354
- time.sleep(0.5) # Increased delay to reduce server load
355
 
356
  except Exception as e:
357
- log_print(f"Error in notification stream: {str(e)}", "ERROR")
358
- yield f"data: {{\"type\": \"error\", \"message\": \"{str(e)}\"}}\n\n"
359
- break
 
 
 
 
 
 
 
 
360
 
361
  return Response(generate(), mimetype='text/event-stream')
362
 
@@ -448,7 +453,9 @@ def compute_marks():
448
  # Dictionary to store results by student folder and image name
449
  results = {}
450
  failed_files = []
451
- extracted_texts = {} # Add this line to store extracted texts
 
 
452
 
453
  try:
454
  # Process each file
@@ -576,6 +583,16 @@ def compute_marks():
576
  results[student_folder][filename] = round(marks, 2)
577
  log_print(f"Assigned marks for {filename} in {student_folder}: {marks}")
578
 
 
 
 
 
 
 
 
 
 
 
579
  except Exception as e:
580
  error_msg = str(e).encode('ascii', 'ignore').decode('ascii')
581
  log_print(f"Error processing file {file.filename}: {error_msg}", "ERROR")
@@ -627,7 +644,7 @@ def compute_marks():
627
  "file": f["file"].encode('ascii', 'ignore').decode('ascii'),
628
  "error": f["error"].encode('ascii', 'ignore').decode('ascii')
629
  } for f in failed_files],
630
- "extracted_texts": { # Add this section to include extracted texts
631
  filename: text.encode('ascii', 'ignore').decode('ascii')
632
  for filename, text in extracted_texts.items()
633
  }
@@ -725,51 +742,25 @@ def ensure_initialization():
725
  wait_for_initialization()
726
 
727
  def cleanup_temp_files():
728
- """Clean up temporary files with proper error handling and timeout"""
729
  try:
730
- # Clean up the temporary processing directory with timeout
731
  temp_processing_dir = os.path.join(BASE_DIR, 'temp_processing')
732
  if os.path.exists(temp_processing_dir):
733
- try:
734
- with timeout(30): # 30 second timeout for cleanup
735
- shutil.rmtree(temp_processing_dir, ignore_errors=True)
736
- except TimeoutError:
737
- log_print("Warning: Cleanup of temp_processing_dir timed out", "WARNING")
738
 
739
- # Clean up the images directory with timeout
740
  if os.path.exists(images_dir):
741
  for file in os.listdir(images_dir):
742
  try:
743
  file_path = os.path.join(images_dir, file)
744
  if os.path.isfile(file_path):
745
- with timeout(5): # 5 second timeout per file
746
- os.unlink(file_path)
747
- except TimeoutError:
748
- log_print(f"Warning: Cleanup of file {file_path} timed out", "WARNING")
749
  except Exception as e:
750
  log_print(f"Warning: Could not delete file {file_path}: {e}", "WARNING")
751
  except Exception as e:
752
  log_print(f"Error cleaning up temporary files: {e}", "ERROR")
753
 
754
- # Add timeout context manager
755
- class timeout:
756
- def __init__(self, seconds):
757
- self.seconds = seconds
758
-
759
- def __enter__(self):
760
- import signal
761
- def timeout_handler(signum, frame):
762
- raise TimeoutError("Timed out!")
763
- # Set the signal handler and a 5-second alarm
764
- self.original_handler = signal.signal(signal.SIGALRM, timeout_handler)
765
- signal.alarm(self.seconds)
766
- return self
767
-
768
- def __exit__(self, type, value, traceback):
769
- import signal
770
- signal.alarm(0)
771
- signal.signal(signal.SIGALRM, self.original_handler)
772
-
773
  if __name__ == '__main__':
774
  try:
775
  # Create essential directories
@@ -778,7 +769,7 @@ if __name__ == '__main__':
778
 
779
  # Configure server for long-running requests
780
  app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
781
- app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # Increase to 50MB
782
 
783
  # Add additional server configurations
784
  app.config['PERMANENT_SESSION_LIFETIME'] = 3600 # 1 hour session lifetime
 
334
  @app.route('/notifications')
335
  def notifications():
336
  def generate():
337
+ error_count = 0
338
+ max_errors = 3
339
 
340
  while True:
341
  try:
 
 
 
 
 
342
  # Get notification from queue (non-blocking)
343
  try:
344
  notification = notification_queue.get_nowait()
345
+ if notification:
346
+ yield "data: " + json.dumps(notification) + "\n\n"
347
+ error_count = 0 # Reset error count on successful notification
348
  except queue.Empty:
349
  # If no notification, yield empty to keep connection alive
350
+ yield "data: " + json.dumps({"type": "ping"}) + "\n\n"
351
+ time.sleep(0.5) # Keep the connection alive
352
 
353
  except Exception as e:
354
+ error_count += 1
355
+ error_msg = str(e).encode('ascii', 'ignore').decode('ascii')
356
+ log_print(f"Error in notification stream: {error_msg}", "ERROR")
357
+
358
+ yield "data: " + json.dumps({
359
+ "type": "error",
360
+ "message": f"Server error: {error_msg}"
361
+ }) + "\n\n"
362
+
363
+ if error_count >= max_errors:
364
+ break
365
 
366
  return Response(generate(), mimetype='text/event-stream')
367
 
 
453
  # Dictionary to store results by student folder and image name
454
  results = {}
455
  failed_files = []
456
+ extracted_texts = {}
457
+ processed_count = 0
458
+ total_files = len(files)
459
 
460
  try:
461
  # Process each file
 
583
  results[student_folder][filename] = round(marks, 2)
584
  log_print(f"Assigned marks for {filename} in {student_folder}: {marks}")
585
 
586
+ # Update progress
587
+ processed_count += 1
588
+ progress_data = {
589
+ "type": "progress",
590
+ "processed": processed_count,
591
+ "total": total_files,
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')
598
  log_print(f"Error processing file {file.filename}: {error_msg}", "ERROR")
 
644
  "file": f["file"].encode('ascii', 'ignore').decode('ascii'),
645
  "error": f["error"].encode('ascii', 'ignore').decode('ascii')
646
  } for f in failed_files],
647
+ "extracted_texts": {
648
  filename: text.encode('ascii', 'ignore').decode('ascii')
649
  for filename, text in extracted_texts.items()
650
  }
 
742
  wait_for_initialization()
743
 
744
  def cleanup_temp_files():
745
+ """Clean up temporary files with proper error handling"""
746
  try:
747
+ # Clean up the temporary processing directory
748
  temp_processing_dir = os.path.join(BASE_DIR, 'temp_processing')
749
  if os.path.exists(temp_processing_dir):
750
+ shutil.rmtree(temp_processing_dir, ignore_errors=True)
 
 
 
 
751
 
752
+ # Clean up the images directory
753
  if os.path.exists(images_dir):
754
  for file in os.listdir(images_dir):
755
  try:
756
  file_path = os.path.join(images_dir, file)
757
  if os.path.isfile(file_path):
758
+ os.unlink(file_path)
 
 
 
759
  except Exception as e:
760
  log_print(f"Warning: Could not delete file {file_path}: {e}", "WARNING")
761
  except Exception as e:
762
  log_print(f"Error cleaning up temporary files: {e}", "ERROR")
763
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
764
  if __name__ == '__main__':
765
  try:
766
  # Create essential directories
 
769
 
770
  # Configure server for long-running requests
771
  app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
772
+ app.config['MAX_CONTENT_LENGTH'] = 50 * 1024 * 1024 # 50MB max file size
773
 
774
  # Add additional server configurations
775
  app.config['PERMANENT_SESSION_LIFETIME'] = 3600 # 1 hour session lifetime
templates/index.html CHANGED
@@ -1295,23 +1295,65 @@
1295
  `;
1296
 
1297
  try {
1298
- const controller = new AbortController();
1299
  const response = await fetch('/compute_marks', {
1300
  method: 'POST',
1301
  body: formData,
1302
- signal: controller.signal,
1303
  keepalive: true
1304
  });
1305
 
1306
  // Set up event source for real-time notifications
1307
  const eventSource = new EventSource('/notifications');
 
 
 
1308
  eventSource.onmessage = function(event) {
1309
- const data = JSON.parse(event.data);
1310
- if (data.type === 'extracted_text') {
1311
- notificationSystem.info(`Extracted text from ${data.filename}:\n${data.text}`, 8000);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1312
  }
1313
  };
1314
 
 
 
 
 
 
 
1315
  let result;
1316
  const contentType = response.headers.get('content-type');
1317
  if (contentType && contentType.includes('application/json')) {
@@ -1349,8 +1391,6 @@
1349
  console.error('Fetch error:', fetchError);
1350
  if (!navigator.onLine) {
1351
  throw new Error('No internet connection. Please check your connection and try again.');
1352
- } else if (fetchError.name === 'AbortError') {
1353
- throw new Error('Request was cancelled. Please try again.');
1354
  } else {
1355
  throw new Error(`Server error: ${fetchError.message}`);
1356
  }
 
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);
1314
+ return;
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) {
1323
+ loadingText.innerHTML = `
1324
+ Processing ${data.total} files...<br>
1325
+ This may take several minutes depending on the number of files.<br>
1326
+ Please keep this window open.<br>
1327
+ <small>Progress: ${data.processed}/${data.total} files processed<br>
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();
1338
+ notificationSystem.error('Lost connection to server. Please refresh the page.');
1339
+ }
1340
+ }
1341
+ } catch (e) {
1342
+ console.error('Error parsing notification data:', e);
1343
+ errorCount++;
1344
+ if (errorCount >= maxErrors) {
1345
+ eventSource.close();
1346
+ notificationSystem.error('Error processing server updates. Please refresh the page.');
1347
+ }
1348
  }
1349
  };
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')) {
 
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 {
1395
  throw new Error(`Server error: ${fetchError.message}`);
1396
  }