allow filters to set junk status, r/sr=mscott, a=asa 224318

This commit is contained in:
bienvenu%nventure.com 2004-03-25 20:08:26 +00:00
parent 85230d5354
commit e64089c82b
10 changed files with 171 additions and 74 deletions

View File

@ -59,6 +59,8 @@ interface nsIMsgRuleAction : nsISupports {
// target label. throws an exception if the action is not label
attribute nsMsgLabelValue label;
attribute long junkScore;
};
[scriptable, uuid(605db0f8-04a1-11d3-a50a-0060b0fc04b7)]

View File

@ -77,5 +77,6 @@ interface nsMsgFilterAction {
const long StopExecution=11;
const long DeleteFromPop3Server=12;
const long LeaveOnPop3Server=13;
const long JunkScore=14;
};

View File

@ -47,6 +47,7 @@ var gActionTargetElement;
var gActionValueDeck;
var gActionPriority;
var gActionLabel;
var gActionJunkScore;
var gFilterBundle;
var gPreFillName;
var nsMsgSearchScope = Components.interfaces.nsMsgSearchScope;
@ -55,6 +56,7 @@ var gMailSession = null;
var gMoveToFolderCheckbox;
var gChangePriorityCheckbox;
var gLabelCheckbox;
var gJunkScoreCheckbox;
var gMarkReadCheckbox;
var gMarkFlaggedCheckbox;
var gDeleteCheckbox;
@ -271,10 +273,13 @@ function initializeFilterWidgets()
gActionTargetElement = document.getElementById("actionTargetFolder");
gActionValueDeck = document.getElementById("actionValueDeck");
gActionPriority = document.getElementById("actionValuePriority");
gActionJunkScore = document.getElementById("actionValueJunkScore");
gActionLabel = document.getElementById("actionValueLabel");
gMoveToFolderCheckbox = document.getElementById("moveToFolder");
gChangePriorityCheckbox = document.getElementById("changePriority");
gChangeJunkScoreCheckbox = document.getElementById("setJunkScore");
gLabelCheckbox = document.getElementById("label");
gJunkScoreCheckbox = document.getElementById("setJunkScore");
gMarkReadCheckbox = document.getElementById("markRead");
gMarkFlaggedCheckbox = document.getElementById("markFlagged");
gDeleteCheckbox = document.getElementById("delete");
@ -324,6 +329,18 @@ function initializeDialog(filter)
gActionLabel.selectedItem = selectedLabel;
}
}
else if (filterAction.type == nsMsgFilterAction.JunkScore)
{
gChangeJunkScoreCheckbox.checked = true;
// initialize junk score
var selectedJunkScore = gActionJunkScore.getElementsByAttribute("value", filterAction.junkScore);
if (selectedJunkScore && selectedJunkScore.length > 0)
{
selectedJunkScore = selectedJunkScore[0];
gActionJunkScore.selectedItem = selectedJunkScore;
}
}
else if (filterAction.type == nsMsgFilterAction.MarkRead)
gMarkReadCheckbox.checked = true;
else if (filterAction.type == nsMsgFilterAction.MarkFlagged)
@ -455,6 +472,14 @@ function saveFilter()
gFilter.appendAction(filterAction);
}
if (gJunkScoreCheckbox.checked)
{
filterAction = gFilter.createAction();
filterAction.type = nsMsgFilterAction.JunkScore;
filterAction.junkScore = gActionJunkScore.selectedItem.getAttribute("value");
gFilter.appendAction(filterAction);
}
if (gMarkReadCheckbox.checked)
{
filterAction = gFilter.createAction();

View File

@ -158,6 +158,21 @@ Contributor(s):
</listcell>
</listitem>
<listitem allowevents="true">
<listcell>
<checkbox id="setJunkScore" label="&setJunkScore.label;"/>
</listcell>
<listcell>
<menulist id="actionValueJunkScore" flex="1">
<menupopup>
<!-- see MailNewsTypes2.idl -->
<menuitem value="100" label="&junk.label;"/>
<menuitem value="0" label="&notJunk.label;"/>
</menupopup>
</menulist>
</listcell>
</listitem>
<listitem allowevents="true">
<listcell>
<checkbox id="kill" enablefornews="true" label="&killThread.label;"/>

View File

@ -24,9 +24,13 @@
<!ENTITY killThread.label "Ignore thread">
<!ENTITY watchThread.label "Watch thread">
<!ENTITY deleteFromServer.label "Delete from POP server">
<!ENTITY setJunkScore.label "Set Junk Status">
<!ENTITY filterName.label "Filter name:">
<!ENTITY filterName.accesskey "i">
<!ENTITY junk.label "Junk">
<!ENTITY notJunk.label "NotJunk">
<!ENTITY lowestPriorityCmd.label "Lowest">
<!ENTITY lowPriorityCmd.label "Low">
<!ENTITY normalPriorityCmd.label "Normal">

View File

@ -132,6 +132,24 @@ nsMsgRuleAction::GetTargetFolderUri(char** aResult)
return NS_OK;
}
NS_IMETHODIMP
nsMsgRuleAction::SetJunkScore(PRInt32 aJunkScore)
{
NS_ENSURE_TRUE(m_type == nsMsgFilterAction::JunkScore && aJunkScore >= 0 && aJunkScore <= 100,
NS_ERROR_ILLEGAL_VALUE);
m_junkScore = aJunkScore;
return NS_OK;
}
NS_IMETHODIMP
nsMsgRuleAction::GetJunkScore(PRInt32 *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_TRUE(m_type == nsMsgFilterAction::JunkScore, NS_ERROR_ILLEGAL_VALUE);
*aResult = m_junkScore;
return NS_OK;
}
nsMsgFilter::nsMsgFilter():
m_temporary(PR_FALSE),
m_unparseable(PR_FALSE),
@ -450,7 +468,7 @@ NS_IMETHODIMP nsMsgFilter::MatchHdr(nsIMsgDBHdr *msgHdr, nsIMsgFolder *folder, n
void
nsMsgFilter::SetFilterList(nsIMsgFilterList *filterList)
{
// hold weak ref
// doesn't hold a ref.
m_filterList = filterList;
}
@ -543,7 +561,7 @@ nsresult nsMsgFilter::ConvertMoveToFolderValue(nsIMsgRuleAction *filterAction, n
nsCOMPtr <nsIMsgFolder> localMailRootMsgFolder = do_QueryInterface(localMailRoot);
localMailRoot->GetURI(getter_Copies(localRootURI));
nsCString destFolderUri;
destFolderUri.Assign( localRootURI);
destFolderUri.Assign( localRootURI);
// need to remove ".sbd" from moveValue, and perhaps escape it.
moveValue.ReplaceSubstring(".sbd/", "/");
@ -578,7 +596,7 @@ nsresult nsMsgFilter::ConvertMoveToFolderValue(nsIMsgRuleAction *filterAction, n
else
filterAction->SetTargetFolderUri(moveValue.get());
return NS_OK;
return NS_OK;
// set m_action.m_value.m_folderUri
}
@ -655,6 +673,12 @@ nsresult nsMsgFilter::SaveRule(nsIOFileStream *aStream)
err = filterList->WriteIntAttr(nsIMsgFilterList::attribActionValue, label, aStream);
}
break;
case nsMsgFilterAction::JunkScore:
{
PRInt32 junkScore;
action->GetJunkScore(&junkScore);
err = filterList->WriteIntAttr(nsIMsgFilterList::attribActionValue, junkScore, aStream);
}
default:
break;
}
@ -724,6 +748,7 @@ static struct RuleActionsTableEntry ruleActionsTable[] =
{ nsMsgFilterAction::StopExecution, nsMsgFilterType::All, 0, "Stop execution"},
{ nsMsgFilterAction::DeleteFromPop3Server, nsMsgFilterType::All, 0, "Delete from Pop3 server"},
{ nsMsgFilterAction::LeaveOnPop3Server, nsMsgFilterType::All, 0, "Leave on Pop3 server"},
{ nsMsgFilterAction::JunkScore, nsMsgFilterType::All, 0, "JunkScore"},
};
const char *nsMsgFilter::GetActionStr(nsMsgRuleActionType action)

View File

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Bienvenu (bienvenu@nventure.com)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -49,8 +50,8 @@ class nsMsgRuleAction : public nsIMsgRuleAction
public:
NS_DECL_ISUPPORTS
nsMsgRuleAction();
virtual ~nsMsgRuleAction();
nsMsgRuleAction();
virtual ~nsMsgRuleAction();
NS_DECL_NSIMSGRULEACTION
@ -59,7 +60,8 @@ private:
// this used to be a union - why bother?
nsMsgPriorityValue m_priority; /* priority to set rule to */
nsMsgLabelValue m_label; /* label to set rule to */
nsCString m_folderUri; /* Or some folder identifier, if such a thing is invented */
nsCString m_folderUri;
PRInt32 m_junkScore; /* junk score (or arbitrary int value?) */
} ;
@ -69,55 +71,53 @@ public:
NS_DECL_ISUPPORTS
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMSGFILTER_IID)
nsMsgFilter();
virtual ~nsMsgFilter ();
nsMsgFilter();
virtual ~nsMsgFilter ();
NS_DECL_NSIMSGFILTER
nsMsgFilterTypeType GetType() {return m_type;}
void SetType(nsMsgFilterTypeType type) {m_type = type;}
PRBool GetEnabled() {return m_enabled;}
void SetFilterScript(nsCString *filterName) ;
void SetFilterList(nsIMsgFilterList* filterList);
PRBool IsRule()
{return (m_type & (nsMsgFilterType::InboxRule |
nsMsgFilterType::NewsRule)) != 0;}
PRBool IsScript() {return (m_type &
(nsMsgFilterType::InboxJavaScript |
nsMsgFilterType::NewsJavaScript)) != 0;}
nsMsgFilterTypeType GetType() {return m_type;}
void SetType(nsMsgFilterTypeType type) {m_type = type;}
PRBool GetEnabled() {return m_enabled;}
void SetFilterScript(nsCString *filterName) ;
void SetFilterList(nsIMsgFilterList* filterList);
PRBool IsRule() {return (m_type & (nsMsgFilterType::InboxRule |
nsMsgFilterType::NewsRule)) != 0;}
// filing routines.
nsresult SaveToTextFile(nsIOFileStream *aStream);
nsresult SaveRule(nsIOFileStream *aStream);
PRBool IsScript() {return (m_type &
(nsMsgFilterType::InboxJavaScript |
nsMsgFilterType::NewsJavaScript)) != 0;}
PRInt16 GetVersion();
// filing routines.
nsresult SaveToTextFile(nsIOFileStream *aStream);
nsresult SaveRule(nsIOFileStream *aStream);
PRInt16 GetVersion();
#ifdef DEBUG
void Dump();
void Dump();
#endif
nsresult ConvertMoveToFolderValue(nsIMsgRuleAction *filterAction, nsCString &relativePath);
static const char *GetActionStr(nsMsgRuleActionType action);
static nsresult GetActionFilingStr(nsMsgRuleActionType action, nsCString &actionStr);
static nsMsgRuleActionType GetActionForFilingStr(nsCString &actionStr);
nsMsgRuleAction m_action;
nsresult ConvertMoveToFolderValue(nsIMsgRuleAction *filterAction, nsCString &relativePath);
static const char *GetActionStr(nsMsgRuleActionType action);
static nsresult GetActionFilingStr(nsMsgRuleActionType action, nsCString &actionStr);
static nsMsgRuleActionType GetActionForFilingStr(nsCString &actionStr);
nsMsgRuleAction m_action;
protected:
nsMsgFilterTypeType m_type;
nsString m_filterName;
nsCString m_scriptFileName; // iff this filter is a script.
nsCString m_description;
nsMsgFilterTypeType m_type;
nsString m_filterName;
nsCString m_scriptFileName; // iff this filter is a script.
nsCString m_description;
nsCString m_unparsedBuffer;
PRPackedBool m_enabled;
PRPackedBool m_temporary;
PRPackedBool m_unparseable;
nsIMsgFilterList *m_filterList; /* owning filter list */
nsCOMPtr<nsISupportsArray> m_termList; /* linked list of criteria terms */
nsCOMPtr<nsIMsgSearchScopeTerm> m_scope; /* default for mail rules is inbox, but news rules could
have a newsgroup - LDAP would be invalid */
nsCOMPtr<nsISupportsArray> m_actionList;
//nsCString m_originalServerPath; //used for 4.x filters
PRPackedBool m_enabled;
PRPackedBool m_temporary;
PRPackedBool m_unparseable;
nsIMsgFilterList *m_filterList; /* owning filter list */
nsCOMPtr<nsISupportsArray> m_termList; /* linked list of criteria terms */
nsCOMPtr<nsIMsgSearchScopeTerm> m_scope; /* default for mail rules is inbox, but news rules could
have a newsgroup - LDAP would be invalid */
nsCOMPtr<nsISupportsArray> m_actionList;
};
#endif

View File

@ -644,7 +644,7 @@ nsImapMailFolder::UpdateFolder(nsIMsgWindow *msgWindow)
// can't file to the sent folder, so we don't add the filter for those servers
if (canFileMessagesOnServer)
{
rv = server->ConfigureTemporaryReturnReceiptsFilter(m_filterList);
rv = server->ConfigureTemporaryFilters(m_filterList);
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to add MDN filter");
}
}
@ -3144,6 +3144,22 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWindo
keysToFlag.Add(msgKey);
StoreImapFlags((filterLabel << 9), PR_TRUE, keysToFlag.GetArray(), keysToFlag.GetSize());
}
case nsMsgFilterAction::JunkScore:
{
nsCAutoString junkScoreStr;
PRInt32 junkScore;
filterAction->GetJunkScore(&junkScore);
junkScoreStr.AppendInt(junkScore);
mDatabase->SetStringProperty(msgKey, "junkscore", junkScoreStr.get());
mDatabase->SetStringProperty(msgKey, "junkscoreorigin", /* ### should this be plugin? */"plugin");
if (junkScore == 100 || !junkScore) // if score is 0 or 100, set up to store junk status on server.
{
nsMsgKeyArray *keysToClassify = m_moveCoalescer->GetKeyBucket((junkScore == 100) ? 0 : 1);
NS_ASSERTION(keysToClassify, "error getting key bucket");
if (keysToClassify)
keysToClassify->Add(msgKey);
}
}
default:
break;
}
@ -4938,12 +4954,7 @@ nsImapMailFolder::HeaderFetchCompleted(nsIImapProtocol* aProtocol)
if (m_performingBiff)
GetNumNewMessages(PR_FALSE, &numNewBiffMsgs);
if (m_moveCoalescer)
{
m_moveCoalescer->PlaybackMoves ();
// we're not going to delete the move coalescer here. We're probably going to
// keep it around forever, though I worry about cycles.
}
PlaybackCoalescedOperations();
if (aProtocol)
{
// check if we should download message bodies because it's the inbox and
@ -7461,6 +7472,24 @@ nsImapMailFolder::StoreCustomKeywords(nsIMsgWindow *aMsgWindow, const char *aFla
return imapService->StoreCustomKeywords(m_eventQueue, this, aMsgWindow, aFlagsToAdd, aFlagsToSubtract, msgIds.get(), _retval);
}
nsresult
nsImapMailFolder::PlaybackCoalescedOperations()
{
if (m_moveCoalescer)
{
nsMsgKeyArray *junkKeysToClassify = m_moveCoalescer->GetKeyBucket(0);
nsMsgKeyArray *nonJunkKeysToClassify = m_moveCoalescer->GetKeyBucket(1);
if (junkKeysToClassify && junkKeysToClassify->GetSize() > 0)
StoreCustomKeywords(m_moveCoalescer->GetMsgWindow(), "Junk", "", junkKeysToClassify->GetArray(), junkKeysToClassify->GetSize(), nsnull);
if (nonJunkKeysToClassify && nonJunkKeysToClassify->GetSize() > 0)
StoreCustomKeywords(m_moveCoalescer->GetMsgWindow(), "NonJunk", "", nonJunkKeysToClassify->GetArray(), nonJunkKeysToClassify->GetSize(), nsnull);
junkKeysToClassify->RemoveAll();
nonJunkKeysToClassify->RemoveAll();
return m_moveCoalescer->PlaybackMoves();
}
return NS_OK; // must not be any coalesced operations
}
NS_IMETHODIMP
nsImapMailFolder::OnMessageClassified(const char *aMsgURI, nsMsgJunkStatus aClassification)
@ -7544,19 +7573,9 @@ nsImapMailFolder::OnMessageClassified(const char *aMsgURI, nsMsgJunkStatus aClas
rv = spamSettings->LogJunkHit(msgHdr, willMoveMessage);
NS_ENSURE_SUCCESS(rv,rv);
}
if (--m_numFilterClassifyRequests == 0 && m_moveCoalescer)
if (--m_numFilterClassifyRequests == 0)
{
nsMsgKeyArray *junkKeysToClassify = m_moveCoalescer->GetKeyBucket(0);
nsMsgKeyArray *nonJunkKeysToClassify = m_moveCoalescer->GetKeyBucket(1);
nsCOMPtr<nsIImapService> imapService(do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
if (junkKeysToClassify && junkKeysToClassify->GetSize() > 0)
StoreCustomKeywords(m_moveCoalescer->GetMsgWindow(), "Junk", "", junkKeysToClassify->GetArray(), junkKeysToClassify->GetSize(), nsnull);
if (nonJunkKeysToClassify && nonJunkKeysToClassify->GetSize() > 0)
StoreCustomKeywords(m_moveCoalescer->GetMsgWindow(), "NonJunk", "", nonJunkKeysToClassify->GetArray(), nonJunkKeysToClassify->GetSize(), nsnull);
m_moveCoalescer->PlaybackMoves();
PlaybackCoalescedOperations();
// If we are performing biff for this folder, tell the server object
if (m_performingBiff)
{
@ -7568,8 +7587,6 @@ nsImapMailFolder::OnMessageClassified(const char *aMsgURI, nsMsgJunkStatus aClas
server->SetPerformingBiff(PR_FALSE);
m_performingBiff = PR_FALSE;
}
junkKeysToClassify->RemoveAll();
nonJunkKeysToClassify->RemoveAll();
}
return NS_OK;
}

View File

@ -421,6 +421,7 @@ protected:
nsCString& msgIds, nsMsgKeyArray& keyArray);
nsresult GetMoveCoalescer();
nsresult PlaybackCoalescedOperations();
virtual nsresult CreateBaseMessageURI(const char *aURI);
// offline-ish methods
nsresult GetClearedOriginalOp(nsIMsgOfflineImapOperation *op, nsIMsgOfflineImapOperation **originalOp,

View File

@ -486,9 +486,9 @@ nsParseMailMessageState::~nsParseMailMessageState()
void nsParseMailMessageState::Init(PRUint32 fileposition)
{
m_state = nsIMsgParseMailMsgState::ParseBodyState;
m_position = fileposition;
m_newMsgHdr = nsnull;
m_state = nsIMsgParseMailMsgState::ParseBodyState;
m_position = fileposition;
m_newMsgHdr = nsnull;
}
NS_IMETHODIMP nsParseMailMessageState::Clear()
@ -556,10 +556,8 @@ NS_IMETHODIMP nsParseMailMessageState::SetEnvelopePos(PRUint32 aEnvelopePos)
NS_IMETHODIMP nsParseMailMessageState::GetNewMsgHdr(nsIMsgDBHdr ** aMsgHeader)
{
if (aMsgHeader)
{
*aMsgHeader = m_newMsgHdr;
NS_IF_ADDREF(*aMsgHeader);
}
NS_IF_ADDREF(*aMsgHeader = m_newMsgHdr);
return NS_OK;
}
@ -591,8 +589,8 @@ PRInt32 nsParseMailMessageState::ParseFolderLine(const char *line, PRUint32 line
}
else
{
/* Otherwise, this line belongs to a header. So append it to the
header data, and stay in MBOX `MIME_PARSE_HEADERS' state.
/* Otherwise, this line belongs to a header. So append it to the
header data, and stay in MBOX `MIME_PARSE_HEADERS' state.
*/
m_headers.AppendBuffer(line, lineLength);
}
@ -1460,7 +1458,7 @@ nsParseNewMailState::Init(nsIMsgFolder *rootFolder, nsIMsgFolder *downloadFolder
rv = server->GetFilterList(aMsgWindow, getter_AddRefs(m_filterList));
if (m_filterList)
rv = server->ConfigureTemporaryReturnReceiptsFilter(m_filterList);
rv = server->ConfigureTemporaryFilters(m_filterList);
m_disableFilters = PR_FALSE;
return NS_OK;
@ -1685,6 +1683,15 @@ NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWi
msgHdr->GetMessageKey(&msgKey);
m_mailDB->SetLabel(msgKey, filterLabel);
break;
case nsMsgFilterAction::JunkScore:
{
nsCAutoString junkScoreStr;
PRInt32 junkScore;
filterAction->GetJunkScore(&junkScore);
junkScoreStr.AppendInt(junkScore);
m_mailDB->SetStringProperty(msgKey, "junkscore", junkScoreStr.get());
m_mailDB->SetStringProperty(msgKey, "junkscoreorigin", /* ### should this be plugin? */"plugin");
}
case nsMsgFilterAction::DeleteFromPop3Server:
{
nsCOMPtr <nsIMsgFolder> downloadFolder;