Summary: | [PATCH] Filters for outgoing messages should be applied before mails are sent | ||
---|---|---|---|
Product: | [Unmaintained] kmail | Reporter: | Andrew Kohlsmith <akohlsmith-kde> |
Component: | filtering | Assignee: | Bruno Bigras <bigras.bruno> |
Status: | RESOLVED FIXED | ||
Severity: | wishlist | CC: | bigras.bruno, cobaco, cshobe, danielb, jannis.fath, jf, max, mfranz, mgd, pentek.imre, sven.burmeister |
Priority: | NOR | ||
Version: | 1.4.7 | ||
Target Milestone: | --- | ||
Platform: | Compiled Sources | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: | kmail.diff |
Description
Andrew Kohlsmith
2002-10-09 20:08:19 UTC
This is no bug but a wish. Furthermore I'm pretty sure that it's a duplicate. Subject: Re: filter for sent mail is too literal
> This is no bug but a wish. Furthermore I'm pretty sure that it's a
> duplicate.
My apologies, I mis-clicked. I didn't notice anything like it in the similar
bugs/wishlist screen that the bug tracker brings up though.
Regards,
Andrew
*** Bug 67298 has been marked as a duplicate of this bug. *** Still would like to keep this as a feature request for 3.2.2+ *** Bug 78816 has been marked as a duplicate of this bug. *** *** Bug 92225 has been marked as a duplicate of this bug. *** *** Bug 61592 has been marked as a duplicate of this bug. *** This is also useful for outgoing mail virus scanning. *** Bug 97243 has been marked as a duplicate of this bug. *** Since the functionality is now in the code but not working should this not be considered a bug now? i.e. what use is setting the sending identity or rewriting headers if they only apply *after* the message leaves? *** Bug 99194 has been marked as a duplicate of this bug. *** Created attachment 19051 [details]
kmail.diff
I have added a checkbox to the Advanced-Tab
"Apply this filter before sending messages"
Filters are processed before sending, at this point in time the mail is already
signed/encrypted. In other words the body can only be seen/manipulated in
filters if the message is not encrypted.
before I continue I'd like to get some feedback if this is required.
some options
a) as is, body in preSend filter is not available
b) pass unencrypted message to filter. Manipulation is still not possible, but
usage in filter criteria should work (to be verified)
c) process filter before encryption. If mail is deleted from outbox it goes
through the filter but is never sent. Moving to different folder will prevent
mail from sending, only mails in outbox are sent. (check: is FilterMgr
accessible at this stage?)
comments?
At this point in time I can't see a real *use* for mangling the body of messages before sending, but I do see the possibility of using a filter to run the entire message through a script or something external (virus scan?) before sending. Personally I like (c) best, but (b) is also pretty nifty... with (b) you can always pass back a "bzzzt, try again" type of error and this bypasses the need to manipulate encrypted messages. I need to check out kdesvn again, as I've upgraded my system and am running 3.5.5 on Slackware. I'm not sure what is the difference between "mangling the body of messages before sending" and "run the entire message through a script". However I'd like to see a hook to change the body of messages before sending simply to allow adding functionality (formatting/changing/replacing/whatever) that KMail does not (yet) provide through the use of scripts. That said I think (c) does exactly that AFAICT. Best, Michael SVN commit 622728 by schaarsc: Add "Apply this filter before sending messages" Note: Quick win. Works for headers and clear text mails. CCBUG: 48938 M +8 -0 branches/work/kdepim-3.5.5+/kmail/kmfilter.cpp M +13 -0 branches/work/kdepim-3.5.5+/kmail/kmfilter.h M +20 -9 branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.cpp M +1 -1 branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.h M +1 -0 branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.cpp M +1 -1 branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.h M +16 -0 branches/work/kdepim-3.5.5+/kmail/kmsender.cpp --- branches/work/kdepim-3.5.5+/kmail/kmfilter.cpp #622727:622728 @@ -51,6 +51,7 @@ mAction = Down; else { bApplyOnInbound = true; + bApplyBeforeOutbound = false; bApplyOnOutbound = false; bApplyOnExplicit = true; bStopProcessingHere = true; @@ -75,6 +76,7 @@ mAction = aFilter.mAction; } else { bApplyOnInbound = aFilter.applyOnInbound(); + bApplyBeforeOutbound = aFilter.applyBeforeOutbound(); bApplyOnOutbound = aFilter.applyOnOutbound(); bApplyOnExplicit = aFilter.applyOnExplicit(); bStopProcessingHere = aFilter.stopProcessingHere(); @@ -231,12 +233,14 @@ else { QStringList sets = config->readListEntry("apply-on"); if ( sets.isEmpty() && !config->hasKey("apply-on") ) { + bApplyBeforeOutbound = false; bApplyOnOutbound = false; bApplyOnInbound = true; bApplyOnExplicit = true; mApplicability = ButImap; } else { bApplyOnInbound = bool(sets.contains("check-mail")); + bApplyBeforeOutbound = bool(sets.contains("before-send-mail")); bApplyOnOutbound = bool(sets.contains("send-mail")); bApplyOnExplicit = bool(sets.contains("manual-filtering")); mApplicability = (AccountType)config->readNumEntry( "Applicability", ButImap ); @@ -317,6 +321,8 @@ QStringList sets; if ( bApplyOnInbound ) sets.append( "check-mail" ); + if ( bApplyBeforeOutbound ) + sets.append( "before-send-mail" ); if ( bApplyOnOutbound ) sets.append( "send-mail" ); if ( bApplyOnExplicit ) @@ -403,6 +409,8 @@ result += "This filter belongs to the following sets:"; if ( bApplyOnInbound ) result += " Inbound"; + if ( bApplyBeforeOutbound ) + result += " before-Outbound"; if ( bApplyOnOutbound ) result += " Outbound"; if ( bApplyOnExplicit ) --- branches/work/kdepim-3.5.5+/kmail/kmfilter.h #622727:622728 @@ -145,12 +145,24 @@ */ void setApplyOnOutbound( bool aApply=TRUE ) { bApplyOnOutbound = aApply; } + /** Set whether this filter should be applied on + outbound messages before sending (@p aApply == TRUE) or not. + See applyOnOutbound applyOnInbound setApplyOnInbound + */ + void setApplyBeforeOutbound( bool aApply=TRUE ) { bApplyBeforeOutbound = aApply; } + /** @return TRUE if this filter should be applied on outbound messages, FALSE otherwise. @see setApplyOnOutbound applyOnInbound setApplyOnInbound */ bool applyOnOutbound() const { return bApplyOnOutbound; } + /** @return TRUE if this filter should be applied on + outbound messages before they are sent, FALSE otherwise. + @see setApplyOnOutbound applyOnInbound setApplyOnInbound + */ + bool applyBeforeOutbound() const { return bApplyBeforeOutbound; } + /** Set whether this filter should be applied on inbound messages (@p aApply == TRUE) or not. @see setApplyOnOutbound applyOnInbound applyOnOutbound @@ -300,6 +312,7 @@ KShortcut mShortcut; bool bPopFilter : 1; bool bApplyOnInbound : 1; + bool bApplyBeforeOutbound : 1; bool bApplyOnOutbound : 1; bool bApplyOnExplicit : 1; bool bStopProcessingHere : 1; --- branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.cpp #622727:622728 @@ -181,7 +181,7 @@ i18n("Advanced Options"), page2); { QWidget *adv_w = new QWidget( mAdvOptsGroup ); - QGridLayout *gl = new QGridLayout( adv_w, 8 /*rows*/, 3 /*cols*/, + QGridLayout *gl = new QGridLayout( adv_w, 10 /*rows*/, 3 /*cols*/, 0 /*border*/, spacingHint() ); QVBoxLayout *vbl3 = new QVBoxLayout( gl, spacingHint(), "vbl3" ); @@ -209,26 +209,29 @@ mAccountList->setSorting( -1 ); gl->addMultiCellWidget( mAccountList, 0, 3, 1, 3 ); + mApplyBeforeOut = new QCheckBox( i18n("Apply this filter before sending messages"), adv_w ); + gl->addMultiCellWidget( mApplyBeforeOut, 4, 4, 0, 3 ); + mApplyOnOut = new QCheckBox( i18n("Apply this filter to &sent messages"), adv_w ); - gl->addMultiCellWidget( mApplyOnOut, 4, 4, 0, 3 ); + gl->addMultiCellWidget( mApplyOnOut, 5, 5, 0, 3 ); mApplyOnCtrlJ = new QCheckBox( i18n("Apply this filter on manual &filtering"), adv_w ); - gl->addMultiCellWidget( mApplyOnCtrlJ, 5, 5, 0, 3 ); + gl->addMultiCellWidget( mApplyOnCtrlJ, 6, 6, 0, 3 ); mStopProcessingHere = new QCheckBox( i18n("If this filter &matches, stop processing here"), adv_w ); gl->addMultiCellWidget( mStopProcessingHere, - 6, 6, /*from to row*/ + 7, 7, /*from to row*/ 0, 3 /*from to col*/ ); mConfigureShortcut = new QCheckBox( i18n("Add this filter to the Apply Filter menu"), adv_w ); - gl->addMultiCellWidget( mConfigureShortcut, 7, 7, 0, 1 ); + gl->addMultiCellWidget( mConfigureShortcut, 8, 8, 0, 1 ); QLabel *keyButtonLabel = new QLabel( i18n( "Shortcut:" ), adv_w ); keyButtonLabel->setAlignment( AlignVCenter | AlignRight ); - gl->addMultiCellWidget( keyButtonLabel, 7, 7, 2, 2 ); + gl->addMultiCellWidget( keyButtonLabel, 8, 8, 2, 2 ); mKeyButton = new KKeyButton( adv_w, "FilterShortcutSelector" ); - gl->addMultiCellWidget( mKeyButton, 7, 7, 3, 3 ); + gl->addMultiCellWidget( mKeyButton, 8, 8, 3, 3 ); mKeyButton->setEnabled( false ); mConfigureToolbar = new QCheckBox( i18n("Additionally add this filter to the toolbar"), adv_w ); - gl->addMultiCellWidget( mConfigureToolbar, 8, 8, 0, 3 ); + gl->addMultiCellWidget( mConfigureToolbar, 9, 9, 0, 3 ); mConfigureToolbar->setEnabled( false ); QHBox *hbox = new QHBox( adv_w ); @@ -243,7 +246,7 @@ mFilterActionIconButton->setIcon( "gear" ); mFilterActionIconButton->setEnabled( false ); - gl->addMultiCellWidget( hbox, 9, 9, 0, 3 ); + gl->addMultiCellWidget( hbox, 10, 10, 0, 3 ); } vbl2->addWidget( mAdvOptsGroup, 0, Qt::AlignTop ); } @@ -273,6 +276,8 @@ this, SLOT(slotApplicabilityChanged()) ); connect( mApplyOnForChecked, SIGNAL(clicked()), this, SLOT(slotApplicabilityChanged()) ); + connect( mApplyBeforeOut, SIGNAL(clicked()), + this, SLOT(slotApplicabilityChanged()) ); connect( mApplyOnOut, SIGNAL(clicked()), this, SLOT(slotApplicabilityChanged()) ); connect( mApplyOnCtrlJ, SIGNAL(clicked()), @@ -376,6 +381,8 @@ << aFilter->applyOnInbound() << endl; kdDebug(5006) << "apply on outbound == " << aFilter->applyOnOutbound() << endl; + kdDebug(5006) << "apply before outbound == " + << aFilter->applyBeforeOutbound() << endl; kdDebug(5006) << "apply on explicit == " << aFilter->applyOnExplicit() << endl; @@ -385,6 +392,7 @@ const bool applyOnIn = aFilter->applyOnInbound(); const bool applyOnForAll = aFilter->applicability() == KMFilter::All; const bool applyOnTraditional = aFilter->applicability() == KMFilter::ButImap; + const bool applyBeforeOut = aFilter->applyBeforeOutbound(); const bool applyOnOut = aFilter->applyOnOutbound(); const bool applyOnExplicit = aFilter->applyOnExplicit(); const bool stopHere = aFilter->stopProcessingHere(); @@ -402,6 +410,7 @@ mApplyOnForChecked->setChecked( !applyOnForAll && !applyOnTraditional ); mAccountList->setEnabled( mApplyOnForChecked->isEnabled() && mApplyOnForChecked->isChecked() ); slotUpdateAccountList(); + mApplyBeforeOut->setChecked( applyBeforeOut ); mApplyOnOut->setChecked( applyOnOut ); mApplyOnCtrlJ->setChecked( applyOnExplicit ); mStopProcessingHere->setChecked( stopHere ); @@ -439,6 +448,7 @@ { if ( mFilter ) { mFilter->setApplyOnInbound( mApplyOnIn->isChecked() ); + mFilter->setApplyBeforeOutbound( mApplyBeforeOut->isChecked() ); mFilter->setApplyOnOutbound( mApplyOnOut->isChecked() ); mFilter->setApplyOnExplicit( mApplyOnCtrlJ->isChecked() ); if ( mApplyOnForAll->isChecked() ) @@ -467,6 +477,7 @@ kdDebug(5006) << "KMFilterDlg: setting filter to be applied at " << ( mFilter->applyOnInbound() ? "incoming " : "" ) << ( mFilter->applyOnOutbound() ? "outgoing " : "" ) + << ( mFilter->applyBeforeOutbound() ? "before_outgoing " : "" ) << ( mFilter->applyOnExplicit() ? "explicit CTRL-J" : "" ) << endl; } --- branches/work/kdepim-3.5.5+/kmail/kmfilterdlg.h #622727:622728 @@ -376,7 +376,7 @@ KMPopFilterActionWidget *mActionGroup; /** Lets the user select whether to apply this filter on inbound/outbound messages, both, or only on explicit CTRL-J. */ - QCheckBox *mApplyOnIn, *mApplyOnOut, *mApplyOnCtrlJ; + QCheckBox *mApplyOnIn, *mApplyOnOut, *mApplyBeforeOut, *mApplyOnCtrlJ; /** For a filter applied to inbound messages selects whether to apply this filter to all accounts or to selected accounts only. */ QRadioButton *mApplyOnForAll, *mApplyOnForTraditional, *mApplyOnForChecked; --- branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.cpp #622727:622728 @@ -301,6 +301,7 @@ ( !account || ( account && (*it)->applyOnAccount( accountId ) ) ) ) || ( (set&Outbound) && (*it)->applyOnOutbound() ) || + ( (set&BeforeOutbound) && (*it)->applyBeforeOutbound() ) || ( (set&Explicit) && (*it)->applyOnExplicit() ) ) { // filter is applicable --- branches/work/kdepim-3.5.5+/kmail/kmfiltermgr.h #622727:622728 @@ -43,7 +43,7 @@ void clear(); enum FilterSet { NoSet = 0x0, Inbound = 0x1, Outbound = 0x2, Explicit = 0x4, - All = Inbound|Outbound|Explicit }; + BeforeOutbound = 0x8, All = Inbound|BeforeOutbound|Outbound|Explicit }; /** Reload filter rules from config file. */ void readConfig(void); --- branches/work/kdepim-3.5.5+/kmail/kmsender.cpp #622727:622728 @@ -462,6 +462,22 @@ } mCurrentMsg->setTransferInProgress( TRUE ); + // apply filters before sending message + // TODO: to support encrypted/signed messages this sould be moved to messagecomposer.cpp + // Disable the emitting of msgAdded signal, because the message is taken out of the + // current folder (outbox) and re-added, to make filter actions changing the message + // work. We don't want that to screw up message counts. + if ( kmkernel->filterMgr() ) { + if ( mCurrentMsg->parent() ) mCurrentMsg->parent()->quiet( true ); + const int processResult = kmkernel->filterMgr()->process( mCurrentMsg, KMFilterMgr::BeforeOutbound ); + if ( mCurrentMsg->parent() ) mCurrentMsg->parent()->quiet( false ); + if ( processResult == 2 /* critical error */ ) { + perror("Critical error: Unable to execute filters before sending message(out of space?)"); + KMessageBox::information(0, i18n("Critical error: " + "during filtering before sending message (out of space?)")); + } + } + // start the sender process or initialize communication if (!mSendInProgress) { *** Bug 147723 has been marked as a duplicate of this bug. *** Added my vote for this, as it's potentially very useful for me and it had me fooled when trying to use it. I usually use sendmail as my mail transport but AOL rejects emails from hosts it doesn't recognise so it would be great if a filter could automatically use my ISP's SMTP server if the email's going to an AOL user without me having to notice who their ISP is. This is very important for users' privacy, e.g. for adding a x-no-archive: yes header. This bug is still present in KMail 1.11.2 SVN commit 1002356 by bbigras: Add support to filter outgoing message before they are sent based on a commit from Christian Schaarschmidt on the kdepim-3.5.5+ branch BUG: 48938 CCMAIL: exit3219@gmail.com M +8 -0 kmfilter.cpp M +13 -0 kmfilter.h M +21 -7 kmfilterdlg.cpp M +1 -1 kmfilterdlg.h M +1 -0 kmfiltermgr.cpp M +1 -1 kmfiltermgr.h M +16 -0 kmsender.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=1002356 |