commit 81b8336f57495e7246316e34dfd7ee12384f0b88 Author: itec78 Date: Tue May 17 14:34:28 2022 +0200 first commit diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..40d94bb --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +BeautifulSoup4 +icalendar \ No newline at end of file diff --git a/zic2ics.py b/zic2ics.py new file mode 100755 index 0000000..3cdb2a2 --- /dev/null +++ b/zic2ics.py @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 + +import requests +import os +from bs4 import BeautifulSoup +from datetime import datetime, timedelta +import locale +import pytz +from icalendar import Calendar, Event + + + + +def zic2ics(): + locale.setlocale(locale.LC_TIME,'it_IT.UTF-8') + os.makedirs('history', exist_ok=True) + + cal = Calendar() + cal.add('prodid', '-//Agenda di zic.it//') + cal.add('version', '2.0') + + page = requests.get("https://zic.it/agenda/") + soup = BeautifulSoup(page.content, "html.parser") + + agenda = soup.find("div", class_="entry-content clearfix") + entries = agenda.find_all("p", style=None) + + for entry in entries: + try: + lnk = entry.find('a', href=True)['href'] + + spe = entry.get_text(strip=True, separator='\n').splitlines() + tit = spe[0].strip() + dat = datetime.strptime(spe[2], "%A %d %B %Y - %H:%M").replace(tzinfo=pytz.timezone('Europe/Rome')) + + det = spe[3][2:-2].split(";") + dov = det[0].strip() + chi = det[1].strip() if 1 < len(det) else "" + # print(" ~ ".join([tit, str(dat), dov, chi])) + + uid = "|".join([dat.strftime("%Y%m%d"), tit, dov]) + + event = Event() + event.add('summary', tit) + event.add('dtstart', dat) + event.add('description', chi) + event.add('location', dov) + event.add('url', lnk) + event.add('uid', uid) + cal.add_component(event) + + except: + pass + + ical = cal.to_ical() + + try: + with open('zic.ics', 'rb') as f: + ical_last = f.read() + except: + ical_last = "" + + if ical != ical_last: + + try: + with open('zic_all.ics', 'rb') as f: + cal_all = Calendar.from_ical(f.read()) + except: + cal_all = Calendar() + ical_all = icalmerge(cal_all, cal).to_ical() + + with open('zic.ics', 'wb') as f: + f.write(ical) + + with open('zic_all.ics', 'wb') as f: + f.write(ical_all) + + with open(os.path.join('history','zic_%s.ics' % datetime.now().strftime("%Y%m%d%H%M%S")), 'wb') as f: + f.write(ical) + + with open(os.path.join('history','zic_%s.html' % datetime.now().strftime("%Y%m%d%H%M%S")), 'wb') as f: + f.write(page.content) + + + + + + +def icalmerge(calold, calnew, delete = False, tolerance = 15): + + cal = Calendar() + cal.add('prodid', calnew.get('prodid').to_ical().decode('utf-8')) + cal.add('version', calnew.get('version').to_ical().decode('utf-8')) + + + #Add a computed UID if missing + for e in calold.walk('VEVENT'): + if e.get('UID') is None: + uid = "|".join([e.decoded('dtstart').strftime("%Y%m%d"), e.get('Summary').to_ical().decode('utf-8'), e.get('Location').to_ical().decode('utf-8')]) + e.add('uid', uid) + + for e in calnew.walk('VEVENT'): + if e.get('UID') is None: + uid = "|".join([e.decoded('dtstart').strftime("%Y%m%d"), e.get('Summary').to_ical().decode('utf-8'), e.get('Location').to_ical().decode('utf-8')]) + e.add('uid', uid) + + calold_uids = [e.get('UID').to_ical().decode('utf-8') for e in calold.walk('VEVENT')] + calnew_uids = [e.get('UID').to_ical().decode('utf-8') for e in calnew.walk('VEVENT')] + + imported_uids = [] + for e in calold.walk('VEVENT'): + uid = e.get('UID').to_ical().decode('utf-8') + + if uid not in calnew_uids: + if e.decoded('dtstart') < datetime.now(pytz.UTC) + timedelta(minutes = tolerance): + print("Past \"%s\"" % uid) + cal.add_component(e) + else: + if delete: + print("Deleted \"%s\"" % uid) + else: + print("Cancelled \"%s\"" % uid) + e.add('status', 'CANCELLED') + cal.add_component(e) + + for e in calnew.walk('VEVENT'): + uid = e.get('UID').to_ical().decode('utf-8') + if uid not in calold_uids: + print("Added \"%s\"" % uid) + cal.add_component(e) + else: + # print("Updated \"%s\"" % uid) + cal.add_component(e) + + return(cal) + + + + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + zic2ics() +