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 MoinMoin.user 15 import os 16 try: 17 import cPickle as pickle 18 except ImportError: 19 import pickle 20 21 Dependencies = ["time"] 22 23 def get_vote_directory(page, name): 24 votes_dir = page.getPagePath("poll") 25 if not os.path.exists(votes_dir): 26 filesys.makeDirs(votes_dir) 27 return votes_dir 28 29 def get_vote_pathname(page, name): 30 votes_dir = get_vote_directory(page, name) 31 filename = wikiutil.quoteWikinameFS(name) 32 return os.path.join(votes_dir, filename) 33 34 def get_lock_directory(page, name): 35 votes_dir = get_vote_directory(page, name) 36 return os.path.join(votes_dir, "__lock__") 37 38 def save_votes(page, poll_name, votes): 39 vote_lock = lock.WriteLock(get_lock_directory(page, poll_name)) 40 vote_lock.acquire() 41 try: 42 _save_votes(page, poll_name, votes) 43 finally: 44 vote_lock.release() 45 46 def _save_votes(page, poll_name, votes): 47 path = get_vote_pathname(page, poll_name) 48 f = open(path, "wb") 49 try: 50 pickle.dump(votes, f) 51 finally: 52 f.close() 53 54 def get_all_votes(page, poll_name): 55 vote_lock = lock.ReadLock(get_lock_directory(page, poll_name)) 56 vote_lock.acquire() 57 try: 58 return _get_all_votes(page, poll_name) 59 finally: 60 vote_lock.release() 61 62 def _get_all_votes(page, poll_name): 63 path = get_vote_pathname(page, poll_name) 64 if not os.path.exists(path): 65 return {} 66 f = open(path, "rb") 67 try: 68 voting = pickle.load(f) 69 return voting 70 finally: 71 f.close() 72 73 def execute(macro, args): 74 request = macro.request 75 form = macro.form 76 fmt = macro.formatter 77 page = fmt.page 78 79 output = [] 80 81 # Obtain the poll name for presentation purposes. 82 83 args = args.split(",") 84 if args: 85 poll_name = args[0] 86 else: 87 output.append(fmt.sysmsg(on=1)) 88 output.append(fmt.text("Please specify a poll name!")) 89 output.append(fmt.sysmsg(on=0)) 90 return ''.join(output) 91 92 # Check for extra arguments. 93 # NOTE: This is only adequate protection if an ACL stops untrusted users 94 # NOTE: from editing the page. This should actually query the ACL in order 95 # NOTE: to prevent such exploits. 96 97 public = "public" in args[1:] 98 99 # Get the user, if known. 100 # Show a message if the user is not logged in and the poll is not public. 101 102 if not public and not request.user.valid: 103 output.append(fmt.emphasis(on=1)) 104 output.append(fmt.text("Please log in to vote!")) 105 output.append(fmt.emphasis(on=0)) 106 return ''.join(output) 107 108 username = MoinMoin.user.getUserIdentification(request) 109 #username = request.user.valid and request.user.name or request.user.host() 110 votes = get_all_votes(page, poll_name) 111 112 # Handle any vote. 113 114 if form and form.has_key("vote") and form.has_key("poll"): 115 poll = form["poll"][0] 116 if poll == poll_name: 117 votes[username] = int(form["vote"][0]) 118 save_votes(page, poll_name, votes) 119 output.append(fmt.emphasis(on=1)) 120 output.append(fmt.text("Vote submitted!")) 121 output.append(fmt.emphasis(on=0)) 122 return ''.join(output) 123 124 # Show the choices. 125 126 values = { 127 "poll" : poll_name, "url" : page.url(request), 128 "on_image" : '/wiki/modern/img/star_on.png', 129 "off_image" : '/wiki/modern/img/star_off.png' 130 } 131 choices = range(1, 6) 132 133 output.append(fmt.rawHTML('<form method="get" name="%(poll)s" action="%(url)s#%(poll)s">' % values)) 134 output.append(fmt.rawHTML('<input type="hidden" name="poll" value="%(poll)s">' % values)) 135 136 for choice in choices: 137 values["choice"] = choice 138 if votes.has_key(username) and choice <= votes[username]: 139 values["default_image"] = values["on_image"] 140 else: 141 values["default_image"] = values["off_image"] 142 output.append( 143 fmt.rawHTML(''' 144 <input type="image" name="vote" value="%(choice)s" src="%(default_image)s" 145 onmouseover="this.src='%(on_image)s'" 146 onmouseout="this.src='%(default_image)s'"> 147 ''' % values)) 148 149 output.append(fmt.rawHTML('</form>')) 150 151 return ''.join(output) 152 153 # vim: tabstop=4 expandtab shiftwidth=4