1 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
3 #include "mailinglist-magic.h"
8 #include <kconfiggroup.h>
12 #include <QStringList>
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() )
30 if ( header
.left( 6 ) == "owner-" )
32 header_name
= "Sender";
33 header_value
= header
;
34 header
= header
.mid( 6, header
.indexOf( '@' ) - 6 );
37 int index
= header
.indexOf( "-owner@ " );
41 header
.truncate( index
);
42 header_name
= "Sender";
43 header_value
= 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 )
58 header_name
= "X-BeenThere";
59 header_value
= header
;
60 header
.truncate( header
.indexOf( '@' ) );
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 )
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() )
89 if ( header
.indexOf( '@' ) < 1 )
92 header_name
= "X-Mailing-List";
93 header_value
= header
;
94 if ( header
[0] == '<' )
95 header
= header
.mid(1, header
.indexOf( '@' ) - 1);
97 header
.truncate( header
.indexOf( '@' ) );
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() )
111 lAnglePos
= header
.indexOf( '<' );
115 firstDotPos
= header
.indexOf( '.', lAnglePos
);
116 if ( firstDotPos
< 0 )
119 header_name
= "List-Id";
120 header_value
= header
.mid( lAnglePos
);
121 header
= header
.mid( lAnglePos
+ 1, firstDotPos
- lAnglePos
- 1 );
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() )
135 int lAnglePos
= header
.indexOf( "<mailto:" );
139 header_name
= "List-Post";
140 header_value
= header
;
141 header
= header
.mid( lAnglePos
+ 8, header
.length());
142 header
.truncate( header
.indexOf('@') );
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() )
155 if (header
.left( 5 ) != "list " || header
.indexOf( '@' ) < 5 )
158 header_name
= "Mailing-List";
159 header_value
= header
;
160 header
= header
.mid(5, header
.indexOf( '@' ) - 5);
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() )
173 if (header
.indexOf( '@' ) < 2 )
176 header_name
= "X-Loop";
177 header_value
= header
;
178 header
.truncate(header
.indexOf( '@' ));
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() )
190 header_name
= "X-ML-Name";
191 header_value
= header
;
192 header
.truncate(header
.indexOf( '@' ));
196 MagicDetectorFunc magic_detector
[] =
201 check_x_mailing_list
,
209 static const int num_detectors
= sizeof (magic_detector
) / sizeof (magic_detector
[0]);
212 headerToAddress( const QString
& header
)
218 if ( header
.isEmpty() )
221 while ( (start
= header
.indexOf( "<", start
)) != -1 ) {
222 if ( (end
= header
.indexOf( ">", ++start
) ) == -1 ) {
223 kDebug(5006)<<"Serious mailing list header parsing error !";
226 kDebug(5006)<<"Mailing list ="<<header
.mid( start
, end
- start
);
227 addr
.append( header
.mid( start
, end
- start
) );
233 MailingList::detect( const KMMessage
*message
)
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" ) );
253 MailingList::name( const KMMessage
*message
, QByteArray
&header_name
,
254 QString
&header_value
)
257 header_name
= QByteArray();
258 header_value
.clear();
263 for (int i
= 0; i
< num_detectors
; i
++) {
264 mlist
= magic_detector
[i
] (message
, header_name
, header_value
);
265 if ( !mlist
.isNull() )
272 MailingList::MailingList()
273 : mFeatures( None
), mHandler( KMail
)
278 MailingList::features() const
284 MailingList::setHandler( MailingList::Handler han
)
289 MailingList::handler() const
295 MailingList::setPostURLS ( const KUrl::List
& lst
)
304 MailingList::postURLS() const
310 MailingList::setSubscribeURLS( const KUrl::List
& lst
)
312 mFeatures
|= Subscribe
;
314 mFeatures
^= Subscribe
;
317 mSubscribeURLS
= lst
;
320 MailingList::subscribeURLS() const
322 return mSubscribeURLS
;
326 MailingList::setUnsubscribeURLS( const KUrl::List
& lst
)
328 mFeatures
|= Unsubscribe
;
330 mFeatures
^= Unsubscribe
;
333 mUnsubscribeURLS
= lst
;
335 KUrl::List
MailingList::unsubscribeURLS() const
337 return mUnsubscribeURLS
;
341 MailingList::setHelpURLS( const KUrl::List
& lst
)
351 MailingList::helpURLS() const
357 MailingList::setArchiveURLS( const KUrl::List
& lst
)
359 mFeatures
|= Archive
;
361 mFeatures
^= Archive
;
367 MailingList::archiveURLS() const
373 MailingList::setId( const QString
& str
)
376 if ( str
.isEmpty() ) {
383 MailingList::id() const
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() );
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() );