#!/usr/bin/env python #-*- encoding: utf-8 import sys from progressbar import progressbar import requests from html.parser import HTMLParser from datetime import datetime as dt, time import caldav from icalendar import Calendar, Event import pytz # Constants definition URL = "https://docs.google.com/spreadsheets/u/0/d/e/2PACX-1vQ9yzFLr5mXbIZVK3ucdUZuScAbLoCyPqzHr-5V0aYeCFEz7LuidPdk_EnkkJT-zjemzQQHaKvpeXW2/pubhtml/sheet?headers=false&gid=1619638924" TIMETABLE = [ ('08:00','08:00'), ('09:00','09:00'), ('10:00','10:15'), ('11:15','11:15'), ('12:15','12:15'), ('13:00','13:00'), ('13:30','13:30'), ('14:30','14:30'), ('15:30','15:45'), ('16:45','16:45'), ('17:45','17:45'), ] DAVURL = "https://cal.edgarpierre.fr" CALURL = "https://cal.edgarpierre.fr/edpibu/817427eb-be7c-4540-872a-dfb723a205a6/" class GoogleSheetsCalParser(HTMLParser): """ Definition of a Google Sheets parser providing a table with each cell and its position and size """ def __init__(self): self.inTable = False self.inCell = False self.inDate = False self.row = -1 self.column = -1 self.nextCol = -1 self.rowspan = 0 self.multirows = {} self.date = {} import priv client = caldav.DAVClient(url=DAVURL, username=priv.USERNAME, password=priv.PASSWORD) self.calendar = caldav.Calendar(client=client, url=CALURL) for ev in progressbar(self.calendar.events()): ev.delete() HTMLParser.__init__(self) def handle_starttag(self, tag, attrs): dAttrs = dict(attrs) if self.inTable: if tag == 'tr': self.row += 1 self.nextCol = -1 elif tag == 'td': while self.nextCol in self.multirows.keys() and self.multirows[self.nextCol][1] > 0: self.nextCol += self.multirows[self.nextCol][0] self.column = self.nextCol if 'colspan' in dAttrs.keys(): self.nextCol += int(dAttrs['colspan']) else: self.nextCol += 1 if not (self.row < 3 or (self.row - 2) % 12 < 2): self.inCell = True if 'rowspan' in dAttrs.keys(): self.rowspan = int(dAttrs['rowspan']) self.multirows[self.column] = [self.nextCol - self.column, self.rowspan] else: self.rowspan = 1 elif (self.row - 2) % 12 == 1: self.inDate = True elif tag == 'tbody': self.inTable = True def handle_endtag(self, tag): if tag == 'td': self.inCell = False self.inDate = False elif tag == 'tr': for mr in self.multirows.values(): mr[1] -= 1 elif tag == 'tbody': self.inTable = False def handle_data(self, data): if self.inDate: self.date[self.column] = dt.strptime(data, '%d-%b-%y').date() print(self.date[self.column]) elif self.inCell and data not in ['', '-']: times = [time.fromisoformat(TIMETABLE[(self.row - 2) % 12 - 2][1]), time.fromisoformat(TIMETABLE[(self.row - 2) % 12 - 2 + self.rowspan][0])] cal = Calendar() cal.add('prodid', '-//edpibu//edt-parser//FR') cal.add('version', '2.0') event = Event() event.add('uid', f'{self.row}x{self.column}') event.add('summary', data) event.add('dtstamp', dt.now()) print(self.row, self.column, times) event.add('dtstart', dt.combine(self.date[self.column], times[0], pytz.timezone('Europe/Paris'))) event.add('dtend', dt.combine(self.date[self.column], times[1], pytz.timezone('Europe/Paris'))) cal.add_component(event) self.calendar.save_event(cal.to_ical().decode('utf-8')) # Getting the Google Sheet try: r = requests.get(URL) except ConnectionError as e: print(e) sys.exit(1) if r.status_code != 200: print(f'Status Code {r.status_code}; could not continue.') sys.exit(1) # Parsing the Sheet calParser = GoogleSheetsCalParser() calParser.feed(r.text)