[Kolab-devel] Extending Calendar Plugin

Thomas Brüderli bruederli at kolabsys.com
Mon Sep 9 14:09:34 CEST 2013


Daniel Morlock wrote:
> Hi,
> 
> On Mon, Sep 2, 2013 at 9:35 AM, Thomas Brüderli <bruederli at kolabsys.com
> <mailto:bruederli at kolabsys.com>> wrote:
> 
>     Daniel Morlock wrote:
>     > Hi,
> 
>     Hello Daniel
>     >
>     > I'd like to add support for adding/modifying public and private iCal
>     > calenders within Roundcube's calendar plugin e.g. Google's Holiday
>     > calendar. Did I get it right, that there is not yet any support to
>     > integrate iCal calenders in such a way?
> 
>     Great! And yes, there's no support yet for this. But we already have a
>     ticket for this feature request:
>     https://issues.kolab.org/show_bug.cgi?id=2007
>     >
>     > If yes I'd try to extend the calendar plugin to enable iCal client
>     > support. A first attempt would be:
>     >
>     > - Create another calendar driver that uses iCal as storage backend.
> 
>     I suppose that would include some local caching, right?
> 
> 
> Local caching seems tricky since it brings up a synchronization problem.

I assume that every iCal subscription will have a "refresh time". At
least for that period local caching makes sense otherwise you'll need to
fetch and parse all feeds every time the client loads event data (e.g.
when switching to the next week).

> So I might skip caching in early versions but keep it in mind for the
> later versions. Any suggestions about how to implement proper caching of
> iCal calendars?

"Proper caching" is very subjective. I could imagine several approaches
with different scores in terms of performance and implementation efforts.

A) The best performance you'll get by caching in a dedicated database
table with some event attributes extracted into individual columns for
querying. For example you want to query the cache by start and end dates
and likely have all recurring events already extracted (beware of
endless recurrences!).

B) Use Roundcube's simple key-value caching functions to store a parsed
end PHP-serialized copy of an ical feed. Bonus points for extracting all
recurrences and sorting events by date. The latter will let you abort
the loop when reaching the end date of the query period.

C) Simply cache the iCal feed data on the local disk to avoid the
network latency of a HTTP request.

With B) and C) you'd still need to iterate over the entire dataset of an
ical feed and pick the events that match the period that is to be
displayed. But by assuming iCal feeds only have a limited number of
events, that might already be enough. Cache the parsed events as PHP
array with var_export and the PHP parser (and maybe APC cache) will load
the cached data into memory very fast.

>     You could consider to use the yet existing database driver for this.
>     That already lets you store events in the local database and to query
>     them (e.g. by date range).
> 
> 
> My first idea was to operate directly on the iCal server - so not doing
> any local database operations at all.
> Only purpose of the local database would be to store the URL's,
> usernames and passwords of a user's subscribed iCal calendars.

Exactly.

For the database driver of the calendar module we already have a
'calendars" table which could simply be extended with a 'feedurl' column.

For the kolab backend we should do it the "Kolab way" right from the
start by using a (yet to be defined) configuration object [1] to store
iCal feed subscriptions and to share them with other clients.

Because this requires a Kolab storage format extension I propose an
intermediate step: save iCal subscriptions in Roundcube's user prefs.
That's something the Kolab backend can then hook into later on and use
configuration objects to store these prefs.

To read prefs:

$feeds = rcmail::get_instance()->config->get('calendar_ical_feeds');

To write prefs:

rcmail::get_instance()->user->save_prefs(array(
  'calendar_ical_feeds' => $feeds
));

[1] http://wiki.kolab.org/KEP:9


But anyways, if you decide to implement an all-new driver and extend the
calendar module to allow multiple drivers, then a dedicated database
table that is also used for caching is the better choice.


Regards,
Thomas


More information about the devel mailing list