[Python-checkins] r56582 - in tracker/instances/python-dev: detectors/busybody.py detectors/config.ini.template detectors/no_texthtml.py detectors/spambayes.py detectors/spamcheck.py detectors/tellteam.py detectors/userauditor.py extensions/spambayes.py html/file.item.html html/issue.item.html html/msg.item.html schema.py
erik.forsberg
python-checkins at python.org
Fri Jul 27 18:26:27 CEST 2007
Author: erik.forsberg
Date: Fri Jul 27 18:26:26 2007
New Revision: 56582
Added:
tracker/instances/python-dev/detectors/spambayes.py
- copied unchanged from r56581, tracker/instances/python-dev-spambayes-integration/detectors/spambayes.py
tracker/instances/python-dev/extensions/spambayes.py
- copied unchanged from r56581, tracker/instances/python-dev-spambayes-integration/extensions/spambayes.py
Removed:
tracker/instances/python-dev/detectors/spamcheck.py
Modified:
tracker/instances/python-dev/detectors/busybody.py
tracker/instances/python-dev/detectors/config.ini.template
tracker/instances/python-dev/detectors/no_texthtml.py
tracker/instances/python-dev/detectors/tellteam.py
tracker/instances/python-dev/detectors/userauditor.py
tracker/instances/python-dev/html/file.item.html
tracker/instances/python-dev/html/issue.item.html
tracker/instances/python-dev/html/msg.item.html
tracker/instances/python-dev/schema.py
Log:
Merged python-dev-spambayes-integration rev 56581 down to python-dev
Modified: tracker/instances/python-dev/detectors/busybody.py
==============================================================================
--- tracker/instances/python-dev/detectors/busybody.py (original)
+++ tracker/instances/python-dev/detectors/busybody.py Fri Jul 27 18:26:26 2007
@@ -22,6 +22,16 @@
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 busyreaction(db, cl, nodeid, oldvalues):
''' busybody mail
'''
@@ -36,7 +46,7 @@
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:
Modified: tracker/instances/python-dev/detectors/config.ini.template
==============================================================================
--- tracker/instances/python-dev/detectors/config.ini.template (original)
+++ tracker/instances/python-dev/detectors/config.ini.template Fri Jul 27 18:26:26 2007
@@ -12,3 +12,6 @@
spambayes_ham_cutoff = 0.2
spambayes_spam_cutoff = 0.85
+spambayes_may_view_spam = User,Coordinator,Developer
+spambayes_may_classify = Coordinator
+spambayes_may_report_misclassified = User,Coordinator,Developer
Modified: tracker/instances/python-dev/detectors/no_texthtml.py
==============================================================================
--- tracker/instances/python-dev/detectors/no_texthtml.py (original)
+++ tracker/instances/python-dev/detectors/no_texthtml.py Fri Jul 27 18:26:26 2007
@@ -1,6 +1,6 @@
def audit_html_files(db, cl, nodeid, newvalues):
- if newvalues['type'] == 'text/html':
+ if newvalues.has_key('type') and newvalues['type'] == 'text/html':
newvalues['type'] = 'text/plain'
Deleted: /tracker/instances/python-dev/detectors/spamcheck.py
==============================================================================
--- /tracker/instances/python-dev/detectors/spamcheck.py Fri Jul 27 18:26:26 2007
+++ (empty file)
@@ -1,38 +0,0 @@
-"""
-spamcheck.py - Auditor that consults a SpamBayes server and scores all form
-submissions. Submissions which are deemed to be spam are rejected. For the
-time being only reject submissions which are assumed to be spam (score >=
-SPAM_CUTOFF). Once a reasonable body of ham and spam submissions have been
-built up you can consider whether to also reject unsure submissions (score >
-HAM_CUTOFF). The current settings make it less likely that you'll reject
-valid submissions at the expense of manual checks to correct spammy items
-which snuck by the screen.
-"""
-
-import xmlrpclib
-import socket
-
-from roundup.exceptions import Reject
-
-def check_spam(_db, _klass, _nodeid, newvalues):
- """Auditor to score a website submission."""
-
- spambayes_uri = _db.config.detectors['SPAMBAYES_URI']
- spam_cutoff = float(_db.config.detectors['SPAMBAYES_SPAM_CUTOFF'])
-
-
- server = xmlrpclib.ServerProxy(spambayes_uri, verbose=False)
- try:
- prob = server.score(newvalues, [], {})
- except (socket.error, xmlrpclib.Error), e:
- pass
- else:
- if prob >= spam_cutoff:
- raise Reject("Looks like spam to me - prob=%.3f" % prob)
-
-def init(database):
- """Initialize auditor."""
- database.issue.audit('create', check_spam)
- database.issue.audit('set', check_spam)
- database.file.audit('create', check_spam)
- database.file.audit('set', check_spam)
Modified: tracker/instances/python-dev/detectors/tellteam.py
==============================================================================
--- tracker/instances/python-dev/detectors/tellteam.py (original)
+++ tracker/instances/python-dev/detectors/tellteam.py Fri Jul 27 18:26:26 2007
@@ -1,5 +1,14 @@
from roundup import roundupdb
+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 newissuetriage(db, cl, nodeid, oldvalues):
''' Copy a message about new issues to a triage address,
set in detectors/config.ini
@@ -14,9 +23,10 @@
triage_email = []
if not triage_email:
return
- for msgid in cl.get(nodeid, 'messages'):
+ for msgid in filter(lambda x: is_spam(db, x), cl.get(nodeid, 'messages')):
try:
# note: last arg must be a list
+
cl.send_message(nodeid, msgid, change_note, triage_email)
except roundupdb.MessageSendError, message:
raise roundupdb.DetectorError, message
Modified: tracker/instances/python-dev/detectors/userauditor.py
==============================================================================
--- tracker/instances/python-dev/detectors/userauditor.py (original)
+++ tracker/instances/python-dev/detectors/userauditor.py Fri Jul 27 18:26:26 2007
@@ -36,7 +36,7 @@
raise ValueError, 'Role "%s" does not exist'%rolename
if None != nodeid and "admin" in roles:
- if not "admin" in [x.lower().strip() for x in cl.get(nodeid, 'roles')]:
+ if not "admin" in [x.lower().strip() for x in cl.get(nodeid, 'roles').split(",")]:
raise ValueError, "Only Admins may assign the Admin role!"
Modified: tracker/instances/python-dev/html/file.item.html
==============================================================================
--- tracker/instances/python-dev/html/file.item.html (original)
+++ tracker/instances/python-dev/html/file.item.html Fri Jul 27 18:26:26 2007
@@ -29,8 +29,17 @@
<td style="border: none" tal:condition="python: context.is_edit_ok()">Please note that
for security reasons, it's not permitted to set content type to <i>text/html</i>.</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>
+
+ <tr tal:condition="python:context.is_edit_ok()">
<td>
<input type="hidden" name="@template" value="item">
@@ -44,10 +53,30 @@
</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>
Modified: tracker/instances/python-dev/html/issue.item.html
==============================================================================
--- tracker/instances/python-dev/html/issue.item.html (original)
+++ tracker/instances/python-dev/html/issue.item.html Fri Jul 27 18:26:26 2007
@@ -243,7 +243,12 @@
</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>
Modified: tracker/instances/python-dev/html/msg.item.html
==============================================================================
--- tracker/instances/python-dev/html/msg.item.html (original)
+++ tracker/instances/python-dev/html/msg.item.html Fri Jul 27 18:26:26 2007
@@ -47,12 +47,50 @@
<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>
+
+ <tr>
+ <th class="header" i18n:translate="">Content</th>
+ <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>
+
<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>
Modified: tracker/instances/python-dev/schema.py
==============================================================================
--- tracker/instances/python-dev/schema.py (original)
+++ tracker/instances/python-dev/schema.py Fri Jul 27 18:26:26 2007
@@ -97,10 +97,14 @@
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()
@@ -141,12 +145,59 @@
##########################
# User permissions
##########################
+
for cl in ('issue_type', 'severity', 'component',
'version', 'priority', 'status', 'resolution',
- 'issue', 'file', 'msg', 'keyword'):
+ 'issue', 'keyword'):
db.security.addPermissionToRole('User', 'View', cl)
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)
+ db.security.addPermissionToRole('User', 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('User', spamcheck)
+ db.security.addPermissionToRole('Anonymous', spamcheck)
+
+
+
for cl in 'file', 'msg':
db.security.addPermissionToRole('User', 'Create', cl)
@@ -264,7 +315,7 @@
# Allow anonymous users access to view issues (and the related, linked
# information)
-for cl in 'issue', 'file', 'msg', 'severity', 'status', 'resolution':
+for cl in 'issue', 'severity', 'status', 'resolution':
db.security.addPermissionToRole('Anonymous', 'View', cl)
# [OPTIONAL]
More information about the Python-checkins
mailing list