Exemple #1
0
    def __init__(self,
                 name,
                 dbpath,
                 path,
                 readonly=False,
                 color='',
                 unicode_symbols=True,
                 locale=None,
                 ctype='calendar'):
        """
        :param name: the name of the calendar
        :type name: str
        :param dbpath: path where the local chaching db should be saved
        :type dbpath: str
        :param readonly: if True, this Calendar cannot be modified
        :type readonly: bool
        :param color: the color which this calendar's events should be
                      printed in
        :type color: str
        :param unicode_symbols: if True, unicode symbols will be used for
                                representing this calendars's events properties
        :type unicode_symbols: bool
        :param locale: the locale settings
        :type locale: dict()
        """
        self._locale = locale

        self.name = name
        self.color = color
        self.path = os.path.expanduser(path)
        create_directory(path)
        if ctype == 'calendar':
            self._dbtool = backend.SQLiteDb(self.name,
                                            dbpath,
                                            locale=self._locale)
            file_ext = '.ics'
        elif ctype == 'birthdays':
            self._dbtool = backend.SQLiteDb_Birthdays(self.name,
                                                      dbpath,
                                                      locale=self._locale)
            file_ext = '.vcf'
        else:
            raise ValueError('ctype must be either `calendar` or `birthdays`')
        self._storage = FilesystemStorage(path, file_ext)
        self._readonly = readonly
        self._unicode_symbols = unicode_symbols

        if self._db_needs_update():
            self.db_update()
Exemple #2
0
def cal_vdir(tmpdir):
    cal = Calendar(cal1,
                   ':memory:',
                   str(tmpdir),
                   color='dark blue',
                   locale=locale)
    vdir = FilesystemStorage(str(tmpdir), '.ics')
    return cal, vdir
Exemple #3
0
def coll_vdirs(tmpdir):
    coll = CalendarCollection(locale=locale)
    vdirs = dict()
    for name in example_cals:
        path = str(tmpdir) + '/' + name
        os.makedirs(path, mode=0o770)
        coll.append(Calendar(name, ':memory:', path, locale=locale))
        vdirs[name] = FilesystemStorage(path, '.ics')
    coll.default_calendar_name = cal1
    return coll, vdirs
Exemple #4
0
def coll_vdirs(tmpdir):
    calendars, vdirs = dict(), dict()
    for name in example_cals:
        path = str(tmpdir) + '/' + name
        os.makedirs(path, mode=0o770)
        calendars[name] = {'name': name, 'path': path, 'color': 'dark blue',
                           'readonly': False, 'unicode_symbols': True}
        vdirs[name] = FilesystemStorage(path, '.ics')
    coll = CalendarCollection(calendars=calendars, dbpath=':memory:', locale=locale)
    coll.default_calendar_name = cal1
    return coll, vdirs
Exemple #5
0
    def __init__(self, name, dbpath, path, readonly=False, color='',
                 unicode_symbols=True, locale=None, ctype='calendar'):
        """
        :param name: the name of the calendar
        :type name: str
        :param dbpath: path where the local chaching db should be saved
        :type dbpath: str
        :param readonly: if True, this Calendar cannot be modified
        :type readonly: bool
        :param color: the color which this calendar's events should be
                      printed in
        :type color: str
        :param unicode_symbols: if True, unicode symbols will be used for
                                representing this calendars's events properties
        :type unicode_symbols: bool
        :param locale: the locale settings
        :type locale: dict()
        """
        self._locale = locale

        self.name = name
        self.color = color
        self.path = os.path.expanduser(path)
        create_directory(path)
        if ctype == 'calendar':
            self._dbtool = backend.SQLiteDb(
                self.name, dbpath, locale=self._locale)
            file_ext = '.ics'
        elif ctype == 'birthdays':
            self._dbtool = backend.SQLiteDb_Birthdays(
                self.name, dbpath, locale=self._locale)
            file_ext = '.vcf'
        else:
            raise ValueError('ctype must be either `calendar` or `birthdays`')
        self._storage = FilesystemStorage(path, file_ext)
        self._readonly = readonly
        self._unicode_symbols = unicode_symbols

        if self._db_needs_update():
            self.db_update()
Exemple #6
0
 def __init__(
     self,
     calendars=None,
     hmethod='fg',
     default_color='',
     multiple='',
     color='',
     highlight_event_days=0,
     locale=None,
     dbpath=None,
 ):
     assert dbpath is not None
     assert calendars is not None
     self._calendars = calendars
     self._default_calendar_name = None
     self._storages = dict()
     for name, calendar in self._calendars.items():
         ctype = calendar.get('ctype', 'calendar')
         if ctype == 'calendar':
             file_ext = '.ics'
         elif ctype == 'birthdays':
             file_ext = '.vcf'
         else:
             raise ValueError(
                 'ctype must be either `calendar` or `birthdays`')
         self._storages[name] = FilesystemStorage(calendar['path'],
                                                  file_ext)
     self.hmethod = hmethod
     self.default_color = default_color
     self.multiple = multiple
     self.color = color
     self.highlight_event_days = highlight_event_days
     self._locale = locale
     self._backend = backend.SQLiteDb(calendars=self.names,
                                      db_path=dbpath,
                                      locale=self._locale)
     self.update_db()
Exemple #7
0
class Calendar(object):

    def __init__(self, name, dbpath, path, readonly=False, color='',
                 unicode_symbols=True, locale=None, ctype='calendar'):
        """
        :param name: the name of the calendar
        :type name: str
        :param dbpath: path where the local chaching db should be saved
        :type dbpath: str
        :param readonly: if True, this Calendar cannot be modified
        :type readonly: bool
        :param color: the color which this calendar's events should be
                      printed in
        :type color: str
        :param unicode_symbols: if True, unicode symbols will be used for
                                representing this calendars's events properties
        :type unicode_symbols: bool
        :param locale: the locale settings
        :type locale: dict()
        """
        self._locale = locale

        self.name = name
        self.color = color
        self.path = os.path.expanduser(path)
        create_directory(path)
        if ctype == 'calendar':
            self._dbtool = backend.SQLiteDb(
                self.name, dbpath, locale=self._locale)
            file_ext = '.ics'
        elif ctype == 'birthdays':
            self._dbtool = backend.SQLiteDb_Birthdays(
                self.name, dbpath, locale=self._locale)
            file_ext = '.vcf'
        else:
            raise ValueError('ctype must be either `calendar` or `birthdays`')
        self._storage = FilesystemStorage(path, file_ext)
        self._readonly = readonly
        self._unicode_symbols = unicode_symbols

        if self._db_needs_update():
            self.db_update()

    @property
    def readonly(self):
        return self._readonly

    def _cover_event(self, event):
        event.color = self.color
        event.readonly = self._readonly
        event.unicode_symbols = self._unicode_symbols
        return event

    def local_ctag(self):
        return os.path.getmtime(self.path)

    def get_allday_by_time_range(self, start):
        return [self._cover_event(event) for event in
                self._dbtool.get_allday_range(start)]

    def get_datetime_by_time_range(self, start, end):
        return [self._cover_event(event) for event in
                self._dbtool.get_time_range(start, end)]

    def get_events_at(self, dtime=datetime.datetime.now()):
        """return events which are scheduled at `dtime`"""
        events = list()
        events.extend(self._dbtool.get_allday_at(dtime))
        events.extend(self._dbtool.get_datetime_at(dtime))
        return [self._cover_event(event) for event in events]

    def get_event(self, href):
        return self._cover_event(self._dbtool.get(href))

    def update(self, event):
        """update an event in the database

        param event: the event that should be updated
        type event: event.Event
        """
        assert event.etag
        if self._readonly:
            raise ReadOnlyCalendarError()

        with self._dbtool.at_once():
            event.etag = self._storage.update(event.href, event, event.etag)
            self._dbtool.update(event.vevent.to_ical(), event.href, event.etag)
            self._dbtool.set_ctag(self.local_ctag())

    def new(self, event):
        """save a new event to the database

        param event: the event that should be updated
        type event: event.Event
        """
        assert not event.etag
        if self._readonly:
            raise ReadOnlyCalendarError()

        with self._dbtool.at_once():
            event.href, event.etag = self._storage.upload(event)
            self._dbtool.update(event.to_ical(), event.href, event.etag)
            self._dbtool.set_ctag(self.local_ctag())

    def delete(self, href, etag):
        """delete event from this collection
        """
        if self._readonly:
            raise ReadOnlyCalendarError()
        self._storage.delete(href, etag)
        self._dbtool.delete(href)

    def _db_needs_update(self):
        if self.local_ctag() == self._dbtool.get_ctag():
            return False
        else:
            return True

    def db_update(self):
        """update the db from the vdir,

        should be called after every change to the vdir
        """
        db_hrefs = set(href for href, etag in self._dbtool.list())
        storage_hrefs = set()

        with self._dbtool.at_once():
            for href, etag in self._storage.list():
                storage_hrefs.add(href)
                dbetag = self._dbtool.get_etag(href)
                if etag != dbetag:
                    logger.debug('Updating {} because {} != {}'
                                 .format(href, etag, dbetag))
                    self._update_vevent(href)
            for href in db_hrefs - storage_hrefs:
                self._dbtool.delete(href)

            self._dbtool.set_ctag(self.local_ctag())

    def _update_vevent(self, href):
        """should only be called during db_update, does not check for
        readonly"""
        event, etag = self._storage.get(href)
        try:
            self._dbtool.update(event.raw, href=href, etag=etag)
            return True
        except Exception as e:
            if not isinstance(e, (UpdateFailed, UnsupportedFeatureError)):
                logger.exception('Unknown exception happened.')
            logger.warning(
                'Skipping {}/{}: {}\n'
                'This event will not be available in khal.'
                .format(self.name, href, str(e))
            )
            return False

    def new_event(self, ical):
        """creates and returns (but does not insert) new event from ical
        string"""
        return Event(ical=ical, calendar=self.name, locale=self._locale)

    def search(self, search_string):
        return [self._cover_event(event) for event in
                self._dbtool.search(search_string)]