PraneshJs commited on
Commit
2d86c33
Β·
verified Β·
1 Parent(s): 8a84b70

fixed formating issues and expected 1 but got 0 issue

Browse files
Files changed (1) hide show
  1. app.py +78 -83
app.py CHANGED
@@ -811,103 +811,103 @@ def auto_refresh_worker():
811
  time.sleep(3600)
812
 
813
  def details_sheet_watcher():
814
- """Background watcher: checks every 30 seconds if 'POINTS LAST UPDATED' changed - optimized timing"""
 
 
 
815
  last_seen_update = None
816
  consecutive_errors = 0
817
  max_errors = 3
818
 
819
  watcher_client = None
820
  watcher_spreadsheet = None
 
821
  last_connection_time = None
822
  connection_duration = 2700 # 45 minutes
823
 
 
 
 
 
 
824
  check_interval = 30 # seconds
 
825
 
826
- print(f"πŸ‘€ Starting optimized details sheet watcher (checks every {check_interval} seconds)...")
827
 
828
  while True:
 
829
  try:
830
  if data_cache["is_loading"]:
831
- print("⏳ Watcher: Skipping check - data loading in progress")
832
- time.sleep(check_interval)
833
- continue
834
-
835
- current_time = datetime.now()
836
- if (watcher_client is None or
837
- watcher_spreadsheet is None or
838
- last_connection_time is None or
839
- (current_time - last_connection_time).total_seconds() > connection_duration):
840
 
841
- try:
842
  print("πŸ”„ Watcher: Refreshing connection...")
843
  watcher_client = authorize()
844
  watcher_spreadsheet = watcher_client.open_by_key(os.getenv('GOOGLE_SHEET_ID'))
 
845
  last_connection_time = current_time
846
- print("βœ… Watcher: Connection refreshed")
847
- except Exception as auth_error:
848
- print(f"⚠️ Watcher connection error: {str(auth_error)[:100]}...")
849
- consecutive_errors += 1
850
- watcher_client = None
851
- watcher_spreadsheet = None
852
- time.sleep(check_interval)
853
- continue
854
 
855
- try:
856
- details_info = get_details_info(watcher_spreadsheet)
857
- except Exception as sheet_error:
858
- print(f"⚠️ Watcher sheet error: {str(sheet_error)[:100]}...")
859
- consecutive_errors += 1
860
- watcher_client = None
861
- watcher_spreadsheet = None
862
- time.sleep(check_interval)
863
- continue
864
-
865
- if details_info and 'last_updated' in details_info:
866
- current_update = details_info['last_updated'].strip()
867
-
868
- if last_seen_update is None:
869
- last_seen_update = current_update
870
- print(f"πŸ•’ Watcher: Monitoring established")
871
- print(f" Current: {current_update[:80]}...")
872
- elif current_update != last_seen_update:
873
- print(f"πŸ”„ CHANGE DETECTED!")
874
- print(f" Old: {last_seen_update[:60]}...")
875
- print(f" New: {current_update[:60]}...")
876
- last_seen_update = current_update
877
-
878
- if not data_cache["is_loading"]:
879
- print("πŸ”„ Reloading data directly...")
880
- try:
881
  load_all_data()
882
- print("βœ… Data reload completed successfully")
883
- except Exception as reload_error:
884
- print(f"❌ Reload error: {str(reload_error)[:100]}...")
885
  else:
886
- print("⏳ Data already loading, skipping reload")
887
- else:
888
- # Show heartbeat every 5 minutes instead of 10
889
- if datetime.now().minute % 5 == 0 and datetime.now(ist).second < check_interval:
890
- print(f"βœ… Watcher: No changes detected ({datetime.now(ist).strftime('%H:%M')})")
891
- else:
892
- print("⚠️ Watcher: Could not extract last_updated info")
893
- consecutive_errors += 1
894
 
895
- if details_info and consecutive_errors > 0:
896
  print(f"βœ… Watcher: Connection restored (cleared {consecutive_errors} errors)")
897
  consecutive_errors = 0
898
 
899
  except Exception as e:
900
  consecutive_errors += 1
901
- print(f"⚠️ Watcher error #{consecutive_errors}: {str(e)[:100]}...")
902
  watcher_client = None
903
  watcher_spreadsheet = None
 
904
  if consecutive_errors >= max_errors:
905
- error_wait = 300 # 5 minutes
906
- print(f"❌ Too many watcher errors, waiting {error_wait//60} minutes...")
907
- time.sleep(error_wait)
908
  consecutive_errors = 0
909
 
910
- time.sleep(check_interval)
 
 
 
911
 
912
 
913
  def get_detailed_student_points(roll_no, studentwise_data):
@@ -1306,44 +1306,39 @@ with gr.Blocks(
1306
  show_label=True
1307
  )
1308
 
1309
- # Event handlers - Fixed order and proper input/output mapping
1310
 
1311
  # 1. Student search handlers
1312
  search_btn.click(
1313
  fn=search_student,
1314
- inputs=[roll_input],
1315
- outputs=[result_output],
1316
- api_name="search_student"
1317
  )
1318
 
1319
  roll_input.submit(
1320
  fn=search_student,
1321
- inputs=[roll_input],
1322
- outputs=[result_output],
1323
- api_name="search_student_submit"
1324
  )
1325
 
1326
- # 2. IP Details handlers - Fixed input parameter
1327
  subject_search_btn.click(
1328
  fn=extract_subjects_and_marks_for_gradio,
1329
- inputs=[subject_roll_input],
1330
- outputs=[subject_output],
1331
- api_name="get_ip_details"
1332
  )
1333
 
1334
  subject_roll_input.submit(
1335
  fn=extract_subjects_and_marks_for_gradio,
1336
- inputs=[subject_roll_input],
1337
- outputs=[subject_output],
1338
- api_name="get_ip_details_submit"
1339
  )
1340
 
1341
- # 3. System info handler - Fixed to not require inputs
1342
  system_btn.click(
1343
  fn=get_system_info,
1344
  inputs=[],
1345
- outputs=[system_output],
1346
- api_name="get_system_info"
1347
  )
1348
 
1349
  # Footer section
@@ -1354,7 +1349,7 @@ with gr.Blocks(
1354
  """
1355
  <div style="text-align: center; margin-top: 20px; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 10px; color: white;">
1356
  <h3 style="margin: 0; color: white;">πŸ’» Developed with ❀️ by</h3>
1357
- <a href="https://pranesh-2005.github.io/My-Portfolio/" target="_blank" style="text-decoration: none;">
1358
  <h2 style="margin: 5px 0; color: #ffd700; cursor: pointer; transition: color 0.3s ease;">PRANESH S</h2>
1359
  </a>
1360
  <div style="margin: 15px 0;">
@@ -1387,11 +1382,11 @@ with gr.Blocks(
1387
  print(error_msg)
1388
  return "⚠️ System information will be available after data loads completely. Please click 'Get System Information' button to retry."
1389
 
1390
- # Load system info on startup - Fixed to use proper event handling
1391
  app.load(
1392
  fn=initialize_system_info,
1393
  inputs=[],
1394
- outputs=[system_output]
1395
  )
1396
 
1397
  # Launch the app
 
811
  time.sleep(3600)
812
 
813
  def details_sheet_watcher():
814
+ """Background watcher: checks every 30 seconds (drift-free, IST logs) if 'POINTS LAST UPDATED' changed"""
815
+ import time
816
+ from datetime import datetime
817
+
818
  last_seen_update = None
819
  consecutive_errors = 0
820
  max_errors = 3
821
 
822
  watcher_client = None
823
  watcher_spreadsheet = None
824
+ watcher_sheet = None
825
  last_connection_time = None
826
  connection_duration = 2700 # 45 minutes
827
 
828
+ # Specific cell coordinates for "POINTS LAST UPDATED"
829
+ TARGET_ROW = 16
830
+ TARGET_COL = 2
831
+ CELL_RANGE = f"R{TARGET_ROW}C{TARGET_COL}" # Row 16, Column 2
832
+
833
  check_interval = 30 # seconds
834
+ next_check = time.time()
835
 
836
+ print(f"πŸ‘€ Starting optimized details sheet watcher (monitoring cell R{TARGET_ROW}C{TARGET_COL} every {check_interval} seconds)...")
837
 
838
  while True:
839
+ start_time = time.time()
840
  try:
841
  if data_cache["is_loading"]:
842
+ print("⏳ Watcher: Skipping check – data loading in progress")
843
+ else:
844
+ current_time = datetime.now()
845
+ if (watcher_client is None or
846
+ watcher_spreadsheet is None or
847
+ watcher_sheet is None or
848
+ last_connection_time is None or
849
+ (current_time - last_connection_time).total_seconds() > connection_duration):
 
850
 
 
851
  print("πŸ”„ Watcher: Refreshing connection...")
852
  watcher_client = authorize()
853
  watcher_spreadsheet = watcher_client.open_by_key(os.getenv('GOOGLE_SHEET_ID'))
854
+ watcher_sheet = watcher_spreadsheet.get_worksheet_by_id(847680829) # Details sheet GID
855
  last_connection_time = current_time
856
+ print(f"βœ… Watcher: Connection refreshed (monitoring cell R{TARGET_ROW}C{TARGET_COL})")
 
 
 
 
 
 
 
857
 
858
+ # Get only the specific cell content
859
+ try:
860
+ # Use batch_get to get specific cell efficiently
861
+ cell_value = watcher_sheet.cell(TARGET_ROW, TARGET_COL).value
862
+ current_update = str(cell_value).strip() if cell_value else ""
863
+
864
+ now_ist = datetime.now(ist).strftime("%Y-%m-%d %H:%M:%S")
865
+
866
+ if last_seen_update is None:
867
+ last_seen_update = current_update
868
+ print(f"πŸ•’ Watcher: Monitoring established ({now_ist})")
869
+ print(f" Target cell R{TARGET_ROW}C{TARGET_COL}: {current_update[:80]}...")
870
+ elif current_update != last_seen_update:
871
+ print(f"πŸ”„ CHANGE DETECTED! ({now_ist})")
872
+ print(f" Old: {last_seen_update[:60]}...")
873
+ print(f" New: {current_update[:60]}...")
874
+ last_seen_update = current_update
875
+
876
+ if not data_cache["is_loading"]:
877
+ print("πŸ”„ Reloading data directly...")
 
 
 
 
 
 
878
  load_all_data()
879
+ print(f"βœ… Data reload completed successfully ({now_ist})")
880
+ else:
881
+ print(f"⏳ Data already loading, skipping reload ({now_ist})")
882
  else:
883
+ # Log heartbeat every 5 minutes in IST
884
+ current_ist = datetime.now(ist)
885
+ if current_ist.minute % 5 == 0 and current_ist.second < check_interval:
886
+ print(f"βœ… Watcher: No changes detected in R{TARGET_ROW}C{TARGET_COL} ({current_ist.strftime('%H:%M:%S')})")
887
+
888
+ except Exception as cell_error:
889
+ print(f"⚠️ Error reading cell R{TARGET_ROW}C{TARGET_COL}: {str(cell_error)[:100]}")
890
+ consecutive_errors += 1
891
 
892
+ if consecutive_errors > 0 and not any([watcher_client is None, watcher_spreadsheet is None, watcher_sheet is None]):
893
  print(f"βœ… Watcher: Connection restored (cleared {consecutive_errors} errors)")
894
  consecutive_errors = 0
895
 
896
  except Exception as e:
897
  consecutive_errors += 1
898
+ print(f"⚠️ Watcher error #{consecutive_errors}: {str(e)[:120]}")
899
  watcher_client = None
900
  watcher_spreadsheet = None
901
+ watcher_sheet = None
902
  if consecutive_errors >= max_errors:
903
+ print("❌ Too many watcher errors, waiting 5 minutes before retry...")
904
+ time.sleep(300)
 
905
  consecutive_errors = 0
906
 
907
+ # Drift-free timing β€” ensures consistent 30s intervals
908
+ next_check += check_interval
909
+ sleep_time = max(0, next_check - time.time())
910
+ time.sleep(sleep_time)
911
 
912
 
913
  def get_detailed_student_points(roll_no, studentwise_data):
 
1306
  show_label=True
1307
  )
1308
 
1309
+ # Event handlers - FIXED: Proper input/output mapping
1310
 
1311
  # 1. Student search handlers
1312
  search_btn.click(
1313
  fn=search_student,
1314
+ inputs=roll_input, # Changed from [roll_input] to roll_input
1315
+ outputs=result_output
 
1316
  )
1317
 
1318
  roll_input.submit(
1319
  fn=search_student,
1320
+ inputs=roll_input, # Changed from [roll_input] to roll_input
1321
+ outputs=result_output
 
1322
  )
1323
 
1324
+ # 2. IP Details handlers - FIXED: Proper input parameter
1325
  subject_search_btn.click(
1326
  fn=extract_subjects_and_marks_for_gradio,
1327
+ inputs=subject_roll_input, # Changed from [subject_roll_input] to subject_roll_input
1328
+ outputs=subject_output
 
1329
  )
1330
 
1331
  subject_roll_input.submit(
1332
  fn=extract_subjects_and_marks_for_gradio,
1333
+ inputs=subject_roll_input, # Changed from [subject_roll_input] to subject_roll_input
1334
+ outputs=subject_output
 
1335
  )
1336
 
1337
+ # 3. System info handler - Correct (no inputs needed)
1338
  system_btn.click(
1339
  fn=get_system_info,
1340
  inputs=[],
1341
+ outputs=system_output
 
1342
  )
1343
 
1344
  # Footer section
 
1349
  """
1350
  <div style="text-align: center; margin-top: 20px; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 10px; color: white;">
1351
  <h3 style="margin: 0; color: white;">πŸ’» Developed with ❀️ by</h3>
1352
+ <a href="https://praneshjs.vercel.app" target="_blank" style="text-decoration: none;">
1353
  <h2 style="margin: 5px 0; color: #ffd700; cursor: pointer; transition: color 0.3s ease;">PRANESH S</h2>
1354
  </a>
1355
  <div style="margin: 15px 0;">
 
1382
  print(error_msg)
1383
  return "⚠️ System information will be available after data loads completely. Please click 'Get System Information' button to retry."
1384
 
1385
+ # Load system info on startup
1386
  app.load(
1387
  fn=initialize_system_info,
1388
  inputs=[],
1389
+ outputs=system_output
1390
  )
1391
 
1392
  # Launch the app