Spaces:
Running
Running
fixed formating issues and expected 1 but got 0 issue
Browse files
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
|
|
|
|
|
|
|
|
|
|
| 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 (
|
| 827 |
|
| 828 |
while True:
|
|
|
|
| 829 |
try:
|
| 830 |
if data_cache["is_loading"]:
|
| 831 |
-
print("β³ Watcher: Skipping check
|
| 832 |
-
|
| 833 |
-
|
| 834 |
-
|
| 835 |
-
|
| 836 |
-
|
| 837 |
-
|
| 838 |
-
|
| 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 |
-
|
| 856 |
-
|
| 857 |
-
|
| 858 |
-
|
| 859 |
-
|
| 860 |
-
|
| 861 |
-
|
| 862 |
-
|
| 863 |
-
|
| 864 |
-
|
| 865 |
-
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
|
| 870 |
-
|
| 871 |
-
|
| 872 |
-
|
| 873 |
-
|
| 874 |
-
|
| 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 |
-
|
| 884 |
-
print(f"
|
| 885 |
else:
|
| 886 |
-
|
| 887 |
-
|
| 888 |
-
|
| 889 |
-
|
| 890 |
-
|
| 891 |
-
|
| 892 |
-
|
| 893 |
-
|
| 894 |
|
| 895 |
-
if
|
| 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)[:
|
| 902 |
watcher_client = None
|
| 903 |
watcher_spreadsheet = None
|
|
|
|
| 904 |
if consecutive_errors >= max_errors:
|
| 905 |
-
|
| 906 |
-
|
| 907 |
-
time.sleep(error_wait)
|
| 908 |
consecutive_errors = 0
|
| 909 |
|
| 910 |
-
|
|
|
|
|
|
|
|
|
|
| 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 -
|
| 1310 |
|
| 1311 |
# 1. Student search handlers
|
| 1312 |
search_btn.click(
|
| 1313 |
fn=search_student,
|
| 1314 |
-
inputs=[roll_input]
|
| 1315 |
-
outputs=
|
| 1316 |
-
api_name="search_student"
|
| 1317 |
)
|
| 1318 |
|
| 1319 |
roll_input.submit(
|
| 1320 |
fn=search_student,
|
| 1321 |
-
inputs=[roll_input]
|
| 1322 |
-
outputs=
|
| 1323 |
-
api_name="search_student_submit"
|
| 1324 |
)
|
| 1325 |
|
| 1326 |
-
# 2. IP Details handlers -
|
| 1327 |
subject_search_btn.click(
|
| 1328 |
fn=extract_subjects_and_marks_for_gradio,
|
| 1329 |
-
inputs=[subject_roll_input]
|
| 1330 |
-
outputs=
|
| 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=
|
| 1338 |
-
api_name="get_ip_details_submit"
|
| 1339 |
)
|
| 1340 |
|
| 1341 |
-
# 3. System info handler -
|
| 1342 |
system_btn.click(
|
| 1343 |
fn=get_system_info,
|
| 1344 |
inputs=[],
|
| 1345 |
-
outputs=
|
| 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://
|
| 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
|
| 1391 |
app.load(
|
| 1392 |
fn=initialize_system_info,
|
| 1393 |
inputs=[],
|
| 1394 |
-
outputs=
|
| 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
|