KDE PIM/Meetings/Osnabrueck 4/API

From KDE Community Wiki

Results of the API discussion on Sunday

Using Extended IMAP as transport protocol
==========================================

Access Modes
-------------

Query:

  All queries can be parameterized with field identifiers (e.g. 'date < 19.12.2005')

  Light Query:
    - returns only a subset of data of a pim item
      (e.g. header, datetime and subject of a mail)

  Full Query:
    - returns the full pim item

  Generic Query:
    - returns generic lists of strings

  ?: Returns data or resourceIds?


Store:


Server Extensions
------------------

The storage server needs some extensions to satisfy our needs.

 - disable security handling
 - disable network handing
 - disable authentication

 - add management (starting/stopping) of resources
 - add 'message deleted/changed' notification
 - add error notification

Implementing Qt-based libakonadi
================================

All actions are encapsulated in Jobs, which provide an asynchronous interface
(plus a synchronous convenience interface) to the lower transport protocol.

Addionally to Marc's API proposal, we'll need ways to cancel/kill a job and to
receive progress/status information and error messages. There is a great
similarity to KIO::Job, so using KIO (at least for a prototype) might be an
option (especially since we have an IMAP KIO slave already).

Jobtypes:

  - ProfileJobs
  - MonitoringJob
  - DataJobs

ProfileJobs
------------
These jobs encapsulate the handling of profiles, which involves the following tasks:
  - get list of all available resource types
  - get list of all profiles
  - get list of resources of a profile
  - add resource to a profile
  - remove resource from a profile
  - reconfigure resource

  - set online/offline state

MonitoringJob
--------------
This job (should be only one per application) provides information about changes in
the storage service. The following changes are possible:
  - new items available
  - items deleted
  - items changed
  - online/offline state changed

DataJobs
---------
These jobs encapsulate the handling of pim items, which are BLOBs with a mimetype assigned.
The following tasks are involved:
  - parameterized search of items (returns referenceIds)
  - query for light pim objects for a list of referenceIds
  - query for full pim objects for a list of referenceIds
  - query for generic pim objects for a list of referenceIds

  - storing a pim object
  - removing a pim object

Implementing KDE-specific libakonadi
====================================
For every pim object type (mail/contact/event), there are reimplementations of
the generic Jobs.

libkabc, libkcal, and libkemail will make use of these specific Jobs.


Marc's basic libakonadi API

  1. ifndef API_H
  2. define API_H

class PIMDataReference {

   QString persistanceID() const;
   QUrl externalUrl() const;

};


class PIMJob : public QObject {

   Q_OBJECT

public:

   void exec() {
       QEventLoop loop( ... );
       connect( this, SIGNAL(done()), &loop, SLOT(quit()) );
       doStart();
       loop.exec();
   }
   void start() {
       doStart();
   }

signals:

   void done();

private:

   virtual void doStart() = 0;

};

class PIMQuery : public PIMJob {

   Q_OBJECT

public:

   void setQueryString( const QString & query ) {
       doSetQueryString( query );
   }
   QList<PIMDataReference> result() const;

private:

   void doStart();

protected:

   virtual void doSetQueryString( const QString & query );

};

class PIMDataRequest : public PIMJob {

   Q_OBJECT

public:

   explicit PIMDataRequest( const PIMDataReference & ref, const QString & part="ALL", const QStringList & acceptableMimeTypes=QStringList() );
   QByteArray data() const;
   QByteArray mimeType() const;

private:

   void doStart();

};

// // // Start convenience API // //

class EMailQuery : public PIMQuery {

   Q_OBJECT

public:

   EMailQuery();

protected:

   void doSetQueryString( const QString & query ) {
       PIMQuery::doSetQueryString( "mimetype=message/rfc822;" + query );
   }

};

class EMailRequest : public PIMDataRequest {

   Q_OBJECT

public:

   explicit EMailRequest( const PIMDataReference & ref, const QString & part="ALL" );
   KMail::Message message() const {
       Q_ASSERT( mimeType() == QLatin1String( "message/rfc822" ) );
       return KMail::Message::fromRfc822( data() );
   }

};

class CalendarEventRequest : public PIMDataRequest {

   Q_OBJECT

public:

   explicit CalendarEventRequest( const PIMDataRequest & ref );
   KCal::FooBar event() const;

};

class NotesRequest : public PIMDataRequest {

   Q_OBJECT

public:

   explicit NotesRequest( const PIMDataRequest & ref );
   KCal::BarBaz note() const;

};

// ...


void example() {

   PIMQuery query;
   query.setQueryString( "mimetype=message/rfc822; folder=/inbox; date>=2005-12-31;" );
   query.exec();
   const QList<PIMDataReference> result = query.result();
   foreach( const PIMDataReference ref, result ) {
       EMailRequest req( ref, "BODY,HEADER" );
       req.exec();
       const KMail::Message msg = req.message();
       // ...
   }

}

  1. endif /* API_H */