Attachment 'VotingStars.py'

Download

   1 #format python
   2 # -*- coding: iso-8859-1 -*-
   3 '''
   4     MoinMoin - VotingStars Macro
   5     Author: Travis Bailey
   6     Date: February 2006
   7   
   8     Purpose:
   9         This macro allows ratings of items using stars (based on Vote macro)
  10     Usage:
  11         [[VotingStars(UniqueName)]]
  12         e.g. 1. NiceShop [[VotingStars(shop1)]]
  13              1. EvenNicerShop [[VotingStars(shop2)]]
  14     Tested:
  15         Firefox 1.5 MoinMoin 1.5.1 Python 2.3
  16 
  17     I basically just slapped this together from the Vote1_3.py script and the
  18     RatingStars.py script.  I wanted to get the benefits of both.  I wanted a
  19     Utility to only allow Registered users to submit, allow them to change
  20     their vote, and to average the results.
  21 
  22     So basically it uses the Vote1_3.py code to track one vote per user.
  23     It averages the total stars given and then displays the number of average
  24     number of rated stars.
  25 
  26     You can have multiple VotingStars on one page (so long as the UniqueNames are unique)
  27     Changing the UniqueName creates a new vote.
  28     Make sure not to conflict with any Vote names you are using
  29 
  30     VotingStars data is stored in data_dir/pages/pagename/votes 
  31     (i.e. alongside the attachments directory for a page).
  32 
  33     You can customise the appearance by defining the following CSS styles:
  34         table.votestars
  35     
  36 '''
  37 import os, pickle
  38 from MoinMoin import wikiutil
  39 from MoinMoin.util import filesys
  40 
  41 def makeFilename(thisPage, voteName):
  42     votesDir = thisPage.getPagePath("votes")
  43     if not os.path.exists(votesDir):
  44         filesys.makeDirs(votesDir)
  45     voteName = wikiutil.quoteWikinameFS(voteName) + '.pik'
  46     return os.path.join(votesDir, voteName)
  47 
  48 def loadVotes(thisPage, voteName):
  49     votesFile = makeFilename(thisPage, voteName)
  50     try:
  51         f = open(votesFile, 'r')
  52         return pickle.load(f)
  53     except: # XXX
  54         return {}
  55 
  56 def saveVotes(thisPage, voteName, votes):
  57     votesFile = makeFilename(thisPage, voteName)
  58     f = open(votesFile, 'w')
  59     pickle.dump(votes, f)
  60 
  61 def countVotes(votes):
  62     results = {}
  63     for v in votes.values():
  64         results.setdefault(v, 0)
  65         results[v] += 1
  66     return results
  67 
  68 def execute(macro, args):
  69     args = args.split(",")
  70     args = map(unicode.strip, args)
  71 
  72     if len(args) < 1:
  73         return macro.formatter.rawHTML('<pre>[[Vote: Insufficient macro arguments]]</pre>')
  74 
  75     pageName = args[0]
  76     voteName = pageName
  77     candidates = ['1','2','3','4','5']
  78     src_litstar = '/wiki/modern/img/star_on.png'
  79     src_unlitstar = '/wiki/modern/img/star_off.png'
  80     
  81     form = macro.form
  82     request = macro.request
  83     if request.user.valid:
  84         voter = request.user.name
  85     else:
  86         voter = ''
  87     thisPage = macro.formatter.page
  88     votes = loadVotes(thisPage, voteName)
  89 
  90     # votes are stored in a dictionary as {user: candidate} to avoid duplicate votes
  91     # (a voter could switch their vote but this UI doesn't expose that facility)
  92     if form.has_key('vote') and form.has_key('voteName') and voter:
  93         if form['voteName'][0] == voteName:
  94             votes[voter] = form['vote'][0]
  95             try:
  96                saveVotes(thisPage, voteName, votes)
  97             except: # XXX
  98                return macro.formatter.rawHTML('<a id="voteform"><pre>[[Vote: failed to store vote]]</pre>')
  99 
 100     # generate dictionary {candidate: numvotes}
 101     results = countVotes(votes)
 102     onestar = results.setdefault(candidates[0],0)
 103     twostar = results.setdefault(candidates[1],0)
 104     threestar = results.setdefault(candidates[2],0)
 105     fourstar = results.setdefault(candidates[3],0)
 106     fivestar = results.setdefault(candidates[4],0)
 107     counts = (onestar+twostar+threestar+fourstar+fivestar)
 108 
 109     if counts == 0:
 110         average = 0
 111     else:
 112         average = (onestar*1+twostar*2+threestar*3+fourstar*4+fivestar*5)/counts
 113 
 114     hasVoted = voter in votes
 115 
 116     # spit out votes table (as part of a form if the user hasn't voted yet)
 117     html = '<a id="voteform"><table class="votestars"><tr><td>'
 118 
 119     if voter:
 120         html += '''
 121             <form method="get" name="%(formname)s" action="%(url)s#voteform">\n
 122             <input type="hidden" name="voteName" value="%(voteName)s">\n
 123             <input type="hidden" name="vote" value="0">
 124             ''' % {
 125                 'formname': voteName,
 126                 'url': thisPage.url(request),
 127                 'voteName': voteName,
 128             }
 129         btnstar = '<input type="image" src="%(isrc)s" OnClick="document.%(form)s.vote.value=%(value)s">\n'  
 130         for i in range(1,6):
 131             if i <= average:
 132                 html += btnstar % {'isrc':src_litstar, 'form':voteName, 'value': i}
 133             if i > average:
 134                 html += btnstar % {'isrc':src_unlitstar, 'form':voteName, 'value': i}
 135         if average == 0:
 136             html += ' No Rating'
 137         #else:
 138         #    html += ' %(avg)s ' % { 'avg': average }
 139         html += '</form></td></tr></table></a>'
 140     else:
 141         html += 'You must be logged in to Rate.</td></tr></table></a>'
 142 
 143     return macro.formatter.rawHTML(html)
 144     

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] (2006-02-02 22:14:48, 4.9 KB) [[attachment:VotingStars.py]]
 All files | Selected Files: delete move to page copy to page

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