143 lines
3.6 KiB
Python
143 lines
3.6 KiB
Python
from getpass import getpass
|
|
from robobrowser import RoboBrowser
|
|
from re import compile
|
|
|
|
url = 'https://galilei-cr-sito.registroelettronico.com/'
|
|
url_main = url + 'news'
|
|
url_login = url + 'login'
|
|
url_marks = url + 'votes/?s='
|
|
|
|
subjects = {}
|
|
br = RoboBrowser(history=False)
|
|
|
|
|
|
def login(user, password):
|
|
'''Authenticate the user'''
|
|
br.open(url_login)
|
|
|
|
# Fill in the login form
|
|
form = br.get_form(id='loginform')
|
|
form['username'].value = user
|
|
form['password'].value = password
|
|
br.submit_form(form)
|
|
|
|
# Check if authenticated
|
|
if 'errati' in br.response.text:
|
|
return False
|
|
return True
|
|
|
|
|
|
def means():
|
|
'''Compute mean for each subject'''
|
|
for i in subjects.keys():
|
|
yield _mean(list(get_marks(i)))
|
|
|
|
|
|
def get_name():
|
|
'''Find the student's name from the registry'''
|
|
br.open(url_main)
|
|
|
|
# Get the content of 'h2' tag with ID 'student_name'
|
|
name = br.select('h2#student_name')[0].text.split()
|
|
return ' '.join([name[-1]] + name[:-1])
|
|
|
|
|
|
def get_subjects():
|
|
'''Create a reversed dictionary of type (subject, id)'''
|
|
br.open(url_main)
|
|
links = br.get_links(href=compile('votes/\?s=\d+'))
|
|
return {i.text.capitalize(): i.attrs['href'][-7:] for i in links}
|
|
|
|
|
|
def get_marks(subject):
|
|
'''Returned the list of marks for a subject'''
|
|
br.open(url_marks + str(subjects[subject]))
|
|
res = br.find_all(text=compile(r'^(\d{1,2}(\+|-|\.\d{1,2})?) '))
|
|
return _parse(i[0:-1] for i in res)
|
|
|
|
|
|
def _parse(marks):
|
|
'''
|
|
Parse marks into floats:
|
|
NC -> 0
|
|
A -> nothing
|
|
n+ -> n + 0.25
|
|
n- -> n - 0.25
|
|
n -> n
|
|
'''
|
|
for i in marks:
|
|
try:
|
|
yield float(i)
|
|
except ValueError:
|
|
if i == 'A':
|
|
pass
|
|
elif i == 'NC':
|
|
yield 0
|
|
elif i[1] == '+':
|
|
yield float(i[0]) + 0.25
|
|
elif i[1] == '-':
|
|
yield float(i[0]) - 0.25
|
|
elif i[2] == '-':
|
|
yield float(i[:-1]) - 0.25
|
|
|
|
|
|
def _mean(marks):
|
|
'''Mean of a list of marks'''
|
|
marks = list(marks)
|
|
return sum(marks) / len(marks)
|
|
|
|
|
|
def _show_means():
|
|
'''Show general mean and for each subject [Procedure]'''
|
|
# Print id, subject, mean for every subject
|
|
print('Media generale: %.2f' % _mean(means()))
|
|
for id, (subject, voto) in enumerate(zip(subjects.keys(), means())):
|
|
print('%d. %s: %.2f' % (id + 1, subject, voto))
|
|
|
|
|
|
def _show_marks():
|
|
'''Prompt for a subject and show the marks [Procedure]'''
|
|
for i, subject in enumerate(subjects.keys()):
|
|
print('%d. %s' % (i + 1, subject))
|
|
while True:
|
|
print('')
|
|
id = int(input('Materia: '))
|
|
if id in range(15):
|
|
name = list(subjects.keys())[id - 1]
|
|
print(name)
|
|
print('Voti:', *get_marks(name))
|
|
print('Media: %.2f' % _mean(get_marks(name)))
|
|
else:
|
|
print('Inserire numero corretto!')
|
|
|
|
|
|
def main():
|
|
# Authentication
|
|
logged = False
|
|
while not logged:
|
|
user, password = input('Username: '), getpass('Password: ')
|
|
logged = login(user, password)
|
|
if not logged:
|
|
print('Autenticazione fallita, riprovare.')
|
|
print('Connesso come %s.\n' % get_name())
|
|
|
|
# So we don't need to recompute every time
|
|
global subjects
|
|
subjects = get_subjects()
|
|
|
|
# Menu
|
|
while True:
|
|
mode = input('Scegli [v]oti o [m]edie: ')
|
|
print('')
|
|
if mode == 'v':
|
|
_show_marks()
|
|
elif mode == 'm':
|
|
_show_means()
|
|
input()
|
|
|
|
if __name__ == '__main__':
|
|
try:
|
|
main()
|
|
except KeyboardInterrupt:
|
|
print('')
|