Attachment 'Vote_1.3.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 	Updated by: Akshat Aranya (aaranya@gmail.com)
   8 
   9     Usage:
  10         [[Vote(pageName, voteTitle, candidate1, ...)]]
  11 
  12     E.g:
  13         [[Vote(MyBlog, Do polls work?, yes)]]
  14     
  15     Just like Martin's Vote macro, except you must specify the name of the
  16     page on which to vote "appears."  Without this information, when a user
  17     votes from an included page, after pressing the Vote button they are
  18     returned to the included page, not the main page.  Also different is
  19     that the current number of votes is hidden until the user has voted.
  20     Lastly, it is possible to have a poll that only has one choice, which
  21     is kind of funny.  The remainder of the description is Martin's:
  22 
  23     You can have multiple votes on one page (so long as the titles are unique).
  24     You can add candidates after a vote has started, but note that renaming 
  25     candidates will lose the votes (and not allow users to recast their votes).
  26     Changing the vote title creates a new vote.
  27 
  28     Vote data is stored in data_dir/pages/pagename/votes 
  29     (i.e. alongside the attachments directory for a page).
  30 
  31     You can customise the appearance by defining the following CSS styles:
  32         table.vote 
  33         td.votelogin (for "must login" message)
  34 '''
  35 
  36 import os, pickle
  37 from MoinMoin import wikiutil
  38 from MoinMoin.util import filesys
  39 
  40 def makeFilename(thisPage, voteName):
  41     votesDir = thisPage.getPagePath("votes")
  42     if not os.path.exists(votesDir):
  43         filesys.makeDirs(votesDir)
  44     voteName = wikiutil.quoteWikinameFS(voteName) + '.pik'
  45     return os.path.join(votesDir, voteName)
  46 
  47 def loadVotes(thisPage, voteName):
  48     votesFile = makeFilename(thisPage, voteName)
  49     try:
  50         f = open(votesFile, 'r')
  51         return pickle.load(f)
  52     except: # XXX
  53         return {}
  54 
  55 def saveVotes(thisPage, voteName, votes):
  56     votesFile = makeFilename(thisPage, voteName)
  57     f = open(votesFile, 'w')
  58     pickle.dump(votes, f)
  59 
  60 def countVotes(votes):
  61     results = {}
  62     for v in votes.values():
  63         results.setdefault(v, 0)
  64         results[v] += 1
  65     return results
  66 
  67 def execute(macro, args):
  68     args = args.split(",")
  69     args = map(unicode.strip, args)
  70 
  71     if len(args) < 3:
  72         return macro.formatter.rawHTML('<pre>[[Vote: Insufficient macro arguments]]</pre>')
  73 
  74     pageName = args[0]
  75     voteName = args[1]
  76     candidates = args[2:]
  77 
  78     form = macro.form
  79     request = macro.request
  80     if request.user.valid:
  81         voter = request.user.name
  82     else:
  83         voter = ''
  84     thisPage = macro.formatter.page
  85     votes = loadVotes(thisPage, 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(thisPage, 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     html += '</a>\n'
 137 
 138     if voter and not hasVoted:
 139         html += '<input type="submit" value="Vote">\n</form>\n'
 140         
 141     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.