sievedebugdialog.cpp
00001 /* 00002 sievedebugdialog.cpp 00003 00004 KMail, the KDE mail client. 00005 Copyright (c) 2005 Martijn Klingens <klingens@kde.org> 00006 00007 This program is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU General Public License, 00009 version 2.0, as published by the Free Software Foundation. 00010 You should have received a copy of the GNU General Public License 00011 along with this program; if not, write to the Free Software Foundation, 00012 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, US 00013 */ 00014 00015 // This file is only compiled when debug is enabled, it is 00016 // not useful enough for non-developers to have this in releases. 00017 #if !defined(NDEBUG) 00018 00019 #ifdef HAVE_CONFIG_H 00020 #include <config.h> 00021 #endif 00022 00023 #include "sievedebugdialog.h" 00024 00025 #include <cassert> 00026 #include <limits.h> 00027 00028 #include <tqdatetime.h> 00029 00030 #include <kdebug.h> 00031 #include <tdelocale.h> 00032 #include <tdemessagebox.h> 00033 00034 #include <kmime_header_parsing.h> 00035 #include <ksieve/error.h> 00036 #include <ksieve/parser.h> 00037 #include <ksieve/scriptbuilder.h> 00038 #include <libkpimidentities/identity.h> 00039 #include <libkpimidentities/identitymanager.h> 00040 00041 #include "kmacctimap.h" 00042 #include "accountmanager.h" 00043 using KMail::AccountManager; 00044 #include "kmkernel.h" 00045 #include "sievejob.h" 00046 #include <tqtextedit.h> 00047 00048 using KMail::SieveJob; 00049 using KMime::Types::AddrSpecList; 00050 00051 namespace 00052 { 00053 00054 class SieveDebugDataExtractor : public KSieve::ScriptBuilder 00055 { 00056 enum Context 00057 { 00058 None = 0, 00059 00060 // command itself: 00061 SieveDebugCommand, 00062 00063 // tagged args: 00064 Days, Addresses 00065 }; 00066 00067 public: 00068 SieveDebugDataExtractor() 00069 : KSieve::ScriptBuilder() 00070 { 00071 kdDebug( 5006 ) << k_funcinfo << endl; 00072 } 00073 00074 virtual ~SieveDebugDataExtractor() 00075 { 00076 kdDebug( 5006 ) << k_funcinfo << endl; 00077 } 00078 00079 private: 00080 void commandStart( const TQString & identifier ) 00081 { 00082 kdDebug( 5006 ) << k_funcinfo << "Identifier: '" << identifier << "'" << endl; 00083 reset(); 00084 } 00085 00086 void commandEnd() 00087 { 00088 kdDebug( 5006 ) << k_funcinfo << endl; 00089 } 00090 00091 void testStart( const TQString & ) 00092 { 00093 kdDebug( 5006 ) << k_funcinfo << endl; 00094 } 00095 00096 void testEnd() 00097 { 00098 kdDebug( 5006 ) << k_funcinfo << endl; 00099 } 00100 00101 void testListStart() 00102 { 00103 kdDebug( 5006 ) << k_funcinfo << endl; 00104 } 00105 00106 void testListEnd() 00107 { 00108 kdDebug( 5006 ) << k_funcinfo << endl; 00109 } 00110 00111 void blockStart() 00112 { 00113 kdDebug( 5006 ) << k_funcinfo << endl; 00114 } 00115 00116 void blockEnd() 00117 { 00118 kdDebug( 5006 ) << k_funcinfo << endl; 00119 } 00120 00121 void hashComment( const TQString & ) 00122 { 00123 kdDebug( 5006 ) << k_funcinfo << endl; 00124 } 00125 00126 void bracketComment( const TQString & ) 00127 { 00128 kdDebug( 5006 ) << k_funcinfo << endl; 00129 } 00130 00131 void lineFeed() 00132 { 00133 kdDebug( 5006 ) << k_funcinfo << endl; 00134 } 00135 00136 void error( const KSieve::Error & e ) 00137 { 00138 kdDebug( 5006 ) << "### " << k_funcinfo << "Error: " << 00139 e.asString() << " @ " << e.line() << "," << e.column() << endl; 00140 } 00141 00142 void finished() 00143 { 00144 kdDebug( 5006 ) << k_funcinfo << endl; 00145 } 00146 00147 void taggedArgument( const TQString & tag ) 00148 { 00149 kdDebug( 5006 ) << k_funcinfo << "Tag: '" << tag << "'" << endl; 00150 } 00151 00152 void stringArgument( const TQString & string, bool, const TQString & ) 00153 { 00154 kdDebug( 5006 ) << k_funcinfo << "String: '" << string << "'" << endl; 00155 } 00156 00157 void numberArgument( unsigned long number, char ) 00158 { 00159 kdDebug( 5006 ) << k_funcinfo << "Number: " << number << endl; 00160 } 00161 00162 void stringListArgumentStart() 00163 { 00164 kdDebug( 5006 ) << k_funcinfo << endl; 00165 } 00166 00167 void stringListEntry( const TQString & string, bool, const TQString & ) 00168 { 00169 kdDebug( 5006 ) << k_funcinfo << "String: '" << string << "'" << endl; 00170 } 00171 00172 void stringListArgumentEnd() 00173 { 00174 kdDebug( 5006 ) << k_funcinfo << endl; 00175 } 00176 00177 private: 00178 void reset() 00179 { 00180 kdDebug( 5006 ) << k_funcinfo << endl; 00181 } 00182 }; 00183 00184 } // Anon namespace 00185 00186 namespace KMail 00187 { 00188 00189 SieveDebugDialog::SieveDebugDialog( TQWidget *parent, const char *name ) 00190 : KDialogBase( parent, name, true, i18n( "Sieve Diagnostics" ), KDialogBase::Ok, 00191 KDialogBase::Ok, true ), 00192 mSieveJob( 0 ) 00193 { 00194 // Collect all accounts 00195 AccountManager *am = kmkernel->acctMgr(); 00196 assert( am ); 00197 for ( KMAccount *a = am->first(); a; a = am->next() ) 00198 mAccountList.append( a ); 00199 00200 mEdit = new TQTextEdit( this ); 00201 mEdit->setReadOnly(true); 00202 setMainWidget( mEdit ); 00203 00204 mEdit->setText( i18n( "Collecting diagnostic information about Sieve support...\n\n" ) ); 00205 00206 setInitialSize( TQSize( 640, 480 ) ); 00207 00208 if ( !mAccountList.isEmpty() ) 00209 TQTimer::singleShot( 0, this, TQT_SLOT( slotDiagNextAccount() ) ); 00210 } 00211 00212 SieveDebugDialog::~SieveDebugDialog() 00213 { 00214 if ( mSieveJob ) 00215 { 00216 mSieveJob->kill(); 00217 mSieveJob = 0; 00218 } 00219 kdDebug( 5006 ) << k_funcinfo << endl; 00220 } 00221 00222 static KURL urlFromAccount( const KMail::ImapAccountBase * a ) { 00223 const SieveConfig sieve = a->sieveConfig(); 00224 if ( !sieve.managesieveSupported() ) 00225 return KURL(); 00226 00227 KURL u; 00228 if ( sieve.reuseConfig() ) { 00229 // assemble Sieve url from the settings of the account: 00230 u.setProtocol( "sieve" ); 00231 u.setHost( a->host() ); 00232 u.setUser( a->login() ); 00233 u.setPass( a->passwd() ); 00234 u.setPort( sieve.port() ); 00235 00236 // Translate IMAP LOGIN to PLAIN: 00237 u.addQueryItem( "x-mech", a->auth() == "*" ? "PLAIN" : a->auth() ); 00238 if ( !a->useSSL() && !a->useTLS() ) 00239 u.addQueryItem( "x-allow-unencrypted", "true" ); 00240 } else { 00241 u = sieve.alternateURL(); 00242 if ( u.protocol().lower() == "sieve" && !a->useSSL() && !a->useTLS() && u.queryItem("x-allow-unencrypted").isEmpty() ) 00243 u.addQueryItem( "x-allow-unencrypted", "true" ); 00244 } 00245 return u; 00246 } 00247 00248 void SieveDebugDialog::slotDiagNextAccount() 00249 { 00250 if ( mAccountList.isEmpty() ) 00251 return; 00252 00253 KMAccount *acc = mAccountList.first(); 00254 mAccountList.pop_front(); 00255 00256 mEdit->append( i18n( "Collecting data for account '%1'...\n" ).arg( acc->name() ) ); 00257 mEdit->append( i18n( "------------------------------------------------------------\n" ) ); 00258 mAccountBase = dynamic_cast<KMail::ImapAccountBase *>( acc ); 00259 if ( mAccountBase ) 00260 { 00261 // Detect URL for this IMAP account 00262 const KURL url = urlFromAccount( mAccountBase ); 00263 if ( !url.isValid() ) 00264 { 00265 mEdit->append( i18n( "(Account does not support Sieve)\n\n" ) ); 00266 } else { 00267 mUrl = url; 00268 00269 mSieveJob = SieveJob::list( mUrl ); 00270 00271 connect( mSieveJob, TQT_SIGNAL( gotList( KMail::SieveJob *, bool, const TQStringList &, const TQString & ) ), 00272 TQT_SLOT( slotGetScriptList( KMail::SieveJob *, bool, const TQStringList &, const TQString & ) ) ); 00273 00274 // Bypass the singleShot timer -- it's fired when we get our data 00275 return; 00276 } 00277 } else { 00278 mEdit->append( i18n( "(Account is not an IMAP account)\n\n" ) ); 00279 } 00280 00281 // Handle next account async 00282 TQTimer::singleShot( 0, this, TQT_SLOT( slotDiagNextAccount() ) ); 00283 } 00284 00285 void SieveDebugDialog::slotDiagNextScript() 00286 { 00287 if ( mScriptList.isEmpty() ) 00288 { 00289 // Continue handling accounts instead 00290 mScriptList.clear(); 00291 TQTimer::singleShot( 0, this, TQT_SLOT( slotDiagNextAccount() ) ); 00292 return; 00293 } 00294 00295 TQString scriptFile = mScriptList.first(); 00296 mScriptList.pop_front(); 00297 00298 mEdit->append( i18n( "Contents of script '%1':\n" ).arg( scriptFile ) ); 00299 00300 mUrl = urlFromAccount( mAccountBase ); 00301 mUrl.setFileName( scriptFile ); 00302 00303 mSieveJob = SieveJob::get( mUrl ); 00304 00305 connect( mSieveJob, TQT_SIGNAL( gotScript( KMail::SieveJob *, bool, const TQString &, bool ) ), 00306 TQT_SLOT( slotGetScript( KMail::SieveJob *, bool, const TQString &, bool ) ) ); 00307 } 00308 00309 void SieveDebugDialog::slotGetScript( SieveJob * /* job */, bool success, 00310 const TQString &script, bool active ) 00311 { 00312 kdDebug( 5006 ) << "SieveDebugDialog::slotGetScript( ??, " << success 00313 << ", ?, " << active << " )" << endl 00314 << "script:" << endl 00315 << script << endl; 00316 mSieveJob = 0; // job deletes itself after returning from this slot! 00317 00318 if ( script.isEmpty() ) 00319 { 00320 mEdit->append( i18n( "(This script is empty.)\n\n" ) ); 00321 } 00322 else 00323 { 00324 mEdit->append( i18n( 00325 "------------------------------------------------------------\n" 00326 "%1\n" 00327 "------------------------------------------------------------\n\n" ).arg( script ) ); 00328 } 00329 00330 // Fetch next script 00331 TQTimer::singleShot( 0, this, TQT_SLOT( slotDiagNextScript() ) ); 00332 } 00333 00334 void SieveDebugDialog::slotGetScriptList( SieveJob *job, bool success, 00335 const TQStringList &scriptList, const TQString &activeScript ) 00336 { 00337 kdDebug( 5006 ) << k_funcinfo << "Success: " << success << ", List: " << scriptList.join( ", " ) << 00338 ", active: " << activeScript << endl; 00339 mSieveJob = 0; // job deletes itself after returning from this slot! 00340 00341 mEdit->append( i18n( "Sieve capabilities:\n" ) ); 00342 TQStringList caps = job->sieveCapabilities(); 00343 if ( caps.isEmpty() ) 00344 { 00345 mEdit->append( i18n( "(No special capabilities available)" ) ); 00346 } 00347 else 00348 { 00349 for ( TQStringList::const_iterator it = caps.begin(); it != caps.end(); ++it ) 00350 mEdit->append( "* " + *it + "\n" ); 00351 mEdit->append( "\n" ); 00352 } 00353 00354 mEdit->append( i18n( "Available Sieve scripts:\n" ) ); 00355 00356 if ( scriptList.isEmpty() ) 00357 { 00358 mEdit->append( i18n( "(No Sieve scripts available on this server)\n\n" ) ); 00359 } 00360 else 00361 { 00362 mScriptList = scriptList; 00363 for ( TQStringList::const_iterator it = scriptList.begin(); it != scriptList.end(); ++it ) 00364 mEdit->append( "* " + *it + "\n" ); 00365 mEdit->append( "\n" ); 00366 mEdit->append( i18n( "Active script: %1\n\n" ).arg( activeScript ) ); 00367 } 00368 00369 // Handle next job: dump scripts for this server 00370 TQTimer::singleShot( 0, this, TQT_SLOT( slotDiagNextScript() ) ); 00371 } 00372 00373 void SieveDebugDialog::slotDialogOk() 00374 { 00375 kdDebug(5006) << "SieveDebugDialog::slotDialogOk()" << endl; 00376 } 00377 00378 void SieveDebugDialog::slotPutActiveResult( SieveJob * job, bool success ) 00379 { 00380 handlePutResult( job, success, true ); 00381 } 00382 00383 void SieveDebugDialog::slotPutInactiveResult( SieveJob * job, bool success ) 00384 { 00385 handlePutResult( job, success, false ); 00386 } 00387 00388 void SieveDebugDialog::handlePutResult( SieveJob *, bool success, bool activated ) 00389 { 00390 if ( success ) 00391 { 00392 KMessageBox::information( 0, activated ? i18n( 00393 "Sieve script installed successfully on the server.\n" 00394 "Out of Office reply is now active." ) 00395 : i18n( "Sieve script installed successfully on the server.\n" 00396 "Out of Office reply has been deactivated." ) ); 00397 } 00398 00399 kdDebug( 5006 ) << "SieveDebugDialog::handlePutResult( ???, " << success << ", ? )" << endl; 00400 mSieveJob = 0; // job deletes itself after returning from this slot! 00401 } 00402 00403 00404 } // namespace KMail 00405 00406 #include "sievedebugdialog.moc" 00407 00408 #endif // NDEBUG 00409