ep2008-dev

Annotated macros/VoteRecorder.py

46:2505e64ef1da
2008-03-21 Paul Boddie Remove edit signature.
paul@36 1
# -*- coding: iso-8859-1 -*-
paul@36 2
"""
paul@36 3
    MoinMoin - VoteRecorder Macro
paul@36 4
paul@36 5
    @copyright: 2008 by Paul Boddie <paul@boddie.org.uk>
paul@36 6
    @license: GNU GPL (v2 or later), see COPYING.txt for details.
paul@36 7
paul@36 8
    This is like the VotingStars macro except that votes are logged for later
paul@36 9
    counting, and the current state of the poll is not shown during voting.
paul@36 10
"""
paul@36 11
paul@37 12
from MoinMoin.util import filesys, lock
paul@36 13
from MoinMoin import wikiutil
paul@43 14
import MoinMoin.user
paul@36 15
import os
paul@37 16
try:
paul@37 17
    import cPickle as pickle
paul@37 18
except ImportError:
paul@37 19
    import pickle
paul@36 20
paul@37 21
Dependencies = ["time"]
paul@36 22
paul@37 23
def get_vote_directory(page, name):
paul@36 24
    votes_dir = page.getPagePath("poll")
paul@36 25
    if not os.path.exists(votes_dir):
paul@36 26
        filesys.makeDirs(votes_dir)
paul@37 27
    return votes_dir
paul@37 28
paul@37 29
def get_vote_pathname(page, name):
paul@37 30
    votes_dir = get_vote_directory(page, name)
paul@36 31
    filename = wikiutil.quoteWikinameFS(name)
paul@36 32
    return os.path.join(votes_dir, filename)
paul@36 33
paul@37 34
def get_lock_directory(page, name):
paul@37 35
    votes_dir = get_vote_directory(page, name)
paul@37 36
    return os.path.join(votes_dir, "__lock__")
paul@37 37
paul@37 38
def save_votes(page, poll_name, votes):
paul@37 39
    vote_lock = lock.WriteLock(get_lock_directory(page, poll_name))
paul@37 40
    vote_lock.acquire()
paul@36 41
    try:
paul@37 42
        _save_votes(page, poll_name, votes)
paul@37 43
    finally:
paul@37 44
        vote_lock.release()
paul@37 45
paul@37 46
def _save_votes(page, poll_name, votes):
paul@37 47
    path = get_vote_pathname(page, poll_name)
paul@37 48
    f = open(path, "wb")
paul@37 49
    try:
paul@37 50
        pickle.dump(votes, f)
paul@36 51
    finally:
paul@36 52
        f.close()
paul@36 53
paul@37 54
def get_all_votes(page, poll_name):
paul@37 55
    vote_lock = lock.ReadLock(get_lock_directory(page, poll_name))
paul@37 56
    vote_lock.acquire()
paul@36 57
    try:
paul@37 58
        return _get_all_votes(page, poll_name)
paul@37 59
    finally:
paul@37 60
        vote_lock.release()
paul@37 61
paul@37 62
def _get_all_votes(page, poll_name):
paul@37 63
    path = get_vote_pathname(page, poll_name)
paul@37 64
    if not os.path.exists(path):
paul@37 65
        return {}
paul@37 66
    f = open(path, "rb")
paul@37 67
    try:
paul@37 68
        voting = pickle.load(f)
paul@36 69
        return voting
paul@36 70
    finally:
paul@36 71
        f.close()
paul@36 72
paul@36 73
def execute(macro, args):
paul@36 74
    request = macro.request
paul@36 75
    form = macro.form
paul@36 76
    fmt = macro.formatter
paul@36 77
    page = fmt.page
paul@36 78
paul@36 79
    output = []
paul@36 80
paul@36 81
    # Obtain the poll name for presentation purposes.
paul@36 82
paul@36 83
    args = args.split(",")
paul@36 84
    if args:
paul@36 85
        poll_name = args[0]
paul@36 86
    else:
paul@36 87
        output.append(fmt.sysmsg(on=1))
paul@36 88
        output.append(fmt.text("Please specify a poll name!"))
paul@36 89
        output.append(fmt.sysmsg(on=0))
paul@36 90
        return ''.join(output)
paul@36 91
paul@43 92
    # Check for extra arguments.
paul@43 93
    # NOTE: This is only adequate protection if an ACL stops untrusted users
paul@43 94
    # NOTE: from editing the page. This should actually query the ACL in order
paul@43 95
    # NOTE: to prevent such exploits.
paul@43 96
paul@43 97
    public = "public" in args[1:]
paul@36 98
paul@36 99
    # Get the user, if known.
paul@43 100
    # Show a message if the user is not logged in and the poll is not public.
paul@36 101
paul@43 102
    if not public and not request.user.valid:
paul@36 103
        output.append(fmt.emphasis(on=1))
paul@36 104
        output.append(fmt.text("Please log in to vote!"))
paul@36 105
        output.append(fmt.emphasis(on=0))
paul@36 106
        return ''.join(output)
paul@36 107
paul@43 108
    username = MoinMoin.user.getUserIdentification(request)
paul@43 109
    #username = request.user.valid and request.user.name or request.user.host()
paul@37 110
    votes = get_all_votes(page, poll_name)
paul@36 111
paul@36 112
    # Handle any vote.
paul@36 113
paul@36 114
    if form and form.has_key("vote") and form.has_key("poll"):
paul@36 115
        poll = form["poll"][0]
paul@36 116
        if poll == poll_name:
paul@37 117
            votes[username] = int(form["vote"][0])
paul@37 118
            save_votes(page, poll_name, votes)
paul@36 119
            output.append(fmt.emphasis(on=1))
paul@36 120
            output.append(fmt.text("Vote submitted!"))
paul@36 121
            output.append(fmt.emphasis(on=0))
paul@36 122
            return ''.join(output)
paul@36 123
paul@36 124
    # Show the choices.
paul@36 125
paul@36 126
    values = {
paul@36 127
        "poll" : poll_name, "url" : page.url(request),
paul@36 128
        "on_image" : '/wiki/modern/img/star_on.png',
paul@36 129
        "off_image" : '/wiki/modern/img/star_off.png'
paul@36 130
        }
paul@36 131
    choices = range(1, 6)
paul@36 132
paul@36 133
    output.append(fmt.rawHTML('<form method="get" name="%(poll)s" action="%(url)s#%(poll)s">' % values))
paul@36 134
    output.append(fmt.rawHTML('<input type="hidden" name="poll" value="%(poll)s">' % values))
paul@37 135
paul@36 136
    for choice in choices:
paul@36 137
        values["choice"] = choice
paul@37 138
        if votes.has_key(username) and choice <= votes[username]:
paul@37 139
            values["default_image"] = values["on_image"]
paul@37 140
        else:
paul@37 141
            values["default_image"] = values["off_image"]
paul@36 142
        output.append(
paul@36 143
            fmt.rawHTML('''
paul@37 144
                <input type="image" name="vote" value="%(choice)s" src="%(default_image)s"
paul@37 145
                    onmouseover="this.src='%(on_image)s'"
paul@37 146
                    onmouseout="this.src='%(default_image)s'">
paul@36 147
                ''' % values))
paul@37 148
paul@36 149
    output.append(fmt.rawHTML('</form>'))
paul@36 150
paul@36 151
    return ''.join(output)
paul@36 152
paul@36 153
# vim: tabstop=4 expandtab shiftwidth=4