akonadi
itemcreatejob.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "itemcreatejob.h"
00022
00023 #include "collection.h"
00024 #include "imapparser_p.h"
00025 #include "item.h"
00026 #include "itemserializer_p.h"
00027 #include "job_p.h"
00028 #include "protocolhelper_p.h"
00029
00030 #include <QtCore/QDateTime>
00031
00032 #include <kdebug.h>
00033
00034 using namespace Akonadi;
00035
00036 class Akonadi::ItemCreateJobPrivate : public JobPrivate
00037 {
00038 public:
00039 ItemCreateJobPrivate( ItemCreateJob *parent )
00040 : JobPrivate( parent )
00041 {
00042 }
00043
00044 Collection mCollection;
00045 Item mItem;
00046 QSet<QByteArray> mParts;
00047 Item::Id mUid;
00048 QDateTime mDatetime;
00049 QByteArray mData;
00050 };
00051
00052 ItemCreateJob::ItemCreateJob( const Item &item, const Collection &collection, QObject * parent )
00053 : Job( new ItemCreateJobPrivate( this ), parent )
00054 {
00055 Q_D( ItemCreateJob );
00056
00057 Q_ASSERT( !item.mimeType().isEmpty() );
00058 d->mItem = item;
00059 d->mParts = d->mItem.loadedPayloadParts();
00060 d->mCollection = collection;
00061 }
00062
00063 ItemCreateJob::~ItemCreateJob()
00064 {
00065 }
00066
00067 void ItemCreateJob::doStart()
00068 {
00069 Q_D( ItemCreateJob );
00070
00071 QByteArray remoteId;
00072
00073 QList<QByteArray> flags;
00074 flags.append( "\\MimeType[" + d->mItem.mimeType().toLatin1() + ']' );
00075 if ( !d->mItem.remoteId().isEmpty() )
00076 flags.append( ImapParser::quote( "\\RemoteId[" + d->mItem.remoteId().toUtf8() + ']' ) );
00077 flags += d->mItem.flags().toList();
00078
00079
00080 if ( d->mItem.attributes().isEmpty() && ( d->mParts.isEmpty() || (d->mParts.size() == 1 && d->mParts.contains( Item::FullPayload )) ) ) {
00081 if ( d->mItem.hasPayload() ) {
00082 int version = 0;
00083 ItemSerializer::serialize( d->mItem, Item::FullPayload, d->mData, version );
00084 }
00085 int dataSize = d->mData.size();
00086
00087 d->writeData( d->newTag() + " APPEND " + QByteArray::number( d->mCollection.id() )
00088 + ' ' + QByteArray::number( d->mItem.size() )
00089 + " (" + ImapParser::join( flags, " " ) + ") {"
00090 + QByteArray::number( dataSize ) + "}\n" );
00091 }
00092 else {
00093 QByteArray command = d->newTag() + " X-AKAPPEND " + QByteArray::number( d->mCollection.id() )
00094 + ' ' + QByteArray::number( d->mItem.size() )
00095 + " (" + ImapParser::join( flags, " " ) + ") ";
00096
00097 QList<QByteArray> partSpecs;
00098 int totalSize = 0;
00099 foreach( const QByteArray &partName, d->mParts ) {
00100 QByteArray partData;
00101 int version = 0;
00102 ItemSerializer::serialize( d->mItem, partName, partData, version );
00103 totalSize += partData.size();
00104 const QByteArray partId = ProtocolHelper::encodePartIdentifier( ProtocolHelper::PartPayload, partName, version );
00105 partSpecs.append( ImapParser::quote( partId ) + ':' + QByteArray::number( partData.size() ) );
00106 d->mData += partData;
00107 }
00108 foreach ( const Attribute* attr, d->mItem.attributes() ) {
00109 const QByteArray data = attr->serialized();
00110 totalSize += data.size();
00111 const QByteArray partId = ProtocolHelper::encodePartIdentifier( ProtocolHelper::PartAttribute, attr->type() );
00112 partSpecs.append( ImapParser::quote( partId ) + ':' + QByteArray::number( data.size() ) );
00113 d->mData += data;
00114 }
00115 command += '(' + ImapParser::join( partSpecs, "," ) + ") " +
00116 '{' + QByteArray::number( totalSize ) + "}\n";
00117
00118 d->writeData( command );
00119 }
00120 }
00121
00122 void ItemCreateJob::doHandleResponse( const QByteArray & tag, const QByteArray & data )
00123 {
00124 Q_D( ItemCreateJob );
00125
00126 if ( tag == "+" ) {
00127 d->writeData( d->mData );
00128 if ( !d->mData.endsWith( '\n' ) )
00129 d->writeData( "\n" );
00130 return;
00131 }
00132 if ( tag == d->tag() ) {
00133 int uidNextPos = data.indexOf( "UIDNEXT" );
00134 if ( uidNextPos != -1 ) {
00135 bool ok = false;
00136 ImapParser::parseNumber( data, d->mUid, &ok, uidNextPos + 7 );
00137 if ( !ok ) {
00138 kDebug() << "Invalid UIDNEXT response to APPEND command: "
00139 << tag << data;
00140 }
00141 }
00142 int dateTimePos = data.indexOf( "DATETIME" );
00143 if ( dateTimePos != -1 ) {
00144 int resultPos = ImapParser::parseDateTime( data, d->mDatetime, dateTimePos + 8 );
00145 if ( resultPos == (dateTimePos + 8) ) {
00146 kDebug() << "Invalid DATETIME response to APPEND command: "
00147 << tag << data;
00148 }
00149 }
00150 }
00151 }
00152
00153 Item ItemCreateJob::item() const
00154 {
00155 Q_D( const ItemCreateJob );
00156
00157 if ( d->mUid == 0 )
00158 return Item();
00159
00160 Item item( d->mItem );
00161 item.setId( d->mUid );
00162 item.setRevision( 0 );
00163 item.setModificationTime( d->mDatetime );
00164 item.setParentCollection( d->mCollection );
00165 item.setStorageCollectionId( d->mCollection.id() );
00166
00167 return item;
00168 }
00169
00170 #include "itemcreatejob.moc"