diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0086938 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +# Editors +.vscode/ +.idea/ + +# Vagrant +.vagrant/ + +# Mac/OSX +.DS_Store + +# Windows +Thumbs.db + +# Source for the following rules: https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +dist_chrome/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# node +node_modules/ + +average.txt +requirements.txt diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c328051 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.10-alpine + +# Copiez les fichiers nécessaires dans le conteneur +COPY getgrades.py . +# COPY average.txt . +# COPY grades.txt . +COPY requirements.txt . +COPY .env . + +# Installez les dépendances +RUN pip install --no-cache-dir -r requirements.txt + +# Commande pour exécuter votre programme Python +CMD ["python", "-u", "getgrades.py"] \ No newline at end of file diff --git a/getgrades.py b/getgrades.py new file mode 100644 index 0000000..92cf44b --- /dev/null +++ b/getgrades.py @@ -0,0 +1,130 @@ +import pronotepy +from pronotepy.ent import ile_de_france +from datetime import date +from datetime import datetime +import schedule +import time +import json +import requests +import os +from dotenv import load_dotenv +load_dotenv() +DISCORD_WEBHOOKS_PRONOTE = os.getenv("DISCORD_WEBHOOKS_PRONOTE") +ENT_USERNAME = os.getenv("ENT_USERNAME") +ENT_PASSWORD = os.getenv("ENT_PASSWORD") +path = 'new/pronote/' +path ='' + +def date_encoder(obj): + if isinstance(obj, date): + return obj.isoformat() + raise TypeError("Type not serializable") + +def envoyer_message_webhook(contenu): + data = { + 'content': contenu + } + response = requests.post(DISCORD_WEBHOOKS_PRONOTE, json=data) + if response.status_code == 204: + print(f'{datetime.now().strftime("%H:%M")} : Send') + else: + print(f"Échec de l'envoi du message. Code d'état : {response.status_code}") + +def refresh(send): + client = pronotepy.Client('https://0910626l.index-education.net/pronote/eleve.html', + username=ENT_USERNAME, + password=ENT_PASSWORD, + ent=ile_de_france) + if not client.logged_in: + exit(1) + + if send == 1: + with open(path + 'grades.txt', 'r') as file: + prev_grades = json.load(file) + + with open(path + 'average.txt', 'r') as file: + prev_average = json.load(file) + + new_average = client.periods[0].overall_average + + new_grades_list = [] + for period in client.periods: + for grade in period.grades: + obj = grade.date + gooddate = obj.isoformat() + grade_dict = { + 'grade': grade.grade, + 'average': grade.average, + 'coefficient': grade.coefficient, + 'comment': grade.comment, + 'date': gooddate, + 'default_out_of': grade.default_out_of, + # 'id': grade.id, + 'is_bonus': grade.is_bonus, + 'is_optional': grade.is_optionnal, + 'is_out_of_20': grade.is_out_of_20, + 'max': grade.max, + 'min': grade.min, + 'out_of': grade.out_of, + # 'period_id': grade.period.id, + 'period_name': grade.period.name, + # 'subject_id': grade.subject.id, + 'subject_groups': grade.subject.groups, + 'subject_name': grade.subject.name, + } + new_grades_list.append(grade_dict) + if send == 1: + if len(new_grades_list) != len(prev_grades): + changes = 0 + while len(new_grades_list) != len(prev_grades): + prev_grades.append('tmp') + for i,old in zip(new_grades_list, prev_grades): + + if i != old: + changes+=1 + if changes == 1: + content = f"""**{i['subject_name']}** : {i['comment']} + {datetime.strptime(str(i['date']), "%Y-%m-%d").strftime("%d %B %Y")} + **{i['grade']}/{i['out_of']}** | Coef : {i['coefficient']} + Moy : **{i['average']}/{i['out_of']}** + :arrow_up_small: : {i['max']}/{i['out_of']} | :arrow_down_small: : {i['min']}/{i['out_of']} + + Moy G : {new_average}({float(new_average)-float(prev_average)}) + """ + print('content: ', content) + envoyer_message_webhook(content) + else: + print(f'{datetime.now().strftime("%H:%M")} : No change') + + ################ + with open(path + 'grades.txt', 'w') as file: + json.dump(new_grades_list, file, indent=2, default=date_encoder) + + with open(path + 'average.txt', 'w') as file: + json.dump(new_average, file, indent=2) + + +# schedule.every(20).minutes.do(refresh) +# print('refresh: 20') +# while True: +# schedule.run_pending() +# time.sleep(1) + + +try: + refresh(send = 0) +except Exception as e: + print(e) + refresh(send = 0) +min = 20 +print('refresh rate: ', 20) +while True: + try: + refresh(send = 1) + except Exception as e: + print(e) + refresh(send = 1) + time.sleep(min*60) + +### debug +# refresh(send=1) \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..5f93b04 --- /dev/null +++ b/test.py @@ -0,0 +1,50 @@ +import pronotepy +from pronotepy.ent import ile_de_france +from datetime import date +from datetime import datetime +import schedule +import time +import json +import requests +import os +from dotenv import load_dotenv +load_dotenv() +DISCORD_WEBHOOKS_PRONOTE = os.getenv("DISCORD_WEBHOOKS_PRONOTE") +ENT_USERNAME = os.getenv("ENT_USERNAME") +ENT_PASSWORD = os.getenv("ENT_PASSWORD") + +client = pronotepy.Client('https://0910626l.index-education.net/pronote/eleve.html', + username=ENT_USERNAME, + password=ENT_PASSWORD, + ent=ile_de_france) +if not client.logged_in: + exit(1) + +new_average = client.periods[0].overall_average + +new_grades_list = [] +for period in client.periods: + for grade in period.grades: + grade_dict = { + 'grade': grade.grade, + 'average': grade.average, + 'coefficient': grade.coefficient, + 'comment': grade.comment, + 'date': grade.date, + 'default_out_of': grade.default_out_of, + 'id': grade.id, + 'is_bonus': grade.is_bonus, + 'is_optional': grade.is_optionnal, + 'is_out_of_20': grade.is_out_of_20, + 'max': grade.max, + 'min': grade.min, + 'out_of': grade.out_of, + 'period_id': grade.period.id, + 'period_name': grade.period.name, + 'subject_id': grade.subject.id, + 'subject_groups': grade.subject.groups, + 'subject_name': grade.subject.name, + } + new_grades_list.append(grade_dict) + +print(new_grades_list) \ No newline at end of file