PraneshJs commited on
Commit
6150a2f
Β·
verified Β·
1 Parent(s): c3de99b

added auto refresh based on sheet reload

Browse files
Files changed (1) hide show
  1. app.py +120 -2
app.py CHANGED
@@ -573,6 +573,119 @@ def auto_refresh_worker():
573
  # If error, wait 1 hour before trying again
574
  time.sleep(3600)
575
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
  def get_detailed_student_points(roll_no, studentwise_data):
577
  """Get detailed points breakdown from studentwise data"""
578
  if not studentwise_data or len(studentwise_data) < 3:
@@ -714,6 +827,11 @@ refresh_thread = threading.Thread(target=auto_refresh_worker, daemon=True)
714
  refresh_thread.start()
715
  print("πŸ•’ Auto-refresh thread started (updates every 12 hours)")
716
 
 
 
 
 
 
717
  # Function to search student with cached data
718
  def search_student(roll_no):
719
  if not roll_no.strip():
@@ -978,8 +1096,8 @@ def check_admin_mode(request: gr.Request) -> bool:
978
  with gr.Blocks(title="Student Reward Points Check", theme=gr.themes.Soft()) as app:
979
  gr.Markdown("# πŸŽ“ Student Reward Points Check")
980
  gr.Markdown("### Search for student details including reward points and redemption dates")
981
- gr.Markdown("πŸ•’ **Auto-Updates**: Data automatically refreshes every 12 hours")
982
-
983
  # Store admin components for conditional visibility
984
  admin_components = gr.State(None)
985
 
 
573
  # If error, wait 1 hour before trying again
574
  time.sleep(3600)
575
 
576
+ # Auto Refersh When Time changes is found
577
+ # Replace the details_sheet_watcher function (lines 577-610)
578
+
579
+ def details_sheet_watcher():
580
+ """Background watcher: checks every 1 minute if 'POINTS LAST UPDATED' changed - FIXED TOKEN SPAM & THREADING"""
581
+ last_seen_update = None
582
+ consecutive_errors = 0
583
+ max_errors = 3
584
+
585
+ # Persistent connection variables to prevent token regeneration
586
+ watcher_client = None
587
+ watcher_spreadsheet = None
588
+ last_connection_time = None
589
+ connection_duration = 2700 # 45 minutes in seconds
590
+
591
+ print("πŸ‘€ Starting optimized details sheet watcher (checks every 1 minute)...")
592
+
593
+ while True:
594
+ try:
595
+ # Skip if data is currently being loaded to prevent conflicts
596
+ if data_cache["is_loading"]:
597
+ print("⏳ Watcher: Skipping check - data loading in progress")
598
+ time.sleep(60)
599
+ continue
600
+
601
+ # Create/refresh connection only when needed (every 45 minutes)
602
+ current_time = datetime.now()
603
+ if (watcher_client is None or
604
+ watcher_spreadsheet is None or
605
+ last_connection_time is None or
606
+ (current_time - last_connection_time).total_seconds() > connection_duration):
607
+
608
+ try:
609
+ print("πŸ”„ Watcher: Refreshing connection...")
610
+ watcher_client = authorize()
611
+ watcher_spreadsheet = watcher_client.open_by_key(os.getenv('GOOGLE_SHEET_ID'))
612
+ last_connection_time = current_time
613
+ print("βœ… Watcher: Connection refreshed")
614
+ except Exception as auth_error:
615
+ print(f"⚠️ Watcher connection error: {str(auth_error)[:100]}...")
616
+ consecutive_errors += 1
617
+ watcher_client = None
618
+ watcher_spreadsheet = None
619
+ time.sleep(60)
620
+ continue
621
+
622
+ # Use persistent connection to get details info
623
+ try:
624
+ details_info = get_details_info(watcher_spreadsheet)
625
+ except Exception as sheet_error:
626
+ print(f"⚠️ Watcher sheet error: {str(sheet_error)[:100]}...")
627
+ consecutive_errors += 1
628
+ # Force connection refresh on next iteration
629
+ watcher_client = None
630
+ watcher_spreadsheet = None
631
+ time.sleep(60)
632
+ continue
633
+
634
+ if details_info and 'last_updated' in details_info:
635
+ current_update = details_info['last_updated'].strip()
636
+
637
+ if last_seen_update is None:
638
+ last_seen_update = current_update
639
+ print(f"πŸ•’ Watcher: Monitoring established")
640
+ print(f" Current: {current_update[:80]}...")
641
+ elif current_update != last_seen_update:
642
+ print(f"πŸ”„ CHANGE DETECTED!")
643
+ print(f" Old: {last_seen_update[:60]}...")
644
+ print(f" New: {current_update[:60]}...")
645
+
646
+ last_seen_update = current_update
647
+
648
+ # FIXED: Direct reload without creating new thread
649
+ if not data_cache["is_loading"]:
650
+ print("πŸ”„ Reloading data directly...")
651
+ try:
652
+ load_all_data()
653
+ print("βœ… Data reload completed successfully")
654
+ except Exception as reload_error:
655
+ print(f"❌ Reload error: {str(reload_error)[:100]}...")
656
+ else:
657
+ print("⏳ Data already loading, skipping reload")
658
+ else:
659
+ # Only log status every 10 minutes to reduce spam
660
+ if datetime.now().minute % 10 == 0:
661
+ print(f"βœ… Watcher: No changes detected ({datetime.now().strftime('%H:%M')})")
662
+ else:
663
+ print("⚠️ Watcher: Could not extract last_updated info")
664
+ consecutive_errors += 1
665
+
666
+ # Reset error counter on successful operation
667
+ if details_info and consecutive_errors > 0:
668
+ print(f"βœ… Watcher: Connection restored (cleared {consecutive_errors} errors)")
669
+ consecutive_errors = 0
670
+
671
+ except Exception as e:
672
+ consecutive_errors += 1
673
+ print(f"⚠️ Watcher error #{consecutive_errors}: {str(e)[:100]}...")
674
+
675
+ # Force connection refresh after errors
676
+ watcher_client = None
677
+ watcher_spreadsheet = None
678
+
679
+ # Progressive backoff for multiple errors
680
+ if consecutive_errors >= max_errors:
681
+ error_wait = 300 # 5 minutes
682
+ print(f"❌ Too many watcher errors, waiting {error_wait//60} minutes...")
683
+ time.sleep(error_wait)
684
+ consecutive_errors = 0
685
+
686
+ # Wait 1 minute before next check
687
+ time.sleep(60)
688
+
689
  def get_detailed_student_points(roll_no, studentwise_data):
690
  """Get detailed points breakdown from studentwise data"""
691
  if not studentwise_data or len(studentwise_data) < 3:
 
827
  refresh_thread.start()
828
  print("πŸ•’ Auto-refresh thread started (updates every 12 hours)")
829
 
830
+ # 1 min auto-refresh thread to watch details sheet changes
831
+ watcher_thread = threading.Thread(target=details_sheet_watcher, daemon=True)
832
+ watcher_thread.start()
833
+ print("πŸ‘€ Details sheet watcher started (checks every 1 minute)")
834
+
835
  # Function to search student with cached data
836
  def search_student(roll_no):
837
  if not roll_no.strip():
 
1096
  with gr.Blocks(title="Student Reward Points Check", theme=gr.themes.Soft()) as app:
1097
  gr.Markdown("# πŸŽ“ Student Reward Points Check")
1098
  gr.Markdown("### Search for student details including reward points and redemption dates")
1099
+ gr.Markdown("πŸ•’ **Auto-Updates**: Data automatically refreshes when there is a change in Reward Points Sheet")
1100
+ gr.Markdown("### Fill this form for any issues/Feedback: [Issue/Feedback Form](https://docs.google.com/forms/d/e/1FAIpQLScnl0udcN2pUDENHl45HIj5HZbvDuwZ0g2eepBbp8tJYg-NvQ/viewform)")
1101
  # Store admin components for conditional visibility
1102
  admin_components = gr.State(None)
1103