25d31ebc8719e675fd4fc2ccb39485cdf09a96fe
[cavote.git] / main.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 from flask import Flask, request, session, g, redirect, url_for, abort, \
5 render_template, flash
6 import sqlite3
7 from datetime import date, time, timedelta
8 import time
9 from contextlib import closing
10 import locale
11 locale.setlocale(locale.LC_ALL, '')
12 import os
13 import hashlib
14 import smtplib
15 import string
16
17 DATABASE = '/tmp/cavote.db'
18 SECRET_KEY = '{J@uRKO,xO-PK7B,jF?>iHbxLasF9s#zjOoy=+:'
19 DEBUG = True
20 TITLE = u"Cavote FFDN"
21 EMAIL = '"' + TITLE + '"' + ' <' + u"cavote@ffdn.org" + '>'
22 BASEURL = "http://localhost:5000" # :TODO:maethor:120605: Find a cleaner way to do this
23 VERSION = "cavote 0.0.1"
24 SMTP_SERVER = "10.33.33.30"
25 PATTERNS = {u'Oui/Non': [u'Oui', u'Non'], u'Oui/Non/Blanc': [u'Oui', u'Non', u'Blanc'], u'Oui/Non/Peut-être': [u'Oui', u'Non', u'Peut-être']}
26
27 app = Flask(__name__)
28 app.config.from_object(__name__)
29
30 def connect_db():
31 return sqlite3.connect(app.config['DATABASE'])
32
33 @app.before_request
34 def before_request():
35 g.db = connect_db()
36 g.db.execute("PRAGMA foreign_keys = ON")
37
38 @app.teardown_request
39 def teardown_request(exception):
40 g.db.close()
41
42 @app.route('/')
43 def home():
44 return render_template('index.html', active_button="home")
45
46 def query_db(query, args=(), one=False):
47 cur = g.db.execute(query, args)
48 rv = [dict((cur.description[idx][0], value)
49 for idx, value in enumerate(row)) for row in cur.fetchall()]
50 return (rv[0] if rv else None) if one else rv
51
52 def init_db():
53 with closing(connect_db()) as db:
54 with app.open_resource('schema.sql') as f:
55 db.cursor().executescript(f.read())
56 db.commit()
57
58 #----------------
59 # Login / Logout
60
61 def valid_login(username, password):
62 return query_db('select * from users where email = ? and password = ?', [username, crypt(password)], one=True)
63
64 def connect_user(user):
65 session['user'] = user
66 del session['user']['password']
67 del session['user']['key']
68
69 def disconnect_user():
70 session.pop('user', None)
71
72 def crypt(passwd):
73 return hashlib.sha1(passwd).hexdigest()
74
75 def keygen():
76 return hashlib.sha1(os.urandom(24)).hexdigest()
77
78 def get_userid():
79 user = session.get('user')
80 if user is None:
81 return -1
82 elif user.get('id') < 0:
83 return -1
84 else:
85 return user.get('id')
86
87 @app.route('/login', methods=['GET', 'POST'])
88 def login():
89 if request.method == 'POST':
90 user = valid_login(request.form['username'], request.form['password'])
91 if user is None:
92 flash(u'Email ou mot de passe invalide.', 'error')
93 else:
94 connect_user(user)
95 flash(u'Vous êtes connecté. Bienvenue, %s !' % user['name'], 'success')
96 return redirect(url_for('home'))
97 return render_template('login.html')
98
99 @app.route('/logout')
100 def logout():
101 disconnect_user()
102 flash(u'Vous avez été déconnecté.', 'info')
103 return redirect(url_for('home'))
104
105 #-----------------
106 # Change password
107
108 @app.route('/password/lost', methods=['GET', 'POST'])
109 def password_lost():
110 info = None
111 if request.method == 'POST':
112 user = query_db('select * from users where email = ?', [request.form['email']], one=True)
113 if user is None:
114 flash('Cet utilisateur n\'existe pas !', 'error')
115 else:
116 key = keygen()
117 g.db.execute('update users set key = ? where id = ?', [key, user['id']])
118 g.db.commit()
119 link = BASEURL + url_for('login_key', userid=user['id'], key=key)
120 BODY = string.join((
121 "From: %s" % EMAIL,
122 "To: %s" % user['email'],
123 "Subject: [Cavote] Password lost",
124 "Date: %s" % time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()),
125 "X-Mailer: %s" % VERSION,
126 "",
127 "You have lost your password.",
128 "This link will log you without password.",
129 "Don't forget to define a new one as soon a possible!",
130 "This link will only work one time.",
131 "",
132 link,
133 "",
134 "If you think this mail is not for you, please ignore and delete it."
135 ), "\r\n")
136 server = smtplib.SMTP(SMTP_SERVER)
137 server.sendmail(EMAIL, [user['email']], BODY)
138 server.quit()
139 flash(u"Un mail a été envoyé à " + user['email'], 'info')
140 return render_template('password_lost.html')
141
142 @app.route('/login/<userid>/<key>')
143 def login_key(userid, key):
144 user = query_db('select * from users where id = ? and key = ?', [userid, key], one=True)
145 if user is None or user['key'] == "invalid":
146 abort(404)
147 else:
148 connect_user(user)
149 g.db.execute('update users set key = "invalid" where id = ?', [user['id']])
150 g.db.commit()
151 flash(u"Veuillez mettre à jour votre mot de passe", 'info')
152 return redirect(url_for('user_password', userid=user['id']))
153
154 #---------------
155 # User settings
156
157 @app.route('/user/<userid>')
158 def user(userid):
159 if int(userid) != get_userid():
160 abort(401)
161 groups = query_db('select * from groups join user_group on id=id_group where id_user = ?', userid)
162 return render_template('user.html', groups=groups)
163
164 @app.route('/user/settings/<userid>', methods=['GET', 'POST'])
165 def user_edit(userid):
166 if int(userid) != get_userid():
167 abort(401)
168 if request.method == 'POST':
169 if query_db('select * from users where email=? and id!=?', [request.form['email'], userid], one=True) is None:
170 if query_db('select * from users where name=? and id!=?', [request.form['name'], userid], one=True) is None:
171 g.db.execute('update users set email = ?, name = ?, organization = ? where id = ?',
172 [request.form['email'], request.form['name'], request.form['organization'], session['user']['id']])
173 g.db.commit()
174 disconnect_user()
175 user = query_db('select * from users where id=?', [userid], one=True)
176 if user is None:
177 flash(u'Une erreur s\'est produite.', 'error')
178 return redirect(url_for('login'))
179 connect_user(user)
180 flash(u'Votre profil a été mis à jour !', 'success')
181 else:
182 flash(u'Le nom ' + request.form['name'] + u' est déjà pris ! Veuillez en choisir un autre.', 'error')
183 else:
184 flash(u'Il existe déjà un compte pour cette adresse e-mail : ' + request.form['email'], 'error')
185 return render_template('user_edit.html')
186
187 @app.route('/user/password/<userid>', methods=['GET', 'POST'])
188 def user_password(userid):
189 if int(userid) != get_userid():
190 abort(401)
191 if request.method == 'POST':
192 if request.form['password'] == request.form['password2']:
193 g.db.execute('update users set password = ? where id = ?', [crypt(request.form['password']), session['user']['id']])
194 g.db.commit()
195 flash(u'Votre mot de passe a été mis à jour.', 'success')
196 else:
197 flash(u'Les mots de passe sont différents.', 'error')
198 return render_template('user_edit.html')
199
200 #------------
201 # User admin
202
203 @app.route('/admin/users')
204 def admin_users():
205 if not session.get('user').get('is_admin'):
206 abort(401)
207 tuples = query_db('select *, groups.name as groupname from (select *, id as userid, name as username from users join user_group on id=id_user order by id desc) join groups on id_group=groups.id')
208 users = dict()
209 for t in tuples:
210 if t['userid'] in users:
211 users[t['userid']]['groups'].append(t["groupname"])
212 else:
213 users[t['userid']] = dict()
214 users[t['userid']]['userid'] = t['userid']
215 users[t['userid']]['email'] = t['email']
216 users[t['userid']]['username'] = t['username']
217 users[t['userid']]['is_admin'] = t['is_admin']
218 users[t['userid']]['groups'] = [t['groupname']]
219
220 return render_template('admin_users.html', users=users.values())
221
222 @app.route('/admin/users/add', methods=['GET', 'POST'])
223 def admin_user_add():
224 if not session.get('user').get('is_admin'):
225 abort(401)
226 if request.method == 'POST':
227 if request.form['email']:
228 if query_db('select * from users where email=?', [request.form['email']], one=True) is None:
229 if request.form['username']:
230 if query_db('select * from users where name=?', [request.form['username']], one=True) is None:
231 password = keygen()
232 admin = 0
233 if 'admin' in request.form.keys():
234 admin = 1
235 key = keygen()
236 g.db.execute('insert into users (email, name, organization, password, is_admin, key) values (?, ?, ?, ?, ?, ?)',
237 [request.form['email'], request.form['username'], request.form['organization'], password, admin, key])
238 g.db.commit()
239 user = query_db('select * from users where email = ?', [request.form["email"]], one=True)
240 if user:
241 groups = request.form.getlist('groups')
242 groups.append('1')
243 for group in groups:
244 if query_db('select id from groups where id = ?', group, one=True) is None:
245 flash(u'Le groupe portant l\'id %s n\'existe pas.' % group, 'warning')
246 else:
247 g.db.execute('insert into user_group values (?, ?)', [user['id'], group])
248 g.db.commit()
249 link = BASEURL + url_for('login_key', userid=user['id'], key=user['key'])
250 BODY = string.join((
251 "From: %s" % EMAIL,
252 "To: %s" % user['email'],
253 "Subject: [Cavote] Welcome",
254 "Date: %s" % time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime()),
255 "X-Mailer: %s" % VERSION,
256 "",
257 "Hi %s!" % user['name'],
258 "Welcome on %s." % TITLE,
259 "Your account's adresse is : %s." % user['email'],
260 "",
261 "To log in for the first time and set your password, please follow this link :",
262 link,
263 ""
264 ), "\r\n")
265 server = smtplib.SMTP(SMTP_SERVER)
266 server.sendmail(EMAIL, [user['email']], BODY)
267 server.quit()
268 flash(u'Le nouvel utilisateur a été créé avec succès', 'success')
269 return redirect(url_for('admin_users'))
270 else:
271 flash(u'Une erreur s\'est produite.', 'error')
272 else:
273 flash(u'Le nom ' + request.form['username'] + u' est déjà pris ! Veuillez en choisir un autre.', 'error')
274 else:
275 flash(u"Vous devez spécifier un nom d'utilisateur.", 'error')
276 else:
277 flash(u'Il existe déjà un compte pour cette adresse e-mail : ' + request.form['email'], 'error')
278 else:
279 flash(u"Vous devez spécifier une adresse email.", 'error')
280 groups = query_db('select * from groups where system=0')
281 return render_template('admin_user_new.html', groups=groups)
282
283 @app.route('/admin/users/edit/<iduser>', methods=['GET', 'POST'])
284 def admin_user_edit(iduser):
285 if not session.get('user').get('is_admin'):
286 abort(401)
287 user = query_db('select * from users where id = ?', [iduser], one=True)
288 user['groups'] = query_db('select groups.* from groups join user_group on groups.id = user_group.id_group where id_user = ?', [iduser])
289 if user is None:
290 abort(404)
291 if request.method == 'POST':
292 if query_db('select * from users where email=? and id!=?', [request.form['email'], iduser], one=True) is None:
293 if query_db('select * from users where name=? and id!=?', [request.form['name'], iduser], one=True) is None:
294 admin = 0
295 if 'admin' in request.form.keys():
296 admin = 1
297 g.db.execute('update users set email = ?, name = ?, organization = ?, is_admin = ? where id = ?',
298 [request.form['email'], request.form['name'], request.form['organization'], admin, iduser])
299 g.db.commit()
300 groups = request.form.getlist('groups')
301 groups.append('1')
302 for group in user['groups']:
303 if not group['id'] in groups:
304 g.db.execute('delete from user_group where id_user = ? and id_group = ?', [iduser, group['id']])
305 g.db.commit()
306 for group in groups:
307 group = query_db('select id from groups where id = ?', group, one=True)
308 if group is None:
309 flash(u'Le groupe portant l\'id %s n\'existe pas.' % group, 'warning')
310 else:
311 if not group in user['groups']:
312 g.db.execute('insert into user_group values (?, ?)', [user['id'], group['id']])
313 g.db.commit()
314 user = query_db('select * from users where id = ?', [iduser], one=True)
315 user['groups'] = query_db('select groups.* from groups join user_group on groups.id = user_group.id_group where id_user = ?', [iduser])
316 flash(u'Le profil a été mis à jour !', 'success')
317 else:
318 flash(u'Le nom ' + request.form['name'] + u' est déjà pris ! Veuillez en choisir un autre.', 'error')
319 else:
320 flash(u'Il existe déjà un compte pour cette adresse e-mail : ' + request.form['email'], 'error')
321 groups = query_db('select * from groups where system=0')
322 return render_template('admin_user_edit.html', user=user, groups=groups)
323
324 @app.route('/admin/users/delete/<iduser>')
325 def admin_user_del(iduser):
326 if not session.get('user').get('is_admin'):
327 abort(401)
328 user = query_db('select * from users where id = ?', [iduser], one=True)
329 if user is None:
330 abort(404)
331 g.db.execute('delete from users where id = ?', [iduser])
332 g.db.commit()
333 return redirect(url_for('admin_users'))
334
335 #-------------
336 # Roles admin
337
338 @app.route('/admin/groups')
339 def admin_groups():
340 if not session.get('user').get('is_admin'):
341 abort(401)
342 groups = query_db('select groups.*, count(user_group.id_user) as nb_users from (select groups.*, count(votes.id) as nb_votes from groups left join votes on votes.id_group = groups.id group by groups.id) as groups left join user_group on user_group.id_group = groups.id group by groups.id')
343 return render_template('admin_groups.html', groups=groups)
344
345 @app.route('/admin/groups/add', methods=['POST'])
346 def admin_group_add():
347 if not session.get('user').get('is_admin'):
348 abort(401)
349 if request.method == 'POST':
350 if request.form['name']:
351 g.db.execute('insert into groups (name) values (?)', [request.form['name']])
352 g.db.commit()
353 else:
354 flash(u"Vous devez spécifier un nom.", "error")
355 return redirect(url_for('admin_groups'))
356
357 @app.route('/admin/groups/delete/<idgroup>')
358 def admin_group_del(idgroup):
359 if not session.get('user').get('is_admin'):
360 abort(401)
361 group = query_db('select * from groups where id = ?', [idgroup], one=True)
362 if group is None:
363 abort(404)
364 if group['system']:
365 abort(401)
366 g.db.execute('delete from groups where id = ?', [idgroup])
367 g.db.commit()
368 return redirect(url_for('admin_groups'))
369
370 #------------
371 # Votes list
372
373 @app.route('/votes/<votes>')
374 def votes(votes):
375 today = date.today()
376 active_button = votes
377 max_votes ='select id_group, count(*) as max_votes from user_group group by id_group'
378 basequery = 'select votes.*, max_votes from votes left join (' + max_votes + ') as max_votes on votes.id_group = max_votes.id_group'
379 nb_votes = 'select id_vote, count(*) as nb_votes from (select id_user, id_vote from user_choice join choices on id_choice = choices.id group by id_user, id_vote) group by id_vote'
380 basequery = 'select * from (' + basequery + ') left join (' + nb_votes + ') on id = id_vote'
381 basequery = 'select *, votes.id as voteid, groups.name as groupname from (' + basequery + ') as votes join groups on groups.id = id_group where is_open=1'
382 if votes == 'all':
383 votes = query_db(basequery + ' order by id desc')
384 elif votes == 'archive':
385 votes = query_db(basequery + ' and is_terminated=1 order by id desc')
386 elif votes == 'current':
387 votes = query_db(basequery + ' and is_terminated=0 order by id desc')
388 elif votes == 'waiting':
389 basequery = 'select votes.* from user_group join (' + basequery + ') as votes on votes.id_group = user_group.id_group where user_group.id_user = ?'
390 already_voted = 'select id_vote from user_choice join choices on user_choice.id_choice = choices.id where id_user = ?'
391 votes = query_db(basequery + ' and votes.id not in (' + already_voted + ') and is_terminated=0', [get_userid(), get_userid()])
392 else:
393 abort(404)
394 for vote in votes:
395 if not vote.get('nb_votes'):
396 vote['nb_votes'] = 0
397 if vote.get('max_votes'):
398 vote['percent'] = int((float(vote['nb_votes']) / float(vote['max_votes'])) * 100)
399 return render_template('votes.html', votes=votes, active_button=active_button)
400
401 #------
402 # Vote
403
404 def can_see_vote(idvote, iduser=-1):
405 vote = query_db('select * from votes where id=?', [idvote], one=True)
406 if vote is None:
407 return False
408 if not vote['is_public']:
409 user = query_db('select * from users where id=?', [iduser], one=True)
410 if query_db('select * from user_group where id_user = ? and id_group = ?', [iduser, vote['id']], one=True) is None:
411 return False
412 return True
413
414 def can_vote(idvote, iduser=-1):
415 vote = query_db('select * from votes where id=?', [idvote], one=True)
416 if vote is None:
417 return False
418 if vote['is_terminated'] == 0:
419 if iduser > 0:
420 if can_see_vote(idvote, iduser):
421 if not has_voted(idvote, iduser):
422 if query_db('select * from user_group where id_user = ? and id_group = ?', [iduser, vote['id_group']], one=True):
423 return True
424 return False
425
426 def has_voted(idvote, iduser=-1):
427 vote = query_db('select * from user_choice join choices on id_choice=choices.id where id_vote = ? and id_user = ?', [idvote, iduser], one=True)
428 return (vote is not None)
429
430 @app.route('/vote/<idvote>', methods=['GET', 'POST'])
431 def vote(idvote):
432 vote = query_db('select votes.*, groups.name as groupname from votes join groups on groups.id=votes.id_group where votes.id=?', [idvote], one=True)
433 if vote is None:
434 abort(404)
435 if can_see_vote(idvote, get_userid()):
436 if request.method == 'POST':
437 if can_vote(idvote, get_userid()):
438 if vote['is_multiplechoice'] == 0:
439 if query_db('select * from choices where id = ?', [request.form['choice']], one=True) is not None:
440 g.db.execute('insert into user_choice (id_user, id_choice) values (?, ?)',
441 [session.get('user').get('id'), request.form['choice']])
442 g.db.commit()
443 else:
444 choices = query_db('select name, id from choices where id_vote=?', [idvote])
445 for choice in choices:
446 if str(choice['id']) in request.form.keys():
447 g.db.execute('insert into user_choice (id_user, id_choice) values (?, ?)',
448 [session.get('user').get('id'), choice['id']])
449 g.db.commit()
450 else:
451 abort(401)
452 tuples = query_db('select choiceid, choicename, users.id as userid, users.name as username from (select choices.id as choiceid, choices.name as choicename, id_user as userid from choices join user_choice on choices.id = user_choice.id_choice where id_vote = ?) join users on userid = users.id', [idvote])
453 users = dict()
454 for t in tuples:
455 if t['userid'] in users:
456 users[t['userid']]['choices'].append(t['choiceid'])
457 else:
458 users[t['userid']] = dict()
459 users[t['userid']]['userid'] = t['userid']
460 users[t['userid']]['username'] = t['username']
461 users[t['userid']]['choices'] = [t['choiceid']]
462 choices = query_db('select choices.name, choices.id, choices.name, choices.id_vote, count(id_choice) as nb from choices left join user_choice on id_choice = choices.id where id_vote = ? group by id_choice, name, id_vote order by id', [idvote])
463 attachments = query_db('select * from attachments where id_vote=?', [idvote])
464 tmp = query_db('select id_group, count(*) as nb from user_group where id_group = ? group by id_group', [vote['id_group']], one=True)
465 if tmp is None:
466 vote['percent'] = 0
467 else:
468 vote['max_votes'] = tmp['nb']
469 tmp = query_db('select id_vote, count(*) as nb from (select id_user, id_vote from user_choice join choices on id_choice = choices.id group by id_user, id_vote) where id_vote = ? group by id_vote', [idvote], one=True)
470 if tmp is None:
471 vote['percent'] = 0
472 vote['nb_votes'] = 0
473 else:
474 vote['nb_votes'] = tmp['nb']
475 vote['percent'] = int((float(vote['nb_votes']) / float(vote['max_votes'])) * 100)
476 # :TODO:maethor:120606: Flash if user is concerned by the vote
477 return render_template('vote.html', vote=vote, attachments=attachments, choices=choices, users=users.values(), can_vote=can_vote(idvote, get_userid()))
478 flash(u'Vous n\'avez pas le droit de voir ce vote, désolé.')
479 return redirect(url_for('home'))
480
481 @app.route('/vote/deletechoices/<idvote>/<iduser>')
482 def vote_deletechoices(idvote, iduser):
483 if int(iduser) != get_userid():
484 abort(401)
485 g.db.execute('delete from user_choice where id_user = ? and id_choice in (select id from choices where id_vote = ?)',
486 [iduser, idvote])
487 g.db.commit()
488 return redirect(url_for('vote', idvote=idvote))
489
490 #-------------
491 # Votes admin
492
493 @app.route('/admin/votes/list')
494 def admin_votes():
495 if not session.get('user').get('is_admin'):
496 abort(401)
497 votes = query_db('select *, votes.id as voteid, groups.name as groupname from votes join groups on groups.id=votes.id_group order by id desc')
498 return render_template('admin_votes.html', votes=votes)
499
500 @app.route('/admin/votes/add', methods=['GET', 'POST'])
501 def admin_vote_add():
502 if not session.get('user').get('is_admin'):
503 abort(401)
504 if request.method == 'POST':
505 if request.form['title']:
506 if query_db('select * from votes where title = ?', [request.form['title']], one=True) is None:
507 date_begin = date.today()
508 date_end = date.today() + timedelta(days=int(request.form['days']))
509 transparent = 0
510 public = 0
511 multiplechoice = 0
512 if 'transparent' in request.form.keys():
513 transparent = 1
514 if 'public' in request.form.keys():
515 public = 1
516 if 'multiplechoice' in request.form.keys():
517 multiplechoice = 1
518 group = query_db('select id from groups where name = ?', [request.form['group']], one=True)
519 if group is None:
520 group[id] = 1
521 g.db.execute('insert into votes (title, description, category, date_begin, date_end, is_transparent, is_public, is_multiplechoice, id_group, id_author) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
522 [request.form['title'], request.form['description'], request.form['category'], date_begin, date_end, transparent, public, multiplechoice, group['id'], session['user']['id']])
523 g.db.commit()
524 vote = query_db('select * from votes where title = ? and date_begin = ? order by id desc',
525 [request.form['title'], date_begin], one=True)
526 if vote is None:
527 flash(u'Une erreur est survenue !', 'error')
528 return redirect(url_for('home'))
529 else:
530 if request.form['pattern'] in PATTERNS.keys():
531 pattern = PATTERNS[request.form['pattern']]
532 for choice in pattern:
533 g.db.execute('insert into choices (name, id_vote) values (?, ?)', [choice, vote['id']])
534 g.db.commit()
535 flash(u"Le vote a été créé", 'info')
536 return redirect(url_for('admin_vote_edit', voteid=vote['id']))
537 else:
538 flash(u'Le titre que vous avez choisi est déjà pris.', 'error')
539 else:
540 flash(u'Vous devez spécifier un titre.', 'error')
541 groups = query_db('select * from groups')
542 return render_template('admin_vote_new.html', groups=groups, patterns=PATTERNS)
543
544 @app.route('/admin/votes/edit/<voteid>', methods=['GET', 'POST'])
545 def admin_vote_edit(voteid):
546 if not session.get('user').get('is_admin'):
547 abort(401)
548 vote = query_db('select * from votes where id = ?', [voteid], one=True)
549 if vote is None:
550 abort(404)
551 if request.method == 'POST':
552 if request.form['title']:
553 # :TODO:maethor:120529: Calculer date_begin pour pouvoir y ajouter duration et obtenir date_end
554 transparent = 0
555 public = 0
556 if 'transparent' in request.form.keys():
557 transparent = 1
558 if 'public' in request.form.keys():
559 public = 1
560 isopen = 0
561 isterminated = 0
562 if request.form['status'] == 'Ouvert':
563 choices = query_db('select id_vote, count(*) as nb from choices where id_vote = ? group by id_vote', [voteid], one=True)
564 if choices is not None and choices['nb'] >= 2:
565 isopen = 1
566 else:
567 flash(u'Vous devez proposer au moins deux choix pour ouvrir le vote.', 'error')
568 elif request.form['status'] == u'Terminé':
569 isterminated = 1
570 if vote['is_open']:
571 isopen = 1
572 g.db.execute('update votes set title = ?, description = ?, category = ?, is_transparent = ?, is_public = ?, is_open = ?, is_terminated = ? where id = ?',
573 [request.form['title'], request.form['description'], request.form['category'], transparent, public, isopen, isterminated, voteid])
574 g.db.commit()
575 vote = query_db('select * from votes where id = ?', [voteid], one=True)
576 flash(u"Le vote a bien été mis à jour.", "success")
577 else:
578 flash(u'Vous devez spécifier un titre.', 'error')
579
580 # :TODO:maethor:120529: Calculer la durée du vote (différence date_end - date_begin)
581 vote['duration'] = 15
582 group = query_db('select name from groups where id = ?', [vote['id_group']], one=True)
583 choices = query_db('select * from choices where id_vote = ?', [voteid])
584 attachments = query_db('select * from attachments where id_vote = ?', [voteid])
585 return render_template('admin_vote_edit.html', vote=vote, group=group, choices=choices, attachments=attachments)
586
587 @app.route('/admin/votes/addchoice/<voteid>', methods=['POST'])
588 def admin_vote_addchoice(voteid):
589 if not session.get('user').get('is_admin'):
590 abort(401)
591 vote = query_db('select * from votes where id = ?', [voteid], one=True)
592 if vote is None:
593 abort(404)
594 g.db.execute('insert into choices (name, id_vote) values (?, ?)', [request.form['title'], voteid])
595 g.db.commit()
596 return redirect(url_for('admin_vote_edit', voteid=voteid))
597
598 @app.route('/admin/votes/editchoice/<voteid>/<choiceid>', methods=['POST', 'DELETE'])
599 def admin_vote_editchoice(voteid, choiceid):
600 if not session.get('user').get('is_admin'):
601 abort(401)
602 choice = query_db('select * from choices where id = ? and id_vote = ?', [choiceid, voteid], one=True)
603 if choice is None:
604 abort(404)
605 if request.method == 'POST':
606 g.db.execute('update choices set name=? where id = ? and id_vote = ?', [request.form['title'], choiceid, voteid])
607 g.db.commit()
608 return redirect(url_for('admin_vote_edit', voteid=voteid))
609
610 @app.route('/admin/votes/deletechoice/<voteid>/<choiceid>')
611 def admin_vote_deletechoice(voteid, choiceid):
612 if not session.get('user').get('is_admin'):
613 abort(401)
614 choice = query_db('select * from choices where id = ? and id_vote = ?', [choiceid, voteid], one=True)
615 if choice is None:
616 abort(404)
617 g.db.execute('delete from choices where id = ? and id_vote = ?', [choiceid, voteid])
618 g.db.commit()
619 choices = query_db('select id_vote, count(*) as nb from choices where id_vote = ? group by id_vote', [voteid], one=True)
620 if choices is None or choices['nb'] < 2:
621 g.db.execute('update votes set is_open=0 where id = ?', [voteid])
622 g.db.commit()
623 flash(u'Attention ! Il y a moins de deux choix. Le vote a été fermé.', 'error')
624 return redirect(url_for('admin_vote_edit', voteid=voteid))
625
626 @app.route('/admin/votes/addattachment/<voteid>', methods=['POST'])
627 def admin_vote_addattachment(voteid):
628 if not session.get('user').get('is_admin'):
629 abort(401)
630 vote = query_db('select * from votes where id = ?', [voteid], one=True)
631 if vote is None:
632 abort(404)
633 g.db.execute('insert into attachments (url, id_vote) values (?, ?)', [request.form['url'], voteid])
634 g.db.commit()
635 return redirect(url_for('admin_vote_edit', voteid=voteid))
636
637 @app.route('/admin/votes/deleteattachment/<voteid>/<attachmentid>')
638 def admin_vote_deleteattachment(voteid, attachmentid):
639 if not session.get('user').get('is_admin'):
640 abort(401)
641 attachment = query_db('select * from attachments where id = ? and id_vote = ?', [attachmentid, voteid], one=True)
642 if attachment is None:
643 abort(404)
644 g.db.execute('delete from attachments where id = ? and id_vote = ?', [attachmentid, voteid])
645 g.db.commit()
646 return redirect(url_for('admin_vote_edit', voteid=voteid))
647
648 #------
649 # Main
650
651 if __name__ == '__main__':
652 app.run()
653