1 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
3 #include "mailinglist-magic.h"
8 #include <kconfiggroup.h>
12 #include <QStringList>
15 using namespace KMail
;
17 typedef QString (*MagicDetectorFunc
) (const KMMessage
*, QByteArray
&, QString
&);
19 /* Sender: (owner-([^@]+)|([^@+]-owner)@ */
20 static QString
check_sender(const KMMessage
*message
,
21 QByteArray
&header_name
,
22 QString
&header_value
)
24 QString header
= message
->headerField( "Sender" );
26 if ( header
.isEmpty() )
29 if ( header
.left( 6 ) == "owner-" )
31 header_name
= "Sender";
32 header_value
= header
;
33 header
= header
.mid( 6, header
.indexOf( '@' ) - 6 );
36 int index
= header
.indexOf( "-owner@ " );
40 header
.truncate( index
);
41 header_name
= "Sender";
42 header_value
= header
;
48 /* X-BeenThere: ([^@]+) */
49 static QString
check_x_beenthere(const KMMessage
*message
,
50 QByteArray
&header_name
,
51 QString
&header_value
)
53 QString header
= message
->headerField( "X-BeenThere" );
54 if ( header
.isNull() || header
.indexOf( '@' ) == -1 )
57 header_name
= "X-BeenThere";
58 header_value
= header
;
59 header
.truncate( header
.indexOf( '@' ) );
63 /* Delivered-To:: <([^@]+) */
64 static QString
check_delivered_to(const KMMessage
*message
,
65 QByteArray
&header_name
,
66 QString
&header_value
)
68 QString header
= message
->headerField( "Delivered-To" );
69 if ( header
.isNull() || header
.left(13 ) != "mailing list"
70 || header
.indexOf( '@' ) == -1 )
73 header_name
= "Delivered-To";
74 header_value
= header
;
76 return header
.mid( 13, header
.indexOf( '@' ) - 13 );
79 /* X-Mailing-List: <?([^@]+) */
80 static QString
check_x_mailing_list(const KMMessage
*message
,
81 QByteArray
&header_name
,
82 QString
&header_value
)
84 QString header
= message
->headerField( "X-Mailing-List");
85 if ( header
.isEmpty() )
88 if ( header
.indexOf( '@' ) < 1 )
91 header_name
= "X-Mailing-List";
92 header_value
= header
;
93 if ( header
[0] == '<' )
94 header
= header
.mid(1, header
.indexOf( '@' ) - 1);
96 header
.truncate( header
.indexOf( '@' ) );
100 /* List-Id: [^<]* <([^.]+) */
101 static QString
check_list_id(const KMMessage
*message
,
102 QByteArray
&header_name
,
103 QString
&header_value
)
105 int lAnglePos
, firstDotPos
;
106 QString header
= message
->headerField( "List-Id" );
107 if ( header
.isEmpty() )
110 lAnglePos
= header
.indexOf( '<' );
114 firstDotPos
= header
.indexOf( '.', lAnglePos
);
115 if ( firstDotPos
< 0 )
118 header_name
= "List-Id";
119 header_value
= header
.mid( lAnglePos
);
120 header
= header
.mid( lAnglePos
+ 1, firstDotPos
- lAnglePos
- 1 );
125 /* List-Post: <mailto:[^< ]*>) */
126 static QString
check_list_post(const KMMessage
*message
,
127 QByteArray
&header_name
,
128 QString
&header_value
)
130 QString header
= message
->headerField( "List-Post" );
131 if ( header
.isEmpty() )
134 int lAnglePos
= header
.indexOf( "<mailto:" );
138 header_name
= "List-Post";
139 header_value
= header
;
140 header
= header
.mid( lAnglePos
+ 8, header
.length());
141 header
.truncate( header
.indexOf('@') );
145 /* Mailing-List: list ([^@]+) */
146 static QString
check_mailing_list(const KMMessage
*message
,
147 QByteArray
&header_name
,
148 QString
&header_value
)
150 QString header
= message
->headerField( "Mailing-List");
151 if ( header
.isEmpty() )
154 if (header
.left( 5 ) != "list " || header
.indexOf( '@' ) < 5 )
157 header_name
= "Mailing-List";
158 header_value
= header
;
159 header
= header
.mid(5, header
.indexOf( '@' ) - 5);
164 /* X-Loop: ([^@]+) */
165 static QString
check_x_loop(const KMMessage
*message
,
166 QByteArray
&header_name
,
167 QString
&header_value
){
168 QString header
= message
->headerField( "X-Loop");
169 if ( header
.isEmpty() )
172 if (header
.indexOf( '@' ) < 2 )
175 header_name
= "X-Loop";
176 header_value
= header
;
177 header
.truncate(header
.indexOf( '@' ));
181 /* X-ML-Name: (.+) */
182 static QString
check_x_ml_name(const KMMessage
*message
,
183 QByteArray
&header_name
,
184 QString
&header_value
){
185 QString header
= message
->headerField( "X-ML-Name");
186 if ( header
.isEmpty() )
189 header_name
= "X-ML-Name";
190 header_value
= header
;
191 header
.truncate(header
.indexOf( '@' ));
195 MagicDetectorFunc magic_detector
[] =
200 check_x_mailing_list
,
208 static const int num_detectors
= sizeof (magic_detector
) / sizeof (magic_detector
[0]);
211 headerToAddress( const QString
& header
)
217 if ( header
.isEmpty() )
220 while ( (start
= header
.indexOf( "<", start
)) != -1 ) {
221 if ( (end
= header
.indexOf( ">", ++start
) ) == -1 ) {
222 kDebug()<<"Serious mailing list header parsing error !";
225 kDebug()<<"Mailing list ="<<header
.mid( start
, end
- start
);
226 addr
.append( header
.mid( start
, end
- start
) );
232 MailingList::detect( const KMMessage
*message
)
236 mlist
.setPostURLS( headerToAddress(
237 message
->headerField( "List-Post" ) ) );
238 mlist
.setHelpURLS( headerToAddress(
239 message
->headerField( "List-Help" ) ) );
240 mlist
.setSubscribeURLS( headerToAddress(
241 message
->headerField( "List-Subscribe" ) ) );
242 mlist
.setUnsubscribeURLS( headerToAddress(
243 message
->headerField( "List-Unsubscribe" ) ) );
244 mlist
.setArchiveURLS( headerToAddress(
245 message
->headerField( "List-Archive" ) ) );
246 mlist
.setId( message
->headerField( "List-Id" ) );
252 MailingList::name( const KMMessage
*message
, QByteArray
&header_name
,
253 QString
&header_value
)
256 header_name
= QByteArray();
257 header_value
.clear();
262 for (int i
= 0; i
< num_detectors
; i
++) {
263 mlist
= magic_detector
[i
] (message
, header_name
, header_value
);
264 if ( !mlist
.isNull() )
271 MailingList::MailingList()
272 : mFeatures( None
), mHandler( KMail
)
277 MailingList::features() const
283 MailingList::setHandler( MailingList::Handler han
)
288 MailingList::handler() const
294 MailingList::setPostURLS ( const KUrl::List
& lst
)
303 MailingList::postURLS() const
309 MailingList::setSubscribeURLS( const KUrl::List
& lst
)
311 mFeatures
|= Subscribe
;
313 mFeatures
^= Subscribe
;
316 mSubscribeURLS
= lst
;
319 MailingList::subscribeURLS() const
321 return mSubscribeURLS
;
325 MailingList::setUnsubscribeURLS( const KUrl::List
& lst
)
327 mFeatures
|= Unsubscribe
;
329 mFeatures
^= Unsubscribe
;
332 mUnsubscribeURLS
= lst
;
334 KUrl::List
MailingList::unsubscribeURLS() const
336 return mUnsubscribeURLS
;
340 MailingList::setHelpURLS( const KUrl::List
& lst
)
350 MailingList::helpURLS() const
356 MailingList::setArchiveURLS( const KUrl::List
& lst
)
358 mFeatures
|= Archive
;
360 mFeatures
^= Archive
;
366 MailingList::archiveURLS() const
372 MailingList::setId( const QString
& str
)
375 if ( str
.isEmpty() ) {
382 MailingList::id() const
388 MailingList::writeConfig( KConfigGroup
& config
) const
390 config
.writeEntry( "MailingListFeatures", mFeatures
);
391 config
.writeEntry( "MailingListHandler", (int)mHandler
);
392 config
.writeEntry( "MailingListId", mId
);
393 config
.writeEntry( "MailingListPostingAddress", mPostURLS
.toStringList() );
394 config
.writeEntry( "MailingListSubscribeAddress", mSubscribeURLS
.toStringList() );
395 config
.writeEntry( "MailingListUnsubscribeAddress", mUnsubscribeURLS
.toStringList() );
396 config
.writeEntry( "MailingListArchiveAddress", mArchiveURLS
.toStringList() );
397 config
.writeEntry( "MailingListHelpAddress", mHelpURLS
.toStringList() );
401 MailingList::readConfig( KConfigGroup
& config
)
403 mFeatures
= config
.readEntry( "MailingListFeatures", 0 );
404 mHandler
= static_cast<MailingList::Handler
>(
405 config
.readEntry( "MailingListHandler", (int)MailingList::KMail
) );
407 mId
= config
.readEntry("MailingListId");
408 mPostURLS
= config
.readEntry( "MailingListPostingAddress", QStringList() );
409 mSubscribeURLS
= config
.readEntry( "MailingListSubscribeAddress", QStringList() );
410 mUnsubscribeURLS
= config
.readEntry( "MailingListUnsubscribeAddress", QStringList() );
411 mArchiveURLS
= config
.readEntry( "MailingListArchiveAddress", QStringList() );
412 mHelpURLS
= config
.readEntry( "MailingListHelpAddress", QStringList() );