Browse Source

first commit

itec78 1 year ago
commit
81b8336f57
2 changed files with 146 additions and 0 deletions
  1. 2 0
      requirements.txt
  2. 144 0
      zic2ics.py

+ 2 - 0
requirements.txt

@@ -0,0 +1,2 @@
+BeautifulSoup4
+icalendar

+ 144 - 0
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()
+