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