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()
def cal_vdir(tmpdir): cal = Calendar(cal1, ':memory:', str(tmpdir), color='dark blue', locale=locale) vdir = FilesystemStorage(str(tmpdir), '.ics') return cal, vdir
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
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
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()
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()
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)]