Last active
January 27, 2016 17:51
-
-
Save bm371613/930066fd2b5ec91bb6bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import email.mime.text | |
import json | |
import os | |
import smtplib | |
import sys | |
import urllib.parse | |
import bs4 | |
import requests | |
URL = "https://logowanie.aps.edu.pl/cas/login?service=https://usosweb.aps.edu.pl/kontroler.php?_action=dla_stud/studia/oceny/index&locale=pl" | |
USERNAME = os.environ.get("USERNAME") | |
PASSWORD = os.environ.get("PASSWORD") | |
DATA_FILE = "data.json" | |
EMAIL = os.environ.get("EMAIL") | |
def usage(): | |
print(""" | |
Usage: | |
%s <cmd> | |
Available commands: | |
print download and print grades | |
init download and save grades | |
check download grades, compare with saved, email about changes, save | |
""" % sys.argv[0]) | |
sys.exit(1) | |
def fetch_grades_page(): | |
s = requests.Session() | |
login_page = bs4.BeautifulSoup(s.get(URL).content, 'html.parser') | |
login_form = login_page.form | |
form_data = {i["name"]: i["value"] for i in login_form.find_all('input')} | |
form_data["username"] = USERNAME | |
form_data["password"] = PASSWORD | |
grades_response = s.request( | |
login_form['method'], | |
urllib.parse.urljoin(URL, login_form['action']), | |
data=form_data, | |
) | |
return bs4.BeautifulSoup(grades_response.content, 'html.parser') | |
def parse_grades(grades_page): | |
result = [] | |
tbodys = grades_page.find_all('tbody') | |
for header_tbody, group_tbody in zip(tbodys[::2], tbodys[1::2]): | |
group_name = header_tbody.text.split("-")[0].strip() | |
for grade_tr in group_tbody.find_all('tr'): | |
name = grade_tr.a.text | |
grade = " ".join( | |
s.text for s in grade_tr.find_all('td')[2].find_all('span') | |
) | |
result.append((group_name, name, grade)) | |
return result | |
def extract_changed(old_grades, grades): | |
old_dict = { | |
(g[0], g[1]): g[2] | |
for g in old_grades | |
} | |
return list(filter(lambda g: old_dict.get((g[0], g[1])) != g[2], grades)) | |
def notify(changed_grades): | |
content = "Changed grades:\n\n" + "\n".join( | |
g[1] + ": " + g[2] for g in changed_grades | |
) | |
print("SENDING NOTIFICATION") | |
print(content) | |
msg = email.mime.text.MIMEText(content, "plain", "utf-8") | |
msg['Subject'] = "Your grades have changed!" | |
msg['From'] = "usos_grades_check" | |
msg['To'] = EMAIL | |
s = smtplib.SMTP('localhost') | |
s.send_message(msg) | |
s.quit() | |
def print_(): | |
grades = parse_grades(fetch_grades_page()) | |
print(json.dumps(grades, indent=4)) | |
def init(): | |
grades = parse_grades(fetch_grades_page()) | |
with open(DATA_FILE, 'w') as f: | |
json.dump(grades, f, indent=4) | |
def check(): | |
with open(DATA_FILE) as f: | |
old_grades = json.load(f) | |
grades = parse_grades(fetch_grades_page()) | |
if not grades: | |
print("FAILED TO FETCH GRADES") | |
sys.exit(2) | |
changed = extract_changed(old_grades, grades) | |
if changed: | |
notify(changed) | |
with open(DATA_FILE, 'w') as f: | |
json.dump(grades, f, indent=4) | |
if __name__ == '__main__': | |
if len(sys.argv) < 2: | |
usage() | |
cmd = sys.argv[1] | |
if cmd == "print": | |
print_() | |
elif cmd == "init": | |
init() | |
elif cmd == "check": | |
check() | |
else: | |
usage() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment