-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsync.py
More file actions
147 lines (112 loc) · 4.72 KB
/
sync.py
File metadata and controls
147 lines (112 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import os
from dataclasses import dataclass
from typing import Optional
from playwright.sync_api import Browser, BrowserContext, Page, Playwright
VPN_URL = "https://gateway.iiserb.ac.in/remote/login"
SHIKSHA_LOGIN_URL = "https://shiksha.iiserb.ac.in/login/"
VPN_USER_ENV = "IISERB_VPN_USER"
VPN_PASS_ENV = "IISERB_VPN_PASS"
SHIKSHA_USER_ENV = "SHIKSHA_USER"
SHIKSHA_PASS_ENV = "SHIKSHA_PASS"
class SessionExpiredError(RuntimeError):
"""Raised when the VPN or Shiksha session has expired and re-login is required."""
def _require_env(name: str) -> str:
value = os.getenv(name)
if not value:
raise RuntimeError(
f"Missing required environment variable: {name}. "
"Set it before running (e.g., in PowerShell: $env:NAME='value')."
)
return value
@dataclass(frozen=True)
class Session:
browser: Browser
context: BrowserContext
shiksha_page: Page
def _looks_like_vpn_login(page: Page) -> bool:
try:
return (
page.locator("input[id='username']").count() > 0
and page.locator("input[id='credential']").count() > 0
and page.locator("button[id='login_button']").count() > 0
)
except Exception:
return False
def _looks_like_shiksha_login(page: Page) -> bool:
try:
return (
page.locator("input[id='ldap']").count() > 0
and page.locator("input[id='secret']").count() > 0
)
except Exception:
return False
def start_session(
p: Playwright,
*,
headless: bool = False,
) -> Session:
vpn_user = _require_env(VPN_USER_ENV)
vpn_pass = _require_env(VPN_PASS_ENV)
shiksha_user = _require_env(SHIKSHA_USER_ENV)
shiksha_pass = _require_env(SHIKSHA_PASS_ENV)
browser = p.chromium.launch(headless=headless)
context = browser.new_context()
page = context.new_page()
# 1) Login to VPN
page.goto(VPN_URL, wait_until="networkidle")
page.fill("input[id='username']", vpn_user)
page.fill("input[id='credential']", vpn_pass)
page.click("button[id='login_button']")
page.wait_for_load_state("networkidle")
# 2) Open Shiksha through VPN URL field
url_input = page.locator("input[name='url']")
url_input.wait_for(state="visible")
url_input.fill(SHIKSHA_LOGIN_URL)
with context.expect_page() as new_page_info:
url_input.press("Enter")
shiksha_page = new_page_info.value
shiksha_page.wait_for_load_state("networkidle")
# 3) Login to Shiksha
shiksha_page.fill("input[id='ldap']", shiksha_user)
shiksha_page.fill("input[id='secret']", shiksha_pass)
shiksha_page.click("button[type='submit']")
shiksha_page.wait_for_load_state("networkidle")
# 4) Go to student reports
goto_student_reports(shiksha_page)
return Session(browser=browser, context=context, shiksha_page=shiksha_page)
def goto_student_reports(shiksha_page: Page) -> None:
target_url = shiksha_page.url
if "/studenthome" in target_url:
target_url = target_url.replace("/studenthome", "/studentReports")
elif not target_url.endswith("/studentReports") and "/studentReports" not in target_url:
# If already logged in but not on a known route, best-effort navigate.
target_url = "https://shiksha.iiserb.ac.in/studentReports"
shiksha_page.goto(target_url, wait_until="networkidle")
def count_report_rows(shiksha_page: Page, *, reload_first: bool = True) -> int:
if reload_first:
shiksha_page.reload(wait_until="networkidle")
else:
shiksha_page.wait_for_load_state("networkidle")
if _looks_like_vpn_login(shiksha_page):
raise SessionExpiredError("VPN session appears to have expired (VPN login page shown).")
if _looks_like_shiksha_login(shiksha_page):
raise SessionExpiredError("Shiksha session appears to have expired (Shiksha login page shown).")
# Ensure we're on the reports page (some redirects keep you logged in but move away).
goto_student_reports(shiksha_page)
shiksha_page.wait_for_load_state("networkidle")
if _looks_like_vpn_login(shiksha_page):
raise SessionExpiredError("VPN session appears to have expired after navigation.")
if _looks_like_shiksha_login(shiksha_page):
raise SessionExpiredError("Shiksha session appears to have expired after navigation.")
rows = shiksha_page.locator("table tbody tr").count()
return rows
if __name__ == "__main__":
# One-shot manual run (closes browser when done).
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
session = start_session(p, headless=False)
try:
rows = count_report_rows(session.shiksha_page)
print("Current row count:", rows)
finally:
session.browser.close()