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.You are not allowed to attach a file to this page.