Mollom meets Pylons, the Mollom Decorator no comments
ทุกวันนี้เรื่องสแปมนับว่าเป็นปัญหาใหญ่มากบนเว็บ การแก้ไขปัญหาที่ดีต้องทำให้มัน 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