kmail

sievedebugdialog.cpp

Go to the documentation of this file.
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 <qdatetime.h>
00029 
00030 #include <kdebug.h>
00031 #include <klocale.h>
00032 #include <kmessagebox.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 <qtextedit.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 QString & 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 QString & )
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 QString & )
00122     {
00123         kdDebug( 5006 ) << k_funcinfo << endl;
00124     }
00125 
00126     void bracketComment( const QString & )
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 QString & tag )
00148     {
00149         kdDebug( 5006 ) << k_funcinfo << "Tag: '" << tag << "'" << endl;
00150     }
00151 
00152     void stringArgument( const QString & string, bool, const QString & )
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 QString & string, bool, const QString & )
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( QWidget *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 QTextEdit( this );
00201     mEdit->setReadOnly(true);
00202     setMainWidget( mEdit );
00203 
00204     mEdit->setText( i18n( "Collecting diagnostic information about Sieve support...\n\n" ) );
00205 
00206     setInitialSize( QSize( 640, 480 ) );
00207 
00208     if ( !mAccountList.isEmpty() )
00209         QTimer::singleShot( 0, this, 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 void SieveDebugDialog::slotDiagNextAccount()
00223 {
00224     if ( mAccountList.isEmpty() )
00225         return;
00226 
00227     KMAccount *acc = mAccountList.first();
00228     mAccountList.pop_front();
00229 
00230     mEdit->append( i18n( "Collecting data for account '%1'...\n" ).arg( acc->name() ) );
00231     mEdit->append( i18n( "------------------------------------------------------------\n" ) );
00232     mAccountBase = dynamic_cast<KMail::ImapAccountBase *>( acc );
00233     if ( mAccountBase )
00234     {
00235         // Detect URL for this IMAP account
00236         SieveConfig sieve = mAccountBase->sieveConfig();
00237         if ( !sieve.managesieveSupported() )
00238         {
00239             mEdit->append( i18n( "(Account does not support Sieve)\n\n" ) );
00240         } else {
00241             if ( sieve.reuseConfig() )
00242             {
00243                 // assemble Sieve url from the settings of the account:
00244                 mUrl.setProtocol( "sieve" );
00245                 mUrl.setHost( mAccountBase->host() );
00246                 mUrl.setUser( mAccountBase->login() );
00247                 mUrl.setPass( mAccountBase->passwd() );
00248                 mUrl.setPort( sieve.port() );
00249 
00250                 // Translate IMAP LOGIN to PLAIN:
00251                 mUrl.setQuery( "x-mech=" + ( mAccountBase->auth() == "*" ? "PLAIN" : mAccountBase->auth() ) );
00252             } else {
00253                 sieve.alternateURL();
00254                 mUrl.setFileName( sieve.vacationFileName() );
00255             }
00256 
00257             mSieveJob = SieveJob::list( mUrl );
00258 
00259             connect( mSieveJob, SIGNAL( gotList( KMail::SieveJob *, bool, const QStringList &, const QString & ) ),
00260                 SLOT( slotGetScriptList( KMail::SieveJob *, bool, const QStringList &, const QString & ) ) );
00261 
00262             // Bypass the singleShot timer -- it's fired when we get our data
00263             return;
00264         }
00265     } else {
00266         mEdit->append( i18n( "(Account is not an IMAP account)\n\n" ) );
00267     }
00268 
00269     // Handle next account async
00270     QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
00271 }
00272 
00273 void SieveDebugDialog::slotDiagNextScript()
00274 {
00275     if ( mScriptList.isEmpty() )
00276     {
00277         // Continue handling accounts instead
00278         mScriptList.clear();
00279         QTimer::singleShot( 0, this, SLOT( slotDiagNextAccount() ) );
00280         return;
00281     }
00282 
00283     QString scriptFile = mScriptList.first();
00284     mScriptList.pop_front();
00285 
00286     mEdit->append( i18n( "Contents of script '%1':\n" ).arg( scriptFile ) );
00287     SieveConfig sieve = mAccountBase->sieveConfig();
00288     if ( sieve.reuseConfig() )
00289     {
00290         // assemble Sieve url from the settings of the account:
00291         mUrl.setProtocol( "sieve" );
00292         mUrl.setHost( mAccountBase->host() );
00293         mUrl.setUser( mAccountBase->login() );
00294         mUrl.setPass( mAccountBase->passwd() );
00295         mUrl.setPort( sieve.port() );
00296         // Translate IMAP LOGIN to PLAIN
00297         mUrl.setQuery( "x-mech=" + ( mAccountBase->auth() == "*" ? "PLAIN" : mAccountBase->auth() ) );
00298         mUrl.setFileName( scriptFile );
00299     } else {
00300         sieve.alternateURL();
00301         mUrl.setFileName( scriptFile );
00302     }
00303 
00304     mSieveJob = SieveJob::get( mUrl );
00305 
00306     connect( mSieveJob, SIGNAL( gotScript( KMail::SieveJob *, bool, const QString &, bool ) ),
00307         SLOT( slotGetScript( KMail::SieveJob *, bool, const QString &, bool ) ) );
00308 }
00309 
00310 void SieveDebugDialog::slotGetScript( SieveJob * /* job */, bool success,
00311     const QString &script, bool active )
00312 {
00313     kdDebug( 5006 ) << "SieveDebugDialog::slotGetScript( ??, " << success
00314               << ", ?, " << active << " )" << endl
00315               << "script:" << endl
00316               << script << endl;
00317     mSieveJob = 0; // job deletes itself after returning from this slot!
00318 
00319     if ( script.isEmpty() )
00320     {
00321         mEdit->append( i18n( "(This script is empty.)\n\n" ) );
00322     }
00323     else
00324     {
00325         mEdit->append( i18n(
00326             "------------------------------------------------------------\n"
00327             "%1\n"
00328             "------------------------------------------------------------\n\n" ).arg( script ) );
00329     }
00330 
00331     // Fetch next script
00332     QTimer::singleShot( 0, this, SLOT( slotDiagNextScript() ) );
00333 }
00334 
00335 void SieveDebugDialog::slotGetScriptList( SieveJob *job, bool success,
00336     const QStringList &scriptList, const QString &activeScript )
00337 {
00338     kdDebug( 5006 ) << k_funcinfo << "Success: " << success << ", List: " << scriptList.join( ", " ) <<
00339         ", active: " << activeScript << endl;
00340     mSieveJob = 0; // job deletes itself after returning from this slot!
00341 
00342     mEdit->append( i18n( "Sieve capabilities:\n" ) );
00343     QStringList caps = job->sieveCapabilities();
00344     if ( caps.isEmpty() )
00345     {
00346         mEdit->append( i18n( "(No special capabilities available)" ) );
00347     }
00348     else
00349     {
00350         for ( QStringList::const_iterator it = caps.begin(); it != caps.end(); ++it )
00351             mEdit->append( "* " + *it + "\n" );
00352         mEdit->append( "\n" );
00353     }
00354 
00355     mEdit->append( i18n( "Available Sieve scripts:\n" ) );
00356 
00357     if ( scriptList.isEmpty() )
00358     {
00359         mEdit->append( i18n( "(No Sieve scripts available on this server)\n\n" ) );
00360     }
00361     else
00362     {
00363         mScriptList = scriptList;
00364         for ( QStringList::const_iterator it = scriptList.begin(); it != scriptList.end(); ++it )
00365             mEdit->append( "* " + *it + "\n" );
00366         mEdit->append( "\n" );
00367         mEdit->append( i18n( "Active script: %1\n\n" ).arg( activeScript ) );
00368     }
00369 
00370     // Handle next job: dump scripts for this server
00371     QTimer::singleShot( 0, this, SLOT( slotDiagNextScript() ) );
00372 }
00373 
00374 void SieveDebugDialog::slotDialogOk()
00375 {
00376     kdDebug(5006) << "SieveDebugDialog::slotDialogOk()" << endl;
00377 }
00378 
00379 void SieveDebugDialog::slotPutActiveResult( SieveJob * job, bool success )
00380 {
00381     handlePutResult( job, success, true );
00382 }
00383 
00384 void SieveDebugDialog::slotPutInactiveResult( SieveJob * job, bool success )
00385 {
00386     handlePutResult( job, success, false );
00387 }
00388 
00389 void SieveDebugDialog::handlePutResult( SieveJob *, bool success, bool activated )
00390 {
00391     if ( success )
00392     {
00393         KMessageBox::information( 0, activated ? i18n(
00394             "Sieve script installed successfully on the server.\n"
00395             "Out of Office reply is now active." )
00396             : i18n( "Sieve script installed successfully on the server.\n"
00397             "Out of Office reply has been deactivated." ) );
00398     }
00399 
00400     kdDebug( 5006 ) << "SieveDebugDialog::handlePutResult( ???, " << success << ", ? )" << endl;
00401     mSieveJob = 0; // job deletes itself after returning from this slot!
00402 }
00403 
00404 
00405 } // namespace KMail
00406 
00407 #include "sievedebugdialog.moc"
00408 
00409 #endif // NDEBUG
00410