зеркало из https://github.com/mozilla/gecko-dev.git
restructure filter code to start on imap filters
This commit is contained in:
Родитель
d0f17077e7
Коммит
aa6f741aaa
|
@ -39,6 +39,12 @@
|
||||||
#include "nsMsgBaseCID.h"
|
#include "nsMsgBaseCID.h"
|
||||||
#include "nsMsgLocalCID.h"
|
#include "nsMsgLocalCID.h"
|
||||||
|
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
#include "nsIMsgFilter.h"
|
||||||
|
#include "nsIMsgFilterService.h"
|
||||||
|
static NS_DEFINE_CID(kMsgFilterServiceCID, NS_MSGFILTERSERVICE_CID);
|
||||||
|
#endif
|
||||||
|
|
||||||
// we need this because of an egcs 1.0 (and possibly gcc) compiler bug
|
// we need this because of an egcs 1.0 (and possibly gcc) compiler bug
|
||||||
// that doesn't allow you to call ::nsISupports::GetIID() inside of a class
|
// that doesn't allow you to call ::nsISupports::GetIID() inside of a class
|
||||||
// that multiply inherits from nsISupports
|
// that multiply inherits from nsISupports
|
||||||
|
@ -127,7 +133,12 @@ NS_IMETHODIMP nsImapMailFolder::QueryInterface(REFNSIID aIID, void** aInstancePt
|
||||||
{
|
{
|
||||||
*aInstancePtr = NS_STATIC_CAST(nsIUrlListener *, this);
|
*aInstancePtr = NS_STATIC_CAST(nsIUrlListener *, this);
|
||||||
}
|
}
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
else if (aIID.Equals(nsIMsgFilterHitNotify::GetIID()))
|
||||||
|
{
|
||||||
|
*aInstancePtr = NS_STATIC_CAST(nsIMsgFilterHitNotify *, this);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if(*aInstancePtr)
|
if(*aInstancePtr)
|
||||||
{
|
{
|
||||||
AddRef();
|
AddRef();
|
||||||
|
@ -401,8 +412,7 @@ NS_IMETHODIMP nsImapMailFolder::GetMessages(nsIEnumerator* *result)
|
||||||
|
|
||||||
char *folderName = nsnull;
|
char *folderName = nsnull;
|
||||||
rv = GetName(&folderName);
|
rv = GetName(&folderName);
|
||||||
// if (folderName && !PL_strcasecmp(folderName, "INBOX"))
|
selectFolder = PR_TRUE;
|
||||||
selectFolder = PR_TRUE;
|
|
||||||
|
|
||||||
delete [] folderName;
|
delete [] folderName;
|
||||||
|
|
||||||
|
@ -1271,6 +1281,19 @@ NS_IMETHODIMP nsImapMailFolder::SetupHeaderParseStream(
|
||||||
if (!mDatabase)
|
if (!mDatabase)
|
||||||
GetDatabase();
|
GetDatabase();
|
||||||
|
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
if (mFlags & MSG_FOLDER_FLAG_INBOX && !m_filterList)
|
||||||
|
{
|
||||||
|
NS_WITH_SERVICE(nsIMsgFilterService, filterService, kMsgFilterServiceCID, &rv);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv;
|
||||||
|
|
||||||
|
// need a file spec for filters...
|
||||||
|
nsFileSpec filterFile("rules.dat");
|
||||||
|
nsresult res = filterService->OpenFilterList(&filterFile, getter_AddRefs(m_filterList));
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
m_nextMessageByteLength = aStreamInfo->size;
|
m_nextMessageByteLength = aStreamInfo->size;
|
||||||
if (!m_msgParser)
|
if (!m_msgParser)
|
||||||
{
|
{
|
||||||
|
@ -1334,8 +1357,24 @@ NS_IMETHODIMP nsImapMailFolder::NormalEndHeaderParseStream(nsIImapProtocol*
|
||||||
m_msgParser->GetNewMsgHdr(getter_AddRefs(newMsgHdr));
|
m_msgParser->GetNewMsgHdr(getter_AddRefs(newMsgHdr));
|
||||||
if (NS_SUCCEEDED(rv) && newMsgHdr)
|
if (NS_SUCCEEDED(rv) && newMsgHdr)
|
||||||
{
|
{
|
||||||
|
char *headers;
|
||||||
|
PRInt32 headersSize;
|
||||||
|
|
||||||
newMsgHdr->SetMessageKey(m_curMsgUid);
|
newMsgHdr->SetMessageKey(m_curMsgUid);
|
||||||
TweakHeaderFlags(aProtocol, newMsgHdr);
|
TweakHeaderFlags(aProtocol, newMsgHdr);
|
||||||
|
// If this is the inbox, try to apply filters.
|
||||||
|
if (mFlags & MSG_FOLDER_FLAG_INBOX)
|
||||||
|
{
|
||||||
|
rv = m_msgParser->GetAllHeaders(&headers, &headersSize);
|
||||||
|
|
||||||
|
if (NS_SUCCEEDED(rv) && headers)
|
||||||
|
{
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
m_filterList->ApplyFiltersToHdr(nsMsgFilterInboxRule, newMsgHdr, this, mDatabase,
|
||||||
|
headers, headersSize, this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
// here we need to tweak flags from uid state..
|
// here we need to tweak flags from uid state..
|
||||||
mDatabase->AddNewHdrToDB(newMsgHdr, PR_TRUE);
|
mDatabase->AddNewHdrToDB(newMsgHdr, PR_TRUE);
|
||||||
m_msgParser->FinishHeader();
|
m_msgParser->FinishHeader();
|
||||||
|
@ -1413,6 +1452,218 @@ NS_IMETHODIMP nsImapMailFolder::EndCopy(PRBool copySucceeded)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, PRBool *applyMore)
|
||||||
|
{
|
||||||
|
nsMsgRuleActionType actionType;
|
||||||
|
void *value = nsnull;
|
||||||
|
PRUint32 newFlags;
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
if (!applyMore)
|
||||||
|
{
|
||||||
|
NS_ASSERTION(PR_FALSE, "need to return status!");
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
}
|
||||||
|
// look at action - currently handle move
|
||||||
|
#ifdef DEBUG_bienvenu
|
||||||
|
printf("got a rule hit!\n");
|
||||||
|
#endif
|
||||||
|
if (NS_SUCCEEDED(filter->GetAction(&actionType, &value)))
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIMsgDBHdr> msgHdr;
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
if (m_msgParser)
|
||||||
|
m_msgParser->GetNewMsgHdr(getter_AddRefs(msgHdr));
|
||||||
|
if (NS_SUCCEEDED(rv) && msgHdr)
|
||||||
|
|
||||||
|
{
|
||||||
|
PRUint32 msgFlags;
|
||||||
|
|
||||||
|
msgHdr->GetFlags(&msgFlags);
|
||||||
|
|
||||||
|
PRBool isRead = (msgFlags & MSG_FLAG_READ);
|
||||||
|
switch (actionType)
|
||||||
|
{
|
||||||
|
case nsMsgFilterActionDelete:
|
||||||
|
{
|
||||||
|
#ifdef DOING_DELETE
|
||||||
|
MSG_IMAPFolderInfoMail *imapFolder = m_folder->GetIMAPFolderInfoMail();
|
||||||
|
PRBool serverIsImap = GetMaster()->GetPrefs()->GetMailServerIsIMAP4();
|
||||||
|
PRBool deleteToTrash = !imapFolder || imapFolder->DeleteIsMoveToTrash();
|
||||||
|
PRBool showDeletedMessages = (!imapFolder) || imapFolder->ShowDeletedMessages();
|
||||||
|
if (deleteToTrash || !serverIsImap)
|
||||||
|
{
|
||||||
|
// set value to trash folder
|
||||||
|
MSG_FolderInfoMail *mailTrash = GetTrashFolder();
|
||||||
|
if (mailTrash)
|
||||||
|
value = (void *) mailTrash->GetPathname();
|
||||||
|
|
||||||
|
msgHdr->OrFlags(MSG_FLAG_READ); // mark read in trash.
|
||||||
|
}
|
||||||
|
else // (!deleteToTrash && serverIsImap)
|
||||||
|
{
|
||||||
|
msgHdr->OrFlags(MSG_FLAG_READ | MSG_FLAG_IMAP_DELETED);
|
||||||
|
nsMsgKeyArray keysToFlag;
|
||||||
|
|
||||||
|
keysToFlag.Add(msgHdr->GetMessageKey());
|
||||||
|
if (imapFolder)
|
||||||
|
imapFolder->StoreImapFlags(m_pane, kImapMsgSeenFlag | kImapMsgDeletedFlag, TRUE, keysToFlag, ((ParseIMAPMailboxState *) this)->GetFilterUrlQueue());
|
||||||
|
if (!showDeletedMessages)
|
||||||
|
msgMoved = TRUE; // this will prevent us from adding the header to the db.
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // DOING_DELETE
|
||||||
|
}
|
||||||
|
case nsMsgFilterActionMoveToFolder:
|
||||||
|
{
|
||||||
|
// if moving to a different file, do it.
|
||||||
|
char *folderName = nsnull;
|
||||||
|
rv = GetName(&folderName);
|
||||||
|
|
||||||
|
if (value && PL_strcasecmp(folderName, (char *) value))
|
||||||
|
{
|
||||||
|
PRUint32 msgFlags;
|
||||||
|
msgHdr->GetFlags(&msgFlags);
|
||||||
|
|
||||||
|
if (msgFlags & MSG_FLAG_MDN_REPORT_NEEDED &&
|
||||||
|
!isRead)
|
||||||
|
{
|
||||||
|
|
||||||
|
#if DOING_MDN // leave it to the user aciton
|
||||||
|
struct message_header to;
|
||||||
|
struct message_header cc;
|
||||||
|
GetAggregateHeader (m_toList, &to);
|
||||||
|
GetAggregateHeader (m_ccList, &cc);
|
||||||
|
msgHdr->SetFlags(msgFlags & ~MSG_FLAG_MDN_REPORT_NEEDED);
|
||||||
|
msgHdr->OrFlags(MSG_FLAG_MDN_REPORT_SENT, &newFlags);
|
||||||
|
if (actionType == nsMsgFilterActionDelete)
|
||||||
|
{
|
||||||
|
MSG_ProcessMdnNeededState processMdnNeeded
|
||||||
|
(MSG_ProcessMdnNeededState::eDeleted,
|
||||||
|
m_pane, m_folder, msgHdr->GetMessageKey(),
|
||||||
|
&state->m_return_path, &state->m_mdn_dnt,
|
||||||
|
&to, &cc, &state->m_subject,
|
||||||
|
&state->m_date, &state->m_mdn_original_recipient,
|
||||||
|
&state->m_message_id, state->m_headers,
|
||||||
|
(PRInt32) state->m_headers_fp, TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MSG_ProcessMdnNeededState processMdnNeeded
|
||||||
|
(MSG_ProcessMdnNeededState::eProcessed,
|
||||||
|
m_pane, m_folder, msgHdr->GetMessageKey(),
|
||||||
|
&state->m_return_path, &state->m_mdn_dnt,
|
||||||
|
&to, &cc, &state->m_subject,
|
||||||
|
&state->m_date, &state->m_mdn_original_recipient,
|
||||||
|
&state->m_message_id, state->m_headers,
|
||||||
|
(PRInt32) state->m_headers_fp, TRUE);
|
||||||
|
}
|
||||||
|
char *tmp = (char*) to.value;
|
||||||
|
PR_FREEIF(tmp);
|
||||||
|
tmp = (char*) cc.value;
|
||||||
|
PR_FREEIF(tmp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
nsresult err = MoveIncorporatedMessage(msgHdr, mDatabase, (char *) value, filter);
|
||||||
|
if (NS_SUCCEEDED(err))
|
||||||
|
m_msgMovedByFilter = PR_TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
delete [] folderName;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionMarkRead:
|
||||||
|
MarkFilteredMessageRead(msgHdr);
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionKillThread:
|
||||||
|
// for ignore and watch, we will need the db
|
||||||
|
// to check for the flags in msgHdr's that
|
||||||
|
// get added, because only then will we know
|
||||||
|
// the thread they're getting added to.
|
||||||
|
msgHdr->OrFlags(MSG_FLAG_IGNORED, &newFlags);
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionWatchThread:
|
||||||
|
msgHdr->OrFlags(MSG_FLAG_WATCHED, &newFlags);
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionChangePriority:
|
||||||
|
msgHdr->SetPriority(*(nsMsgPriority *) &value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr,
|
||||||
|
nsIMsgDatabase *sourceDB,
|
||||||
|
char *destFolder,
|
||||||
|
nsIMsgFilter *filter)
|
||||||
|
{
|
||||||
|
nsresult err = NS_OK;
|
||||||
|
|
||||||
|
if (fUrlQueue && fUrlQueue->GetPane())
|
||||||
|
{
|
||||||
|
// look for matching imap folders, then pop folders
|
||||||
|
MSG_FolderInfoContainer *imapContainer = m_imapContainer;
|
||||||
|
nsIMsgFolder *sourceFolder = imapContainer->FindMailPathname(m_mailboxName);
|
||||||
|
nsIMsgFolder *destinationFolder = imapContainer->FindMailPathname(destFolder);
|
||||||
|
if (!destinationFolder)
|
||||||
|
destinationFolder = m_mailMaster->FindMailFolder(destFolder, FALSE);
|
||||||
|
|
||||||
|
if (destinationFolder)
|
||||||
|
{
|
||||||
|
nsIMsgFolder *inbox=nsnull;
|
||||||
|
imapContainer->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, &inbox, 1);
|
||||||
|
if (inbox)
|
||||||
|
{
|
||||||
|
MSG_FolderInfoMail *destMailFolder = destinationFolder->GetMailFolderInfo();
|
||||||
|
// put the header into the source db, since it needs to be there when we copy it
|
||||||
|
// and we need a valid header to pass to StartAsyncCopyMessagesInto
|
||||||
|
nsMsgKey keyToFilter = mailHdr->GetMessageKey();
|
||||||
|
|
||||||
|
if (sourceDB && destMailFolder)
|
||||||
|
{
|
||||||
|
PRBool imapDeleteIsMoveToTrash = m_host->GetDeleteIsMoveToTrash();
|
||||||
|
|
||||||
|
nsMsgKeyArray *idsToMoveFromInbox = destMailFolder->GetImapIdsToMoveFromInbox();
|
||||||
|
idsToMoveFromInbox->Add(keyToFilter);
|
||||||
|
|
||||||
|
// this is our last best chance to log this
|
||||||
|
if (m_filterList->LoggingEnabled())
|
||||||
|
filter->LogRuleHit(GetLogFile(), mailHdr);
|
||||||
|
|
||||||
|
if (imapDeleteIsMoveToTrash)
|
||||||
|
{
|
||||||
|
if (m_parseMsgState->m_newMsgHdr)
|
||||||
|
{
|
||||||
|
m_parseMsgState->m_newMsgHdr->Release();
|
||||||
|
m_parseMsgState->m_newMsgHdr = nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destinationFolder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW);
|
||||||
|
|
||||||
|
if (imapDeleteIsMoveToTrash)
|
||||||
|
err = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// we have to return an error because we do not actually move the message
|
||||||
|
// it is done async and that can fail
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // DOING_FILTERS
|
||||||
|
|
||||||
// both of these algorithms assume that key arrays and flag states are sorted by increasing key.
|
// both of these algorithms assume that key arrays and flag states are sorted by increasing key.
|
||||||
void nsImapMailFolder::FindKeysToDelete(const nsMsgKeyArray &existingKeys, nsMsgKeyArray &keysToDelete, nsImapFlagAndUidState *flagState)
|
void nsImapMailFolder::FindKeysToDelete(const nsMsgKeyArray &existingKeys, nsMsgKeyArray &keysToDelete, nsImapFlagAndUidState *flagState)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,13 @@
|
||||||
#include "nsIUrlListener.h"
|
#include "nsIUrlListener.h"
|
||||||
#include "nsIImapIncomingServer.h" // we need this for its IID
|
#include "nsIImapIncomingServer.h" // we need this for its IID
|
||||||
#include "nsIMsgParseMailMsgState.h"
|
#include "nsIMsgParseMailMsgState.h"
|
||||||
|
#ifdef DEBUG_bienvenu
|
||||||
|
//#define DOING_FILTERS
|
||||||
|
#endif
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
#include "nsIMsgFilterHitNotify.h"
|
||||||
|
#include "nsIMsgFilterList.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* fa32d000-f6a0-11d2-af8d-001083002da8 */
|
/* fa32d000-f6a0-11d2-af8d-001083002da8 */
|
||||||
#define NS_IMAPRESOURCE_CID \
|
#define NS_IMAPRESOURCE_CID \
|
||||||
|
@ -43,6 +50,9 @@ class nsImapMailFolder : public nsMsgDBFolder,
|
||||||
public nsIImapMiscellaneousSink,
|
public nsIImapMiscellaneousSink,
|
||||||
public nsICopyMessageListener,
|
public nsICopyMessageListener,
|
||||||
public nsIUrlListener
|
public nsIUrlListener
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
,public nsIMsgFilterHitNotify
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsImapMailFolder();
|
nsImapMailFolder();
|
||||||
|
@ -231,6 +241,15 @@ public:
|
||||||
NS_IMETHOD ProcessTunnel(nsIImapProtocol* aProtocol,
|
NS_IMETHOD ProcessTunnel(nsIImapProtocol* aProtocol,
|
||||||
TunnelInfo *aInfo);
|
TunnelInfo *aInfo);
|
||||||
|
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
// nsIMsgFilterHitNotification method(s)
|
||||||
|
NS_IMETHOD ApplyFilterHit(nsIMsgFilter *filter, PRBool *applyMore);
|
||||||
|
|
||||||
|
nsresult MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr,
|
||||||
|
nsIMsgDatabase *sourceDB,
|
||||||
|
char *destFolder,
|
||||||
|
nsIMsgFilter *filter)
|
||||||
|
#endif // DOING_FILTERS
|
||||||
protected:
|
protected:
|
||||||
// Helper methods
|
// Helper methods
|
||||||
void FindKeysToAdd(const nsMsgKeyArray &existingKeys, nsMsgKeyArray
|
void FindKeysToAdd(const nsMsgKeyArray &existingKeys, nsMsgKeyArray
|
||||||
|
@ -263,6 +282,10 @@ protected:
|
||||||
PRBool m_haveDiscoverAllFolders;
|
PRBool m_haveDiscoverAllFolders;
|
||||||
PRBool m_haveReadNameFromDB;
|
PRBool m_haveReadNameFromDB;
|
||||||
nsCOMPtr<nsIMsgParseMailMsgState> m_msgParser;
|
nsCOMPtr<nsIMsgParseMailMsgState> m_msgParser;
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
nsCOMPtr<nsIMsgFilterList> m_filterList;
|
||||||
|
PRBool m_msgMovedByFilter;
|
||||||
|
#endif
|
||||||
nsMsgKey m_curMsgUid;
|
nsMsgKey m_curMsgUid;
|
||||||
PRInt32 m_nextMessageByteLength;
|
PRInt32 m_nextMessageByteLength;
|
||||||
nsCOMPtr<nsIEventQueue> m_eventQueue;
|
nsCOMPtr<nsIEventQueue> m_eventQueue;
|
||||||
|
|
|
@ -46,6 +46,7 @@ public:
|
||||||
NS_IMETHOD ParseAFolderLine(const char *line, PRUint32 lineLength) = 0;
|
NS_IMETHOD ParseAFolderLine(const char *line, PRUint32 lineLength) = 0;
|
||||||
NS_IMETHOD GetNewMsgHdr(nsIMsgDBHdr ** aMsgHeader) = 0;
|
NS_IMETHOD GetNewMsgHdr(nsIMsgDBHdr ** aMsgHeader) = 0;
|
||||||
NS_IMETHOD FinishHeader() = 0;
|
NS_IMETHOD FinishHeader() = 0;
|
||||||
|
NS_IMETHOD GetAllHeaders(char **headers, PRInt32 *headersSize) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* nsIMsgParseMailMsgState_h___ */
|
#endif /* nsIMsgParseMailMsgState_h___ */
|
||||||
|
|
|
@ -605,6 +605,16 @@ NS_IMETHODIMP nsParseMailMessageState::FinishHeader()
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsParseMailMessageState::GetAllHeaders(char ** pHeaders, PRInt32 *pHeadersSize)
|
||||||
|
{
|
||||||
|
if (!pHeaders || !pHeadersSize)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
*pHeaders = m_headers.GetBuffer();
|
||||||
|
*pHeadersSize = m_headers.GetBufferPos();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct message_header *nsParseMailMessageState::GetNextHeaderInAggregate (nsVoidArray &list)
|
struct message_header *nsParseMailMessageState::GetNextHeaderInAggregate (nsVoidArray &list)
|
||||||
{
|
{
|
||||||
// When parsing a message with multiple To or CC header lines, we're storing each line in a
|
// When parsing a message with multiple To or CC header lines, we're storing each line in a
|
||||||
|
@ -1332,6 +1342,10 @@ nsParseNewMailState::nsParseNewMailState()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
NS_IMPL_ISUPPORTS_INHERITED(nsParseNewMailState, nsMsgMailboxParser, nsIMsgFilterHitNotify)
|
||||||
|
#endif
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsParseNewMailState::Init(nsIFolder *rootFolder, nsFileSpec &folder, nsIOFileStream *inboxFileStream)
|
nsParseNewMailState::Init(nsIFolder *rootFolder, nsFileSpec &folder, nsIOFileStream *inboxFileStream)
|
||||||
{
|
{
|
||||||
|
@ -1538,186 +1552,160 @@ nsIMsgFolder *nsParseNewMailState::GetTrashFolder()
|
||||||
|
|
||||||
void nsParseNewMailState::ApplyFilters(PRBool *pMoved)
|
void nsParseNewMailState::ApplyFilters(PRBool *pMoved)
|
||||||
{
|
{
|
||||||
nsIMsgFilter *filter;
|
|
||||||
PRUint32 filterCount = 0;
|
|
||||||
PRBool msgMoved = FALSE;
|
PRBool msgMoved = FALSE;
|
||||||
PRUint32 newFlags;
|
|
||||||
|
m_msgMovedByFilter = PR_FALSE;
|
||||||
|
|
||||||
nsIMsgDBHdr *msgHdr = m_newMsgHdr;
|
nsIMsgDBHdr *msgHdr = m_newMsgHdr;
|
||||||
if (m_filterList != nsnull)
|
nsCOMPtr <nsIMsgFolder> inbox;
|
||||||
m_filterList->GetFilterCount(&filterCount);
|
nsCOMPtr <nsIMsgFolder> rootMsgFolder = do_QueryInterface(m_rootFolder);
|
||||||
|
if (rootMsgFolder)
|
||||||
for (PRUint32 filterIndex = 0; filterIndex < filterCount; filterIndex++)
|
|
||||||
{
|
{
|
||||||
if (NS_SUCCEEDED(m_filterList->GetFilterAt(filterIndex, &filter)))
|
PRUint32 numFolders;
|
||||||
{
|
rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, getter_AddRefs(inbox), 1, &numFolders);
|
||||||
PRBool isEnabled;
|
char * headers = m_headers.GetBuffer();
|
||||||
nsMsgFilterType filterType;
|
PRUint32 headersSize = m_headers.GetBufferPos();
|
||||||
|
nsresult matchTermStatus = m_filterList->ApplyFiltersToHdr(nsMsgFilterInboxRule, msgHdr, inbox,
|
||||||
|
m_mailDB, headers, headersSize, this);
|
||||||
|
}
|
||||||
|
|
||||||
filter->IsFilterEnabled(&isEnabled);
|
if (pMoved)
|
||||||
if (!isEnabled)
|
*pMoved = m_msgMovedByFilter;
|
||||||
continue;
|
}
|
||||||
|
|
||||||
filter->GetFilterType(&filterType);
|
NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, PRBool *applyMore)
|
||||||
if (filterType == nsMsgFilterInboxJavaScript)
|
{
|
||||||
{
|
nsMsgRuleActionType actionType;
|
||||||
#ifdef DOING_JSFILTERS
|
void *value = nsnull;
|
||||||
if (JSMailFilter_execute(this, filter, msgHdr, m_mailDB, &msgMoved) == SearchError_Success)
|
PRUint32 newFlags;
|
||||||
break;
|
nsresult rv = NS_OK;
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (filterType == nsMsgFilterInboxRule)
|
|
||||||
{
|
|
||||||
nsresult matchTermStatus = NS_OK;
|
|
||||||
|
|
||||||
{
|
if (!applyMore)
|
||||||
// how are we going to do this? Probably we need to load
|
{
|
||||||
// the offline mail search service and run the filter,
|
NS_ASSERTION(PR_FALSE, "need to return status!");
|
||||||
// or perhaps just add an interface on the filter object
|
return NS_ERROR_NULL_POINTER;
|
||||||
// that does it internally.
|
}
|
||||||
|
// look at action - currently handle move
|
||||||
nsCOMPtr <nsIMsgFolder> inbox;
|
|
||||||
nsCOMPtr <nsIMsgFolder> rootMsgFolder = do_QueryInterface(m_rootFolder);
|
|
||||||
if (rootMsgFolder)
|
|
||||||
{
|
|
||||||
PRUint32 numFolders;
|
|
||||||
rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, getter_AddRefs(inbox), 1, &numFolders);
|
|
||||||
char * headers = m_headers.GetBuffer();
|
|
||||||
PRUint32 headersSize = m_headers.GetBufferPos();
|
|
||||||
matchTermStatus = filter->MatchHdr(msgHdr, inbox, m_mailDB, headers, headersSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (matchTermStatus == NS_OK)
|
|
||||||
{
|
|
||||||
nsMsgRuleActionType actionType;
|
|
||||||
void *value = nsnull;
|
|
||||||
// look at action - currently handle move
|
|
||||||
#ifdef DEBUG_bienvenu
|
#ifdef DEBUG_bienvenu
|
||||||
printf("got a rule hit!\n");
|
printf("got a rule hit!\n");
|
||||||
#endif
|
#endif
|
||||||
if (NS_SUCCEEDED(filter->GetAction(&actionType, &value)))
|
if (NS_SUCCEEDED(filter->GetAction(&actionType, &value)))
|
||||||
{
|
{
|
||||||
PRUint32 msgFlags;
|
nsIMsgDBHdr *msgHdr = m_newMsgHdr;
|
||||||
|
PRUint32 msgFlags;
|
||||||
|
|
||||||
msgHdr->GetFlags(&msgFlags);
|
msgHdr->GetFlags(&msgFlags);
|
||||||
|
|
||||||
PRBool isRead = (msgFlags & MSG_FLAG_READ);
|
PRBool isRead = (msgFlags & MSG_FLAG_READ);
|
||||||
switch (actionType)
|
switch (actionType)
|
||||||
{
|
{
|
||||||
case nsMsgFilterActionDelete:
|
case nsMsgFilterActionDelete:
|
||||||
{
|
{
|
||||||
#ifdef DOING_DELETE
|
#ifdef DOING_DELETE
|
||||||
MSG_IMAPFolderInfoMail *imapFolder = m_folder->GetIMAPFolderInfoMail();
|
MSG_IMAPFolderInfoMail *imapFolder = m_folder->GetIMAPFolderInfoMail();
|
||||||
PRBool serverIsImap = GetMaster()->GetPrefs()->GetMailServerIsIMAP4();
|
PRBool serverIsImap = GetMaster()->GetPrefs()->GetMailServerIsIMAP4();
|
||||||
PRBool deleteToTrash = !imapFolder || imapFolder->DeleteIsMoveToTrash();
|
PRBool deleteToTrash = !imapFolder || imapFolder->DeleteIsMoveToTrash();
|
||||||
PRBool showDeletedMessages = (!imapFolder) || imapFolder->ShowDeletedMessages();
|
PRBool showDeletedMessages = (!imapFolder) || imapFolder->ShowDeletedMessages();
|
||||||
if (deleteToTrash || !serverIsImap)
|
if (deleteToTrash || !serverIsImap)
|
||||||
{
|
{
|
||||||
// set value to trash folder
|
// set value to trash folder
|
||||||
MSG_FolderInfoMail *mailTrash = GetTrashFolder();
|
MSG_FolderInfoMail *mailTrash = GetTrashFolder();
|
||||||
if (mailTrash)
|
if (mailTrash)
|
||||||
value = (void *) mailTrash->GetPathname();
|
value = (void *) mailTrash->GetPathname();
|
||||||
|
|
||||||
msgHdr->OrFlags(MSG_FLAG_READ); // mark read in trash.
|
msgHdr->OrFlags(MSG_FLAG_READ); // mark read in trash.
|
||||||
}
|
}
|
||||||
else // (!deleteToTrash && serverIsImap)
|
else // (!deleteToTrash && serverIsImap)
|
||||||
{
|
{
|
||||||
msgHdr->OrFlags(MSG_FLAG_READ | MSG_FLAG_IMAP_DELETED);
|
msgHdr->OrFlags(MSG_FLAG_READ | MSG_FLAG_IMAP_DELETED);
|
||||||
nsMsgKeyArray keysToFlag;
|
nsMsgKeyArray keysToFlag;
|
||||||
|
|
||||||
keysToFlag.Add(msgHdr->GetMessageKey());
|
keysToFlag.Add(msgHdr->GetMessageKey());
|
||||||
if (imapFolder)
|
if (imapFolder)
|
||||||
imapFolder->StoreImapFlags(m_pane, kImapMsgSeenFlag | kImapMsgDeletedFlag, TRUE, keysToFlag, ((ParseIMAPMailboxState *) this)->GetFilterUrlQueue());
|
imapFolder->StoreImapFlags(m_pane, kImapMsgSeenFlag | kImapMsgDeletedFlag, TRUE, keysToFlag, ((ParseIMAPMailboxState *) this)->GetFilterUrlQueue());
|
||||||
if (!showDeletedMessages)
|
if (!showDeletedMessages)
|
||||||
msgMoved = TRUE; // this will prevent us from adding the header to the db.
|
msgMoved = TRUE; // this will prevent us from adding the header to the db.
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // DOING_DELETE
|
#endif // DOING_DELETE
|
||||||
}
|
}
|
||||||
case nsMsgFilterActionMoveToFolder:
|
case nsMsgFilterActionMoveToFolder:
|
||||||
// if moving to a different file, do it.
|
// if moving to a different file, do it.
|
||||||
if (value && PL_strcasecmp(m_mailboxName, (char *) value))
|
if (value && PL_strcasecmp(m_mailboxName, (char *) value))
|
||||||
{
|
{
|
||||||
PRUint32 msgFlags;
|
PRUint32 msgFlags;
|
||||||
msgHdr->GetFlags(&msgFlags);
|
msgHdr->GetFlags(&msgFlags);
|
||||||
|
|
||||||
if (msgFlags & MSG_FLAG_MDN_REPORT_NEEDED &&
|
if (msgFlags & MSG_FLAG_MDN_REPORT_NEEDED &&
|
||||||
!isRead)
|
!isRead)
|
||||||
{
|
{
|
||||||
struct message_header to;
|
struct message_header to;
|
||||||
struct message_header cc;
|
struct message_header cc;
|
||||||
GetAggregateHeader (m_toList, &to);
|
GetAggregateHeader (m_toList, &to);
|
||||||
GetAggregateHeader (m_ccList, &cc);
|
GetAggregateHeader (m_ccList, &cc);
|
||||||
msgHdr->SetFlags(msgFlags & ~MSG_FLAG_MDN_REPORT_NEEDED);
|
msgHdr->SetFlags(msgFlags & ~MSG_FLAG_MDN_REPORT_NEEDED);
|
||||||
msgHdr->OrFlags(MSG_FLAG_MDN_REPORT_SENT, &newFlags);
|
msgHdr->OrFlags(MSG_FLAG_MDN_REPORT_SENT, &newFlags);
|
||||||
|
|
||||||
#if DOING_MDN // leave it to the user aciton
|
#if DOING_MDN // leave it to the user aciton
|
||||||
if (actionType == nsMsgFilterActionDelete)
|
if (actionType == nsMsgFilterActionDelete)
|
||||||
{
|
{
|
||||||
MSG_ProcessMdnNeededState processMdnNeeded
|
MSG_ProcessMdnNeededState processMdnNeeded
|
||||||
(MSG_ProcessMdnNeededState::eDeleted,
|
(MSG_ProcessMdnNeededState::eDeleted,
|
||||||
m_pane, m_folder, msgHdr->GetMessageKey(),
|
m_pane, m_folder, msgHdr->GetMessageKey(),
|
||||||
&state->m_return_path, &state->m_mdn_dnt,
|
&state->m_return_path, &state->m_mdn_dnt,
|
||||||
&to, &cc, &state->m_subject,
|
&to, &cc, &state->m_subject,
|
||||||
&state->m_date, &state->m_mdn_original_recipient,
|
&state->m_date, &state->m_mdn_original_recipient,
|
||||||
&state->m_message_id, state->m_headers,
|
&state->m_message_id, state->m_headers,
|
||||||
(PRInt32) state->m_headers_fp, TRUE);
|
(PRInt32) state->m_headers_fp, TRUE);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MSG_ProcessMdnNeededState processMdnNeeded
|
|
||||||
(MSG_ProcessMdnNeededState::eProcessed,
|
|
||||||
m_pane, m_folder, msgHdr->GetMessageKey(),
|
|
||||||
&state->m_return_path, &state->m_mdn_dnt,
|
|
||||||
&to, &cc, &state->m_subject,
|
|
||||||
&state->m_date, &state->m_mdn_original_recipient,
|
|
||||||
&state->m_message_id, state->m_headers,
|
|
||||||
(PRInt32) state->m_headers_fp, TRUE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
char *tmp = (char*) to.value;
|
|
||||||
PR_FREEIF(tmp);
|
|
||||||
tmp = (char*) cc.value;
|
|
||||||
PR_FREEIF(tmp);
|
|
||||||
}
|
|
||||||
nsresult err = MoveIncorporatedMessage(msgHdr, m_mailDB, (char *) value, filter);
|
|
||||||
if (NS_SUCCEEDED(err))
|
|
||||||
msgMoved = TRUE;
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case nsMsgFilterActionMarkRead:
|
|
||||||
MarkFilteredMessageRead(msgHdr);
|
|
||||||
break;
|
|
||||||
case nsMsgFilterActionKillThread:
|
|
||||||
// for ignore and watch, we will need the db
|
|
||||||
// to check for the flags in msgHdr's that
|
|
||||||
// get added, because only then will we know
|
|
||||||
// the thread they're getting added to.
|
|
||||||
msgHdr->OrFlags(MSG_FLAG_IGNORED, &newFlags);
|
|
||||||
break;
|
|
||||||
case nsMsgFilterActionWatchThread:
|
|
||||||
msgHdr->OrFlags(MSG_FLAG_WATCHED, &newFlags);
|
|
||||||
break;
|
|
||||||
case nsMsgFilterActionChangePriority:
|
|
||||||
msgHdr->SetPriority(*(nsMsgPriority *) &value);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
PRBool loggingEnabled;
|
|
||||||
m_filterList->IsLoggingEnabled(&loggingEnabled);
|
|
||||||
if (loggingEnabled && !msgMoved && actionType != nsMsgFilterActionMoveToFolder)
|
|
||||||
filter->LogRuleHit(GetLogFile(), msgHdr);
|
|
||||||
}
|
}
|
||||||
break;
|
else
|
||||||
|
{
|
||||||
|
MSG_ProcessMdnNeededState processMdnNeeded
|
||||||
|
(MSG_ProcessMdnNeededState::eProcessed,
|
||||||
|
m_pane, m_folder, msgHdr->GetMessageKey(),
|
||||||
|
&state->m_return_path, &state->m_mdn_dnt,
|
||||||
|
&to, &cc, &state->m_subject,
|
||||||
|
&state->m_date, &state->m_mdn_original_recipient,
|
||||||
|
&state->m_message_id, state->m_headers,
|
||||||
|
(PRInt32) state->m_headers_fp, TRUE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
char *tmp = (char*) to.value;
|
||||||
|
PR_FREEIF(tmp);
|
||||||
|
tmp = (char*) cc.value;
|
||||||
|
PR_FREEIF(tmp);
|
||||||
}
|
}
|
||||||
|
nsresult err = MoveIncorporatedMessage(msgHdr, m_mailDB, (char *) value, filter);
|
||||||
|
if (NS_SUCCEEDED(err))
|
||||||
|
m_msgMovedByFilter = PR_TRUE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionMarkRead:
|
||||||
|
MarkFilteredMessageRead(msgHdr);
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionKillThread:
|
||||||
|
// for ignore and watch, we will need the db
|
||||||
|
// to check for the flags in msgHdr's that
|
||||||
|
// get added, because only then will we know
|
||||||
|
// the thread they're getting added to.
|
||||||
|
msgHdr->OrFlags(MSG_FLAG_IGNORED, &newFlags);
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionWatchThread:
|
||||||
|
msgHdr->OrFlags(MSG_FLAG_WATCHED, &newFlags);
|
||||||
|
break;
|
||||||
|
case nsMsgFilterActionChangePriority:
|
||||||
|
msgHdr->SetPriority(*(nsMsgPriority *) &value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
PRBool loggingEnabled;
|
||||||
|
m_filterList->LoggingEnabled(&loggingEnabled);
|
||||||
|
if (loggingEnabled && !m_msgMovedByFilter && actionType != nsMsgFilterActionMoveToFolder)
|
||||||
|
filter->LogRuleHit(GetLogFile(), msgHdr);
|
||||||
}
|
}
|
||||||
if (pMoved)
|
return rv;
|
||||||
*pMoved = msgMoved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int nsParseNewMailState::MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr)
|
int nsParseNewMailState::MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr)
|
||||||
|
@ -1897,7 +1885,7 @@ nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr,
|
||||||
// We are logging the hit with the old mailHdr, which should work, as long
|
// We are logging the hit with the old mailHdr, which should work, as long
|
||||||
// as LogRuleHit doesn't assume the new hdr.
|
// as LogRuleHit doesn't assume the new hdr.
|
||||||
PRBool loggingEnabled;
|
PRBool loggingEnabled;
|
||||||
m_filterList->IsLoggingEnabled(&loggingEnabled);
|
m_filterList->LoggingEnabled(&loggingEnabled);
|
||||||
if (loggingEnabled)
|
if (loggingEnabled)
|
||||||
filter->LogRuleHit(GetLogFile(), mailHdr);
|
filter->LogRuleHit(GetLogFile(), mailHdr);
|
||||||
|
|
||||||
|
@ -2016,7 +2004,7 @@ nsresult ParseIMAPMailboxState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr,
|
||||||
idsToMoveFromInbox->Add(keyToFilter);
|
idsToMoveFromInbox->Add(keyToFilter);
|
||||||
|
|
||||||
// this is our last best chance to log this
|
// this is our last best chance to log this
|
||||||
if (m_filterList->IsLoggingEnabled())
|
if (m_filterList->LoggingEnabled())
|
||||||
filter->LogRuleHit(GetLogFile(), mailHdr);
|
filter->LogRuleHit(GetLogFile(), mailHdr);
|
||||||
|
|
||||||
if (imapDeleteIsMoveToTrash)
|
if (imapDeleteIsMoveToTrash)
|
||||||
|
|
|
@ -32,7 +32,12 @@
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_bienvenu
|
#ifdef DEBUG_bienvenu
|
||||||
#define DOING_FILTERS
|
//#define DOING_FILTERS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
#include "nsIMsgFilterList.h"
|
||||||
|
#include "nsIMsgFilterHitNotify.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class nsFileSpec;
|
class nsFileSpec;
|
||||||
|
@ -75,7 +80,7 @@ public:
|
||||||
NS_IMETHOD ParseAFolderLine(const char *line, PRUint32 lineLength);
|
NS_IMETHOD ParseAFolderLine(const char *line, PRUint32 lineLength);
|
||||||
NS_IMETHOD GetNewMsgHdr(nsIMsgDBHdr ** aMsgHeader);
|
NS_IMETHOD GetNewMsgHdr(nsIMsgDBHdr ** aMsgHeader);
|
||||||
NS_IMETHOD FinishHeader();
|
NS_IMETHOD FinishHeader();
|
||||||
|
NS_IMETHOD GetAllHeaders(char **headers, PRInt32 *headersSize);
|
||||||
void Init(PRUint32 fileposition);
|
void Init(PRUint32 fileposition);
|
||||||
virtual PRInt32 ParseFolderLine(const char *line, PRUint32 lineLength);
|
virtual PRInt32 ParseFolderLine(const char *line, PRUint32 lineLength);
|
||||||
virtual int StartNewEnvelope(const char *line, PRUint32 lineLength);
|
virtual int StartNewEnvelope(const char *line, PRUint32 lineLength);
|
||||||
|
@ -233,11 +238,16 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
class nsParseNewMailState : public nsMsgMailboxParser
|
class nsParseNewMailState : public nsMsgMailboxParser
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
, public nsIMsgFilterHitNotify
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsParseNewMailState();
|
nsParseNewMailState();
|
||||||
virtual ~nsParseNewMailState();
|
virtual ~nsParseNewMailState();
|
||||||
|
#ifdef DOING_FILTERS
|
||||||
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
#endif
|
||||||
nsresult Init(nsIFolder *rootFolder, nsFileSpec &folder, nsIOFileStream *inboxFileStream);
|
nsresult Init(nsIFolder *rootFolder, nsFileSpec &folder, nsIOFileStream *inboxFileStream);
|
||||||
|
|
||||||
virtual void DoneParsingFolder();
|
virtual void DoneParsingFolder();
|
||||||
|
@ -255,6 +265,9 @@ public:
|
||||||
PRBool *pMoved);
|
PRBool *pMoved);
|
||||||
#endif
|
#endif
|
||||||
#ifdef DOING_FILTERS
|
#ifdef DOING_FILTERS
|
||||||
|
// nsIMsgFilterHitNotification method(s)
|
||||||
|
NS_IMETHOD ApplyFilterHit(nsIMsgFilter *filter, PRBool *applyMore);
|
||||||
|
|
||||||
nsOutputFileStream *GetLogFile();
|
nsOutputFileStream *GetLogFile();
|
||||||
#endif // DOING_FILTERS
|
#endif // DOING_FILTERS
|
||||||
protected:
|
protected:
|
||||||
|
@ -277,6 +290,7 @@ protected:
|
||||||
char *m_tmpdbName; // Temporary filename of new database
|
char *m_tmpdbName; // Temporary filename of new database
|
||||||
PRBool m_usingTempDB;
|
PRBool m_usingTempDB;
|
||||||
PRBool m_disableFilters;
|
PRBool m_disableFilters;
|
||||||
|
PRBool m_msgMovedByFilter;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef IMAP_NEW_MAIL_HANDLED
|
#ifdef IMAP_NEW_MAIL_HANDLED
|
||||||
|
|
Загрузка…
Ссылка в новой задаче