saphsync.py 3.02 KB
Newer Older
erdnaxe's avatar
erdnaxe committed
1 2
#!/usr/bin/env python3

erdnaxe's avatar
erdnaxe committed
3
import logging
4
import os.path
5
from datetime import datetime, timedelta
erdnaxe's avatar
erdnaxe committed
6

7 8
import caldav
import icalendar
9 10
import keyring
import yaml
11 12
from caldav.objects import dav, Calendar

13 14 15 16
import filters


class Configuration:
erdnaxe's avatar
erdnaxe committed
17
    """Regroup user DavCal configuration"""
18 19

    def __init__(self, yaml_file):
erdnaxe's avatar
erdnaxe committed
20
        """Fetch DavCal from YAML configuration and keyring"""
21
        with open(yaml_file, 'r') as f:
erdnaxe's avatar
erdnaxe committed
22 23 24 25 26 27 28
            c = yaml.load(f)
            logging.info("Fetching {}".format(c['url']))
            password = keyring.get_password('sogo', c['username'])
            client = caldav.DAVClient(c['url'], username=c['username'],
                                      password=password)
            self.calendars = client.principal().calendars()
            self.selected_groups = c['selected_groups']
29 30 31 32 33
            if 'output_directory' in c.keys():
                self.output_directory = c['output_directory']
            else:
                self.output_directory = '.'

erdnaxe's avatar
erdnaxe committed
34

erdnaxe's avatar
erdnaxe committed
35 36 37 38 39 40 41 42 43 44
    def get_all_dav_components(self):
        """Return all components from the given calendars"""
        components = []
        for cal in self.calendars:
            n = cal.get_properties([dav.DisplayName(), ])['{DAV:}displayname']
            logging.info("Loading '\033[1;1m{}\033[1;0m'".format(n))
            from_date = datetime.today() - timedelta(weeks=1)  # Future events
            components += cal.date_search(from_date)
            components += cal.todos() + cal.journals()
        return components
erdnaxe's avatar
erdnaxe committed
45 46


erdnaxe's avatar
erdnaxe committed
47
def write_calendar_from_dav(f, dav_components, selected_groups):
erdnaxe's avatar
erdnaxe committed
48 49 50 51 52 53 54 55 56
    """Write a master calendar in file f using components from CalDav"""
    f.write(b'BEGIN:VCALENDAR\nPRODID:-//SaphSync//EN\nVERSION:2.0\n')
    for dav_component in dav_components:
        dav_component.load()  # Download CalDav component
        ical = icalendar.Event.from_ical(dav_component.data)  # Parse ical
        ical_components = [c for c in ical.walk() if c.name != 'VCALENDAR']
        for ical_component in ical_components:
            if ical_component.name == "VEVENT":
                # If it is an event, then check it is in the correct group
erdnaxe's avatar
erdnaxe committed
57
                if filters.group(ical_component, selected_groups):
erdnaxe's avatar
erdnaxe committed
58 59 60 61
                    f.write(ical_component.to_ical())
            else:
                f.write(ical_component.to_ical())
    f.write(b'END:VCALENDAR')
62 63


erdnaxe's avatar
erdnaxe committed
64 65 66 67 68 69 70 71
if __name__ == '__main__':
    # Configure logging system
    logging.addLevelName(logging.INFO, "\033[1;36mINFO\033[1;0m")
    logging.addLevelName(logging.WARNING, "\033[1;103mWARNING\033[1;0m")
    logging.addLevelName(logging.ERROR, "\033[1;41mERROR\033[1;0m")
    logging.basicConfig(
            level=logging.INFO,
            format='\033[1;90m%(asctime)s\033[1;0m %(levelname)s %(message)s')
72

erdnaxe's avatar
erdnaxe committed
73 74
    conf = Configuration('config.yml')  # Load user configuration and calendars
    dav_components = conf.get_all_dav_components()  # Load components
75
    with open(os.path.join(conf.output_directory, 'calendar.ics'), 'wb') as f:  # Write master calendar
erdnaxe's avatar
erdnaxe committed
76
        write_calendar_from_dav(f, dav_components, conf.selected_groups)