COREBlog でも SpamBayes を使う
もう冬眠すれば良いのにコメントスパムが大量に発生してます。
今回はこのブログでも SpamBayes を利用しフィルタリングしてみました。
Spam データベースは
BBS 用に作成したもの
をそのまま利用したので楽でしたし、結果は良好。
以下の説明は COREBlog の中から SpamDB (JSpamFilter インスタンス) が呼び出せるものとしてあります。 たとえば SpamDB は Zope のルート直下に置きます。
1. Spam確率値を得るスクリプト
まず Spam確率値を得る Python Script メソッドを追加します。 COREBlog から呼び出せるフォルダに probSpam と云う名前で保存します。 私の環境では COREBlog インスタンス直下に methods と云うフォルダが作ってあるので、 その中に置きました。
## Script (Python) "probSpam"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=body='',name='',addr=''
##title=スパム値を得る
##
from Products.PythonScripts.standard import html_quote
request = container.REQUEST
response = request.response
body = html_quote(body)
name = html_quote(name)
addr = html_quote(addr)
r = container.SpamDB.prob(body, name, addr)
return ('%.2f') % (r * 100,)
これを呼び出すには COREBlog エントリ表示を修正します。 修正するソースは COREBlog/dtml ディレクトリ内にある manage_listCommentForm.dtml です。 そうすれば先頭に表示してあるような画像がみられます。 (なんて不親切な;;)
<td align="left" valign="top">
<dtml-var "methods.probSpam(body, author, url)"> %
</td>
2. コメント編集画面の修正
次に SpamDB をトレーニングしないといけません。
それはコメント編集画面でおこないます。
コメント編集画面 manage_editCommentForm.dtml の先頭あたりに次のコードを挿入します。
<p class="form-help">Spam Comment informations.</p>
<table border="0" cellpadding="0" cellspacing="1">
<dtml-with "getComment(comment_id=comment_id)">
<form action="methods" METHOD="POST">
<input type="hidden" name="SpamName" value="<dtml-var author html_quote missing="">" />
<input type="hidden" name="SpamAddr" value="<dtml-var url html_quote missing="">" />
<input type="hidden" name="SpamBody" value="<dtml-var body html_quote missing="">" />
<tr>
<td align="left" valign="top">
<div class="form-label">
Spam:
<dtml-var "methods.probSpam(body, author, url)"> %
</div>
<input class="form-element" type="submit"
name="trainAsGood:method" value="Train as Good" />
<input class="form-element" type="submit"
name="trainAsSpam:method" value="Train as Spam" />
</td>
</tr>
</form>
</dtml-with>
</table>
ここで trainAsGood, trainAsSpam と云う二つの新しいメソッドがあります。 ともに引数なしの Python Script です。
request = container.REQUEST
response = request.response
body = request.get('SpamBody', '')
name = request.get('SpamName', '')
addr = request.get('SpamAddr', '')
container.SpamDB.trainAsGood(body, name, addr)
return response.redirect(request['HTTP_REFERER'])
request = container.REQUEST
response = request.response
body = request.get('SpamBody', '')
name = request.get('SpamName', '')
addr = request.get('SpamAddr', '')
container.SpamDB.trainAsSpam(body, name, addr)
return response.redirect(request['HTTP_REFERER'])
3. フィルタリング
最後にフィルタリングスクリプト beforeAddComment です。
## Script (Python) "beforeAddComment"
##bind container=container
##bind context=context
##bind namespace=
##bind script=script
##bind subpath=traverse_subpath
##parameters=md
##title=コメント受付チェック(SpamBayes版)
##
if md.get('moderated', 0):
try:
from Products.PythonScripts.standard import html_quote
body = html_quote(md.get('body', ''))
name = html_quote(md.get('author', ''))
addr = html_quote(md.get('url', ''))
r = container.SpamDB.prob(body, name, addr)
if r > 0.4:
md['moderated'] = 0
except:
pass
return md