Update of /cvsroot/mahogany/M/src/modules/spam
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24290/src/modules/spam

Modified Files:
        DspamFilter.cpp 
Log Message:
added Train button to dspam page

Index: DspamFilter.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/modules/spam/DspamFilter.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -b -u -2 -r1.4 -r1.5
--- DspamFilter.cpp     11 Jul 2004 19:04:36 -0000      1.4
+++ DspamFilter.cpp     11 Jul 2004 20:29:47 -0000      1.5
@@ -27,5 +27,8 @@
 #endif //USE_PCH
 
+#include "MFolder.h"
+#include "MailFolder.h"
 #include "Message.h"
+#include "HeaderInfo.h"
 
 #include "SpamFilter.h"
@@ -41,4 +44,11 @@
 
 // ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// currently we always use the same user name...
+static const char *M_DSPAM_USER = "mahogany";
+
+// ----------------------------------------------------------------------------
 // DspamCtx simple wrapper around DSPAM_CTX
 // ----------------------------------------------------------------------------
@@ -78,4 +88,12 @@
    DspamFilter();
 
+   // these public methods are used by GUI class (DspamOptionsPage below)
+
+   // show dspam statistics to the user
+   void ShowStats(wxWindow *parent);
+
+   // train dsapm
+   void Train(wxWindow *parent);
+
 protected:
    virtual void DoReclassify(const Message& msg, bool isSpam);
@@ -138,8 +156,58 @@
                       _T("(c) 2004 Vadim Zeitlin <[EMAIL PROTECTED]>"));
 
+// ----------------------------------------------------------------------------
+// DspamOptionsPage
+// ----------------------------------------------------------------------------
+
+class DspamOptionsPage : public wxOptionsPageDynamic
+{
+public:
+   DspamOptionsPage(DspamFilter *filter,
+                    wxNotebook *parent,
+                    const wxChar *title,
+                    Profile *profile,
+                    FieldInfoArray aFields,
+                    ConfigValuesArray aDefaults,
+                    size_t nFields,
+                    int image = -1)
+      : wxOptionsPageDynamic
+        (
+            parent,
+            title,
+            profile,
+            aFields,
+            aDefaults,
+            nFields,
+            0,          // offset
+            -1,         // help id
+            image
+        )
+   {
+      m_filter = filter;
+   }
+
+protected:
+   void OnButton(wxCommandEvent& event);
+
+private:
+   DspamFilter *m_filter;
+
+   DECLARE_EVENT_TABLE()
+};
+
+BEGIN_EVENT_TABLE(DspamOptionsPage, wxOptionsPageDynamic)
+   EVT_BUTTON(wxID_ANY, DspamOptionsPage::OnButton)
+END_EVENT_TABLE()
+
+
+
 // ============================================================================
 // DspamFilter implementation
 // ============================================================================
 
+// ----------------------------------------------------------------------------
+// DspamFilter public API implementation
+// ----------------------------------------------------------------------------
+
 DspamFilter::DspamFilter()
 {
@@ -155,5 +223,5 @@
    DspamCtx ctx(dspam_init
                 (
-                  "mahogany",
+                  M_DSPAM_USER,
                   NULL,
                   DSM_PROCESS,
@@ -245,10 +313,133 @@
 
 // ----------------------------------------------------------------------------
+// DspamFilter other (private) methods
+// ----------------------------------------------------------------------------
+
+void DspamFilter::ShowStats(wxWindow *parent)
+{
+   DspamCtx ctx(dspam_init(M_DSPAM_USER, NULL, DSM_CLASSIFY, 0));
+
+   if ( !ctx )
+   {
+      ERRORMESSAGE((_("DSPAM: library initialization failed.")));
+
+      return;
+   }
+
+   const _ds_spam_totals& t = ctx->totals;
+   wxMessageBox
+   (
+      wxString::Format
+      (
+        _T("Total Spam:\t%6ld\n")
+        _T("Total Innocent:\t%6ld\n")
+        _T("Spam Misclassified:\t%6ld\n")
+        _T("Innocent Misclassified:\t%6ld\n")
+        _T("Spam Corpusfed:\t%6ld\n")
+        _T("Innocent Corpusfed:\t%6ld\n")
+        _T("Training Left:\t%6ld\n"),
+        wxMax(0, t.spam_learned +
+                 t.spam_classified -
+                 t.spam_misclassified -
+                 t.spam_corpusfed),
+        wxMax(0, t.innocent_learned +
+                 t.innocent_classified -
+                 t.innocent_misclassified -
+                 t.innocent_corpusfed),
+        t.spam_misclassified,
+        t.innocent_misclassified,
+        t.spam_corpusfed,
+        t.innocent_corpusfed,
+        wxMax(0, 2500 - (t.innocent_learned + t.innocent_classified))
+      ),
+      _("DSPAM Statistics"),
+      wxOK | wxICON_INFORMATION,
+      parent
+   );
+}
+
+void DspamFilter::Train(wxWindow *parent)
+{
+   MFolder_obj folder(MDialog_FolderChoose(parent, NULL, MDlg_Folder_Open));
+   if ( !folder )
+      return;
+
+   const String name = folder->GetFullName();
+
+   bool isSpam;
+   switch ( MDialog_YesNoCancel
+            (
+               wxString::Format
+               (
+                  _("Does the folder \"%s\" contain spam?"),
+                  name.c_str()
+               ),
+               parent,
+               _("Choose DSPAM training mode")
+            ) )
+   {
+      case MDlg_Yes:
+         isSpam = true;
+         break;
+
+      case MDlg_No:
+         isSpam = false;
+         break;
+
+      default:
+         FAIL_MSG( _T("unexpected MDialog_YesNoCancel() result") );
+         // fall through
+
+      case MDlg_Cancel:
+         return;
+   }
+
+   MailFolder_obj mf(MailFolder::OpenFolder(folder, MailFolder::ReadOnly));
+   if ( !mf )
+   {
+      wxLogError(_("Failed to open folder \"%s\" with training messages."),
+                 name.c_str());
+      return;
+   }
+
+   // FIXME: this is horribly inefficient, we have to use UIDs while we
+   //        simply want to get all messages!
+
+   HeaderInfoList_obj hil(mf->GetHeaders());
+   if ( !hil )
+   {
+      wxLogError(_("Failed to get headers of the training messages."));
+      return;
+   }
+
+   const size_t count = hil->Count();
+   for ( size_t n = 0; n < count; n++ )
+   {
+      HeaderInfo *hi = hil->GetItemByIndex(n);
+      if ( hi )
+      {
+         Message_obj msg(mf->GetMessage(hi->GetUId()));
+         if ( msg )
+         {
+            DoTrain(*msg, isSpam);
+
+            continue;
+         }
+      }
+
+      wxLogWarning(_("Failed to retrieve message #%lu."));
+   }
+}
+
+// ----------------------------------------------------------------------------
 // DspamFilter user-configurable options
 // ----------------------------------------------------------------------------
 
+// TODO: add "Clean"
+
 enum
 {
    DspamPageField_Help,
+   DspamPageField_Train,
    DspamPageField_ShowStats,
    DspamPageField_Max
@@ -260,10 +451,30 @@
    {
       {
-         gettext_noop("This page allows you to configure DSPAM,\n"
-                      "a powerful statistical hybrid anti-spam filter."),
+         gettext_noop
+         (
+            "This page allows you to configure DSPAM,\n"
+            "a powerful statistical hybrid anti-spam filter.\n"
+            "\n"
+            "Before it can be used with maximal efficiency, DSPAM\n"
+            "has to be trained, that is fed some known spam and\n"
+            "non-spam (ham) messages. The simplest way to do this\n"
+            "is to use the buttons below to train using all messages\n"
+            "from an existing folder. You can also check the statistics\n"
+            "to see how much training is still required.\n"
+            "\n"
+            "Alternatively, you can start using DSPAM immediately, but\n"
+            "then it would probably misclassify some of the messages and\n"
+            "you would need to correct it using the \"Message|Spam\" menu\n"
+            "entries."
+         ),
          wxOptionsPage::Field_Message,
          -1
       },
       {
+         gettext_noop("&Train..."),
+         wxOptionsPage::Field_SubDlg,
+         -1
+      },
+      {
          gettext_noop("Show &statistics"),
          wxOptionsPage::Field_SubDlg,
@@ -280,12 +491,14 @@
       ConfigValueNone(),
       ConfigValueNone(),
+      ConfigValueNone(),
    };
 
-   wxCOMPILE_TIME_ASSERT2( WXSIZEOF(s_fields) == DspamPageField_Max,
+   wxCOMPILE_TIME_ASSERT2( WXSIZEOF(s_values) == DspamPageField_Max,
                               ValuesNotInSync, DspamValues );
 
 
-   return new wxOptionsPageDynamic
+   return new DspamOptionsPage
               (
+                  const_cast<DspamFilter *>(this),
                   notebook,
                   gettext_noop("DSPAM"),
@@ -294,8 +507,28 @@
                   s_values,
                   DspamPageField_Max,
-                  0,          // offset
-                  -1,         // help id
                   notebook->GetPageCount()      // image id
               );
 }
 
+// ============================================================================
+// DspamOptionsPage implementation
+// ============================================================================
+
+void DspamOptionsPage::OnButton(wxCommandEvent& event)
+{
+   wxObject * const obj = event.GetEventObject();
+   if ( obj == GetControl(DspamPageField_ShowStats) )
+   {
+      m_filter->ShowStats(this);
+   }
+   else if ( obj == GetControl(DspamPageField_Train) )
+   {
+      m_filter->Train(this);
+   }
+   else
+   {
+      event.Skip();
+   }
+}
+
+



-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to