#!/usr/bin/env python3
import os
import pickle
import pytz
import requests
import auth # from auth.py
import json
from datetime import datetime, timedelta
GRADES_FILE = "grades.pkl"
def get(endpoint, credentials):
headers = {
"Authorization": f'Bearer {credentials.access_token}',
"Accept": 'application/json',
"Origin": 'https://somtoday.nl',
"Range": 'items=0-1000'
}
url = f'{credentials.api_url}{endpoint}'
response = requests.get(url, headers=headers)
return response.json()
def fetch_student_id(credentials):
data = get('/rest/v1/leerlingen', credentials)
return data['items'][0]['links'][0]['id']
def fetch_grades(student_id, credentials):
data = get(f'/rest/v1/resultaten/huidigVoorLeerling/{student_id}', credentials)
items = data['items']
# We're not interested in averages, we're only interested in the grades themselves.
useless_types = ["PeriodeGemiddeldeKolom", "RapportGemiddeldeKolom", "SEGemiddeldeKolom"]
useless_subjects = ["4a-in", "5a-in", "6a-in", "LOB", "MEN", "PWS", "LO"]
items = list(filter(lambda item: not item['type'] in useless_types, items))
items = list(filter(lambda item: not item["vak"]["afkorting"] in useless_subjects, items))
# Filter out grades that do not actually contain a grade. Ghost grades.
items = list(filter(lambda item: "geldendResultaat" in item or "resultaatLabelAfkorting" in item, items))
sort_by_datetime = lambda x: parse_item_datetime(x)
items = sorted(items, key = sort_by_datetime, reverse = True)
grade_list = []
for grade in items:
try: result = grade["geldendResultaat"]
# For letter grades, as opposed to 1-10 results.
except KeyError: result = grade["resultaatLabelAfkorting"]
datetime = parse_item_datetime(grade).strftime("%d/%m/%Y %H:%M:%S")
subject = grade["vak"]["naam"]
title = grade["omschrijving"]
weight = grade["weging"]
grade_list.append({
"result": result,
"datetime": datetime,
"subject": subject,
"title": title,
"weight": weight
})
return grade_list
def diff_grades(credentials):
student_id = fetch_student_id(credentials)
grade_list = fetch_grades(student_id, credentials)
if grade_list != load_existing_grades():
write_new_grades(grade_list)
subject = grade_list[0]["subject"]
send_notification(f'New grade for {subject}')
def send_notification(message):
body = {
"content": message,
"components": [],
"actions": {}
}
endpoint = "https://discord.com/api/webhooks/..."
requests.post(endpoint, json=body)
# Helpers
def parse_item_datetime(item):
return datetime.strptime(item["datumInvoer"], "%Y-%m-%dT%H:%M:%S.%f%z")
def load_existing_grades():
if not os.path.isfile(GRADES_FILE):
return []
else:
with open(GRADES_FILE, "rb") as file:
return pickle.load(file)
def write_new_grades(grades):
with open(GRADES_FILE, "wb") as file:
pickle.dump(grades, file)
# Main program :)
credentials = auth.refresh()
student_id = fetch_student_id(credentials)
diff_grades(credentials)
Simple script that sends Discord notifications when teachers publish grades