Work in progress changes for bayesian spam filter. sr=sspitzer, r=ducarroz

git-svn-id: svn://10.0.0.236/trunk@131019 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
beard%netscape.com
2002-10-02 20:04:09 +00:00
parent d71c9f4edb
commit d24ce995d9
3 changed files with 114 additions and 71 deletions

View File

@@ -327,7 +327,7 @@
<!-- Settings for "FTP Panel" panel -->
<SETTING><NAME>MWFTP_Post_hostName</NAME><VALUE></VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_username</NAME><VALUE></VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_password</NAME><VALUE>0</VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_password</NAME><VALUE>0&#255;&#221;&#184;</VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_remoteDir</NAME><VALUE></VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_ftp_PathVersion</NAME><VALUE>1</VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_ftp_PathType</NAME><VALUE>0</VALUE></SETTING>
@@ -1136,6 +1136,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMsgFilterPlugin.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@@ -1428,6 +1435,11 @@
<PATH>nsISpamSettings.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMsgFilterPlugin.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
<TARGET>
@@ -1704,7 +1716,7 @@
<!-- Settings for "FTP Panel" panel -->
<SETTING><NAME>MWFTP_Post_hostName</NAME><VALUE></VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_username</NAME><VALUE></VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_password</NAME><VALUE>0</VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_password</NAME><VALUE>0&#255;&#221;&#184;</VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_remoteDir</NAME><VALUE></VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_ftp_PathVersion</NAME><VALUE>1</VALUE></SETTING>
<SETTING><NAME>MWFTP_Post_ftp_PathType</NAME><VALUE>0</VALUE></SETTING>
@@ -2513,6 +2525,13 @@
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
<FILE>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMsgFilterPlugin.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
<FILEKIND>Text</FILEKIND>
<FILEFLAGS></FILEFLAGS>
</FILE>
</FILELIST>
<LINKORDER>
<FILEREF>
@@ -2805,6 +2824,11 @@
<PATH>nsISpamSettings.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMsgFilterPlugin.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
</LINKORDER>
</TARGET>
</TARGETLIST>
@@ -3102,6 +3126,12 @@
<PATH>nsIMsgFilterList.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>
<PATH>nsIMsgFilterPlugin.idl</PATH>
<PATHFORMAT>MacOS</PATHFORMAT>
</FILEREF>
<FILEREF>
<TARGETNAME>headers</TARGETNAME>
<PATHTYPE>Name</PATHTYPE>

View File

@@ -429,44 +429,36 @@ function doHelpButton()
// XXX The following junkmail code might be going away or changing
const NS_BAYESIANFILTER_CONTRACTID = "@mozilla.org/messenger/filter-plugin;1?name=bayesianfilter";
const nsIJunkMailPlugin = Components.interfaces.nsIJunkMailPlugin;
var gJunkmailComponent;
function getJunkmailComponent()
{
if (!gJunkmailComponent) {
gJunkmailComponent = Components.classes['@mozilla.org/messenger/filter-plugin;1?name=junkmail']
.getService(Components.interfaces.nsISupports).wrappedJSObject;
gJunkmailComponent.initComponent();
gJunkmailComponent = Components.classes[NS_BAYESIANFILTER_CONTRACTID].getService(nsIJunkMailPlugin);
// gJunkmailComponent.initComponent();
// who calls init method?
}
}
function analyze(aMessage, aNextFunction)
{
function callback(aScore) {
}
callback.prototype =
var listener = {
onMessageClassified: function(aMsgURL, aClassification)
{
onMessageScored: function processNext(aScore)
{
if (aMessage) {
//if (aScore == -1) debugger;
if (aScore == 0) {
aMessage.setStringProperty("score", "0");
}
else if (aScore == 1) {
aMessage.setStringProperty("score", "100");
}
}
aNextFunction();
}
};
dump(aMsgURL + ' is ' + (aClassification == nsIJunkMailPlugin.JUNK ? 'JUNK' : 'GOOD') + '\n');
var score = (aClassification == nsIJunkMailPlugin.JUNK ? "100" : "0");
aMessage.setStringProperty("score", score);
aNextFunction();
}
};
// XXX TODO jumping through hoops here.
var messageURI = aMessage.folder.generateMessageURI(aMessage.messageKey) + "?fetchCompleteMessage=true";
var messageURL = mailSession.ConvertMsgURIToMsgURL(messageURI, msgWindow);
gJunkmailComponent.calculate(messageURL, new callback);
gJunkmailComponent.classifyMessage(messageURL, listener);
}
function analyzeFolder()
@@ -509,6 +501,7 @@ function analyzeMessages()
++counter;
while (!message.isRead) {
if (counter == messages.length) {
dump('[bayesian filter message analysis complete.]\n');
gJunkmailComponent.mBatchUpdate = false;
return;
}
@@ -519,6 +512,7 @@ function analyzeMessages()
analyze(message, processNext);
}
else {
dump('[bayesian filter message analysis complete.]\n');
gJunkmailComponent.batchUpdate = false;
}
}
@@ -527,6 +521,7 @@ function analyzeMessages()
var messages = GetSelectedMessages();
var counter = 0;
gJunkmailComponent.batchUpdate = true;
dump('[bayesian filter message analysis begins.]\n');
processNext();
}
@@ -541,38 +536,22 @@ function mark(aMessage, aSpam, aNextFunction)
// XXX TODO jumping through hoops here.
var score = aMessage.getStringProperty("score");
var action;
if (aSpam) {
if (score == "100") {
// Marking a spam message as spam does nothing
return;
}
if (score == "0") {
// Marking a non-spam message as spam
action = Components.interfaces.nsIMsgFilterPlugin.hamToSpam;
}
else
action = Components.interfaces.nsIMsgFilterPlugin.unknownToSpam;
}
else {
if (score == "0") {
// Marking a non-spam message as non-spam does nothing
return;
}
if (score == "100") {
// Marking a spam message as non-spam
action = Components.interfaces.nsIMsgFilterPlugin.spamToHam;
}
else
action = Components.interfaces.nsIMsgFilterPlugin.unknownToHam;
}
var oldClassification = ((score == "100") ? nsIJunkMailPlugin.JUNK :
(score == "0") ? nsIJunkMailPlugin.GOOD : nsIJunkMailPlugin.UNCLASSIFIED);
var newClassification = (aSpam ? nsIJunkMailPlugin.JUNK : nsIJunkMailPlugin.GOOD);
var messageURI = aMessage.folder.generateMessageURI(aMessage.messageKey) + "?fetchCompleteMessage=true";
var messageURL = mailSession.ConvertMsgURIToMsgURL(messageURI, msgWindow);
gJunkmailComponent.mark(messageURL, action, aNextFunction);
var listener = (aNextFunction == null ? null :
{
onMessageClassified: function(aMsgURL, aClassification)
{
aNextFunction();
}
});
gJunkmailComponent.setMessageClassification(messageURL, oldClassification, newClassification, listener);
}
function JunkSelectedMessages(setAsJunk)
@@ -620,6 +599,7 @@ function markFolderAsJunk(aSpam)
message.setStringProperty("score","0");
}
else {
dump('[folder marking complete.]\n');
gJunkmailComponent.batchUpdate = false;
}
}
@@ -628,5 +608,6 @@ function markFolderAsJunk(aSpam)
var folder = GetFirstSelectedMsgFolder();
var messages = folder.getMessages(msgWindow);
gJunkmailComponent.batchUpdate = true;
dump('[folder marking starting.]\n');
processNext();
}

View File

@@ -47,11 +47,6 @@ interface nsIStreamListener;
[scriptable, uuid(e2e56690-a676-11d6-80c9-00008646b737)]
interface nsIMsgFilterPlugin : nsISupports
{
const long unknownToSpam = 0;
const long unknownToHam = 1;
const long hamToSpam = 2;
const long spamToHam = 3;
/**
* Initialize the plugin object.
*
@@ -61,8 +56,9 @@ interface nsIMsgFilterPlugin : nsISupports
void init(in ACString aServerPrefsKey);
/**
* Filter a message by headers.
* Filter an email message by content or headers, your choice.
*
* @param aMsgURL URL to fetch full contents of this message.
* @param aMsgHdr Can be used to set properties on the header of the
* message (e.g. for attaching a score to it).
*
@@ -78,17 +74,12 @@ interface nsIMsgFilterPlugin : nsISupports
*
* @param aMsgWindow Passed back to the listener.
*/
void filterMsgByHeaders(in nsIMsgDBHdr aMsgHdr, in unsigned long aCount,
[array, size_is(aCount)] in string aHeaders,
in nsIMsgFilterHitNotify aListener,
in nsIMsgWindow aMsgWindow);
/**
* XXX |string| -- should really be a UTF8 String
*/
void filterMsg(in string aMessageURL,
in nsIMsgDBHdr aMsgHdr,
in nsIMsgFilterHitNotify aListener);
void filterMessage(in string aMsgURL,
in nsIMsgDBHdr aMsgHdr,
in unsigned long aCount,
[array, size_is(aCount)] in string aHeaders,
in nsIMsgFilterHitNotify aListener,
in nsIMsgWindow aMsgWindow);
/**
* Do any necessary cleanup: flush and close any open files, etc.
@@ -113,3 +104,44 @@ interface nsIMsgFilterPlugin : nsISupports
};
/**
* Rather than passing low level details about scores and such, abstract
* this away by informing a listener of a message's classification, which
* can be one of 3 values: UNCLASSIFIED, GOOD, or JUNK.
*/
[scriptable, uuid(0243f3d6-d583-11d6-898a-00039310a47a)]
interface nsIJunkMailClassificationListener : nsISupports
{
void onMessageClassified(in string aMsgURL, in long classification);
};
[scriptable, uuid(caf3d467-d57c-11d6-96a9-00039310a47a)]
interface nsIJunkMailPlugin : nsIMsgFilterPlugin
{
/**
* Message classifications.
*/
const long UNCLASSIFIED = 0;
const long GOOD = 1;
const long JUNK = 2;
/**
* Given a message URL, determine what its current classification is
* according to the current training set.
*/
void classifyMessage(in string aMsgURL,
in nsIJunkMailClassificationListener aListener);
void classifyMessages(in unsigned long aCount,
[array, size_is(aCount)] in string aMsgURLs,
in nsIJunkMailClassificationListener aListener);
/**
* Called when a user forces the classification of a message. Should
* cause the training set to be updated appropriately.
*/
void setMessageClassification(in string aMsgURL,
in long aOldClassification,
in long aNewClassification,
in nsIJunkMailClassificationListener aListener);
};