Skip to content

Instantly share code, notes, and snippets.

@meskarune
Created August 27, 2018 14:23
Show Gist options
  • Save meskarune/b8edb20806034f9f42d38d33f25be622 to your computer and use it in GitHub Desktop.
Save meskarune/b8edb20806034f9f42d38d33f25be622 to your computer and use it in GitHub Desktop.
python icalendar .ics parser that prints out 3 months worth of events
BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VEVENT
CREATED:20170220T182458Z
LAST-MODIFIED:20170220T182458Z
DTSTAMP:20170220T182458Z
UID:a79d1ffd-f62b-4c14-98b7-22eaa494a7fd
SUMMARY:Arch Linux Women Monthly Project Meeting
RRULE:FREQ=MONTHLY;BYDAY=2SA
DTSTART;VALUE=DATE:20170211T160000Z
DTEND;VALUE=DATE:30000211T180000Z
LOCATION:#archlinux-women @ irc.freenode.net
DESCRIPTION:https://archwomen.org/wiki/meetings
URL:https://archwomen.org/wiki/meetings:start
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
CREATED:20120514T060851Z
LAST-MODIFIED:20120514T061031Z
DTSTAMP:20120514T061031Z
UID:e0639f9c-5ab0-4001-9da9-3003611b6e94
SUMMARY:Bug Day
RRULE:FREQ=WEEKLY
DTSTART;VALUE=DATE:20120821T000000Z
DTEND;VALUE=DATE:20120822T000000Z
LOCATION:#archlinux-bugs @ Freenode IRC
DESCRIPTION:http://bugs.archlinux.org/
TRANSP:TRANSPARENT
END:VEVENT
BEGIN:VEVENT
CREATED:20170220T182458Z
LAST-MODIFIED:20170220T182458Z
DTSTAMP:20170220T182458Z
UID:0c9acbbb-f82e-444d-b941-50c3a9953d86
SUMMARY:Test unique date
DTSTART;VALUE=DATE:20170303T110000Z
DTEND;VALUE=DATE:20170303T113000Z
LOCATION:My computer
DESCRIPTION:A test for a one time event
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" Parse ical file and report all events in the next 2 months """
from datetime import datetime, timedelta, tzinfo
#Python3 only:
#from datetime import datetime, timedelta, timezone
import icalendar
from dateutil.rrule import *
ZERO = timedelta(0)
class UTC(tzinfo):
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
def parse_recurrences(recur_rule, start, exclusions):
""" Find all reoccuring events """
rules = rruleset()
first_rule = rrulestr(recur_rule, dtstart=start)
rules.rrule(first_rule)
if not isinstance(exclusions, list):
exclusions = [exclusions]
for xdate in exclusions:
try:
rules.exdate(xdate.dts[0].dt)
except AttributeError:
pass
now = datetime.now(utc)
#Python3 only:
#now = datetime.now(timezone.utc)
this_year = now + timedelta(days=90)
dates = []
for rule in rules.between(now, this_year):
dates.append(rule.strftime("%D %H:%M UTC "))
return dates
if __name__ == "__main__":
""" Open ical and print data """
with open('us_en.ics','rb') as f:
icalfile = f.read()
gcal = icalendar.Calendar.from_ical(icalfile)
events = []
for component in gcal.walk():
if component.name == "VEVENT":
summary = component.get('summary')
description = component.get('description')
location = component.get('location')
startdt = component.get('dtstart').dt
#enddt = component.get('dtend').dt
exdate = component.get('exdate')
if component.get('rrule'):
reoccur = component.get('rrule').to_ical().decode('utf-8')
for item in parse_recurrences(reoccur, startdt, exdate):
events.append("{0} {1}: {2} - {3}\n"
.format(item, summary, description, location))
else:
events.append("{0}-{1} {2}: {3} - {4}\n"
.format(startdt.strftime("%D %H:%M UTC"),
enddt.strftime("%D %H:%M UTC"),
summary, description, location))
events = sorted(events)
print('%s' % ''.join(map(str, events)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment