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