Mollom meets Pylons, the Mollom Decorator   no comments

Posted at 9:52 pm in Wired

ทุกวันนี้เรื่องสแปมนับว่าเป็นปัญหาใหญ่มากบนเว็บ การแก้ไขปัญหาที่ดีต้องทำให้มัน transparent ที่สุดเท่าที่จะเป็นได้—ก็คือต้องให้ผู้ใช้สามารถใช้งานเว็บได้ปกติ โดยไม่จำเป็นต้องสนใจว่ามีระบบป้องกันอะไรอยู่ ทางเลือกที่เหลืออยู่จึงกลายเป็นการใช้บริการต่อต้านสแปมอย่าง Akismet หรือ Mollom ที่จะทำให้ผู้ใช้มีส่วนเกี่ยวข้องน้อยที่สุดในกระบวนการ

ส่วนตัวแล้วผมเลือกใช้ Mollom ส่วนหนึ่งเพราะลิมิท API call ไว้สูงที่ 100,000 calls ต่อเดือน และเป็นบริการโดยผู้สร้าง Drupal ส่วนอีกเหตุผลหลักอีกอันหนึ่งก็คือจะใช้สแปมฟิลเตอร์ผสม CAPTCHA อยู่แล้ว ก็เลยไม่ลำบาก ใช้อันที่มีอยู่แล้วไปเลยดีกว่า

เนื่องจากว่าในเว็บ จำเป็นต้องเรียกใช้ Mollom หลายที่มาก ในหลายๆ ส่วนที่ structure ภายในค่อนข้างต่างกันพอสมควร เลยคิดว่าเป็นไอเดียที่ดี ถ้าหากจะทำ Mollom Decorator ขึ้นมาใช้ในกรณีนี้ในรูปแบบนี้

1
2
3
4
5
6
7
@checkspam(content_field='comment')
def comment_save(self, id):
    comment = Comment()
    comment.post_id = id
    comment.content = request.POST.get('comment')
    Session.save(comment)
    Session.commit()

โชคดีที่มี Mollom wrapper บน Python อยู่แล้วโดย Andy Georges ดังนั้นก็พอจะเอามาใช้งานทำ Mollom Decorator ได้เลย โดยไม่ต้องไปวุ่นวายกับ API call อะไรต่อมิอะไรเอง

ก่อนอื่นก็ import Mollom wrapper และสร้าง mollom instance ก่อน ส่วนตัวแล้วผมโยนมันไว้ใน appname/lib/util.py

1
2
3
4
# Mollom wrapper by Andy Georges
# http://itkovian.net/base/python-wrapper-mollom
import Mollom
mollom = MollomAPI(publicKey="yourkeyhere", privateKey="yourkeyhere")

แล้วก็โยนโค้ดนี่ลงไปที่ไหนซักแห่ง เช่นว่า appname/lib/decorators.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
from decorator import decorator
from pylons import c, request, session
from pylons.templating import render
 
from appname.lib.util import mollom
 
def checkspam(content_field=None, title_field=None):
    def wrapper(func, self, *args, **kwargs):
        if mollom:
            session_id = None
            title = request.POST.get(title_field, None)
            content = request.POST.get(content_field, None)
            if 'HTTP_X_FORWARDED_FOR' in request.environ:
                ipaddr = request.environ.get('HTTP_X_FORWARDED_FOR', None)
            else: ipaddr = request.environ.get('REMOTE_ADDR', None)
            if "mollom_session" in session:
                session_id = session['mollom_session']
                if "solution" in request.POST:
                    solution = request.POST.get('solution', '')
                    if mollom.checkCaptcha(sessionID=session_id,
                                           solution=solution) == True:
                        return func(self, *args, **kwargs)
            result = mollom.checkContent(sessionID=session_id, authorIP=ipaddr,
                                         postTitle=title, postBody=content)
            if not "mollom_session" in session:
                session_id = result['session_id']
                session['mollom_session'] = result['session_id']
                session.save()
            if result['spam'] != 1:
                if result['spam'] == 3:
                    captcha = mollom.getImageCaptcha(sessionID=session_id)
                    c.chance = True
                    c.contents = request.POST
                    c.captcha = captcha['url']
                return render("/spam.mako")
        return func(self, *args, **kwargs)
    return decorator(wrapper)

แล้วก็สร้าง spam.mako ไว้ใน appname/templates/ หน้าตาประมาณนี้

1
2
3
4
5
6
7
8
9
10
11
12
% if c.chance:
  <form method="post">
    <img src="${c.captcha}" alt="CAPTCHA" width="110" height="50" />
    ${h.text_field('solution')}
    ${h.submit('Proceed', name='proceed')}
    % for r in c.contents:
      ${h.hidden_field(r, value=c.contents[r])}
    % endfor
  </form>
% else:
  <p>You're blocked</p>
% endif

สุดท้ายก็ไป import มันใน lib/base.py

1
from appname.lib.decorators import checkspam

แล้วก็จะสามารถเรียกใช้ใน controller ได้ทันที โดยไม่ต้องเขียนซ้ำไปซ้ำมา พร้อมจัดการเรื่องส่ง IP address กลับไปยัง Mollom ให้เสร็จสรรพ เท่านี้ก็น่าจะ OK

Written by Sirn on August 18th, 2008

Tagged with , , ,

Leave a Reply