"""
This plugin reduces comment spam by requiring that the user answer a simple
question to help ensure that they are an actual person and not a spambot.

A random question is selected when a story is displayed and the answer for that
question is stored in the user's session. When a comment submission is received
the user's answer is compared against the answer stored in the session.

The question is written to the "spam_question" template variable. The user's
answer is expected in a "spam_answer" form variable. These two items need to be
added to the comment form template of your blog.

A single configuration variable is required:

  spam_questions
    datatype:       [(question, answer), ...]
    default value:  []
    description:    The question/answer spam question pairs 
    example:        
        py['spam_questions'] = (
            ('What is the name of our planet?', 'earth'),
            ('What is the first letter of the alphabet?', 'a'),
        )


This plugin was inspired by the nospam and Magic Word plugins.

Requires: The "comments" plugin and the "session" plugin.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Copyright 2007 Menno Smits
"""

__author__ = 'Menno Smits'
__version__ = '0.2'
__url__ = "http://freshfoo.com/code/"
__description__ = "Asks a randomly selected question to confirm a " \
    "comment poster is a real person."  

from Pyblosxom import tools
import random
import time

SESSION_KEY = 'spamquestion_answer'

def verify_installation(request):
    config = request.getConfiguration()

    questions = _get_questions(request)
    if not questions:
        print "Missing config property 'spam_questions'."
        print "The spamquestion plugin will not function if this option is not set."
        return 0

    return 1

def cb_story(args):
    log = tools.getLogger()
    request = args['request']
    log.debug('adding spam question')

    all_questions = _get_questions(request)
    if not all_questions:
        log.error('no spam questions configured')
        return args['template']

    question, answer = random.choice(all_questions)

    session = request.getSession()
    session[SESSION_KEY] = answer
    session.save()

    entry = args['entry']
    entry['spam_question'] = question
    log.debug('spam_question is: %r' % question)
    return args['template']

def cb_comment_reject(args):
    """
    Verifies that the commenter answered with the correct answer.
    """
    log = tools.getLogger()
    request = args['request']
    session = request.getSession()

    request = args['request']
    log.debug('checking spam answer')

    all_questions = _get_questions(request)
    if not all_questions:
        # No questions set so just allow the comment 
        log.error('no spam questions set, allowing comment')
        return False

    try:
        answer = session[SESSION_KEY]
    except KeyError:
        log.debug('no spamquestion entry in session, rejecting comment')
        return True

    form = request.getForm()
    try:
        form_answer = form["spam_answer"].value.strip().lower()
        if form_answer == answer:
            log.debug('spam question answered correctly')
            return False
        else:
            log.debug('incorrect answer, got %r, expected %r', form_answer,
                answer)
    except KeyError:
        log.debug('missing spam_answer in form data, rejecting comment')
        pass
    return True

def _get_questions(request):
    """Return the quetions from the config.
    """
    config = request.getConfiguration()
    return config.get('spam_questions', None)
