Backport r950340 | aacid | 2009-04-06 23:21:18 +0200 (Mon, 06 Apr 2009) | 4 lines
[kdepim.git] / kmail / mailinglist-magic.cpp
blob26c4d54dd7227495b0ecc3741646594f666fe87b
1 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
3 #include "mailinglist-magic.h"
5 #include "kmmessage.h"
7 #include <kconfig.h>
8 #include <kconfiggroup.h>
9 #include <kurl.h>
10 #include <kdebug.h>
12 #include <QStringList>
13 //Added by qt3to4:
14 #include <QByteArray>
16 using namespace KMail;
18 typedef QString (*MagicDetectorFunc) (const KMMessage *, QByteArray &, QString &);
20 /* Sender: (owner-([^@]+)|([^@+]-owner)@ */
21 static QString check_sender(const KMMessage *message,
22 QByteArray &header_name,
23 QString &header_value )
25 QString header = message->headerField( "Sender" );
27 if ( header.isEmpty() )
28 return QString();
30 if ( header.left( 6 ) == "owner-" )
32 header_name = "Sender";
33 header_value = header;
34 header = header.mid( 6, header.indexOf( '@' ) - 6 );
36 } else {
37 int index = header.indexOf( "-owner@ " );
38 if ( index == -1 )
39 return QString();
41 header.truncate( index );
42 header_name = "Sender";
43 header_value = header;
46 return header;
49 /* X-BeenThere: ([^@]+) */
50 static QString check_x_beenthere(const KMMessage *message,
51 QByteArray &header_name,
52 QString &header_value )
54 QString header = message->headerField( "X-BeenThere" );
55 if ( header.isNull() || header.indexOf( '@' ) == -1 )
56 return QString();
58 header_name = "X-BeenThere";
59 header_value = header;
60 header.truncate( header.indexOf( '@' ) );
61 return header;
64 /* Delivered-To:: <([^@]+) */
65 static QString check_delivered_to(const KMMessage *message,
66 QByteArray &header_name,
67 QString &header_value )
69 QString header = message->headerField( "Delivered-To" );
70 if ( header.isNull() || header.left(13 ) != "mailing list"
71 || header.indexOf( '@' ) == -1 )
72 return QString();
74 header_name = "Delivered-To";
75 header_value = header;
77 return header.mid( 13, header.indexOf( '@' ) - 13 );
80 /* X-Mailing-List: <?([^@]+) */
81 static QString check_x_mailing_list(const KMMessage *message,
82 QByteArray &header_name,
83 QString &header_value )
85 QString header = message->headerField( "X-Mailing-List");
86 if ( header.isEmpty() )
87 return QString();
89 if ( header.indexOf( '@' ) < 1 )
90 return QString();
92 header_name = "X-Mailing-List";
93 header_value = header;
94 if ( header[0] == '<' )
95 header = header.mid(1, header.indexOf( '@' ) - 1);
96 else
97 header.truncate( header.indexOf( '@' ) );
98 return header;
101 /* List-Id: [^<]* <([^.]+) */
102 static QString check_list_id(const KMMessage *message,
103 QByteArray &header_name,
104 QString &header_value )
106 int lAnglePos, firstDotPos;
107 QString header = message->headerField( "List-Id" );
108 if ( header.isEmpty() )
109 return QString();
111 lAnglePos = header.indexOf( '<' );
112 if ( lAnglePos < 0 )
113 return QString();
115 firstDotPos = header.indexOf( '.', lAnglePos );
116 if ( firstDotPos < 0 )
117 return QString();
119 header_name = "List-Id";
120 header_value = header.mid( lAnglePos );
121 header = header.mid( lAnglePos + 1, firstDotPos - lAnglePos - 1 );
122 return header;
126 /* List-Post: <mailto:[^< ]*>) */
127 static QString check_list_post(const KMMessage *message,
128 QByteArray &header_name,
129 QString &header_value )
131 QString header = message->headerField( "List-Post" );
132 if ( header.isEmpty() )
133 return QString();
135 int lAnglePos = header.indexOf( "<mailto:" );
136 if ( lAnglePos < 0 )
137 return QString();
139 header_name = "List-Post";
140 header_value = header;
141 header = header.mid( lAnglePos + 8, header.length());
142 header.truncate( header.indexOf('@') );
143 return header;
146 /* Mailing-List: list ([^@]+) */
147 static QString check_mailing_list(const KMMessage *message,
148 QByteArray &header_name,
149 QString &header_value )
151 QString header = message->headerField( "Mailing-List");
152 if ( header.isEmpty() )
153 return QString();
155 if (header.left( 5 ) != "list " || header.indexOf( '@' ) < 5 )
156 return QString();
158 header_name = "Mailing-List";
159 header_value = header;
160 header = header.mid(5, header.indexOf( '@' ) - 5);
161 return header;
165 /* X-Loop: ([^@]+) */
166 static QString check_x_loop(const KMMessage *message,
167 QByteArray &header_name,
168 QString &header_value ){
169 QString header = message->headerField( "X-Loop");
170 if ( header.isEmpty() )
171 return QString();
173 if (header.indexOf( '@' ) < 2 )
174 return QString();
176 header_name = "X-Loop";
177 header_value = header;
178 header.truncate(header.indexOf( '@' ));
179 return header;
182 /* X-ML-Name: (.+) */
183 static QString check_x_ml_name(const KMMessage *message,
184 QByteArray &header_name,
185 QString &header_value ){
186 QString header = message->headerField( "X-ML-Name");
187 if ( header.isEmpty() )
188 return QString();
190 header_name = "X-ML-Name";
191 header_value = header;
192 header.truncate(header.indexOf( '@' ));
193 return header;
196 MagicDetectorFunc magic_detector[] =
198 check_list_id,
199 check_list_post,
200 check_sender,
201 check_x_mailing_list,
202 check_mailing_list,
203 check_delivered_to,
204 check_x_beenthere,
205 check_x_loop,
206 check_x_ml_name
209 static const int num_detectors = sizeof (magic_detector) / sizeof (magic_detector[0]);
211 static QStringList
212 headerToAddress( const QString& header )
214 QStringList addr;
215 int start = 0;
216 int end = 0;
218 if ( header.isEmpty() )
219 return addr;
221 while ( (start = header.indexOf( "<", start )) != -1 ) {
222 if ( (end = header.indexOf( ">", ++start ) ) == -1 ) {
223 kDebug(5006)<<"Serious mailing list header parsing error !";
224 return addr;
226 kDebug(5006)<<"Mailing list ="<<header.mid( start, end - start );
227 addr.append( header.mid( start, end - start ) );
229 return addr;
232 MailingList
233 MailingList::detect( const KMMessage *message )
235 MailingList mlist;
237 mlist.setPostURLS( headerToAddress(
238 message->headerField( "List-Post" ) ) );
239 mlist.setHelpURLS( headerToAddress(
240 message->headerField( "List-Help" ) ) );
241 mlist.setSubscribeURLS( headerToAddress(
242 message->headerField( "List-Subscribe" ) ) );
243 mlist.setUnsubscribeURLS( headerToAddress(
244 message->headerField( "List-Unsubscribe" ) ) );
245 mlist.setArchiveURLS( headerToAddress(
246 message->headerField( "List-Archive" ) ) );
247 mlist.setId( message->headerField( "List-Id" ) );
249 return mlist;
252 QString
253 MailingList::name( const KMMessage *message, QByteArray &header_name,
254 QString &header_value )
256 QString mlist;
257 header_name = QByteArray();
258 header_value.clear();
260 if ( !message )
261 return QString();
263 for (int i = 0; i < num_detectors; i++) {
264 mlist = magic_detector[i] (message, header_name, header_value);
265 if ( !mlist.isNull() )
266 return mlist;
269 return QString();
272 MailingList::MailingList()
273 : mFeatures( None ), mHandler( KMail )
278 MailingList::features() const
280 return mFeatures;
283 void
284 MailingList::setHandler( MailingList::Handler han )
286 mHandler = han;
288 MailingList::Handler
289 MailingList::handler() const
291 return mHandler;
294 void
295 MailingList::setPostURLS ( const KUrl::List& lst )
297 mFeatures |= Post;
298 if ( lst.empty() ) {
299 mFeatures ^= Post;
301 mPostURLS = lst;
303 KUrl::List
304 MailingList::postURLS() const
306 return mPostURLS;
309 void
310 MailingList::setSubscribeURLS( const KUrl::List& lst )
312 mFeatures |= Subscribe;
313 if ( lst.empty() ) {
314 mFeatures ^= Subscribe;
317 mSubscribeURLS = lst;
319 KUrl::List
320 MailingList::subscribeURLS() const
322 return mSubscribeURLS;
325 void
326 MailingList::setUnsubscribeURLS( const KUrl::List& lst )
328 mFeatures |= Unsubscribe;
329 if ( lst.empty() ) {
330 mFeatures ^= Unsubscribe;
333 mUnsubscribeURLS = lst;
335 KUrl::List MailingList::unsubscribeURLS() const
337 return mUnsubscribeURLS;
340 void
341 MailingList::setHelpURLS( const KUrl::List& lst )
343 mFeatures |= Help;
344 if ( lst.empty() ) {
345 mFeatures ^= Help;
348 mHelpURLS = lst;
350 KUrl::List
351 MailingList::helpURLS() const
353 return mHelpURLS;
356 void
357 MailingList::setArchiveURLS( const KUrl::List& lst )
359 mFeatures |= Archive;
360 if ( lst.empty() ) {
361 mFeatures ^= Archive;
364 mArchiveURLS = lst;
366 KUrl::List
367 MailingList::archiveURLS() const
369 return mArchiveURLS;
372 void
373 MailingList::setId( const QString& str )
375 mFeatures |= Id;
376 if ( str.isEmpty() ) {
377 mFeatures ^= Id;
380 mId = str;
382 QString
383 MailingList::id() const
385 return mId;
388 void
389 MailingList::writeConfig( KConfigGroup & config ) const
391 config.writeEntry( "MailingListFeatures", mFeatures );
392 config.writeEntry( "MailingListHandler", (int)mHandler );
393 config.writeEntry( "MailingListId", mId );
394 config.writeEntry( "MailingListPostingAddress", mPostURLS.toStringList() );
395 config.writeEntry( "MailingListSubscribeAddress", mSubscribeURLS.toStringList() );
396 config.writeEntry( "MailingListUnsubscribeAddress", mUnsubscribeURLS.toStringList() );
397 config.writeEntry( "MailingListArchiveAddress", mArchiveURLS.toStringList() );
398 config.writeEntry( "MailingListHelpAddress", mHelpURLS.toStringList() );
401 void
402 MailingList::readConfig( KConfigGroup & config )
404 mFeatures = config.readEntry( "MailingListFeatures", 0 );
405 mHandler = static_cast<MailingList::Handler>(
406 config.readEntry( "MailingListHandler", (int)MailingList::KMail ) );
408 mId = config.readEntry("MailingListId");
409 mPostURLS = config.readEntry( "MailingListPostingAddress", QStringList() );
410 mSubscribeURLS = config.readEntry( "MailingListSubscribeAddress", QStringList() );
411 mUnsubscribeURLS = config.readEntry( "MailingListUnsubscribeAddress", QStringList() );
412 mArchiveURLS = config.readEntry( "MailingListArchiveAddress", QStringList() );
413 mHelpURLS = config.readEntry( "MailingListHelpAddress", QStringList() );