• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

akonadi

itemfetchjob.cpp

00001 /*
00002     Copyright (c) 2006 - 2007 Volker Krause <vkrause@kde.org>
00003 
00004     This library is free software; you can redistribute it and/or modify it
00005     under the terms of the GNU Library General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or (at your
00007     option) any later version.
00008 
00009     This library is distributed in the hope that it will be useful, but WITHOUT
00010     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00011     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00012     License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to the
00016     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00017     02110-1301, USA.
00018 */
00019 
00020 #include "itemfetchjob.h"
00021 
00022 #include "attributefactory.h"
00023 #include "collection.h"
00024 #include "collectionselectjob.h"
00025 #include "imapparser_p.h"
00026 #include "itemfetchscope.h"
00027 #include "itemserializer.h"
00028 #include "itemserializerplugin.h"
00029 #include "job_p.h"
00030 #include "entity_p.h"
00031 #include "protocol_p.h"
00032 #include "protocolhelper.h"
00033 
00034 #include <kdebug.h>
00035 
00036 #include <QtCore/QStringList>
00037 #include <QtCore/QTimer>
00038 
00039 using namespace Akonadi;
00040 
00041 class Akonadi::ItemFetchJobPrivate : public JobPrivate
00042 {
00043   public:
00044     ItemFetchJobPrivate( ItemFetchJob *parent )
00045       : JobPrivate( parent )
00046     {
00047     }
00048 
00049     void timeout()
00050     {
00051       Q_Q( ItemFetchJob );
00052 
00053       mEmitTimer->stop(); // in case we are called by result()
00054       if ( !mPendingItems.isEmpty() ) {
00055         emit q->itemsReceived( mPendingItems );
00056         mPendingItems.clear();
00057       }
00058     }
00059 
00060     void startFetchJob();
00061     void selectDone( KJob * job );
00062 
00063     Q_DECLARE_PUBLIC( ItemFetchJob )
00064 
00065     Collection mCollection;
00066     Item mItem;
00067     Item::List mItems;
00068     ItemFetchScope mFetchScope;
00069     Item::List mPendingItems; // items pending for emitting itemsReceived()
00070     QTimer* mEmitTimer;
00071 };
00072 
00073 void ItemFetchJobPrivate::startFetchJob()
00074 {
00075   QByteArray command = newTag();
00076   if ( !mItem.isValid() )
00077     command += " " AKONADI_CMD_ITEMFETCH " 1:*";
00078   else
00079     command += " " AKONADI_CMD_UID " " AKONADI_CMD_ITEMFETCH " " + QByteArray::number( mItem.id() );
00080 
00081   if ( mFetchScope.fullPayload() )
00082     command += " " AKONADI_PARAM_FULLPAYLOAD;
00083   if ( mFetchScope.allAttributes() )
00084     command += " " AKONADI_PARAM_ALLATTRIBUTES;
00085   if ( mFetchScope.cacheOnly() )
00086     command += " " AKONADI_PARAM_CACHEONLY;
00087 
00088   command += " (UID REMOTEID FLAGS";
00089   foreach ( const QByteArray &part, mFetchScope.payloadParts() )
00090     command += ' ' + ProtocolHelper::encodePartIdentifier( ProtocolHelper::PartPayload, part );
00091   foreach ( const QByteArray &part, mFetchScope.attributes() )
00092     command += ' ' + ProtocolHelper::encodePartIdentifier( ProtocolHelper::PartAttribute, part );
00093   command += ")\n";
00094 
00095   writeData( command );
00096 }
00097 
00098 void ItemFetchJobPrivate::selectDone( KJob * job )
00099 {
00100   if ( !job->error() )
00101     // the collection is now selected, fetch the message(s)
00102     startFetchJob();
00103 }
00104 
00105 ItemFetchJob::ItemFetchJob( const Collection &collection, QObject * parent )
00106   : Job( new ItemFetchJobPrivate( this ), parent )
00107 {
00108   Q_D( ItemFetchJob );
00109 
00110   d->mEmitTimer = new QTimer( this );
00111   d->mEmitTimer->setSingleShot( true );
00112   d->mEmitTimer->setInterval( 100 );
00113   connect( d->mEmitTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
00114   connect( this, SIGNAL(result(KJob*)), this, SLOT(timeout()) );
00115 
00116   d->mCollection = collection;
00117 }
00118 
00119 ItemFetchJob::ItemFetchJob( const Item & item, QObject * parent)
00120   : Job( new ItemFetchJobPrivate( this ), parent )
00121 {
00122   Q_D( ItemFetchJob );
00123 
00124   d->mEmitTimer = new QTimer( this );
00125   d->mEmitTimer->setSingleShot( true );
00126   d->mEmitTimer->setInterval( 100 );
00127   connect( d->mEmitTimer, SIGNAL(timeout()), this, SLOT(timeout()) );
00128   connect( this, SIGNAL(result(KJob*)), this, SLOT(timeout()) );
00129 
00130   d->mCollection = Collection::root();
00131   d->mItem = item;
00132 }
00133 
00134 ItemFetchJob::~ItemFetchJob()
00135 {
00136 }
00137 
00138 void ItemFetchJob::doStart()
00139 {
00140   Q_D( ItemFetchJob );
00141 
00142   if ( !d->mItem.isValid() ) { // collection content listing
00143     if ( d->mCollection == Collection::root() ) {
00144       setErrorText( QLatin1String("Cannot list root collection.") );
00145       setError( Unknown );
00146       emitResult();
00147     }
00148     CollectionSelectJob *job = new CollectionSelectJob( d->mCollection, this );
00149     connect( job, SIGNAL(result(KJob*)), SLOT(selectDone(KJob*)) );
00150     addSubjob( job );
00151   } else
00152     d->startFetchJob();
00153 }
00154 
00155 void ItemFetchJob::doHandleResponse( const QByteArray & tag, const QByteArray & data )
00156 {
00157   Q_D( ItemFetchJob );
00158 
00159   if ( tag == "*" ) {
00160     int begin = data.indexOf( "FETCH" );
00161     if ( begin >= 0 ) {
00162 
00163       // split fetch response into key/value pairs
00164       QList<QByteArray> fetchResponse;
00165       ImapParser::parseParenthesizedList( data, fetchResponse, begin + 6 );
00166 
00167       // create a new item object
00168       Item::Id uid = -1;
00169       int rev = -1;
00170       QString rid;
00171       QString mimeType;
00172 
00173       for ( int i = 0; i < fetchResponse.count() - 1; i += 2 ) {
00174         const QByteArray key = fetchResponse.value( i );
00175         const QByteArray value = fetchResponse.value( i + 1 );
00176 
00177         if ( key == "UID" )
00178           uid = value.toLongLong();
00179         else if ( key == "REV" )
00180           rev = value.toInt();
00181         else if ( key == "REMOTEID" )
00182           rid = QString::fromUtf8( value );
00183         else if ( key == "MIMETYPE" )
00184           mimeType = QString::fromLatin1( value );
00185       }
00186 
00187       if ( uid < 0 || rev < 0 || mimeType.isEmpty() ) {
00188         kWarning( 5250 ) << "Broken fetch response: UID, RID, REV or MIMETYPE missing!";
00189         return;
00190       }
00191 
00192       Item item( uid );
00193       item.setRemoteId( rid );
00194       item.setRevision( rev );
00195       item.setMimeType( mimeType );
00196       if ( !item.isValid() )
00197         return;
00198 
00199       // parse fetch response fields
00200       for ( int i = 0; i < fetchResponse.count() - 1; i += 2 ) {
00201         const QByteArray key = fetchResponse.value( i );
00202         // skip stuff we dealt with already
00203         if ( key == "UID" || key == "REV" || key == "REMOTEID" || key == "MIMETYPE" )
00204           continue;
00205         // flags
00206         if ( key == "FLAGS" ) {
00207           QList<QByteArray> flags;
00208           ImapParser::parseParenthesizedList( fetchResponse[i + 1], flags );
00209           foreach ( const QByteArray &flag, flags ) {
00210             item.setFlag( flag );
00211           }
00212         } else {
00213           int version = 0;
00214           QByteArray plainKey( key );
00215           ProtocolHelper::PartNamespace ns;
00216 
00217           ImapParser::splitVersionedKey( key, plainKey, version );
00218           plainKey = ProtocolHelper::decodePartIdentifier( plainKey, ns );
00219 
00220           switch ( ns ) {
00221             case ProtocolHelper::PartPayload:
00222               ItemSerializer::deserialize( item, plainKey, fetchResponse.value( i + 1 ), version );
00223               break;
00224             case ProtocolHelper::PartAttribute:
00225             {
00226               Attribute* attr = AttributeFactory::createAttribute( plainKey );
00227               Q_ASSERT( attr );
00228               attr->deserialize( fetchResponse.value( i + 1 ) );
00229               item.addAttribute( attr );
00230               break;
00231             }
00232             case ProtocolHelper::PartGlobal:
00233             default:
00234               kWarning() << "Unknown item part type:" << key;
00235           }
00236         }
00237       }
00238 
00239       item.d_ptr->resetChangeLog();
00240       d->mItems.append( item );
00241       d->mPendingItems.append( item );
00242       if ( !d->mEmitTimer->isActive() )
00243         d->mEmitTimer->start();
00244       return;
00245     }
00246   }
00247   kDebug( 5250 ) << "Unhandled response: " << tag << data;
00248 }
00249 
00250 Item::List ItemFetchJob::items() const
00251 {
00252   Q_D( const ItemFetchJob );
00253 
00254   return d->mItems;
00255 }
00256 
00257 void ItemFetchJob::setFetchScope( ItemFetchScope &fetchScope )
00258 {
00259   Q_D( ItemFetchJob );
00260 
00261   d->mFetchScope = fetchScope;
00262 }
00263 
00264 ItemFetchScope &ItemFetchJob::fetchScope()
00265 {
00266   Q_D( ItemFetchJob );
00267 
00268   return d->mFetchScope;
00269 }
00270 
00271 #include "itemfetchjob.moc"

akonadi

Skip menu "akonadi"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  • kabc
  • kblog
  • kcal
  • kimap
  • kioslave
  •   imap4
  •   mbox
  • kldap
  • kmime
  • kpimidentities
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal