Commits

Anonymous committed 28c46b7 Draft

Integrate with spambayes.

Comments (0)

Files changed (7)

detectors/mailonmsgchanges.py

 
 from roundup import roundupdb, hyperdb
 
+def is_spam(db, msgid):
+    cutoff_score = float(db.config.detectors['SPAMBAYES_SPAM_CUTOFF'])    
+
+    msg = db.getnode("msg", msgid)
+    if msg.has_key('spambayes_score') and \
+           msg['spambayes_score'] > cutoff_score:
+        return False
+    return True
+
 def mailonmsgchange(db, cl, nodeid, oldvalues):
     ''' busybody mail
     '''
     else:
         note = cl.generateChangeNote(nodeid, oldvalues)
 
-    for msgid in msgIDS:
+    for msgid in filter(lambda x: is_spam(db, x), msgIDS):
         try:
             cl.send_message(nodeid, msgid, note, sendto)
         except roundupdb.MessageSendError, message:

detectors/spambayes.py

+../../spambayes_integration/detectors/spambayes.py

extensions/spambayes.py

+../../spambayes_integration/extensions/spambayes.py

html/file.item.html

  </tr>
 
  <tr>
+  <th i18n:translate="">SpamBayes Score</th>
+  <td tal:content="structure context/spambayes_score/plain"></td>
+ </tr>
+
+ <tr>
+  <th i18n:translate="">Marked as misclassified</th>
+  <td tal:content="structure context/spambayes_misclassified/plain"></td>
+ </tr>
+
+ <tr>
   <td>
    &nbsp;
    <input type="hidden" name="@template" value="item">
 </table>
 </form>
 
-<a tal:condition="python:context.id and context.is_view_ok()"
+<p tal:condition="python:utils.sb_is_spam(context)" class="error-message">
+   File has been classified as spam.</p>
+
+<a tal:condition="python:context.id and utils.sb_is_view_ok(context)"
  tal:attributes="href string:file${context/id}/${context/name}"
  i18n:translate="">download</a>
 
+<p tal:condition="python:context.id and not utils.sb_is_view_ok(context)">
+   Files classified as spam are not available for download by
+   unathorized users. If you think the file has been misclassified,
+   please login and click on the button for reclassification.
+</p>
+
+
+     <form method="POST" onSubmit="return submit_once()"
+       enctype="multipart/form-data"
+       tal:attributes="action context/designator"
+       tal:condition="python:utils.sb_may_classify(context)">
+ 
+      <input type="hidden" name="@action" value="spambayes_classify">
+      <input type="submit" name="trainspam" value="Mark as SPAM" i18n:attributes="value">
+      <input type="submit" name="trainham" value="Mark as HAM (not SPAM)" i18n:attributes="value">
+     </form>
+
 <tal:block tal:condition="context/id" tal:replace="structure context/history" />
 
 </td>

html/issue.item.html

   </tr>
   <tr>
    <td colspan="4" class="content">
-    <pre tal:content="structure msg/content/hyperlinked">content</pre>
+    <p class="error-message"
+       tal:condition="python:utils.sb_is_spam(msg)">
+       Message has been classified as spam.
+    </p>
+    <pre tal:condition="python:utils.sb_is_view_ok(msg)"
+         tal:content="structure msg/content/hyperlinked">content</pre>
    </td>
   </tr>
  </tal:block>

html/msg.item.html

  <th i18n:translate="">Date</th>
  <td tal:content="context/date"></td>
 </tr>
+
+ <tr>
+  <th i18n:translate="">SpamBayes Score</th>
+  <td tal:content="structure context/spambayes_score/plain"></td>
+ </tr>
+
+ <tr>
+  <th i18n:translate="">Marked as misclassified</th>
+  <td tal:content="structure context/spambayes_misclassified/plain"></td>
+ </tr>
+
 </table>
 
+<p tal:condition="python:utils.sb_is_spam(context)" class="error-message">
+   Message has been classified as spam</p>
+
 <table class="messages">
  <tr><th colspan=2 class="header" i18n:translate="">Content</th></tr>
+   <th class="header" tal:condition="python:utils.sb_may_classify(context)">
+     <form method="POST" onSubmit="return submit_once()"
+       enctype="multipart/form-data"
+       tal:attributes="action context/designator">
+ 
+      <input type="hidden" name="@action" value="spambayes_classify">
+      <input type="submit" name="trainspam" value="Mark as SPAM" i18n:attributes="value">
+      <input type="submit" name="trainham" value="Mark as HAM (not SPAM)" i18n:attributes="value">
+     </form>
+   </th>
  <tr>
-  <td class="content" colspan=2><pre tal:content="structure context/content/hyperlinked"></pre></td>
+  <td class="content" colspan=2
+   tal:condition="python:utils.sb_is_view_ok(context)"><pre
+   tal:content="structure context/content/hyperlinked"></pre></td>
+  <td class="content" colspan=2
+      tal:condition="python:not utils.sb_is_view_ok(context)">
+            Message has been classified as spam and is therefore not
+      available to unathorized users. If you think this is
+      incorrect, please login and report the message as being
+      misclassified. 
+  </td> 
  </tr>
 </table>
 
                 summary=String(),
                 files=Multilink("file"),
                 messageid=String(),
-                inreplyto=String())
+                inreplyto=String(),
+                spambayes_score=Number(),
+                spambayes_misclassified=Boolean(),)
 
 file = FileClass(db, "file",
-                name=String())
+                name=String(),
+                spambayes_score=Number(),
+                spambayes_misclassified=Boolean(),)
 
 # IssueClass automatically gets these properties in addition to the Class ones:
 #   title = String()
 # See the configuration and customisation document for information
 # about security setup.
 
+db.security.addRole(name='Coordinator', description='A coordinator')
+
 #
 # REGULAR USERS
 #
 
 # Allow anonymous users access to view issues (and the related, linked
 # information)
-for cl in 'issue', 'file', 'msg', 'keyword', 'priority', 'status':
+for cl in 'issue', 'keyword', 'priority', 'status':
     db.security.addPermissionToRole('Anonymous', 'View', cl)
 
+class may_view_spam:
+    def __init__(self, klassname):
+        self.klassname = klassname
+
+    def __call__(self, db, userid, itemid):
+        cutoff_score = float(db.config.detectors['SPAMBAYES_SPAM_CUTOFF'])
+        klass = db.getclass(self.klassname)
+
+        try:
+            score = klass.get(itemid, 'spambayes_score')
+        except KeyError:
+            return True
+
+        if score > cutoff_score:
+            roles = set(db.user.get(userid, "roles").lower().split(","))
+            allowed = set(db.config.detectors['SPAMBAYES_MAY_VIEW_SPAM'].lower().split(","))
+            return bool(roles.intersection(allowed))
+
+        return True
+
+
+for cl in 'file', 'msg':
+    p = db.security.addPermission(name='View', klass=cl,
+                                  description="allowed to see metadata of file object regardless of spam status",
+                                  properties=('creation', 'activity',
+                                              'creator', 'actor',
+                                              'name', 'spambayes_score',
+                                              'spambayes_misclassified',
+                                              'author', 'recipients',
+                                              'date', 'files', 'messageid',
+                                              'inreplyto', 'type',
+                                              ))
+
+    db.security.addPermissionToRole('Anonymous', p)
+    
+    spamcheck = db.security.addPermission(name='View', klass=cl,
+                                          description="allowed to see metadata of file object regardless of spam status",
+                                          properties=('content', 'summary'),
+                                          check=may_view_spam(cl))
+    
+    db.security.addPermissionToRole('Anonymous', spamcheck)
+    
+
 # [OPTIONAL]
 # Allow anonymous users access to create or edit "issue" items (and the
 # related file and message items)