Téléchargement fonctionnel + création d'agenda google.
This commit is contained in:
parent
510589b375
commit
642c82f7f2
2 changed files with 98 additions and 56 deletions
|
@ -1,5 +1,6 @@
|
|||
Un script du cancer codé avec les pieds pour aller chercher l'emploi du temps
|
||||
sur NTNOE.
|
||||
Un script pour aller chercher l'emploi du temps
|
||||
sur NTNOE. Il crée un agenda `ntnoe` dans votre Google agenda pour y
|
||||
synchroniser l'agenda NTNOE.
|
||||
|
||||
Vous avec besoin d'une clé API google, allez la chercher
|
||||
[ici](https://developers.google.com/google-apps/calendar/quickstart/python) et
|
||||
|
@ -17,6 +18,4 @@ Créez un fichier `ntnoe_credentials` sur le modèle de
|
|||
python3 main.py
|
||||
```
|
||||
|
||||
Par contre ça gère pas les modifications de cours de façon tip top, donc
|
||||
synchronisez pas trop dans le future. Pour modifier ce temps, voir la variable
|
||||
`TIMEDELTA_SYNCHRO`.
|
||||
Après le tout s'automatise bien avec un petit `cron` des familles.
|
||||
|
|
115
main.py
115
main.py
|
@ -1,9 +1,38 @@
|
|||
"""
|
||||
NTNOE SYNC is a simple script tha allows you to synchronize your NTNOE diary
|
||||
with Google Calendar.
|
||||
|
||||
It will create a `ntnoe` calendar among your Google calendars and write your
|
||||
NTNOE calendar into. NTNOE_SYNC is availabe under the MIT license.
|
||||
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Hugo LEVY-FALK
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import httplib2
|
||||
import urllib
|
||||
import os
|
||||
import requests
|
||||
import shutil
|
||||
|
||||
from apiclient import discovery
|
||||
from oauth2client import client
|
||||
|
@ -13,18 +42,22 @@ from oauth2client.file import Storage
|
|||
import icalendar
|
||||
|
||||
|
||||
TIMEDELTA_SYNCHRO = datetime.timedelta(days=7) # Number of days to look for
|
||||
TIMEDELTA_SYNCHRO = datetime.timedelta(days=15) # Number of days to look for
|
||||
# for synchronization
|
||||
|
||||
with open('ntnoe_credentials') as f:
|
||||
NTNOE_ID, NTNOE_PASS, _ = f.read().split('\n')
|
||||
|
||||
|
||||
SCOPES = 'https://www.googleapis.com/auth/calendar'
|
||||
CLIENT_SECRET_FILE = 'client_secret.json'
|
||||
APPLICATION_NAME = 'Google Calendar API Python Quickstart'
|
||||
|
||||
|
||||
class Event:
|
||||
"""
|
||||
The event class allows a simple convertion between `icalendar.cal.Event`
|
||||
and a formatted `dict` for the google API.
|
||||
"""
|
||||
|
||||
# ColorId corresponding to course code
|
||||
EVENT_COLOR = {
|
||||
'9': '9', # Amphi
|
||||
|
@ -41,12 +74,14 @@ class Event:
|
|||
self.start = e.decoded('DTSTART')
|
||||
self.end = e.decoded('DTEND')
|
||||
self.location = e.decoded('LOCATION').decode('utf-8')
|
||||
self.colorid = self.EVENT_COLOR.get(e.decoded('DESCRIPTION').decode('utf-8'), '1')
|
||||
self.colorid = self.EVENT_COLOR.get(
|
||||
e.decoded('DESCRIPTION').decode('utf-8'), '1')
|
||||
|
||||
def __str__(self):
|
||||
return str(self.as_google())
|
||||
|
||||
def as_google(self):
|
||||
"""Returns the event as a formatted `dict` for the google API."""
|
||||
return {
|
||||
'summary': self.summary,
|
||||
'location': self.location,
|
||||
|
@ -63,6 +98,7 @@ class Event:
|
|||
'useDefault': False,
|
||||
'overrides': [],
|
||||
},
|
||||
'description': 'ntnoe_calendar',
|
||||
|
||||
}
|
||||
|
||||
|
@ -94,48 +130,58 @@ def get_credentials():
|
|||
|
||||
|
||||
def get_ntnoe():
|
||||
url = "http://ntnoe.metz.supelec.fr/ical/EdTcustom/Eleves/edt_{}.ics"
|
||||
url = url.format(NTNOE_ID)
|
||||
|
||||
data = {'envoyer':'Utf8_All','submit':'Générer'}
|
||||
|
||||
r = requests.get(
|
||||
"""Retrieves the calendar on NTNOE."""
|
||||
r = requests.post(
|
||||
"https://ntnoe.metz.supelec.fr/ical/index.php",
|
||||
data=urllib.parse.urlencode(data),
|
||||
data={"envoyer":"Utf8_All","submit":"G%E9n%E9rer"},
|
||||
auth=(NTNOE_ID, NTNOE_PASS),
|
||||
)
|
||||
url = "https://ntnoe.metz.supelec.fr/ical/EdTcustom/Eleves/edt_{id}.ics".format(id=NTNOE_ID)
|
||||
r = requests.get(url, auth=(NTNOE_ID, NTNOE_PASS), stream=True)
|
||||
with open("edt_{}.ics".format(NTNOE_ID), 'wb') as f:
|
||||
f.write(r.content)
|
||||
|
||||
url = "https://ntnoe.metz.supelec.fr/ical/EdTcustom/Eleves/edt_{}.ics"
|
||||
url = url.format(NTNOE_ID)
|
||||
r = requests.get(url, auth=(NTNOE_ID, NTNOE_PASS))
|
||||
return r.content
|
||||
|
||||
def main():
|
||||
"""Get the events on NTNOE the puts them on Google Calendar.
|
||||
|
||||
"""
|
||||
get_ntnoe()
|
||||
credentials = get_credentials()
|
||||
http = credentials.authorize(httplib2.Http())
|
||||
service = discovery.build('calendar', 'v3', http=http)
|
||||
|
||||
with open("edt_" + NTNOE_ID + ".ics") as f:
|
||||
c = icalendar.Calendar.from_ical(f.read())
|
||||
ical = icalendar.Calendar.from_ical(get_ntnoe())
|
||||
|
||||
calendars = service.calendarList().list().execute()
|
||||
ntnoe_calendar_id = None
|
||||
for c in calendars['items']:
|
||||
if c['summary'] == 'ntnoe':
|
||||
ntnoe_calendar_id = c['id']
|
||||
|
||||
if not ntnoe_calendar_id:
|
||||
print("Creating ntnoe calendar...")
|
||||
created = service.calendars().insert(body={
|
||||
'defaultReminders' : [],
|
||||
'selected' : True,
|
||||
'summary' : 'ntnoe',
|
||||
}).execute()
|
||||
ntnoe_calendar_id = created['id']
|
||||
|
||||
now = datetime.datetime.now()
|
||||
then = now + TIMEDELTA_SYNCHRO
|
||||
time_search = datetime.datetime(now.year, now.month, now.day, 1)
|
||||
response = service.events().list(
|
||||
calendarId='primary',
|
||||
timeMin=time_search.isoformat()+'Z',
|
||||
timeMax=then.isoformat()+'Z',
|
||||
|
||||
former_ones = service.events().list(
|
||||
calendarId=ntnoe_calendar_id,
|
||||
).execute()
|
||||
|
||||
existing_events = set()
|
||||
for e in response['items']:
|
||||
if 'summary' in e.keys():
|
||||
existing_events.add(e['summary'])
|
||||
for e in c.walk('VEVENT'):
|
||||
for event in former_ones['items']:
|
||||
print('Deleting event : {}'.format(event['id']))
|
||||
service.events().delete(
|
||||
calendarId=ntnoe_calendar_id,
|
||||
eventId=event['id']
|
||||
).execute()
|
||||
|
||||
for e in ical.walk('VEVENT'):
|
||||
event = Event(e)
|
||||
t = (
|
||||
event.summary,
|
||||
|
@ -146,15 +192,12 @@ def main():
|
|||
if now >= event.end or event.start >= then:
|
||||
continue
|
||||
|
||||
if existing_events.intersection({event.summary}):
|
||||
continue
|
||||
|
||||
event = service.events().insert(
|
||||
calendarId='primary',
|
||||
calendarId=ntnoe_calendar_id,
|
||||
body=event.as_google()
|
||||
).execute()
|
||||
print("Added event : {}".format(event.get('htmlLink')))
|
||||
print("Adding event : {}".format(event['id']))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
|
|
Loading…
Reference in a new issue