manipulate Evolution, KCalExtended/mkcal, QtContacts PIM items via uniform command line

The current development version of SyncEvolution, the one which will become 1.1, has some new features which may be useful for command line aficionados like myself: query and manipulate items in the databases that can be accessed with SyncEvolution backends.

This is particularly useful for the new PIM storages in MeeGo, QtContacts and mkcal (formerly known as KCalExtended). Both are part of MeeGo Core, but come without any kind of frontend in Core. SyncEvolution provides a uniform way of testing these new storages using the command line or scripts.


In MeeGo, make sure that at least rpms (required for mkcal) or better, (for QtContacts) get installed. The core “syncevolution” rpm is needed plus “syncevolution-kcalextended” resp. “syncevolution-qtcontacts”.

When compiling from source, check out the master branch of “syncevolution” and “libsynthesis” and follow the instructions in the “HACKING” document. Add –enable-kcalextended resp. –enable-qtcontacts as needed…


These examples illustrate how to use the new options in combination with mkcal. In, “mkcal” can be used as type instead of “kcalextended”, as in the examples below. Only events are supported at the moment, todos and journal entries in the calendar are ignored.

Wipe out calendar data the hard way:

rm -f ~/.calendardb*

Import an event:

$ cat >/tmp/example.ics <<EOF
PRODID:-//Ximian//NONSGML Evolution Calendar//EN
SUMMARY:first event

$ syncevolution --import /tmp/example.ics --source-property type=kcalextended @foo bar
#0: 3f630f1d-8009-4465-907b-3ec28248b90b-rid
[ERROR] stderr: kdedate/ksystemtimezone.cpp: 313 - cannot get wall_clock_info (localzone) - QDBusError("org.freedesktop.DBus.Error.ServiceUnknown", "The name was not provided by any .service files")

Because many of these system libraries don’t expect to be used by command line users, they spew out a lot of debugging information. The SyncEvolution command line filters this output and suppresses most of it. Developers who want to see it, can set the SYNCEVOLUTION_DEBUG environment variable to 1. They should also add –daemon=no to run the operation inside the “syncevolution” process instead of the “syncevo-dbus-server”.

The error in this case is MeeGo bug, which I’ll strip from the output of the following examples.

The command line above works without any “@foo” configuration and “bar” data source, because the source type is specified explicitly. Configuring this value permanently makes the command line shorter:

$ syncevolution --configure --source-property type=kcalextended @default calendar

List all events:

$ syncevolution --daemon=no --print-items @default calendar
3f630f1d-8009-4465-907b-3ec28248b90b-rid: first event

Export events to stdout:

$ syncevolution --export - @default calendar
PRODID:-//K Desktop Environment//NONSGML libkcal 4.3//EN
SUMMARY:first event

Export one specific event into a file (like everything else, this also works for multiple events, writing into a single file or a directory):

$ syncevolution --export /tmp/exported.ics @default calendar 3f630f1d-8009-4465-907b-3ec28248b90b-rid

Update that event, showing of reading from stdin here:

$ perl -p -e 's/first event/first event modified/' /tmp/example.ics | syncevolution --daemon=no --update - @default calendar 3f630f1d-8009-4465-907b-3ec28248b90b-rid
#0: 3f630f1d-8009-4465-907b-3ec28248b90b-rid

$ syncevolution --daemon=no --export - @default calendar | grep SUMMARY
SUMMARY:first event

Hmm, that didn’t work as intended. Need to investigate… ah, I haven’t reimplemented that part with the new mkcal API yet. Will be fixed in

Delete the event:

$ syncevolution --delete-items @default calendar 3f630f1d-8009-4465-907b-3ec28248b90b-rid
[INFO] calendar: deleting "first event"


$ syncevolution --help
List items:
  syncevolution --print-items <config> <source>
Export item(s):
  syncevolution [--delimiter <string>] --export <dir>|<file>|- <config> <source> [<luid> ...]
Add item(s):
  syncevolution [--delimiter <string>|none] --import <dir>|<file>|- <config> <source>
Update item(s)
  syncevolution --update <dir> <config> <source>
  syncevolution [--delimiter <string>|none] --update <file>|- <config> <source> <luid> ...
Remove item(s):
  syncevolution --delete-items <config> <source> <luid> ...
  Shows all existing items using one line per item using
  the format "<luid>[: <short description>]". Whether the description
  is available depends on the backend and the kind of data that it

  Writes all items in the source or all items whose <luid> is
  given into a directory if the --export parameter exists and is a
  directory. The <luid> of each item is used as file name. Otherwise it
  creates a new file under that name and writes the selected items
  separated by the chosen delimiter string. stdout can be selected with
  a dash.

  The default delimiter are two newline characters for a blank line. This
  works for vCard 3.0 and iCalendar 2.0, which never contain blank lines.
  Because items may or may not end in a newline, as a special case the
  initial newline of a delimiter is skipped if the item ends in a newline.

  Adds all items found in the directory or input file to the
  source.  When reading from a directory, each file is treated as one
  item. Otherwise the input is split at the chosen delimiter. "none" as
  delimiter disables splitting of the input.

  Overwrites the content of existing items. When updating from a
  directory, the name of each file is taken as its luid. When updating
  from file or stdin, the number of luids given on the command line
  must match with the number of items in the input.

  Removes the specified items from the source. Most backends print
  some progress information about this, but besides that, no further
  output is produced. Trying to remove an item which does not exist
  typically leads to an ERROR message, but is not reflected in a
  non-zero result of the command line invocation itself because the
  situation is not reported as an error by backends (removal of
  non-existent items is not an error in SyncML).