main.py 31 KB

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