Add hebece module implementation and rewrite of the code
This commit is contained in:
parent
1e6f30aec6
commit
7651641fd3
7 changed files with 154 additions and 356 deletions
0
src/impl/hebece/src/__init__.py
Normal file
0
src/impl/hebece/src/__init__.py
Normal file
|
@ -2,8 +2,9 @@ from datetime import datetime
|
||||||
import requests
|
import requests
|
||||||
import json
|
import json
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from signer import *
|
from impl.hebece.src.signer import *
|
||||||
from utils import *
|
from impl.hebece.src.utils import *
|
||||||
|
from impl.hebece.src.const import *
|
||||||
|
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
certificate, fingerprint, private_key = generate_key_pair()
|
certificate, fingerprint, private_key = generate_key_pair()
|
||||||
|
@ -27,109 +28,71 @@ def APILogin(login, password):
|
||||||
token_input = soup.find('input', {'name': '__RequestVerificationToken'})
|
token_input = soup.find('input', {'name': '__RequestVerificationToken'})
|
||||||
token = {"__RequestVerificationToken": token_input['value']}
|
token = {"__RequestVerificationToken": token_input['value']}
|
||||||
|
|
||||||
# Combine all cookies into a single string format for the Cookie header
|
|
||||||
cookies = {**response1.cookies.get_dict(), **response2.cookies.get_dict()}
|
cookies = {**response1.cookies.get_dict(), **response2.cookies.get_dict()}
|
||||||
cookies_str = "; ".join([f"{key}={value}" for key, value in cookies.items()])
|
cookies_str = "; ".join([f"{key}={value}" for key, value in cookies.items()])
|
||||||
cookies_str += f"; __RequestVerificationToken={token_input['value']}"
|
cookies_str += f"; __RequestVerificationToken={token_input['value']}"
|
||||||
|
|
||||||
# Prometheus
|
# Prometheus
|
||||||
url = "https://eduvulcan.pl/logowanie?ReturnUrl=%2fapi%2fap"
|
url = "https://eduvulcan.pl/logowanie?ReturnUrl=%2fapi%2fap"
|
||||||
headers = {
|
headers = makeLoginHeader(cookies_str)
|
||||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
|
||||||
"Accept-Encoding": "gzip, deflate, br, zstd",
|
|
||||||
"Accept-Language": "en-US,en;q=0.9",
|
|
||||||
"Cache-Control": "max-age=0",
|
|
||||||
"Connection": "keep-alive",
|
|
||||||
"Content-Type": "application/x-www-form-urlencoded",
|
|
||||||
"Cookie": cookies_str, # Use the formatted cookies string here
|
|
||||||
"Host": "eduvulcan.pl",
|
|
||||||
"Origin": "https://eduvulcan.pl",
|
|
||||||
"Referer": "https://eduvulcan.pl/logowanie?ReturnUrl=%2fapi%2fap",
|
|
||||||
"sec-ch-ua": "\"Chromium\";v=\"130\", \"Android WebView\";v=\"130\", \"Not?A_Brand\";v=\"99\"",
|
|
||||||
"sec-ch-ua-mobile": "?1",
|
|
||||||
"sec-ch-ua-platform": "\"Android\"",
|
|
||||||
"Sec-Fetch-Dest": "document",
|
|
||||||
"Sec-Fetch-Mode": "navigate",
|
|
||||||
"Sec-Fetch-Site": "same-origin",
|
|
||||||
"Sec-Fetch-User": "?1",
|
|
||||||
"Upgrade-Insecure-Requests": "1",
|
|
||||||
"User-Agent": "Mozilla/5.0 (Linux; Android 13; SM-G935F Build/TQ3A.230901.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Mobile Safari/537.36",
|
|
||||||
"X-Requested-With": "pl.edu.vulcan.hebe.ce",
|
|
||||||
}
|
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"Alias": login,
|
"Alias": login,
|
||||||
"Password": password,
|
"Password": password,
|
||||||
"captchaUser": "",
|
"captchaUser": "",
|
||||||
"__RequestVerificationToken": token_input['value'], # Use the actual token value here
|
"__RequestVerificationToken": token_input['value'],
|
||||||
}
|
}
|
||||||
|
|
||||||
response = session.post(url, headers=headers, data=data)
|
response = session.post(url, headers=headers, data=data)
|
||||||
content = response.text
|
content = response.text
|
||||||
cookie_jar = response.cookies.get_dict()
|
cookie_jar = response.cookies.get_dict()
|
||||||
|
|
||||||
soup = BeautifulSoup(content, "html.parser")
|
try:
|
||||||
input_element = soup.find("input", {"id": "ap"})
|
soup = BeautifulSoup(content, "html.parser")
|
||||||
value = input_element["value"]
|
input_element = soup.find("input", {"id": "ap"})
|
||||||
parsed_json = json.loads(value)
|
value = input_element["value"]
|
||||||
|
parsed_json = json.loads(value)
|
||||||
|
|
||||||
tokens = parsed_json.get("Tokens", [])
|
tokens = parsed_json.get("Tokens", [])
|
||||||
token = " ".join(tokens)
|
token = " ".join(tokens)
|
||||||
|
|
||||||
return token
|
return token
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
def JWTLogin(token, debug=False):
|
def JWTLogin(token, debug=False):
|
||||||
|
|
||||||
timestamp = datetime.now()
|
|
||||||
date = timestamp.strftime("%a, %d %b %Y %H:%M:%S GMT")
|
|
||||||
tenant = get_tenant_from_jwt(token)
|
tenant = get_tenant_from_jwt(token)
|
||||||
|
|
||||||
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/api/mobile/register/jwt"
|
|
||||||
|
|
||||||
NotificationToken = None
|
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}{JWT}"
|
||||||
RequestId = getRandomIdentifier() # Ensure this is a value (not a function)
|
|
||||||
|
RequestId = getRandomIdentifier()
|
||||||
|
SelfIdentifier = getRandomIdentifier()
|
||||||
|
|
||||||
OS = "Android"
|
|
||||||
Certificate = certificate
|
Certificate = certificate
|
||||||
CertificateThumbprint = fingerprint
|
CertificateThumbprint = fingerprint
|
||||||
SelfIdentifier = getRandomIdentifier() # Ensure this is a value (not a function)
|
|
||||||
Tokens = token
|
Tokens = token
|
||||||
DeviceModel = "SM-G935F"
|
|
||||||
|
|
||||||
signerurl = url
|
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body=None, full_url=url, timestamp=datetime.now())
|
||||||
signerbody = None
|
|
||||||
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, signerbody, signerurl, timestamp)
|
headers = makeHeader(signature, canonical_url)
|
||||||
|
|
||||||
headers = {
|
|
||||||
"accept-encoding": "gzip",
|
|
||||||
"content-type": "application/json",
|
|
||||||
"host": "lekcjaplus.vulcan.net.pl",
|
|
||||||
"signature": signature,
|
|
||||||
"user-agent": "Dart/3.3 (dart:io)",
|
|
||||||
"vapi": "1",
|
|
||||||
"vcanonicalurl": "api%2fmobile%2fregister%2fjwt",
|
|
||||||
"vdate": date,
|
|
||||||
"vos": "Android",
|
|
||||||
"vversioncode": "640",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bodytimestamp = getCurrentTimestamp()
|
|
||||||
|
|
||||||
|
timestamp = datetime.now()
|
||||||
|
date = getDate()
|
||||||
|
|
||||||
body = {
|
body = {
|
||||||
"AppName": "DzienniczekPlus 3.0",
|
"AppName": "DzienniczekPlus 3.0",
|
||||||
"AppVersion": "24.11.07 (G)",
|
"AppVersion": "24.11.07 (G)",
|
||||||
"NotificationToken": str(NotificationToken) if NotificationToken else None,
|
"NotificationToken": None,
|
||||||
"API": 1,
|
"API": 1,
|
||||||
"RequestId": str(RequestId), # Ensure RequestId is serializable
|
"RequestId": str(RequestId),
|
||||||
"Timestamp": bodytimestamp,
|
"Timestamp": getTimestamp(),
|
||||||
"TimestampFormatted": date,
|
"TimestampFormatted": str(date),
|
||||||
"Envelope": {
|
"Envelope": {
|
||||||
"OS": OS,
|
"OS": DEVICE_OS,
|
||||||
"Certificate": Certificate,
|
"Certificate": Certificate,
|
||||||
"CertificateType": "X509",
|
"CertificateType": "X509",
|
||||||
"DeviceModel": DeviceModel,
|
"DeviceModel": DEVICE,
|
||||||
"SelfIdentifier": str(SelfIdentifier), # Ensure serializability
|
"SelfIdentifier": str(SelfIdentifier),
|
||||||
"CertificateThumbprint": CertificateThumbprint,
|
"CertificateThumbprint": CertificateThumbprint,
|
||||||
"Tokens": [Tokens]
|
"Tokens": [Tokens]
|
||||||
}
|
}
|
||||||
|
@ -147,25 +110,11 @@ def JWTLogin(token, debug=False):
|
||||||
return content
|
return content
|
||||||
|
|
||||||
def HEBELogin(tenant, debug=False):
|
def HEBELogin(tenant, debug=False):
|
||||||
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/api/mobile/register/hebe?mode=2&lastSyncDate=1970-01-01%2001%3A00%3A00"
|
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}{HEBE}?mode=2&lastSyncDate=1970-01-01%2001%3A00%3A00"
|
||||||
signerurl = f"https://lekcjaplus.vulcan.net.pl/{tenant}/api/mobile/register/hebe?mode=2&lastSyncDate=1970-01-01%2001%3A00%3A00"
|
|
||||||
body = None
|
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body=None, full_url=url, timestamp=datetime.now())
|
||||||
timestamp1 = datetime.now()
|
|
||||||
date1 = timestamp1.strftime("%a, %d %b %Y %H:%M:%S GMT")
|
|
||||||
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body, signerurl, timestamp=timestamp1)
|
|
||||||
|
|
||||||
headers = {
|
headers = makeHeader(signature, canonical_url)
|
||||||
"accept-encoding": "gzip",
|
|
||||||
"content-type": "application/json",
|
|
||||||
"host": "lekcjaplus.vulcan.net.pl",
|
|
||||||
"signature": signature,
|
|
||||||
"user-agent": "Dart/3.3 (dart:io)",
|
|
||||||
"vapi": "1",
|
|
||||||
"vcanonicalurl": canonical_url,
|
|
||||||
"vdate": date1,
|
|
||||||
"vos": "Android",
|
|
||||||
"vversioncode": "640",
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
content = response.text
|
content = response.text
|
||||||
|
@ -178,65 +127,28 @@ def HEBELogin(tenant, debug=False):
|
||||||
|
|
||||||
def getLuckyNumber(tenant, schoolid, pupilid, constituentid, debug=False):
|
def getLuckyNumber(tenant, schoolid, pupilid, constituentid, debug=False):
|
||||||
timestamp = datetime.now()
|
timestamp = datetime.now()
|
||||||
date = timestamp.strftime("%Y-%m-%d")
|
date = timestamp.strftime("%Y-%m-%d")
|
||||||
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}/api/mobile/school/lucky?pupilId={pupilid}&constituentId={constituentid}&day={date}"
|
|
||||||
|
|
||||||
signerurl = url
|
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}{LUCKY}?pupilId={pupilid}&constituentId={constituentid}&day={date}"
|
||||||
body = None
|
|
||||||
date1 = timestamp.strftime("%a, %d %b %Y %H:%M:%S GMT")
|
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body=None, full_url=url, timestamp=datetime.now())
|
||||||
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body, signerurl, timestamp=timestamp)
|
headers = makeHeader(signature, canonical_url)
|
||||||
|
|
||||||
headers = {
|
|
||||||
"accept-encoding": "gzip",
|
|
||||||
"content-type": "application/json",
|
|
||||||
"host": "lekcjaplus.vulcan.net.pl",
|
|
||||||
"signature": signature,
|
|
||||||
"user-agent": "Dart/3.3 (dart:io)",
|
|
||||||
"vapi": "1",
|
|
||||||
"vcanonicalurl": canonical_url,
|
|
||||||
"vdate": date1,
|
|
||||||
"vos": "Android",
|
|
||||||
"vversioncode": "640",
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
content = response.text
|
content = response.text
|
||||||
|
|
||||||
data = json.loads(content)
|
|
||||||
Envelope = data.get("Envelope", {})
|
|
||||||
|
|
||||||
LuckyNumberDay = Envelope.get("Day", {})
|
|
||||||
LuckyNumber = Envelope.get("Number", {})
|
|
||||||
|
|
||||||
if debug:
|
if debug:
|
||||||
dinfo = getDebugInfo(content)
|
dinfo = getDebugInfo(content)
|
||||||
return LuckyNumber, LuckyNumberDay, dinfo
|
return content, dinfo
|
||||||
|
|
||||||
return LuckyNumber, LuckyNumberDay
|
return content
|
||||||
|
|
||||||
|
|
||||||
def getGrades(tenant, schoolid, pupilid, unitid, periodid, debug=False):
|
def getGrades(tenant, schoolid, pupilid, unitid, periodid, debug=False):
|
||||||
timestamp = datetime.now()
|
|
||||||
date = timestamp.strftime("%Y-%m-%d")
|
|
||||||
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}/api/mobile/grade/byPupil?unitId={unitid}&pupilId={pupilid}&periodId={periodid}&lastSyncDate=1970-01-01%2001%3A00%3A00&lastId=-2147483648&pageSize=500"
|
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}/api/mobile/grade/byPupil?unitId={unitid}&pupilId={pupilid}&periodId={periodid}&lastSyncDate=1970-01-01%2001%3A00%3A00&lastId=-2147483648&pageSize=500"
|
||||||
|
|
||||||
signerurl = url
|
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body=None, full_url=url, timestamp=datetime.now())
|
||||||
body = None
|
|
||||||
date1 = timestamp.strftime("%a, %d %b %Y %H:%M:%S GMT")
|
|
||||||
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body, signerurl, timestamp=timestamp)
|
|
||||||
|
|
||||||
headers = {
|
headers = makeHeader(signature, canonical_url)
|
||||||
"accept-encoding": "gzip",
|
|
||||||
"content-type": "application/json",
|
|
||||||
"host": "lekcjaplus.vulcan.net.pl",
|
|
||||||
"signature": signature,
|
|
||||||
"user-agent": "Dart/3.3 (dart:io)",
|
|
||||||
"vapi": "1",
|
|
||||||
"vcanonicalurl": canonical_url,
|
|
||||||
"vdate": date1,
|
|
||||||
"vos": "Android",
|
|
||||||
"vversioncode": "640",
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
content = response.text
|
content = response.text
|
||||||
|
@ -250,23 +162,10 @@ def getGrades(tenant, schoolid, pupilid, unitid, periodid, debug=False):
|
||||||
|
|
||||||
def getTimetable(tenant, schoolid, pupilid, start_date, end_date, debug=False):
|
def getTimetable(tenant, schoolid, pupilid, start_date, end_date, debug=False):
|
||||||
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}/api/mobile/schedule/withchanges/byPupil?pupilId={pupilid}&dateFrom={start_date}&dateTo={end_date}&lastId=-2147483648&pageSize=500&lastSyncDate=1970-01-01%2001%3A00%3A00"
|
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}/api/mobile/schedule/withchanges/byPupil?pupilId={pupilid}&dateFrom={start_date}&dateTo={end_date}&lastId=-2147483648&pageSize=500&lastSyncDate=1970-01-01%2001%3A00%3A00"
|
||||||
signerurl = url
|
|
||||||
body = None
|
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body=None, full_url=url, timestamp=datetime.now())
|
||||||
date1 = datetime.now().strftime("%a, %d %b %Y %H:%M:%S GMT")
|
|
||||||
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body, signerurl, timestamp=datetime.now())
|
|
||||||
|
|
||||||
headers = {
|
headers = makeHeader(signature, canonical_url)
|
||||||
"accept-encoding": "gzip",
|
|
||||||
"content-type": "application/json",
|
|
||||||
"host": "lekcjaplus.vulcan.net.pl",
|
|
||||||
"signature": signature,
|
|
||||||
"user-agent": "Dart/3.3 (dart:io)",
|
|
||||||
"vapi": "1",
|
|
||||||
"vcanonicalurl": canonical_url,
|
|
||||||
"vdate": date1,
|
|
||||||
"vos": "Android",
|
|
||||||
"vversioncode": "640",
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
content = response.text
|
content = response.text
|
||||||
|
@ -279,24 +178,10 @@ def getTimetable(tenant, schoolid, pupilid, start_date, end_date, debug=False):
|
||||||
|
|
||||||
def getExams(tenant, schoolid, pupilid, start_date, end_date, debug=False):
|
def getExams(tenant, schoolid, pupilid, start_date, end_date, debug=False):
|
||||||
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}/api/mobile/exam/byPupil?pupilId={pupilid}&dateFrom={start_date}&dateTo={end_date}&lastId=-2147483648&pageSize=500&lastSyncDate=1970-01-01%2001%3A00%3A00"
|
url = f"https://lekcjaplus.vulcan.net.pl/{tenant}/{schoolid}/api/mobile/exam/byPupil?pupilId={pupilid}&dateFrom={start_date}&dateTo={end_date}&lastId=-2147483648&pageSize=500&lastSyncDate=1970-01-01%2001%3A00%3A00"
|
||||||
signerurl = url
|
|
||||||
body = None
|
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body=None, full_url=url, timestamp=datetime.now())
|
||||||
date1 = datetime.now().strftime("%a, %d %b %Y %H:%M:%S GMT")
|
|
||||||
digest, canonical_url, signature = get_signature_values(fingerprint, private_key, body, signerurl, timestamp=datetime.now())
|
headers = makeHeader(signature, canonical_url)
|
||||||
|
|
||||||
headers = {
|
|
||||||
"accept-encoding": "gzip",
|
|
||||||
"content-type": "application/json",
|
|
||||||
"host": "lekcjaplus.vulcan.net.pl",
|
|
||||||
"signature": signature,
|
|
||||||
"user-agent": "Dart/3.3 (dart:io)",
|
|
||||||
"vapi": "1",
|
|
||||||
"vcanonicalurl": canonical_url,
|
|
||||||
"vdate": date1,
|
|
||||||
"vos": "Android",
|
|
||||||
"vversioncode": "640",
|
|
||||||
}
|
|
||||||
|
|
||||||
response = requests.get(url, headers=headers)
|
response = requests.get(url, headers=headers)
|
||||||
content = response.text
|
content = response.text
|
||||||
|
|
||||||
|
|
52
src/impl/hebece/src/const.py
Normal file
52
src/impl/hebece/src/const.py
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
from impl.hebece.src.utils import *
|
||||||
|
# Endpoints
|
||||||
|
|
||||||
|
JWT = "/api/mobile/register/jwt"
|
||||||
|
HEBE = "/api/mobile/register/hebe"
|
||||||
|
LUCKY = "/api/mobile/school/lucky"
|
||||||
|
GRADES = "/api/mobile/grade/byPupil"
|
||||||
|
TIMETABLE = "/api/mobile/schedule/withchanges/byPupil"
|
||||||
|
EXAMS = "/api/mobile/exam/byPupil"
|
||||||
|
|
||||||
|
# Header
|
||||||
|
DEVICE = "SM-G935F"
|
||||||
|
DEVICE_OS = "Android"
|
||||||
|
APPVERSION = "24.11.07 (G)"
|
||||||
|
|
||||||
|
def makeHeader(signature, canonical_url):
|
||||||
|
return {
|
||||||
|
"accept-encoding": "gzip",
|
||||||
|
"content-type": "application/json",
|
||||||
|
"host": "lekcjaplus.vulcan.net.pl",
|
||||||
|
"signature": signature,
|
||||||
|
"user-agent": "Dart/3.3 (dart:io)",
|
||||||
|
"vapi": "1",
|
||||||
|
"vcanonicalurl": canonical_url,
|
||||||
|
"vdate": getDate(),
|
||||||
|
"vos": DEVICE_OS,
|
||||||
|
"vversioncode": "640",
|
||||||
|
}
|
||||||
|
|
||||||
|
def makeLoginHeader(cookies):
|
||||||
|
return {
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||||
|
"Accept-Encoding": "gzip, deflate, br, zstd",
|
||||||
|
"Accept-Language": "en-US,en;q=0.9",
|
||||||
|
"Cache-Control": "max-age=0",
|
||||||
|
"Connection": "keep-alive",
|
||||||
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
|
"Cookie": cookies,
|
||||||
|
"Host": "eduvulcan.pl",
|
||||||
|
"Origin": "https://eduvulcan.pl",
|
||||||
|
"Referer": "https://eduvulcan.pl/logowanie?ReturnUrl=%2fapi%2fap",
|
||||||
|
"sec-ch-ua": "\"Chromium\";v=\"130\", \"Android WebView\";v=\"130\", \"Not?A_Brand\";v=\"99\"",
|
||||||
|
"sec-ch-ua-mobile": "?1",
|
||||||
|
"sec-ch-ua-platform": "\"Android\"",
|
||||||
|
"Sec-Fetch-Dest": "document",
|
||||||
|
"Sec-Fetch-Mode": "navigate",
|
||||||
|
"Sec-Fetch-Site": "same-origin",
|
||||||
|
"Sec-Fetch-User": "?1",
|
||||||
|
"Upgrade-Insecure-Requests": "1",
|
||||||
|
"User-Agent": "Mozilla/5.0 (Linux; Android 13; SM-G935F Build/TQ3A.230901.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/130.0.6723.107 Mobile Safari/537.36",
|
||||||
|
"X-Requested-With": "pl.edu.vulcan.hebe.ce",
|
||||||
|
}
|
|
@ -5,10 +5,9 @@ import hashlib
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
import base64
|
import base64
|
||||||
from signer import *
|
from impl.hebece.src.signer import *
|
||||||
from utils import *
|
from impl.hebece.src.utils import *
|
||||||
from sqlite import *
|
from impl.hebece.src.api import *
|
||||||
from api import *
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
@ -65,13 +64,9 @@ if __name__ == '__main__':
|
||||||
print(f"Lucky number: {LuckyNumber}")
|
print(f"Lucky number: {LuckyNumber}")
|
||||||
|
|
||||||
content, dinfoGRADE = getGrades(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, unitid=UnitID, periodid=PeriodID, debug=debug)
|
content, dinfoGRADE = getGrades(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, unitid=UnitID, periodid=PeriodID, debug=debug)
|
||||||
ImportGradesToSQLite(content)
|
|
||||||
print("Grades imported to SQLite database")
|
|
||||||
|
|
||||||
response, dinfoTIME = getTimetable(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, start_date=start_date, end_date=end_date, debug=debug)
|
response, dinfoTIME = getTimetable(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, start_date=start_date, end_date=end_date, debug=debug)
|
||||||
|
|
||||||
ImportTimetableToSQLite(response)
|
|
||||||
print("Timetable imported to SQLite database")
|
|
||||||
|
|
||||||
r = getTimetableForDay(day=today)
|
r = getTimetableForDay(day=today)
|
||||||
print(f"\nLessons for {today}:")
|
print(f"\nLessons for {today}:")
|
|
@ -1,174 +0,0 @@
|
||||||
import sqlite3
|
|
||||||
import json
|
|
||||||
|
|
||||||
def ImportGradesToSQLite(content):
|
|
||||||
data = json.loads(content)
|
|
||||||
|
|
||||||
conn = sqlite3.connect('grades.db')
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
cursor.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS grades (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
pupil_id INTEGER,
|
|
||||||
content_raw TEXT,
|
|
||||||
content TEXT,
|
|
||||||
value INTEGER,
|
|
||||||
description TEXT,
|
|
||||||
date_created TEXT,
|
|
||||||
date_modified TEXT,
|
|
||||||
creator_name TEXT,
|
|
||||||
creator_surname TEXT,
|
|
||||||
lesson_name TEXT,
|
|
||||||
lesson_code TEXT,
|
|
||||||
category_name TEXT,
|
|
||||||
category_code TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
for entry in data['Envelope']:
|
|
||||||
column = entry.get('Column') or {}
|
|
||||||
subject = column.get('Subject') or {}
|
|
||||||
category = column.get('Category') or {}
|
|
||||||
creator = entry.get('Creator') or {}
|
|
||||||
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT or IGNORE INTO grades (
|
|
||||||
id, pupil_id, content_raw, content, value, description,
|
|
||||||
date_created, date_modified, creator_name, creator_surname,
|
|
||||||
lesson_name, lesson_code, category_name, category_code
|
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
entry.get('Id'),
|
|
||||||
entry.get('PupilId'),
|
|
||||||
entry.get('ContentRaw'),
|
|
||||||
entry.get('Content'),
|
|
||||||
entry.get('Value'),
|
|
||||||
entry.get('Comment'),
|
|
||||||
entry.get('DateCreated', {}).get('DateDisplay'),
|
|
||||||
entry.get('DateModify', {}).get('DateDisplay'),
|
|
||||||
creator.get('Name'),
|
|
||||||
creator.get('Surname'),
|
|
||||||
subject.get('Name'),
|
|
||||||
subject.get('Kod'),
|
|
||||||
category.get('Name'),
|
|
||||||
category.get('Code')
|
|
||||||
))
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
def ImportTimetableToSQLite(content):
|
|
||||||
data = json.loads(content)
|
|
||||||
|
|
||||||
conn = sqlite3.connect('timetable.db')
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
cursor.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS timetable (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
date TEXT,
|
|
||||||
start_time TEXT,
|
|
||||||
end_time TEXT,
|
|
||||||
subject_name TEXT,
|
|
||||||
teacher_name TEXT,
|
|
||||||
teacher_surname TEXT,
|
|
||||||
room_code TEXT,
|
|
||||||
class_display TEXT,
|
|
||||||
position INTEGER
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
for entry in data['Envelope']:
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT OR IGNORE INTO timetable (
|
|
||||||
id, date, start_time, end_time, subject_name, teacher_name,
|
|
||||||
teacher_surname, room_code, class_display, position
|
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
entry.get('Id'),
|
|
||||||
entry.get('Date', {}).get('DateDisplay'),
|
|
||||||
entry.get('TimeSlot', {}).get('Start'),
|
|
||||||
entry.get('TimeSlot', {}).get('End'),
|
|
||||||
entry.get('Subject', {}).get('Name'),
|
|
||||||
entry.get('TeacherPrimary', {}).get('Name'),
|
|
||||||
entry.get('TeacherPrimary', {}).get('Surname'),
|
|
||||||
entry.get('Room', {}).get('Code'),
|
|
||||||
entry.get('Clazz', {}).get('DisplayName'),
|
|
||||||
entry.get('TimeSlot', {}).get('Position') or 0
|
|
||||||
))
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
def getTimetableForDay(day):
|
|
||||||
conn = sqlite3.connect('timetable.db')
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
def get_lessons_for_day_sorted(date):
|
|
||||||
cursor.execute('SELECT * FROM timetable WHERE date = ? ORDER BY position ASC', (date,))
|
|
||||||
lessons = cursor.fetchall()
|
|
||||||
return lessons
|
|
||||||
|
|
||||||
|
|
||||||
day_to_check = day
|
|
||||||
lessons_for_day_sorted = get_lessons_for_day_sorted(day_to_check)
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
return lessons_for_day_sorted
|
|
||||||
|
|
||||||
def ImportExamsToSQLite(content):
|
|
||||||
data = json.loads(content)
|
|
||||||
|
|
||||||
conn = sqlite3.connect("exams.db")
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
cursor.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS exams (
|
|
||||||
id INTEGER PRIMARY KEY,
|
|
||||||
type TEXT,
|
|
||||||
content TEXT,
|
|
||||||
date_created TEXT,
|
|
||||||
date_modified TEXT,
|
|
||||||
deadline TEXT,
|
|
||||||
creator_name TEXT,
|
|
||||||
creator_surname TEXT,
|
|
||||||
subject_name TEXT,
|
|
||||||
pupil_id INTEGER
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
for entry in data['Envelope']:
|
|
||||||
cursor.execute('''
|
|
||||||
INSERT OR IGNORE INTO exams (
|
|
||||||
id, type, content, date_created, date_modified, deadline,
|
|
||||||
creator_name, creator_surname, subject_name, pupil_id
|
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
entry.get('Id'),
|
|
||||||
entry.get('Type'),
|
|
||||||
entry.get('Content'),
|
|
||||||
entry.get('DateCreated', {}).get('DateDisplay'),
|
|
||||||
entry.get('DateModify', {}).get('DateDisplay'),
|
|
||||||
entry.get('Deadline', {}).get('DateDisplay'),
|
|
||||||
entry.get('Creator', {}).get('Name'),
|
|
||||||
entry.get('Creator', {}).get('Surname'),
|
|
||||||
entry.get('Subject', {}).get('Name'),
|
|
||||||
entry.get('PupilId')
|
|
||||||
))
|
|
||||||
|
|
||||||
conn.commit()
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
def getExamsForWeek(start_date, end_date):
|
|
||||||
conn = sqlite3.connect("exams.db")
|
|
||||||
cursor = conn.cursor()
|
|
||||||
|
|
||||||
cursor.execute('''
|
|
||||||
SELECT * FROM exams
|
|
||||||
WHERE deadline BETWEEN ? AND ?
|
|
||||||
ORDER BY deadline ASC
|
|
||||||
''', (start_date, end_date))
|
|
||||||
exams = cursor.fetchall()
|
|
||||||
conn.close()
|
|
||||||
return exams
|
|
|
@ -28,12 +28,6 @@ def get_tenant_from_jwt(token):
|
||||||
print(f"Error decoding JWT: {e}")
|
print(f"Error decoding JWT: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getCurrentTimestamp():
|
|
||||||
now = datetime.now()
|
|
||||||
Timestamp = int(now.timestamp())
|
|
||||||
|
|
||||||
return Timestamp
|
|
||||||
|
|
||||||
def getRandomIdentifier():
|
def getRandomIdentifier():
|
||||||
ruuid = str(uuid.uuid4())
|
ruuid = str(uuid.uuid4())
|
||||||
|
|
||||||
|
@ -48,4 +42,13 @@ def get_current_week():
|
||||||
end_of_week = start_of_week + timedelta(days=6)
|
end_of_week = start_of_week + timedelta(days=6)
|
||||||
|
|
||||||
# Return the dates as formatted strings
|
# Return the dates as formatted strings
|
||||||
return start_of_week.strftime('%Y-%m-%d'), end_of_week.strftime('%Y-%m-%d')
|
return start_of_week.strftime('%Y-%m-%d'), end_of_week.strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
def getDate():
|
||||||
|
return datetime.now().strftime("%a, %d %b %Y %H:%M:%S GMT")
|
||||||
|
|
||||||
|
def getTimestamp():
|
||||||
|
now = datetime.now()
|
||||||
|
Timestamp = now.timestamp()
|
||||||
|
|
||||||
|
return Timestamp
|
37
src/test.py
Normal file
37
src/test.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
from impl.hebece.src.api import *
|
||||||
|
from impl.hebece.src.sdkmain import *
|
||||||
|
from impl.hebece.src.utils import *
|
||||||
|
from impl.hebece.src.signer import *
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
today = datetime.today().strftime('%d-%m-%y')
|
||||||
|
start_date, end_date = get_current_week()
|
||||||
|
|
||||||
|
token = APILogin(login = input("login: "),password = input("password: "))
|
||||||
|
if not token:
|
||||||
|
print("You entered wrong login, password or VULCAN asked for captcha. Verify your login and password and try to log into eduVULCAN from your browser.")
|
||||||
|
input("Press Enter to exit...")
|
||||||
|
exit()
|
||||||
|
|
||||||
|
tenant = get_tenant_from_jwt(token)
|
||||||
|
|
||||||
|
content, dinfoJWT = JWTLogin(token, debug=True)
|
||||||
|
|
||||||
|
content, dinfoHEBE = HEBELogin(tenant, debug=True)
|
||||||
|
|
||||||
|
Name, SecondName, Surname, Class, PupilID, SchoolID, ConstituentID, UnitID, PeriodID = getUserInfo(tenant)
|
||||||
|
|
||||||
|
content, dinfoLUCK = getLuckyNumber(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, constituentid=ConstituentID, debug=True)
|
||||||
|
|
||||||
|
content, dinfoGRADE = getGrades(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, unitid=UnitID, periodid=PeriodID, debug=True)
|
||||||
|
|
||||||
|
content, dinfoTIME = getTimetable(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, start_date=start_date, end_date=end_date, debug=True)
|
||||||
|
|
||||||
|
content, dinfoEXAM = getExams(tenant=tenant, schoolid=SchoolID, pupilid=PupilID, start_date=start_date, end_date=end_date, debug=True)
|
||||||
|
|
||||||
|
print(f"\nJWT Status: {dinfoJWT[0]} {dinfoJWT[1]}")
|
||||||
|
print(f"HEBE Status: {dinfoHEBE[0]} {dinfoHEBE[1]}")
|
||||||
|
print(f"Lucky Number Status: {dinfoLUCK[0]} {dinfoLUCK[1]}")
|
||||||
|
print(f"Grades Status: {dinfoGRADE[0]} {dinfoGRADE[1]}")
|
||||||
|
print(f"Timetable Status: {dinfoTIME[0]} {dinfoTIME[1]}")
|
||||||
|
print(f"Exams Status: {dinfoEXAM[0]} {dinfoEXAM[1]}")
|
Loading…
Add table
Reference in a new issue