iyadsultan commited on
Commit
fee90dc
·
1 Parent(s): d21edc9

Implement document index persistence and streamline evaluation actions

Browse files

Refactor the evaluation process to load and save the current document index from a file, enhancing user experience by maintaining progress across sessions. Simplify handling of jump, skip, and submit actions, while improving feedback messages for document navigation. Update logging for better traceability of user actions during evaluations.

Files changed (2) hide show
  1. app.py +68 -208
  2. templates/evaluate.html +13 -3
app.py CHANGED
@@ -418,225 +418,59 @@ def evaluate():
418
  # Create sessions directory if it doesn't exist
419
  os.makedirs(os.path.join(DATA_DIR, 'sessions'), exist_ok=True)
420
 
421
- # Initialize current document index if not set (start fresh each session, 1-based)
422
- if 'current_document_index' not in session:
423
- session['current_document_index'] = 1
424
 
425
- # Check for jump_to parameter to jump to a specific document number
426
  jump_to = request.args.get('jump_to', type=int)
427
  if jump_to is not None:
428
- # Ensure jump_to is within valid range
429
  documents = load_documents()
430
- if jump_to >= 1 and jump_to <= len(documents):
431
- session['current_document_index'] = jump_to # Store as 1-based index
432
- print(f"DEBUG JUMP: Setting document index to {jump_to}")
433
- log_error(f"JUMP: Setting document index to {jump_to}")
434
- else:
435
- flash(f"Invalid document number. Please enter a number between 1 and {len(documents)}.")
436
- log_error(f"Invalid jump_to value: {jump_to}")
437
- else:
438
- # Log current position when not jumping
439
- current_idx = session.get('current_document_index', 1)
440
- print(f"DEBUG CONTINUE: Current document index is {current_idx}")
441
- log_error(f"CONTINUE: Current document index is {current_idx}")
442
-
443
-
444
 
445
- # Process POST request (form submission)
446
  if request.method == 'POST':
447
- try:
448
- # Debug session state at start of POST
449
- current_session_index = session.get('current_document_index', 1)
450
- print(f"DEBUG POST START: action={request.form.get('action')}, session_index={current_session_index}")
451
-
452
- # Handle different button actions
453
- action = request.form.get('action', 'submit')
454
-
455
- # Handle "Stop and Save" action
456
- if action == 'stop_save':
457
- # First save the current evaluation if form data is provided
458
- try:
459
- # Check if we have evaluation data to save
460
- has_criteria_data = any(f"criteria_{i}" in request.form for i in range(len(CRITERIA)))
461
- has_note_origin = 'note_origin' in request.form
462
-
463
- if has_criteria_data and has_note_origin:
464
- # Get all documents
465
- all_documents = load_documents()
466
- current_index = session.get('current_document_index', 1)
467
-
468
- if current_index <= len(all_documents):
469
- document = all_documents[current_index - 1] # Convert to 0-based for array access
470
-
471
- # Prepare evaluation data
472
- evaluation_data = {
473
- 'document_title': document.get('filename', 'Unknown'),
474
- 'description': document.get('description', ''),
475
- 'mrn': document.get('mrn', ''),
476
- 'investigator_name': evaluator_name,
477
- }
478
-
479
- # Get criteria scores
480
- for i, criterion in enumerate(CRITERIA):
481
- score_key = f"criteria_{i}"
482
- if score_key in request.form:
483
- evaluation_data[criterion] = request.form[score_key]
484
-
485
- # Get note origin assessment
486
- if 'note_origin' in request.form:
487
- evaluation_data['note_origin'] = request.form['note_origin']
488
-
489
- # Save evaluation data
490
- save_result = save_evaluation(evaluation_data)
491
-
492
- if save_result:
493
- log_error("Current evaluation saved before stopping")
494
- flash("Current evaluation saved. You can resume later from where you left off.")
495
- else:
496
- flash("Session progress saved (current evaluation could not be saved).")
497
- else:
498
- flash("Session progress saved. You can resume later from where you left off.")
499
- else:
500
- flash("Session progress saved. You can resume later from where you left off.")
501
- except Exception as e:
502
- log_error(f"Error saving current evaluation on stop: {str(e)}")
503
- flash("Session progress saved. You can resume later from where you left off.")
504
-
505
- return redirect(url_for('results'))
506
-
507
- # Handle "Skip" action
508
- if action == 'skip':
509
- current_index = session.get('current_document_index', 1)
510
- new_index = current_index + 1
511
- session['current_document_index'] = new_index
512
- print(f"DEBUG SKIP: Moved from document {current_index} to {new_index}")
513
- log_error(f"SKIP: Moved from document {current_index} to {new_index}")
514
-
515
- # Debug session state before redirect
516
- final_session_index = session.get('current_document_index', 1)
517
- print(f"DEBUG SKIP REDIRECT: final_session_index={final_session_index}")
518
-
519
- flash("Document skipped.")
520
- return redirect(url_for('evaluate'))
521
-
522
- # Handle regular evaluation submission
523
- # Get all documents
524
- all_documents = load_documents()
525
- log_error(f"Loaded {len(all_documents)} total documents for POST")
526
-
527
- if not all_documents:
528
- flash("No documents available for evaluation.")
529
- return redirect(url_for('index'))
530
-
531
- current_index = session.get('current_document_index', 1)
532
- if current_index > len(all_documents):
533
- flash("All documents have been processed.")
534
- return redirect(url_for('results'))
535
-
536
- document = all_documents[current_index - 1] # Convert to 0-based for array access
537
- log_error(f"Processing evaluation for document: {document.get('filename')}")
538
-
539
- # Prepare evaluation data
540
- evaluation_data = {
541
- 'document_title': document.get('filename', 'Unknown'),
542
- 'description': document.get('description', ''),
543
- 'mrn': document.get('mrn', ''),
544
- 'investigator_name': evaluator_name,
545
- }
546
-
547
- # Get criteria scores
548
- for i, criterion in enumerate(CRITERIA):
549
- score_key = f"criteria_{i}"
550
- if score_key in request.form:
551
- evaluation_data[criterion] = request.form[score_key]
552
-
553
- # Get note origin assessment
554
- if 'note_origin' in request.form:
555
- evaluation_data['note_origin'] = request.form['note_origin']
556
- log_error(f"Note origin: {evaluation_data['note_origin']}")
557
-
558
- # Save evaluation data
559
- save_result = save_evaluation(evaluation_data)
560
-
561
- if save_result:
562
- flash("Evaluation saved successfully!")
563
-
564
- # Move to next document
565
- new_index = current_index + 1
566
- session['current_document_index'] = new_index
567
- print(f"DEBUG SUBMIT: Moved from document {current_index} to {new_index}")
568
- log_error(f"SUBMIT: Moved from document {current_index} to {new_index}")
569
-
570
- # Check if all documents have been processed
571
- if session['current_document_index'] > len(all_documents):
572
- flash("All documents have been evaluated. Thank you!")
573
- return redirect(url_for('results'))
574
-
575
- # Debug session state before redirect
576
- final_session_index = session.get('current_document_index', 1)
577
- print(f"DEBUG SUBMIT REDIRECT: final_session_index={final_session_index}")
578
-
579
- # Redirect to next document
580
- return redirect(url_for('evaluate'))
581
- else:
582
- flash("Error saving evaluation. Please try again.")
583
-
584
- except Exception as e:
585
- error_msg = f"Error processing evaluation: {str(e)}"
586
- log_error(error_msg)
587
- log_error(traceback.format_exc())
588
- flash(error_msg)
589
-
590
- # Handle GET request (display evaluation form)
591
- try:
592
- # Load all documents
593
- all_documents = load_documents()
594
- log_error(f"Loaded {len(all_documents)} total documents for GET")
595
 
596
- # Check if there are documents to evaluate
597
- if not all_documents:
598
- log_error("No documents found, redirecting")
599
- return render_template('no_documents.html')
 
600
 
601
- # Get current document index (1-based)
602
- current_index = session.get('current_document_index', 1)
603
-
604
- # Check if we've reached the end
605
- if current_index > len(all_documents):
606
- flash("All documents have been processed in this session.")
607
  return redirect(url_for('results'))
608
 
609
- # Get the current document
610
- document = all_documents[current_index - 1] # Convert to 0-based for array access
611
- log_error(f"Selected document at index {current_index - 1} (note #{current_index}): {document.get('filename')}")
612
-
613
- # Get current session progress (only for this session)
614
- total_docs = len(all_documents)
615
- current_progress = current_index - 1 # Convert to 0-based for progress calculation
616
- progress = int((current_progress / total_docs) * 100) if total_docs > 0 else 0
617
-
618
- log_error(f"Session Progress: {current_progress}/{total_docs} documents ({progress}%)")
619
-
620
- # Render evaluation template
621
- return render_template('evaluate.html',
622
- evaluator_name=evaluator_name,
623
- note=document.get('note', ''),
624
- description=document.get('description', ''),
625
- mrn=document.get('mrn', ''),
626
- criteria=CRITERIA,
627
- descriptions=CRITERIA_DESCRIPTIONS,
628
- score_range=range(1, 6),
629
- note_origins=NOTE_ORIGINS,
630
- total_docs=total_docs,
631
- evaluated_docs=current_progress,
632
- progress=progress,
633
- current_note_number=current_index)
634
 
635
- except Exception as e:
636
- log_error(f"Error in evaluate route: {str(e)}")
637
- log_error(f"Traceback: {traceback.format_exc()}")
638
- flash(f"An error occurred: {str(e)}")
639
- return redirect(url_for('index'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
640
 
641
  @app.route('/jump', methods=['POST'])
642
  def jump_to_document():
@@ -948,6 +782,32 @@ def get_stored_evaluator_name():
948
  log_error(f"Error retrieving evaluator name: {str(e)}")
949
  return None
950
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
951
  if __name__ == '__main__':
952
  print("\n===== Application Startup at", datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "=====\n")
953
 
 
418
  # Create sessions directory if it doesn't exist
419
  os.makedirs(os.path.join(DATA_DIR, 'sessions'), exist_ok=True)
420
 
421
+ # Initialize current document index from file
422
+ current_index = load_current_index(evaluator_name)
 
423
 
424
+ # Handle jump requests
425
  jump_to = request.args.get('jump_to', type=int)
426
  if jump_to is not None:
 
427
  documents = load_documents()
428
+ if 1 <= jump_to <= len(documents):
429
+ current_index = jump_to
430
+ save_current_index(evaluator_name, current_index)
 
 
 
 
 
 
 
 
 
 
 
431
 
432
+ # Handle form submissions
433
  if request.method == 'POST':
434
+ action = request.form.get('action', 'submit')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
 
436
+ if action == 'skip':
437
+ current_index += 1
438
+ save_current_index(evaluator_name, current_index)
439
+ flash("Document skipped.")
440
+ return redirect(url_for('evaluate'))
441
 
442
+ elif action == 'stop_save':
443
+ # Handle save logic
 
 
 
 
444
  return redirect(url_for('results'))
445
 
446
+ elif action == 'submit':
447
+ # Save evaluation logic
448
+ current_index += 1
449
+ save_current_index(evaluator_name, current_index)
450
+ flash("Evaluation saved successfully!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
 
452
+ # Load current document
453
+ documents = load_documents()
454
+ if current_index > len(documents):
455
+ flash("All documents have been evaluated.")
456
+ return redirect(url_for('results'))
457
+
458
+ document = documents[current_index - 1]
459
+
460
+ # Render template with current_index
461
+ return render_template('evaluate.html',
462
+ current_note_number=current_index,
463
+ evaluator_name=evaluator_name,
464
+ note=document.get('note', ''),
465
+ description=document.get('description', ''),
466
+ mrn=document.get('mrn', ''),
467
+ criteria=CRITERIA,
468
+ descriptions=CRITERIA_DESCRIPTIONS,
469
+ score_range=range(1, 6),
470
+ note_origins=NOTE_ORIGINS,
471
+ total_docs=len(documents),
472
+ evaluated_docs=current_index - 1,
473
+ progress=int((current_index - 1) / len(documents) * 100) if len(documents) > 0 else 0)
474
 
475
  @app.route('/jump', methods=['POST'])
476
  def jump_to_document():
 
782
  log_error(f"Error retrieving evaluator name: {str(e)}")
783
  return None
784
 
785
+ # Add these new functions for progress tracking
786
+ def get_progress_file(evaluator_name):
787
+ """Get path to progress file for an evaluator"""
788
+ return os.path.join(DATA_DIR, f'{evaluator_name}_progress.txt')
789
+
790
+ def save_current_index(evaluator_name, index):
791
+ """Save current document index to file"""
792
+ try:
793
+ with open(get_progress_file(evaluator_name), 'w') as f:
794
+ f.write(str(index))
795
+ return True
796
+ except Exception as e:
797
+ log_error(f"Error saving progress: {str(e)}")
798
+ return False
799
+
800
+ def load_current_index(evaluator_name):
801
+ """Load current document index from file"""
802
+ try:
803
+ if os.path.exists(get_progress_file(evaluator_name)):
804
+ with open(get_progress_file(evaluator_name), 'r') as f:
805
+ return int(f.read().strip())
806
+ return 1 # Start at 1 if no progress file
807
+ except Exception as e:
808
+ log_error(f"Error loading progress: {str(e)}")
809
+ return 1
810
+
811
  if __name__ == '__main__':
812
  print("\n===== Application Startup at", datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "=====\n")
813
 
templates/evaluate.html CHANGED
@@ -112,9 +112,19 @@
112
  </div>
113
 
114
  <div class="form-buttons">
115
- <button type="submit" name="action" value="submit" class="submit-btn">Submit Evaluation</button>
116
- <button type="submit" name="action" value="skip" class="skip-btn">Skip Document</button>
117
- <button type="submit" name="action" value="stop_save" class="stop-save-btn">Stop and Save Progress</button>
 
 
 
 
 
 
 
 
 
 
118
  </div>
119
  </form>
120
 
 
112
  </div>
113
 
114
  <div class="form-buttons">
115
+ <form method="POST" action="{{ url_for('evaluate') }}">
116
+ <button type="submit" name="action" value="submit" class="submit-btn">Submit Evaluation</button>
117
+ </form>
118
+
119
+ <div class="action-buttons">
120
+ <form method="POST" action="{{ url_for('evaluate') }}" onsubmit="return confirm('Are you sure you want to skip this document?');">
121
+ <button type="submit" name="action" value="skip" class="skip-btn">Skip Document</button>
122
+ </form>
123
+
124
+ <form method="POST" action="{{ url_for('evaluate') }}">
125
+ <button type="submit" name="action" value="stop_save" class="stop-save-btn">Stop and Save Progress</button>
126
+ </form>
127
+ </div>
128
  </div>
129
  </form>
130