2
Copyright (c) 2007 Till Adam <adam@kde.org>
4
This library is free software; you can redistribute it and/or modify it
5
under the terms of the GNU Library General Public License as published by
6
the Free Software Foundation; either version 2 of the License, or (at your
7
option) any later version.
9
This library is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12
License for more details.
14
You should have received a copy of the GNU Library General Public License
15
along with this library; see the file COPYING.LIB. If not, write to the
16
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20
#include "akonadi_serializer_mail.h"
22
#include <QtCore/qplugin.h>
25
#include <kmime/kmime_message.h>
26
#include <boost/shared_ptr.hpp>
28
#include <akonadi/item.h>
29
#include <akonadi/kmime/messageparts.h>
30
#include <akonadi/private/imapparser_p.h>
32
using namespace Akonadi;
33
using namespace KMime;
35
typedef boost::shared_ptr<KMime::Message> MessagePtr;
37
template <typename T> static void parseAddrList( const QList<QByteArray> &addrList, T *hdr )
39
for ( QList<QByteArray>::ConstIterator it = addrList.constBegin(); it != addrList.constEnd(); ++it ) {
40
QList<QByteArray> addr;
41
ImapParser::parseParenthesizedList( *it, addr );
42
if ( addr.count() != 4 ) {
43
kWarning( 5264 ) << "Error parsing envelope address field: " << addr;
46
KMime::Types::Mailbox addrField;
47
addrField.setNameFrom7Bit( addr[0] );
48
addrField.setAddress( addr[2] + '@' + addr[3] );
49
hdr->addAddress( addrField );
54
bool SerializerPluginMail::deserialize( Item& item, const QByteArray& label, QIODevice& data, int version )
58
if ( label != MessagePart::Body && label != MessagePart::Envelope && label != MessagePart::Header )
62
if ( !item.hasPayload() ) {
63
Message *m = new Message();
64
msg = MessagePtr( m );
65
item.setPayload( msg );
67
msg = item.payload<MessagePtr>();
70
QByteArray buffer = data.readAll();
71
if ( buffer.isEmpty() )
73
if ( label == MessagePart::Body ) {
74
msg->setContent( buffer );
76
} else if ( label == MessagePart::Header ) {
77
if ( !msg->body().isEmpty() && !msg->contents().isEmpty() ) {
78
msg->setHead( buffer );
81
} else if ( label == MessagePart::Envelope ) {
82
QList<QByteArray> env;
83
ImapParser::parseParenthesizedList( buffer, env );
84
if ( env.count() < 10 ) {
85
kWarning( 5264 ) << "Akonadi KMime Deserializer: Got invalid envelope: " << env;
88
Q_ASSERT( env.count() >= 10 );
90
msg->date()->from7BitString( env[0] );
92
msg->subject()->from7BitString( env[1] );
94
QList<QByteArray> addrList;
95
ImapParser::parseParenthesizedList( env[2], addrList );
96
if ( !addrList.isEmpty() )
97
parseAddrList( addrList, msg->from() );
99
ImapParser::parseParenthesizedList( env[2], addrList );
100
if ( !addrList.isEmpty() )
101
parseAddrList( addrList, msg->sender() );
103
ImapParser::parseParenthesizedList( env[4], addrList );
104
if ( !addrList.isEmpty() )
105
parseAddrList( addrList, msg->replyTo() );
107
ImapParser::parseParenthesizedList( env[5], addrList );
108
if ( !addrList.isEmpty() )
109
parseAddrList( addrList, msg->to() );
111
ImapParser::parseParenthesizedList( env[6], addrList );
112
if ( !addrList.isEmpty() )
113
parseAddrList( addrList, msg->cc() );
115
ImapParser::parseParenthesizedList( env[7], addrList );
116
if ( !addrList.isEmpty() )
117
parseAddrList( addrList, msg->bcc() );
119
msg->inReplyTo()->from7BitString( env[8] );
121
msg->messageID()->from7BitString( env[9] );
127
static QByteArray quoteImapListEntry( const QByteArray &b )
131
return ImapParser::quote( b );
134
static QByteArray buildImapList( const QList<QByteArray> &list )
136
if ( list.isEmpty() )
138
return QByteArray( "(" ) + ImapParser::join( list, " " ) + QByteArray( ")" );
141
template <typename T> static QByteArray buildAddrStruct( T const *hdr )
143
QList<QByteArray> addrList;
144
KMime::Types::Mailbox::List mb = hdr->mailboxes();
145
foreach ( const KMime::Types::Mailbox mbox, mb ) {
146
QList<QByteArray> addrStruct;
147
addrStruct << quoteImapListEntry( KMime::encodeRFC2047String( mbox.name(), "utf-8" ) );
148
addrStruct << quoteImapListEntry( QByteArray() );
149
addrStruct << quoteImapListEntry( mbox.addrSpec().localPart.toUtf8() );
150
addrStruct << quoteImapListEntry( mbox.addrSpec().domain.toUtf8() );
151
addrList << buildImapList( addrStruct );
153
return buildImapList( addrList );
156
void SerializerPluginMail::serialize( const Item& item, const QByteArray& label, QIODevice& data, int &version )
160
boost::shared_ptr<Message> m = item.payload< boost::shared_ptr<Message> >();
162
if ( label == MessagePart::Body ) {
163
data.write( m->encodedContent() );
164
} else if ( label == MessagePart::Envelope ) {
165
QList<QByteArray> env;
166
env << quoteImapListEntry( m->date()->as7BitString( false ) );
167
env << quoteImapListEntry( m->subject()->as7BitString( false ) );
168
env << buildAddrStruct( m->from() );
169
env << buildAddrStruct( m->sender() );
170
env << buildAddrStruct( m->replyTo() );
171
env << buildAddrStruct( m->to() );
172
env << buildAddrStruct( m->cc() );
173
env << buildAddrStruct( m->bcc() );
174
env << quoteImapListEntry( m->inReplyTo()->as7BitString( false ) );
175
env << quoteImapListEntry( m->messageID()->as7BitString( false ) );
176
data.write( buildImapList( env ) );
177
} else if ( label == MessagePart::Header ) {
178
data.write( m->head() );
182
QSet<QByteArray> SerializerPluginMail::parts(const Item & item) const
184
if ( !item.hasPayload<MessagePtr>() )
185
return QSet<QByteArray>();
186
MessagePtr msg = item.payload<MessagePtr>();
187
QSet<QByteArray> set;
188
// FIXME: we actually want "has any header" here, but the kmime api doesn't offer that yet
189
if ( msg->hasContent() || msg->hasHeader( "Message-ID" ) ) {
190
set << MessagePart::Envelope << MessagePart::Header;
191
if ( !msg->body().isEmpty() || !msg->contents().isEmpty() )
192
set << MessagePart::Body;
197
Q_EXPORT_PLUGIN2( akonadi_serializer_mail, SerializerPluginMail )
199
#include "akonadi_serializer_mail.moc"