Benoit DebledSoftware Developer
Enhance iCal Calendars
My university uses a web app called HyperPlanning to communicate students schedule.
Unfortunately, the title of every classes I have is full of useless information which make my schedule unreadable at a first glance! So, I’ve decided to do something about it, and I’ve created a small Python script that would rename each event into a more readable version of it.
So the principle is very simple : I’ve created a script on my server that download every hour the .ics file of the calendar I wish to enhance. Once downloaded, I look if an event’s title contains a specific string. If it does, then I replace the event’s title with a readable title. I put then the new .ics file to a web server.
This program is basically based on two libraries :
- urllib3 to download the .ics from the school server
- icalendar to parse and modify the iCal To reduce the ics file, I deleted any classes from the semester I was not in. To do that, it was easier to create a new calendar and append every classes of my current semester than deleting the classes from my old semester.
I also wanted to keep the information of whether the class would be a teaching class or an exercise session.
So here is the python code :
#!/usr/bin/python3 from icalendar import Calendar, Event import os import urllib3, io #Documentation : http://icalendar.readthedocs.org/en/latest/index.html classes = [ ["S-PHYS-016",""], ["S-MATH-020",""], ["I-TCTS-003",""], ["S-INFO-075",""], ["W-COGE-018",""], ["I-INFO-008",""], ["S-INFO-020",""], ["I-MARO-011",""], ["Statistique multidimensionnell", "Stat. Multi."], ["Intelligence artificielle", "IA"], ["Simulation", "Simulation"], ["Compilation", "Compilation"], ["Bases de données II", "BDD II"], ["Sém. Informatique en gestion", "Séminaire"] ] typ = ["Cours", "TP", "Exercices", "Crs/exerc"] #Download ics file urllib3.disable_warnings() http = urllib3.PoolManager() res = http.urlopen('GET',"http://www.domain.com/foo.ics?", preload_content=False) i = io.BufferedReader(res, 2048) #Create inCal inCal = Calendar.from_ical(i.read()) i.close() #Create outCal outCal = Calendar() outCal.add('version', '2.0') outCal.add('prodid', 'Debled_Copyright') #Do actions on events for component in inCal.walk(): if component.name == "VEVENT": event_ok = False summary = component.get('summary') cancelled = "" if "ANNULÉ" in component.get('uid'): cancelled = "[Annulé] - " for c in classes: if c in summary: event_ok = True if c != "": component['summary'] = cancelled + c for t in typ: if t in summary : component['summary'] += " - " + t outCal.add_component(component) if event_ok == False: outCal.add_component(component) o = open(os.path.join('/path/to/your/web/home/folder/foo.ics'), 'wb') o.write(outCal.to_ical()) o.close()
So, now that you can transform your ics file as you wish, this script needs to be run at a periodic time.
For that to happen, you need to have this
#!/usr/bin/python3 as a first line of your python file. It basically says that if this script is ran, then, it should be interpreted by the interpreter the OS can find at the path
/usr/bin/python3. This path might be different on your own server. To know what’s the path of your python3 interpreter, type
which python3 in your bash.
Once this is done, you need to make your python file executable by running this command :
chmod +x foo.py.
You can now execute your script by typing
To run this script every hour, just edit your crontab file :
vim /etc/crontab and add this line :
0 * * * * root /path/to/your/script/foo.py
That’s it! You can now import an iCal, modify it, and publish the modified one on your website. So you can import your awesome new calendar to your device with the adress www.yourdomain.com/foo.ics for example!