Attachment 'vote2_moin12.py'

Download

   1 #format python
   2 '''
   3     Simple Vote macro for MoinMoin.
   4     Author: Martin Stone <martins@evos.net>
   5     Hacked by: John Cocula (john@cocula.com)
   6                Thomas Waldmann
   7 
   8     Usage:
   9         [[Vote(pageName, voteTitle, candidate1, ...)]]
  10 
  11     E.g:
  12         [[Vote(MyBlog, Do polls work?, yes)]]
  13     
  14     Just like Martin's Vote macro, except you must specify the name of the
  15     page on which to vote "appears."  Without this information, when a user
  16     votes from an included page, after pressing the Vote button they are
  17     returned to the included page, not the main page.  Also different is
  18     that the current number of votes is hidden until the user has voted.
  19     Lastly, it is possible to have a poll that only has one choice, which
  20     is kind of funny.  The remainder of the description is Martin's:
  21 
  22     You can have multiple votes on one page (so long as the titles are unique).
  23     You can add candidates after a vote has started, but note that renaming 
  24     candidates will lose the votes (and not allow users to recast their votes).
  25     Changing the vote title creates a new vote.
  26 
  27     Vote data is stored in data_dir/pages/pagename/votes 
  28     (i.e. alongside the attachments directory for a page).
  29 
  30     You can customise the appearance by defining the following CSS styles:
  31         table.vote 
  32         td.votelogin (for "must login" message)
  33 '''
  34 
  35 import os, pickle
  36 from MoinMoin import wikiutil
  37 from MoinMoin.util import filesys
  38 
  39 def makeFilename(thisPage, voteName):
  40     votesDir = wikiutil.getPagePath(thisPage, 'votes')
  41     if not os.path.exists(votesDir):
  42         filesys.makeDirs(votesDir)
  43     voteName = wikiutil.quoteFilename(voteName) + '.pik'
  44     return os.path.join(votesDir, voteName)
  45 
  46 def loadVotes(thisPage, voteName):
  47     votesFile = makeFilename(thisPage, voteName)
  48     try:
  49         f = open(votesFile, 'r')
  50         return pickle.load(f)
  51     except: # XXX
  52         return {}
  53 
  54 def saveVotes(thisPage, voteName, votes):
  55     votesFile = makeFilename(thisPage, voteName)
  56     f = open(votesFile, 'w')
  57     pickle.dump(votes, f)
  58 
  59 def countVotes(votes):
  60     results = {}
  61     for v in votes.values():
  62         results.setdefault(v, 0)
  63         results[v] += 1
  64     return results
  65 
  66 def execute(macro, args):
  67     args = args.split(",")
  68     args = map(str.strip, args)
  69 
  70     if len(args) < 3:
  71         return macro.formatter.rawHTML('<pre>[[Vote: Insufficient macro arguments]]</pre>')
  72 
  73     pageName = args[0]
  74     voteName = args[1]
  75     candidates = args[2:]
  76 
  77     form = macro.form
  78     request = macro.request
  79     if request.user.valid:
  80         voter = request.user.name
  81     else:
  82         voter = ''
  83     thisPage = macro.formatter.page
  84     thisPageName = thisPage.page_name
  85     votes = loadVotes(thisPageName, voteName)
  86 
  87     # votes are stored in a dictionary as {user: candidate} to avoid duplicate votes
  88     # (a voter could switch their vote but this UI doesn't expose that facility)
  89     if form.has_key('vote') and form.has_key('voteName') and voter:
  90         if form['voteName'][0] == voteName:
  91             votes[voter] = form['vote'][0]
  92             try:
  93                saveVotes(thisPageName, voteName, votes)
  94             except: # XXX
  95                return macro.formatter.rawHTML('<a id="voteform"><pre>[[Vote: failed to store vote]]</pre>')
  96 
  97     # generate dictionary {candidate: numvotes}
  98     results = countVotes(votes)
  99 
 100     hasVoted = voter in votes
 101 
 102     # spit out votes table (as part of a form if the user hasn't voted yet)
 103     html = ''
 104     if voter and not hasVoted:
 105         voteButton = '<td><input type="radio" name="vote" value="%s">vote</td>'
 106         html += '''
 107             <form method="get" action="%(url)s#voteform">\n
 108             <input type="hidden" name="voteName" value="%(voteName)s">
 109             ''' % {
 110                 'url': thisPage.url(request),
 111                 'voteName': voteName,
 112             }
 113     else:
 114         voteButton = ''
 115 
 116     html += '<a id="voteform"><table class="vote"><tr><th colspan="2">%s</th></tr>' % voteName
 117 
 118     for candidate in candidates:
 119         button = voteButton and (voteButton % candidate)
 120         if voter:
 121             if hasVoted:
 122                 button = candidate
 123                 count = results.setdefault(candidate, 0)
 124             else:
 125                 button = '<td><input type="radio" name="vote" value="%s">%s</td>' % (candidate, candidate)
 126                 count = '???'
 127         else:
 128             button = candidate
 129             count = '???'
 130         html += '<tr><td>%s</td><td>%s</td></tr>\n' % (button, count)
 131 
 132     if not voter:
 133         html += '<tr><td colspan="3" class="votelogin">You need to login to vote</td></tr>'
 134 
 135     html += '</table>\n'
 136 
 137     if voter and not hasVoted:
 138         html += '<input type="submit" value="Vote">\n</form>\n'
 139         
 140     return macro.formatter.rawHTML(html)

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2005-10-20 19:56:49, 4.7 KB) [[attachment:Vote_1.3.py]]
  • [get | view] (2004-07-21 10:34:13, 4.7 KB) [[attachment:vote2_moin12.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.