Le repo des sources pour le site web des JM2L
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 

1600 linhas
70 KiB

  1. # -*- coding: utf8 -*-
  2. from pyramid.httpexceptions import HTTPFound, HTTPNotFound, HTTPForbidden
  3. from pyramid.httpexceptions import HTTPBadRequest, HTTPUnauthorized
  4. from pyramid.renderers import render_to_response
  5. from pyramid.response import Response
  6. from pyramid.view import notfound_view_config, forbidden_view_config
  7. from pyramid.view import view_config
  8. from pyramid_mailer import get_mailer
  9. from mako.template import Template
  10. # Import Web Forms
  11. from .forms import *
  12. # Database access imports
  13. from .models import *
  14. from sqlalchemy.exc import DBAPIError
  15. from sqlalchemy import func, or_
  16. # Usefull tools
  17. from slugify import slugify
  18. from icalendar import Calendar
  19. from pytz import timezone
  20. from icalendar import Event as Evt
  21. from pyramid_mailer import get_mailer
  22. from pyramid_mailer.message import Attachment, Message
  23. # Then, standard libs
  24. import webhelpers.paginate as paginate
  25. import unicodedata
  26. import time
  27. import datetime
  28. import re
  29. CurrentYear = 2015
  30. ## =-=- Here, We keep some usefull function -=-=
  31. def remove_accents(input_str):
  32. """ This function is intended to remove all accent from input unicode string """
  33. nkfd_form = unicodedata.normalize('NFKD', input_str)
  34. only_ascii = nkfd_form.encode('ASCII', 'ignore')
  35. return only_ascii
  36. def embeed_video(mime_type, link):
  37. Container = "<video controls='controls' preload='metadata' style='width:60%'>"
  38. Container += "<source type='%s' " % mime_type
  39. Container += "src='%s' />" % link
  40. Container += "</video>"
  41. return Container
  42. ## =-=- Here, We handle ICal requests -=-=
  43. @view_config(route_name='progr_iCal', renderer="string")
  44. def ICal_Progamme_Request(request):
  45. year = int(request.matchdict.get('year', CurrentYear))
  46. # Initialization
  47. # Compute days used by all events matching the specified input year
  48. Events = DBSession.query(Event)\
  49. .filter(Event.for_year == year)\
  50. .filter(Event.event_type != 'Stand')\
  51. .order_by(Event.start_time)
  52. cal = Calendar()
  53. cal.add('prodid', '-//Programme %d//jm2l.linux-azur.org//' % year)
  54. cal.add('version', '2.0')
  55. tz = timezone('Europe/Paris')
  56. for ev in Events:
  57. if ev.event_type:
  58. event = Evt()
  59. event['uid'] = "%d/%d" % ( year, ev.uid )
  60. event.add('summary', ev.name )
  61. event.add('dtstart', ev.start_time.replace(tzinfo=tz) )
  62. event.add('dtend', ev.end_time.replace(tzinfo=tz) )
  63. event.add('created', ev.last_change.replace(tzinfo=tz) )
  64. event.add('description', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) )
  65. event.add('url', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) )
  66. event.add('priority', 5)
  67. cal.add_component(event)
  68. request.response.content_type = "text/calendar"
  69. return cal.to_ical()
  70. ## =-=- Here, We handle Json requests -=-=
  71. @view_config(route_name='users_json', renderer="json")
  72. def JSON_User_Request(request):
  73. """ Build a JSON answer with active users and pagination handling """
  74. # Check arguments consitency
  75. pageSize = request.params.get('pageSize',"8")
  76. current_page = request.params.get('pageNum',"1")
  77. UserQuery = request.params.get('searchTerm', u"")
  78. # Don't answer to users that aren't logged
  79. if not request.user:
  80. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  81. # Check consistancy of parameters
  82. if pageSize.isdigit() and current_page.isdigit():
  83. current_page = int(current_page)
  84. pageSize = int(pageSize)
  85. else:
  86. return HTTPBadRequest('pageSize and pageNum accept only digits.')
  87. # Query database
  88. Users = DBSession.query(User.uid, User.nom, User.prenom)\
  89. .filter(User.slug.contains( remove_accents(UserQuery) ))
  90. page_url = paginate.PageURL_WebOb(request)
  91. records = paginate.Page(Users, current_page, url=page_url, items_per_page=pageSize)
  92. ListMatchUser = map( lambda u:{"id": u.uid, "text":"%s %s" % ( u.prenom, u.nom )}, records )
  93. return { "Results": ListMatchUser, "Total":records.item_count,
  94. "logged_in":request.authenticated_userid }
  95. @view_config(route_name='tiers_json', renderer="json")
  96. def JSON_Tiers_Request(request):
  97. """ Build a JSON answer with active users and pagination handling """
  98. # Check arguments consitency
  99. pageSize = request.params.get('pageSize',"8")
  100. current_page = request.params.get('pageNum',"1")
  101. TiersQuery = request.params.get('searchTerm', u"")
  102. # Don't answer to users that aren't logged
  103. if not request.user:
  104. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  105. # Check consistancy of parameters
  106. if pageSize.isdigit() and current_page.isdigit():
  107. current_page = int(current_page)
  108. pageSize = int(pageSize)
  109. else:
  110. return HTTPBadRequest('pageSize and pageNum accept only digits.')
  111. # Query database
  112. JTiers = DBSession.query(Tiers.uid, Tiers.name)\
  113. .filter(Tiers.slug.contains( remove_accents(TiersQuery) ))
  114. page_url = paginate.PageURL_WebOb(request)
  115. records = paginate.Page(JTiers, current_page, url=page_url, items_per_page=pageSize)
  116. ListMatchTiers = map( lambda t:{"id": t.uid, "text": t.name }, records )
  117. return { "Results": ListMatchTiers, "Total":records.item_count,
  118. "logged_in":request.authenticated_userid }
  119. @view_config(route_name='progr_json', renderer="json")
  120. def JSON_Progamme_Request(request):
  121. year = int(request.matchdict.get('year', CurrentYear))
  122. # Initialization
  123. DicResult = dict()
  124. # Query database
  125. # Compute days used by all events matching the specified input year
  126. Days = DBSession.query( func.strftime('%d', Event.start_time).label('day') )\
  127. .filter(Event.for_year == year)\
  128. .filter(Event.event_type != None)\
  129. .group_by(func.strftime('%d', Event.start_time)).all()
  130. for Day in Days:
  131. Events = DBSession.query(Event)\
  132. .filter(Event.for_year == year)\
  133. .filter(Event.event_type != 'Stand')\
  134. .filter("strftime('%d', start_time) = :dow").params(dow=Day.day)\
  135. .order_by(Event.start_time)
  136. ListEv = []
  137. for ev in Events:
  138. if ev.event_type:
  139. ListEv.append( {
  140. "uid":"%d/%d" % ( year, ev.uid ),
  141. "desc":ev.name,
  142. "startDate":ev.start_time.strftime('%Y-%m-%dT%H:%M:%S'),
  143. "endDate":ev.end_time.strftime('%Y-%m-%dT%H:%M:%S'),
  144. "placeName":ev.Salle and (ev.Salle.name or "unk") ,
  145. "status":ev.event_type
  146. } )
  147. DicResult[Day.day] = ListEv
  148. return { 'all':DicResult }
  149. @view_config(route_name='timeline_json', renderer="json")
  150. def JSON_TimeLine_Request(request):
  151. year = int(request.matchdict.get('year', CurrentYear))
  152. # Initialization
  153. DicResult = dict()
  154. # Query database
  155. # Compute days used by all events matching the specified input year
  156. Days = DBSession.query( func.strftime('%d', Event.start_time).label('day') )\
  157. .filter(Event.for_year == year)\
  158. .filter(Event.event_type != None)\
  159. .group_by(func.strftime('%d', Event.start_time)).all()
  160. ListEv = []
  161. for Day in Days:
  162. Events = DBSession.query(Event)\
  163. .filter(Event.for_year == year)\
  164. .filter(Event.event_type != 'Stand')\
  165. .filter("strftime('%d', start_time) = :dow").params(dow=Day.day)\
  166. .order_by(Event.start_time)
  167. #ListEv = []
  168. for ev in Events:
  169. if ev.event_type:
  170. CurMedia = ev.video.first() or ""
  171. if CurMedia:
  172. Container = "<video controls='controls' preload='metadata' style='width:60%'>"
  173. Container += "<source type='%s' " % CurMedia.mime_type
  174. Container += "src='%s' />" % CurMedia.get_path
  175. Container += "</video>"
  176. else:
  177. Container = ""
  178. ListEv.append( {
  179. #"uid":"%d/%d" % ( year, ev.uid ),
  180. "headline":ev.name,
  181. "startDate":ev.start_time.strftime('%Y,%m,%d,%H,%M'),
  182. "endDate":ev.end_time.strftime('%Y,%m,%d,%H,%M'),
  183. "text":ev.Salle and (ev.Salle.name or "unk"),
  184. #"text":ev.description[:100],
  185. "tags":ev.Salle and (ev.Salle.salle_id or "unk") ,
  186. #"status":ev.event_type,
  187. "asset": {
  188. "media": Container,
  189. "credit": ",".join(["%s %s" % (i.prenom, i.nom) for i in ev.intervenants]),
  190. "caption":"" }
  191. } )
  192. if year==2015:
  193. DicResult = {
  194. "lang":"fr",
  195. "headline":"JM2L 2015",
  196. "type":"default",
  197. "startDate":"2015,11,28,10",
  198. "text":"<i><span class='c1'>9ème Édition</span></i>",
  199. "asset":
  200. {
  201. "media":"https://www.youtube.com/watch?v=DnfjrxVoLao",
  202. "credit":"JM2L",
  203. "caption":""
  204. }
  205. }
  206. elif year==2011:
  207. DicResult = {
  208. "lang":"fr",
  209. "headline":"JM2L 2011",
  210. "type":"default",
  211. "startDate":"2011,11,25,10",
  212. "text":"<i><span class='c1'>6ème Édition</span></i>",
  213. "asset":
  214. {
  215. "media":"https://www.youtube.com/embed/rcaNeXuAEhs",
  216. "credit":"JM2L",
  217. "caption":"Reportage FR3"
  218. },
  219. }
  220. elif year==2010:
  221. DicResult = {
  222. "lang":"fr",
  223. "headline":"JM2L 2010",
  224. "type":"default",
  225. "text":"<i><span class='c1'>5ème Édition</span></i>",
  226. "asset":
  227. {
  228. "media":embeed_video("video/ogg","http://jm2l.linux-azur.org/resources/2010/Video/reportages/JM2L2010-PleinSudTV.ogv"),
  229. "credit":"<a href='http://pleinsudtv.com/index.php/casa/affichage-en-vignettes/93-casa-culture/582-les-jm-du-logiciel-libre-2010'>Le reportage Plein-sud TV</a>",
  230. "caption":"JM2L",
  231. }
  232. }
  233. elif year==2007:
  234. DicResult = {
  235. "lang":"fr",
  236. "headline":"JM2L 2007",
  237. "type":"default",
  238. "text":"<i><span class='c1'>2ème Édition</span></i>",
  239. "asset":
  240. {
  241. "media":embeed_video("video/ogg","http://jm2l.linux-azur.org/resources/2007/Video/20071110-linux.ogv"),
  242. "credit":"<a href='http://pleinsudtv.com/index.php/casa/affichage-en-vignettes/93-casa-culture/245-logiciel-libre-linux-jm2l'>Le reportage Plein-sud TV</a>",
  243. "caption":"JM2L 2007",
  244. }
  245. }
  246. else:
  247. DicResult = {
  248. "lang":"fr",
  249. "headline":"JM2L %d" % year,
  250. "type":"default",
  251. "asset":
  252. {
  253. "media":"",
  254. "credit":"JM2L",
  255. "caption":""
  256. }
  257. }
  258. DicResult["date"] = ListEv
  259. return { 'timeline':DicResult }
  260. ## =-=- Here, We handle HTTP requests - Public Part -=-=
  261. @view_config(route_name='home', renderer="jm2l:templates/NewIndex.mako")
  262. def index_page(request):
  263. year = request.matchdict.get('year')
  264. if year:
  265. year=int(year[:-1])
  266. content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
  267. if content:
  268. content = content.description
  269. else:
  270. content = ""
  271. if 2004<year<=CurrentYear:
  272. if year==2006:
  273. return {'year': year, 'content':content, 'edition':u"1<sup>ère</sup>" }
  274. elif year==2015:
  275. return {'year': year, 'content':content, 'edition':u"9<sup>ème</sup>" }
  276. else:
  277. edition = year - 2005
  278. return {'year': year, 'content':content, 'edition':u"%d<sup>ème</sup>" % edition }
  279. else:
  280. raise HTTPNotFound()
  281. else:
  282. content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==CurrentYear).first().description
  283. return {'year': CurrentYear, 'content':content, 'edition':u"9<sup>ème</sup>"}
  284. @view_config(route_name='edit_index', renderer="jm2l:templates/Staff/EditIndex.mako")
  285. def edit_index(request):
  286. year = int(request.matchdict.get('year', None))
  287. if not request.user.Staff:
  288. # Don't answer to users that aren't logged
  289. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  290. content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
  291. form = IndexForm(request.POST, content, meta={'csrf_context': request.session})
  292. if request.method == 'POST' and form.validate():
  293. form.populate_obj(content)
  294. return HTTPFound(location=request.route_url('home', year="%d/" % year))
  295. MainTab = {'home':'active', "logged_in":request.authenticated_userid,
  296. 'form':form, 'DisplayYear':year}
  297. return MainTab
  298. @view_config(route_name='programme', renderer="jm2l:templates/Public/Programme.mako")
  299. def programme(request):
  300. year = int(request.matchdict.get('year'))
  301. if 2006 > year:
  302. return HTTPBadRequest('The first JM2L event was in 2006.')
  303. # Query database about selected Year.
  304. Events = DBSession.query(Event)\
  305. .filter(Event.for_year == year)\
  306. .order_by(Event.start_time)
  307. Days = DBSession.query(func.strftime('%d-%m-%Y', Event.start_time))\
  308. .filter(Event.for_year == year)\
  309. .filter(Event.event_type != None)\
  310. .group_by(func.strftime('%d', Event.start_time)).all()
  311. ListDay = []
  312. for day in Days:
  313. RefDay = datetime.datetime.strptime(day[0],'%d-%m-%Y')
  314. ListDay.append( ( RefDay.strftime('%A %d %b %Y'),
  315. RefDay.strftime('%d') ) )
  316. MainTab = {'programme':'active','DisplayYear':year, \
  317. 'Events':Events, 'Event':Event, 'Days':ListDay, "logged_in":request.authenticated_userid }
  318. return MainTab
  319. @view_config(route_name='presse', renderer="jm2l:templates/Public/Presse.mako")
  320. def static_presse(request):
  321. year = int(request.matchdict.get('year', None))
  322. content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
  323. MainTab = {'presse':'active', "logged_in":request.authenticated_userid, 'content':content, 'DisplayYear':year}
  324. return MainTab
  325. @view_config(route_name='edit_presse', renderer="jm2l:templates/Staff/EditPresse.mako")
  326. def edit_presse(request):
  327. year = int(request.matchdict.get('year', None))
  328. if request.user is None:
  329. # Don't answer to users that aren't logged
  330. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  331. if not request.user.Staff:
  332. # Don't answer to users that aren't logged
  333. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  334. content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
  335. form = DossPresse(request.POST, content, meta={'csrf_context': request.session})
  336. if request.method == 'POST' and form.validate():
  337. form.populate_obj(content)
  338. MainTab = {'presse':'active', "logged_in":request.authenticated_userid, 'form':form, 'DisplayYear':year}
  339. return MainTab
  340. @view_config(route_name='plan', renderer="jm2l:templates/Public/Plan.mako")
  341. def static_plan(request):
  342. session = request.session
  343. session['year'] = 2015
  344. MainTab = {'plan':'active', "logged_in":request.authenticated_userid }
  345. return MainTab
  346. ## =-=- Here, We handle HTTP requests - Staff Logged Part -=-=
  347. @view_config(route_name='list_task', renderer='jm2l:templates/Staff/list.mako')
  348. def list_view(request):
  349. if request.user is None:
  350. # Don't answer to users that aren't logged
  351. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  352. if not request.user.Staff:
  353. # Don't answer to users that aren't logged
  354. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  355. DicTask = {}
  356. taskgroup = DBSession.query( TasksArea ).all()
  357. for grp in taskgroup:
  358. tasks = DBSession.query( Tasks )\
  359. .filter( Tasks.area_uid==grp.uid )\
  360. .order_by(Tasks.closed, Tasks.due_date).all()
  361. DicTask[grp] = tasks
  362. return {'tasks': DicTask }
  363. @view_config(route_name='handle_task', renderer='jm2l:templates/Staff/tasks.mako')
  364. def tasks(request):
  365. if request.user is None:
  366. # Don't answer to users that aren't logged
  367. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  368. if not request.user.Staff:
  369. # Don't answer to users that aren't logged
  370. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  371. task_id = request.matchdict.get('task_id')
  372. # Convert the pole_id GET parameter to int or 0
  373. try:
  374. pole_id = int(request.params.get('pole_id'))
  375. except (ValueError, TypeError):
  376. pole_id = 0
  377. # Get areas from db
  378. Areas = DBSession.query(TasksArea.uid, TasksArea.name)\
  379. .order_by('name').all()
  380. # Get users from db
  381. Users = DBSession.query(User)\
  382. .filter(User.Staff==1)\
  383. .order_by('nom').all()
  384. if task_id:
  385. Task = Tasks.by_id(int(task_id))
  386. if not Task:
  387. raise HTTPNotFound()
  388. form = EditStaffTasks(request.POST, Task, meta={'csrf_context': request.session})
  389. else:
  390. Task = Tasks()
  391. # Check if the supplied pole_id is in the Areas' range
  392. Task.area_uid = pole_id if 1 < pole_id <= len(Areas) else 1
  393. form = StaffTasks(request.POST, Task, meta={'csrf_context': request.session})
  394. # Put some areas on form
  395. form.area_uid.choices = Areas
  396. # Put some users on form
  397. form.closed_by.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
  398. for u in Users]
  399. form.due_date.type = "date"
  400. if request.method == 'POST' and form.validate():
  401. form.populate_obj(Task)
  402. Task.closed = False
  403. if 'uid' in form._fields.keys():
  404. DBSession.merge(Task)
  405. else:
  406. DBSession.add(Task)
  407. DBSession.flush()
  408. return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name))
  409. return {'form':form, 'area':slugify(Areas[Task.area_uid-1].name)}
  410. @view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako')
  411. def tasks_area(request):
  412. if request.user is None:
  413. # Don't answer to users that aren't logged
  414. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  415. if not request.user.Staff:
  416. # Don't answer to users that aren't logged
  417. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  418. pole_id = request.matchdict.get('pole_id')
  419. if pole_id:
  420. Pole = TasksArea.by_id(int(pole_id))
  421. if not Pole:
  422. raise HTTPNotFound()
  423. form = EditStaffArea(request.POST, Pole, meta={'csrf_context': request.session})
  424. else:
  425. Pole = TasksArea()
  426. form = StaffArea(request.POST, Pole, meta={'csrf_context': request.session})
  427. if request.method == 'POST' and form.validate():
  428. form.populate_obj(Pole)
  429. if 'uid' in form._fields.keys():
  430. DBSession.merge(Pole)
  431. else:
  432. DBSession.add(Pole)
  433. return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Pole.name))
  434. return {'form':form }
  435. @view_config(route_name='action_task')
  436. def action_task(request):
  437. if request.user is None:
  438. # Don't answer to users that aren't logged
  439. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  440. if not request.user.Staff:
  441. # Don't answer to users that aren't logged
  442. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  443. action = request.matchdict.get('action')
  444. task_id = request.matchdict.get('task_id')
  445. Task = Tasks.by_id(int(task_id))
  446. if action=='close':
  447. Task.closed = True
  448. request.session.flash(('info', u'La tâche a été fermé, Félicitations !'))
  449. DBSession.merge(Task)
  450. if action=='open':
  451. Task.closed = False
  452. request.session.flash(('info', u'La tâche a été ré-ouverte !'))
  453. DBSession.merge(Task)
  454. if action=='delete':
  455. request.session.flash(('info', u'La tâche a été supprimée !'))
  456. DBSession.delete(Task)
  457. return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name))
  458. @view_config(route_name='action_task_area')
  459. def action_task_area(request):
  460. if request.user is None:
  461. # Don't answer to users that aren't logged
  462. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  463. if not request.user.Staff:
  464. # Don't answer to users that aren't logged
  465. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  466. action = request.matchdict.get('action')
  467. pole_id = request.matchdict.get('pole_id')
  468. Pole = TasksArea.by_id(int(pole_id))
  469. if not Pole:
  470. raise HTTPNotFound()
  471. if action=='delete':
  472. request.session.flash(('info', u'Le pôle a été supprimé !'))
  473. DBSession.delete(Pole)
  474. return HTTPFound(location=request.route_url('list_task'))
  475. @view_config(route_name='list_salles', renderer='jm2l:templates/Salles/list.mako')
  476. def list_salles(request):
  477. if request.user is None:
  478. # Don't answer to users that aren't logged
  479. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  480. if not request.user.Staff:
  481. # Don't answer to users that aren't logged
  482. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  483. DicSalle = {}
  484. years = DBSession.query( JM2L_Year ).all()
  485. for year in years:
  486. salles = DBSession.query( Salles )\
  487. .filter( Salles.year_uid==year.year_uid )\
  488. .order_by(Salles.name).all()
  489. DicSalle[year] = salles
  490. return {'DicSalle': DicSalle }
  491. @view_config(route_name='handle_salle', renderer='jm2l:templates/Salles/salle.mako')
  492. def handle_salle(request):
  493. if request.user is None:
  494. # Don't answer to users that aren't logged
  495. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  496. if not request.user.Staff:
  497. # Don't answer to users that aren't logged
  498. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  499. salle_id = request.matchdict.get('salle_id')
  500. if salle_id:
  501. Salle = Salles.by_id(int(salle_id))
  502. if not Salle:
  503. raise HTTPNotFound()
  504. form = EditSalleForm(request.POST, Salle, meta={'csrf_context': request.session})
  505. else:
  506. Salle = Salles()
  507. form = SalleForm(request.POST, Salle, meta={'csrf_context': request.session})
  508. form.year_uid.choices = map(tuple, DBSession.query(JM2L_Year.year_uid, JM2L_Year.year_uid).all())
  509. form.phy_salle_id.choices = map(tuple, DBSession.query(SallePhy.uid, SallePhy.name).all())
  510. if request.method == 'POST' and form.validate():
  511. form.populate_obj(Salle)
  512. if 'uid' in form._fields.keys():
  513. DBSession.merge(Salle)
  514. else:
  515. DBSession.add(Salle)
  516. return HTTPFound(location=request.route_url('list_salles'))
  517. return {'form':form }
  518. @view_config(route_name='handle_salle_phy', renderer='jm2l:templates/Salles/salle_phy.mako')
  519. def handle_salle_phy(request):
  520. if request.user is None:
  521. # Don't answer to users that aren't logged
  522. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  523. if not request.user.Staff:
  524. # Don't answer to users that aren't logged
  525. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  526. salle_id = request.matchdict.get('salle_id')
  527. if salle_id:
  528. Salle = SallePhy.by_id(int(salle_id))
  529. if not Salle:
  530. raise HTTPNotFound()
  531. form = EditSallePhyForm(request.POST, Salle, meta={'csrf_context': request.session})
  532. else:
  533. Salle = SallePhy()
  534. form = SallePhyForm(request.POST, Salle, meta={'csrf_context': request.session})
  535. if request.method == 'POST' and form.validate():
  536. form.populate_obj(Salle)
  537. Salle.slug = slugify(Salle.name)
  538. if 'uid' in form._fields.keys():
  539. DBSession.merge(Salle)
  540. else:
  541. DBSession.add(Salle)
  542. return HTTPFound(location=request.route_url('list_salles'))
  543. return {'form':form }
  544. @view_config(route_name='action_salle')
  545. def action_salle(request):
  546. if request.user is None:
  547. # Don't answer to users that aren't logged
  548. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  549. if not request.user.Staff:
  550. # Don't answer to users that aren't logged
  551. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  552. action = request.matchdict.get('action')
  553. salle_id = request.matchdict.get('salle_id')
  554. Salle = Salles.by_id(int(salle_id))
  555. if not Salle:
  556. raise HTTPNotFound()
  557. if action=='delete':
  558. request.session.flash(('info', u'La Salle a été supprimée !'))
  559. DBSession.delete(Salle)
  560. return HTTPFound(location=request.route_url('list_salles'))
  561. ## =-=- Here, We handle HTTP requests - User Logged Part -=-=
  562. @view_config(route_name='exchange', renderer="jm2l:templates/Logistique/Logistique.mako")
  563. def exchange(request):
  564. modtype = request.matchdict.get('modtype', None)
  565. action = request.matchdict.get('action', None)
  566. uid = int(request.matchdict.get('id', -1))
  567. Exch = Exchange.by_id(uid)
  568. if not Exch:
  569. MainTab = {
  570. 'Exchanges':Exchange,
  571. 'Type':modtype[-1:],
  572. 'reload':True,
  573. 'logged_in':request.authenticated_userid
  574. }
  575. return MainTab
  576. if action in ['delete', 'accept', 'refuse', 'deal']:
  577. if action=='delete': # delete exchange
  578. DBSession.delete(Exch)
  579. elif action=='accept': # accept exchange
  580. Exch.exch_done=True
  581. DBSession.merge(Exch)
  582. elif action=='refuse': # refuse exchange
  583. Exch.exch_done=False
  584. if Exch.exch_state=="Ask":
  585. Exch.provider_id = None
  586. elif Exch.exch_state=="Proposal":
  587. Exch.asker_id = None
  588. DBSession.merge(Exch)
  589. elif action=='deal':
  590. # ask to deal the exchange
  591. if Exch.exch_state=="Ask":
  592. Exch.provider_id = request.user.uid
  593. elif Exch.exch_state=="Proposal":
  594. Exch.asker_id = request.user.uid
  595. # Return javascript to parent page
  596. response = render_to_response('jm2l:templates/modals_js.mako',
  597. {'modtype':modtype, 'action':action},
  598. request=request)
  599. response.content_type = 'text/javascript'
  600. return response
  601. else:
  602. MainTab = {
  603. 'Exchanges':Exchange,
  604. 'Type':modtype[-1:],
  605. 'reload':True,
  606. 'logged_in':request.authenticated_userid
  607. }
  608. return MainTab
  609. @view_config(route_name='miam')
  610. def miam(request):
  611. if request.user is None:
  612. # Don't answer to users that aren't logged
  613. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  614. miam_form = MiamForm(request.POST, request.user, meta={'csrf_context': request.session})
  615. if request.method == 'POST' and miam_form.validate():
  616. FicheSejour = Sejour.by_user(request.user.uid)
  617. if FicheSejour:
  618. Update=True
  619. else:
  620. FicheSejour = Sejour()
  621. FicheSejour.created = datetime.datetime.now()
  622. Update=False
  623. Repas=0
  624. for num, item in enumerate(['RepasVendredi', 'RepasSamediMidi', 'RepasSamediSoir']):
  625. if request.params.get(item)==u"1":
  626. Repas += 2**num
  627. FicheSejour.repas = Repas
  628. FicheSejour.repas_allerg = request.params.get('Allergies')
  629. FicheSejour.repas_contr = request.params.get('Contraintes')
  630. FicheSejour.user_id = request.user.uid
  631. FicheSejour.for_year = CurrentYear
  632. if Update:
  633. DBSession.merge(FicheSejour)
  634. else:
  635. DBSession.add(FicheSejour)
  636. request.session.flash(('info',u'Votre fiche a été mise à jour avec succès'))
  637. else:
  638. request.session.flash(('error',u'Un problème est survenu'))
  639. return HTTPFound(location='/MesJM2L#Miam')
  640. @view_config(route_name='sejour')
  641. def sejour(request):
  642. if request.user is None:
  643. # Don't answer to users that aren't logged
  644. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  645. if request.method == 'POST':
  646. FicheSejour = Sejour.by_user(request.user.uid)
  647. if FicheSejour:
  648. Update=True
  649. else:
  650. FicheSejour = Sejour()
  651. FicheSejour.created = datetime.datetime.now()
  652. Update=False
  653. FicheSejour.user_id = request.user.uid
  654. FicheSejour.last_change = datetime.datetime.now()
  655. FicheSejour.for_year = CurrentYear
  656. # Arrival
  657. ArrDate = datetime.datetime.strptime(request.params.get('Arrival:Day'),"%d/%m/%y")
  658. ArrTime = datetime.datetime.strptime(request.params.get('Arrival:Hour'),"%H:%M")
  659. FicheSejour.arrival_time = datetime.datetime.combine(ArrDate.date(), ArrTime.time())
  660. ArrivalCheck=0
  661. for num, item in enumerate(['Arrival:PMR', 'Arrival:Cov', 'Arrival:Bras', 'Arrival:Other']):
  662. if request.params.get(item):
  663. ArrivalCheck += 2**num
  664. FicheSejour.arrival_check = ArrivalCheck
  665. FicheSejour.arrival_text = request.params.get('Arrival:Comment')
  666. FicheSejour.arrival_place = request.params.get('Arrival:Place')
  667. # Departure
  668. DepDate = datetime.datetime.strptime(request.params.get('Departure:Day'),"%d/%m/%y")
  669. DepTime = datetime.datetime.strptime(request.params.get('Departure:Hour'),"%H:%M")
  670. FicheSejour.depart_time = datetime.datetime.combine(DepDate.date(), DepTime.time())
  671. DepartCheck=0
  672. for num, item in enumerate(['Departure:PMR', 'Departure:Cov', 'Departure:Bras', 'Departure:Other']):
  673. if request.params.get(item):
  674. DepartCheck += 2**num
  675. FicheSejour.depart_check = DepartCheck
  676. FicheSejour.depart_text = request.params.get('Departure:Comment')
  677. FicheSejour.depart_place = request.params.get('Departure:Place')
  678. if Update:
  679. DBSession.merge(FicheSejour)
  680. request.session.flash(('info',u'Vos modifications de séjour ont été pris en compte.'))
  681. else:
  682. DBSession.add(FicheSejour)
  683. request.session.flash(('info',u'\\o/ Votre séjour est enregistré ! Complétez la partie Logistique.'))
  684. return HTTPFound(location='/MesJM2L#Sejour')
  685. @view_config(route_name='vote_logo')
  686. def vote_logo(request):
  687. if request.user is None:
  688. # Don't answer to users that aren't logged
  689. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  690. else:
  691. vote = int(request.matchdict.get('num', -1))
  692. come = request.params.get('come_from')
  693. if vote:
  694. request.user.vote_logo=vote
  695. DBSession.merge(request.user)
  696. request.session.flash(('info',u'Votre vote à été pris en compte.'))
  697. return HTTPFound('/')
  698. else:
  699. request.session.flash(('warning',u"Votre vote n'a été pris en compte."))
  700. if come:
  701. return HTTPFound(location=come)
  702. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  703. @view_config(route_name='list_users', renderer="jm2l:templates/Participant/list.mako")
  704. def list_users(request):
  705. Data = DBSession.query(User, Sejour).outerjoin(Sejour).all()
  706. Repas = DBSession.query(Sejour.repas).all()
  707. DicRepas = {"Ven":0, "Midi":0, "Soir":0}
  708. for r in Repas:
  709. if (r[0] & 1 == 1): DicRepas["Ven"]+=1
  710. if (r[0] & 2 == 2): DicRepas["Midi"]+=1
  711. if (r[0] & 4 == 4): DicRepas["Soir"]+=1
  712. return { 'Users':Data, 'UserEvent' : User_Event, "DicRepas":DicRepas }
  713. @view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako")
  714. def jm2l_page(request):
  715. if request.user is None:
  716. # Don't answer to users that aren't logged
  717. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  718. UserNum = request.params.get('user')
  719. if UserNum:
  720. profil = User.by_id(int(UserNum))
  721. if not profil:
  722. raise HTTPNotFound()
  723. if not request.user.Staff:
  724. raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
  725. else:
  726. profil = request.user
  727. FicheSejour = Sejour()
  728. FicheSejour.created = datetime.datetime.now()
  729. # Build Form
  730. profil_form = ProfilForm(request.POST, profil, meta={'csrf_context': request.session})
  731. miam_form = MiamForm(request.POST, profil, meta={'csrf_context': request.session})
  732. # Feed FicheSejour if any
  733. FicheSejour = Sejour.by_user(profil.uid)
  734. if FicheSejour:
  735. if FicheSejour.repas is not None:
  736. for num, item in enumerate(['RepasVendredi', 'RepasSamediMidi', 'RepasSamediSoir']):
  737. if FicheSejour.repas & 2**num:
  738. miam_form._fields[item].data = "1"
  739. else:
  740. miam_form._fields[item].data = "0"
  741. miam_form._fields['Allergies'].data = FicheSejour.repas_allerg
  742. miam_form._fields['Contraintes'].data = FicheSejour.repas_contr
  743. if request.method == 'POST' and profil_form.validate():
  744. ToDelete = list()
  745. # First, we remove entries no more present
  746. for obj in profil_form.tiersship.object_data:
  747. MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
  748. profil_form.tiersship.entries )
  749. if not MatchEntry:
  750. ToDelete.append(obj)
  751. # Then, it's time to consider new entries
  752. for entry in profil_form.tiersship.entries:
  753. if entry.object_data is None:
  754. TmpUser = User_Tiers()
  755. entry.object_data = TmpUser
  756. profil.tiersship.append(TmpUser)
  757. profil_form.tiersship.object_data = profil.tiersship
  758. profil_form.populate_obj(profil)
  759. # We should remove it as it's not in original data
  760. for obj in ToDelete:
  761. #profil.tiersship.remove(obj)
  762. DBSession.delete(obj)
  763. profil.last_change = datetime.datetime.utcnow()
  764. profil.slug = slugify(remove_accents('%s %s' % (profil.prenom, profil.nom)).lower().strip())
  765. DBSession.merge(profil)
  766. request.session.flash(('info',u'Votre fiche a été mise à jour avec succès'))
  767. MainTab = {'participer':'active',
  768. 'Places':Place.get_list(False),
  769. 'DBTiers':Tiers,
  770. 'DBTiersOpt':TiersOpt,
  771. 'Exchanges':Exchange,
  772. 'profil_form':profil_form,
  773. 'miam_form':miam_form,
  774. 'uprofil':profil,
  775. 'logged_in':request.authenticated_userid
  776. }
  777. return MainTab
  778. @view_config(route_name='modal', renderer="jm2l:templates/modals.mako")
  779. def Modal(request):
  780. year = int(request.matchdict.get('year', None))
  781. modtype = request.matchdict.get('modtype', None)
  782. uid = int(request.matchdict.get('id', -1))
  783. session = request.session
  784. if modtype=='Password':
  785. form = UserPasswordForm(request.POST, request.user, meta={'csrf_context': request.session})
  786. if request.method == 'POST' and form.validate():
  787. response = render_to_response('jm2l:templates/modals_js.mako',
  788. {'modtype':modtype},
  789. request=request)
  790. request.user.password = form.password.data
  791. DBSession.merge(request.user)
  792. response.content_type = 'text/javascript'
  793. return response
  794. if modtype=='UserPicture':
  795. form = None
  796. if request.method == 'POST':
  797. response = render_to_response('jm2l:templates/modals_js.mako',
  798. {'modtype':modtype},
  799. request=request)
  800. response.content_type = 'text/javascript'
  801. return response
  802. if modtype=='Place':
  803. if uid>0:
  804. place = Place.by_id(uid)
  805. if not place:
  806. raise HTTPNotFound()
  807. form = PlaceUpdateForm(request.POST, place, meta={'csrf_context': request.session})
  808. else:
  809. place = Place()
  810. form = PlaceCreateForm(request.POST, meta={'csrf_context': request.session})
  811. if request.method == 'POST' and form.validate():
  812. form.populate_obj(place)
  813. place.created_by=request.user.uid
  814. if uid>0:
  815. DBSession.merge(place)
  816. else:
  817. DBSession.add(place)
  818. response = render_to_response('jm2l:templates/modals_js.mako',
  819. {'modtype':modtype},
  820. request=request)
  821. response.content_type = 'text/javascript'
  822. return response
  823. if modtype in ['AskC', 'AskH', 'AskM', 'PropC', 'PropH', 'PropM']:
  824. if uid>0:
  825. Exch = Exchange.by_id(uid)
  826. if not Exch:
  827. raise HTTPNotFound()
  828. if modtype in ['AskC','PropC']:
  829. form = globals()["Update%sForm" % modtype](request.POST, Exch,
  830. start_place = Exch.Itin.start_place,
  831. arrival_place = Exch.Itin.arrival_place,
  832. Hour_start = Exch.start_time.strftime("%H:%M"),
  833. Day_start = Exch.start_time.strftime("%w"),
  834. exch_id = uid, meta={'csrf_context': request.session}
  835. )
  836. elif modtype in ['AskM','PropM']:
  837. form = globals()["Update%sForm" % modtype](request.POST, Exch,
  838. description = Exch.description,
  839. exch_categ = Exch.exch_categ,
  840. Hour_start = Exch.start_time.strftime("%H:%M"),
  841. Day_start = Exch.start_time.strftime("%w"),
  842. Hour_end = Exch.end_time.strftime("%H:%M"),
  843. Day_end = Exch.end_time.strftime("%w"),
  844. exch_id = uid, meta={'csrf_context': request.session}
  845. )
  846. elif modtype in ['AskH','PropH']:
  847. form = globals()["Update%sForm" % modtype](request.POST, Exch,
  848. description = Exch.description,
  849. exch_categ = Exch.exch_categ,
  850. Day_start = Exch.start_time.strftime("%w"),
  851. exch_id = uid, meta={'csrf_context': request.session}
  852. )
  853. # Itinerary, first get itinerary
  854. if 0:
  855. form.itin.form.start_place.data = Exch.Itin.start_place
  856. form.itin.form.arrival_place.data = Exch.Itin.arrival_place
  857. form.dateform.form.Hour.data = Exch.start_time.strftime("%H:%M")
  858. form.dateform.form.Day.data = Exch.start_time.strftime("%w")
  859. form.exch_id.data = uid
  860. else:
  861. Exch = Exchange()
  862. form = globals()["%sForm" % modtype](request.POST, meta={'csrf_context': request.session})
  863. if modtype in ['AskC', 'PropC']:
  864. # Put some place on form
  865. Places = DBSession.query(Place.place_id, Place.display_name)\
  866. .order_by('name').all()
  867. form.start_place.choices = Places
  868. form.arrival_place.choices = Places
  869. if modtype in ['PropH']:
  870. form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\
  871. .filter( Exchange_Cat.exch_type=='H' ).all()
  872. form.place_id.choices = DBSession.query( Place.place_id, Place.display_name)\
  873. .filter( Place.created_by==request.user.uid ).all()
  874. if modtype in ['AskM', 'PropM']:
  875. form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\
  876. .filter( Exchange_Cat.exch_type=='M' ).all()
  877. if request.method == 'POST' and form.validate():
  878. # Form has been validated, it's time to create our Exchange
  879. Exch.for_year = year
  880. Exch.exch_state = {'Ask':'Ask', 'Prop':'Proposal'}[modtype[:-1]]
  881. Exch.exch_type = modtype[-1:]
  882. if modtype in ['AskC', 'PropC']:
  883. # Itinerary, first Let's see if itinerary exist
  884. Itinerary = DBSession.query(Itineraire)\
  885. .filter(Itineraire.start_place==form.start_place.data) \
  886. .filter(Itineraire.arrival_place==form.arrival_place.data) \
  887. .filter(Itineraire.tr_voiture==True) \
  888. .first()
  889. if not Itinerary: # Not exist yet !
  890. Itinerary = Itineraire(start_place=form.start_place.data, \
  891. arrival_place=form.arrival_place.data, \
  892. tr_voiture=True, \
  893. created_by=1
  894. )
  895. DBSession.add(Itinerary)
  896. DBSession.flush()
  897. Exch.itin_id = Itinerary.itin_id
  898. # Start Time
  899. StartEvent = DBSession.query(JM2L_Year.start_time).filter(JM2L_Year.year_uid==year).first()
  900. Week = StartEvent[0].strftime("%W")
  901. # populate
  902. form.populate_obj(Exch)
  903. if modtype in ['AskC', 'PropC']:
  904. Exch.itin_id = Itinerary.itin_id
  905. if form._fields.has_key("Hour_start"):
  906. TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
  907. int(form.Day_start.data), form.Hour_start.data), "%Y %W %w %H:%M")
  908. Exch.start_time = TargetTime
  909. elif form._fields.has_key("Day_start"):
  910. TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
  911. int(form.Day_start.data)), "%Y %W %w")
  912. Exch.start_time = TargetTime
  913. if form._fields.has_key("Hour_end"):
  914. TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
  915. int(form.Day_end.data), form.Hour_end.data), "%Y %W %w %H:%M")
  916. Exch.end_time = TargetTime
  917. elif form._fields.has_key("Day_end"):
  918. TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
  919. int(form.Day_end.data)), "%Y %W %w")
  920. Exch.end_time = TargetTime
  921. Exch.last_change = datetime.datetime.utcnow()
  922. if Exch.exch_state=='Ask':
  923. Exch.asker_id = request.user.uid
  924. elif Exch.exch_state=='Proposal':
  925. Exch.provider_id = request.user.uid
  926. #print vars(form.itin.form)
  927. if uid>0:
  928. DBSession.merge(Exch)
  929. else:
  930. DBSession.add(Exch)
  931. response = render_to_response('jm2l:templates/modals_js.mako',
  932. {'modtype':modtype},
  933. request=request)
  934. response.content_type = 'text/javascript'
  935. return response
  936. # Fallback to HTML Display with errors
  937. return {'modtype':modtype, 'form':form, 'update':uid>0,
  938. 'logged_in':request.authenticated_userid }
  939. if modtype in ['ShowC', 'ShowH', 'ShowM']:
  940. if uid>0:
  941. Exch = Exchange.by_id(uid)
  942. if not Exch:
  943. raise HTTPNotFound()
  944. else:
  945. raise HTTPNotFound()
  946. # Show Details around the Current Exchange
  947. return {'modtype':modtype, 'Exch':Exch, 'logged_in':request.authenticated_userid }
  948. MainTab = {'modtype':modtype, 'form':form, 'update':uid>0, 'uid':uid,
  949. 'DisplayYear':year, 'session':session,
  950. 'logged_in':request.authenticated_userid }
  951. return MainTab
  952. @view_config(route_name='participer', renderer="jm2l:templates/Participer.mako")
  953. def participer(request):
  954. session = request.session
  955. session['year'] = 2015
  956. TmpUsr = User()
  957. form = UserRegisterForm(request.POST, TmpUsr, meta={'csrf_context': request.session})
  958. MyLink=None
  959. if request.method == 'POST' and form.validate():
  960. # Prepare mailer
  961. form.populate_obj(TmpUsr)
  962. TmpUsr.nom = TmpUsr.nom.capitalize()
  963. TmpUsr.prenom = TmpUsr.prenom.capitalize()
  964. TmpUsr.slug = slugify(remove_accents('%s %s' % (form.prenom.data, form.nom.data)).lower().strip())
  965. TmpUsr.password = TmpUsr.my_hash
  966. if len(TmpUsr.slug):
  967. CheckExist = DBSession.query(User)\
  968. .filter(User.slug==TmpUsr.slug)\
  969. .first()
  970. else:
  971. CheckExist=None
  972. if CheckExist:
  973. MyLink = CheckExist.my_hash
  974. NewUser = CheckExist
  975. else:
  976. DBSession.add(TmpUsr)
  977. DBSession.flush()
  978. MyLink = TmpUsr.my_hash
  979. NewUser = TmpUsr
  980. # Send the Welcome Mail
  981. mailer = request.registry['mailer']
  982. # Prepare Plain Text Message :
  983. Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
  984. mail_plain = Mail_template.render(request=request, User=NewUser, action="Welcome")
  985. # Prepare HTML Message :
  986. Mail_template = Template(filename='jm2l/templates/mail_html.mako')
  987. mail_html = Mail_template.render(request=request, User=NewUser, action="Welcome")
  988. # Prepare Message
  989. message = Message(subject="[JM2L] Mon inscription au site web JM2L",
  990. sender="contact@jm2l.linux-azur.org",
  991. recipients=[NewUser.mail or TmpUsr.mail],
  992. body=mail_plain, html=mail_html)
  993. message.add_bcc("spam@style-python.fr")
  994. mailer.send(message)
  995. request.session.flash(('info',u"Un mail vous a été envoyé afin de continuer votre quête !"))
  996. MainTab = {'programme':'','presse':'', 'plan':'',
  997. 'participer':'active', 'form':form, "link": MyLink,
  998. 'logged_in':request.authenticated_userid }
  999. return MainTab
  1000. @view_config(route_name='year')
  1001. def change_year(request):
  1002. year = int(request.matchdict.get('year', -1))
  1003. session = request.session
  1004. if year>-1:
  1005. session['year'] = year
  1006. return HTTPFound(location='/%s/' % year)
  1007. return HTTPFound(location=request.route_url('home', year=''))
  1008. @view_config(route_name='pict_user', renderer="jm2l:templates/Profil/pict_user.mako")
  1009. def pict_user(request):
  1010. return {"uprofil":request.user}
  1011. @view_config(route_name='pict_salle', renderer="jm2l:templates/Salles/pict_salle.mako")
  1012. def pict_salle(request):
  1013. salle_id = int(request.matchdict.get('salle_id', -1))
  1014. return {"Salles":Salles, "IdSalle":salle_id}
  1015. @view_config(route_name='event', renderer="jm2l:templates/view_event.mako")
  1016. def show_event(request):
  1017. year = int(request.matchdict.get('year', -1))
  1018. event_id = request.matchdict.get('event_id')
  1019. if event_id.isdigit():
  1020. TheEvent = Event.by_id(event_id)
  1021. if TheEvent is None:
  1022. raise HTTPNotFound()
  1023. else:
  1024. TheEvent = Event.by_slug(event_id, year)
  1025. if TheEvent is None:
  1026. raise HTTPNotFound()
  1027. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1028. 'event':TheEvent, 'logged_in':request.authenticated_userid, "Salles":Salles }
  1029. return MainTab
  1030. @view_config(route_name='link_event_user')
  1031. def link_event_user(request):
  1032. """ Get user and add it to current event """
  1033. if request.user is None:
  1034. # Don't answer to users that aren't logged
  1035. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1036. year = int(request.matchdict.get('year', -1))
  1037. form = AddIntervenant(request.POST, meta={'csrf_context': request.session})
  1038. intervention = request.matchdict.get('intervention', None)
  1039. TargetEvent = Event.by_id(form.event_uid.data)
  1040. Exist = User.by_id(form.intervenant.data)
  1041. if not Exist:
  1042. request.session.flash(('error',u"Une erreur s'est produite lors de l'ajout de votre intervenant !"))
  1043. return HTTPFound(location=request.route_url('edit_event', sep='/',
  1044. year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
  1045. else:
  1046. TargetUser = Exist
  1047. uev = User_Event(year_uid=year, role=u"Animateur d'un évenement JM2L", user_uid=TargetUser.uid)
  1048. TargetEvent.interventions.append( uev )
  1049. return HTTPFound(location=request.route_url('edit_event', sep='/',
  1050. year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
  1051. @view_config(route_name='link_event_tiers')
  1052. def link_event_tiers(request):
  1053. """ Create user if not exist, add it to current event """
  1054. if request.user is None:
  1055. # Don't answer to users that aren't logged
  1056. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1057. year = int(request.matchdict.get('year', -1))
  1058. form = AddTiers(request.POST, meta={'csrf_context': request.session})
  1059. intervention = request.matchdict.get('intervention', None)
  1060. TargetEvent = Event.by_id(form.event_uid.data)
  1061. Exist = Tiers.by_id(form.tiers.data)
  1062. if not Exist:
  1063. request.session.flash(('error',u"Une erreur s'est produite lors de l'ajout de votre entité !"))
  1064. return HTTPFound(location=request.route_url('edit_event', sep='/',
  1065. year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
  1066. else:
  1067. TargetTiers = Exist
  1068. if len(DBSession.query(Role_Tiers)\
  1069. .filter(Role_Tiers.year_uid==year)\
  1070. .filter(Role_Tiers.tiers_role=="Exposant")\
  1071. .filter(Role_Tiers.tiers_uid==TargetTiers.uid)\
  1072. .all())==0:
  1073. tev = Role_Tiers(year_uid=year, tiers_role="Exposant", tiers_uid=TargetTiers.uid)
  1074. DBSession.add(tev)
  1075. return HTTPFound(location=request.route_url('edit_event', sep='/',
  1076. year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
  1077. @view_config(route_name='edit_event', renderer="jm2l:templates/edit_event.mako")
  1078. def edit_event(request):
  1079. if request.user is None:
  1080. # Don't answer to users that aren't logged
  1081. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1082. year = int(request.matchdict.get('year', -1))
  1083. event_id = request.matchdict.get('event_id')
  1084. intervention = request.matchdict.get('intervention', None)
  1085. IntervLabel = intervention.replace('_',' ').lower()
  1086. if intervention=='Conference':
  1087. IntervLabel = u'conférence'
  1088. # Check intervention
  1089. if not intervention in ['Stand', 'Table ronde', 'Atelier', 'Conference', 'Concert']:
  1090. raise HTTPNotFound(u"Ce type d'évenement n'est pas reconnu")
  1091. TheYear = DBSession.query(JM2L_Year)\
  1092. .filter(JM2L_Year.year_uid==year)\
  1093. .first()
  1094. # Check year avaibility
  1095. if not TheYear:
  1096. raise HTTPNotFound(u"Cette année n'est pas pris en charge")
  1097. # Generate Timeslots for current year
  1098. TimeSlots = list(enumerate( [ x.strftime('%a %d %b %H:%M') for x in
  1099. TheYear.AvailableTimeSlots ] ))
  1100. if event_id:
  1101. # We try to update an existing record
  1102. if event_id.isdigit():
  1103. TheEvent = Event.by_id(event_id)
  1104. if TheEvent is None:
  1105. raise HTTPNotFound(u"Cette réference n'existe pas")
  1106. else:
  1107. TheEvent = Event.by_slug(event_id, year)
  1108. if TheEvent is None:
  1109. raise HTTPNotFound(u"Cette réference n'existe pas")
  1110. if request.user is None or not (request.user.Staff or request.user in TheEvent.intervenants):
  1111. raise HTTPForbidden(u"Vous n'êtes pas identifié comme étant un participant à cette intervention.")
  1112. # Compute some field value from selected event
  1113. if TheEvent.start_time in TheYear.AvailableTimeSlots:
  1114. start_sel = TheYear.AvailableTimeSlots.index(TheEvent.start_time)
  1115. else:
  1116. start_sel = len(TimeSlots)
  1117. TimeSlots.append( (len(TimeSlots), TheEvent.start_time.strftime('%a %d %b %H:%M')))
  1118. duration = (TheEvent.end_time - TheEvent.start_time).total_seconds()/60
  1119. end = TheEvent.start_time + datetime.timedelta(minutes=duration)
  1120. # prepare the form with update
  1121. form = ConfUpdateForm(request.POST, TheEvent, start_sel=start_sel, duration=duration, end_time=end,
  1122. meta={'csrf_context': request.session} )
  1123. # Customize labels
  1124. form.name.label.text += IntervLabel
  1125. form.description.label.text += IntervLabel
  1126. # Each event can get severals members
  1127. formAdd = AddIntervenant(event_uid=TheEvent.uid)
  1128. # Build list of intervenant
  1129. # Get users from db
  1130. Users = DBSession.query(User)\
  1131. .filter(User.Staff==1)\
  1132. .order_by('nom').all()
  1133. # Put some users on form
  1134. formAdd.intervenant.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
  1135. for u in Users]
  1136. # Each event can get severals entities
  1137. formAddT = AddTiers(event_uid=TheEvent.uid)
  1138. # Build list of entities
  1139. # Get entities from db
  1140. TmpTiers = DBSession.query(Tiers)\
  1141. .order_by('name').limit(10)
  1142. # Put some entities on form
  1143. formAddT.tiers.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
  1144. for u in Users]
  1145. else:
  1146. TheEvent = Event()
  1147. # prepare the form for creation
  1148. form = ConfCreateForm(request.POST,
  1149. event_type=intervention,
  1150. for_year=str(year), meta={'csrf_context': request.session}
  1151. )
  1152. # Customize labels
  1153. form.name.label.text += IntervLabel
  1154. form.description.label.text += IntervLabel
  1155. duration=60
  1156. # No intervenant
  1157. formAdd = None
  1158. formAddT = None
  1159. SalleDispo = DBSession.query(Salles)\
  1160. .filter(Salles.year_uid==year)\
  1161. .order_by('name')
  1162. if intervention=="Conference":
  1163. form.duration.choices =[
  1164. (15,u'Lighting talk ( 5 min)'),
  1165. (30,u'Conférence (20 min)'),
  1166. (60,u'Conférence (50 min)'),
  1167. (90,u'Conférence (75 min)'),
  1168. ]
  1169. if not duration in [15, 30, 60, 90]:
  1170. form.duration.choices.append( (duration,u'Conférence (%d min)' % duration) )
  1171. if not form._fields.has_key("uid"):
  1172. form.duration.data=60
  1173. SalleDispo = SalleDispo.filter(Salles.place_type=='Conference')
  1174. elif intervention=="Stand":
  1175. form.duration.choices =[
  1176. (8*60, u'Toute la journée'),
  1177. (4*60, u'une demi-journée')
  1178. ]
  1179. SalleDispo = SalleDispo.filter(Salles.place_type=='Stand')
  1180. elif intervention=="Atelier":
  1181. form.duration.choices = map( lambda d:(d, u'Atelier (%dh%.2d)' % (d/60, d%60) ), \
  1182. [60, 90, 120, 150, 180, 210, 240] )
  1183. if not duration in map(lambda (d,y): d, form.duration.choices):
  1184. form.duration.choices.append( (duration,u'Atelier (%dh%.2d)' % (duration/60, duration%60) ) )
  1185. SalleDispo = SalleDispo.filter(Salles.place_type=='Ateliers')
  1186. elif intervention=="Table ronde":
  1187. form.duration.choices = map( lambda d:(d, u'Table ronde (%dh%.2d)' % (d/60, d%60) ), \
  1188. [60, 90, 120, 150] )
  1189. if not duration in map(lambda (d,y): d, form.duration.choices):
  1190. form.duration.choices.append( (duration,u'Table ronde (%dh%.2d)' % (duration/60, duration%60) ) )
  1191. SalleDispo = SalleDispo.filter(Salles.place_type=='Conference')
  1192. elif intervention=="Concert":
  1193. form.duration.choices = map( lambda d:(d, u'Concert (%dh%.2d)' % (d/60, d%60) ), \
  1194. [60, 90, 120, 150, 180, 210, 240] )
  1195. if not duration in map(lambda (d,y): d, form.duration.choices):
  1196. form.duration.choices.append( (duration,u'Concert (%dh%.2d)' % (duration/60, duration%60) ) )
  1197. SalleDispo = SalleDispo.filter(Salles.place_type=='Stand')
  1198. else:
  1199. raise HTTPForbidden(u"Pas encore disponible.")
  1200. form.salle_uid.choices = [(s.salle_id, s.name) for s in SalleDispo]
  1201. form.start_sel.choices = TimeSlots
  1202. if request.method == 'POST' and form.validate():
  1203. form.populate_obj(TheEvent)
  1204. TheEvent.start_time = TheYear.AvailableTimeSlots[form.start_sel.data]
  1205. TheEvent.end_time = TheEvent.start_time + datetime.timedelta(minutes=form.duration.data)
  1206. # Ok, time to put in database
  1207. if not form._fields.has_key("uid"):
  1208. TheEvent.slug = slugify(TheEvent.name)
  1209. DBSession.add(TheEvent)
  1210. # Append creator by default
  1211. if request.user.uid!=1:
  1212. uev = User_Event(year_uid=TheYear.year_uid, role="Animateur")
  1213. uev.user_uid = request.user.uid
  1214. TheEvent.interventions.append( uev )
  1215. DBSession.flush()
  1216. request.session.flash(('sucess',u'Votre intervention a été créee !'))
  1217. return HTTPFound(location=request.route_url('edit_event', sep='/',
  1218. year=str(year), intervention=intervention, event_id=str(TheEvent.slug)))
  1219. else:
  1220. DBSession.merge(TheEvent)
  1221. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1222. 'event':TheEvent, 'form':form, 'formAdd':formAdd, 'formAddT':formAddT,
  1223. 'Salles':Salles,
  1224. 'logged_in':request.authenticated_userid }
  1225. return MainTab
  1226. @view_config(route_name='entities', renderer="jm2l:templates/list_tiers.mako")
  1227. def list_tiers(request):
  1228. Entities = dict()
  1229. EntityType = DBSession.query(TiersOpt.entity_type)\
  1230. .group_by(TiersOpt.entity_type).all()
  1231. for EType in EntityType:
  1232. Entities[EType.entity_type] = DBSession.query(Tiers).join(TiersOpt)\
  1233. .filter(TiersOpt.entity_type==EType.entity_type)\
  1234. .order_by(TiersOpt.entity_subtype, Tiers.name)
  1235. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1236. 'entities':Entities, 'logged_in':request.authenticated_userid }
  1237. return MainTab
  1238. @view_config(route_name='show_entity', renderer="jm2l:templates/view_tiers.mako")
  1239. def show_tiers(request):
  1240. tiers_type = request.matchdict.get('tiers_type')
  1241. entity_id = request.matchdict.get('entity_id')
  1242. if entity_id.isdigit():
  1243. TheTiers = Tiers.by_id(entity_id)
  1244. if TheTiers is None:
  1245. raise HTTPNotFound()
  1246. else:
  1247. TheTiers = Tiers.by_slug(entity_id)
  1248. if TheTiers is None:
  1249. raise HTTPNotFound()
  1250. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1251. 'entity':TheTiers, 'logged_in':request.authenticated_userid }
  1252. return MainTab
  1253. @view_config(route_name='delete_entity')
  1254. def delete_tiers(request):
  1255. if request.user is None:
  1256. # Don't answer to users that aren't logged
  1257. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1258. entity_id = request.matchdict.get('entity_id', None)
  1259. if entity_id:
  1260. if entity_id.isdigit():
  1261. TheTiers = Tiers.by_id(int(entity_id))
  1262. if TheTiers is None:
  1263. raise HTTPNotFound()
  1264. else:
  1265. TheTiers = Tiers.by_slug(entity_id)
  1266. if TheTiers is None:
  1267. raise HTTPNotFound()
  1268. if len(TheTiers.membership)!=0:
  1269. request.session.flash(('error', u"Vous devez supprimer tous les membres liés avant la suppression d'une entité."))
  1270. return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, tiers_type=TheTiers.get_entity_type.slug_entity_type))
  1271. if len(TheTiers.membership)!=0:
  1272. request.session.flash(('error', u"Vous devez supprimer tous les roles liés avant la suppression d'une entité."))
  1273. return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, tiers_type=TheTiers.get_entity_type.slug_entity_type))
  1274. DBSession.delete(TheTiers)
  1275. request.session.flash(('info', u"L'entité a bien été supprimée"))
  1276. return HTTPFound(location=request.route_url('entities'))
  1277. else:
  1278. raise HTTPNotFound()
  1279. @view_config(route_name='add_entity', renderer="jm2l:templates/edit_tiers.mako")
  1280. @view_config(route_name='edit_entity', renderer="jm2l:templates/edit_tiers.mako")
  1281. def edit_tiers(request):
  1282. entity_id = request.matchdict.get('entity_id', None)
  1283. TargetList = list()
  1284. if request.user is None:
  1285. # Don't answer to users that aren't logged
  1286. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1287. entity_types = DBSession.query(TiersOpt.entity_type).group_by(TiersOpt.entity_type).all()
  1288. for entity_type in entity_types:
  1289. entity_subtypes = DBSession.query(TiersOpt)\
  1290. .filter(TiersOpt.entity_type==entity_type.entity_type)\
  1291. .group_by(TiersOpt.entity_subtype).all()
  1292. ListType = [(i.uid, i.entity_subtype) for i in entity_subtypes]
  1293. TargetList.append( (entity_type.entity_type, ListType) )
  1294. if entity_id:
  1295. if entity_id.isdigit():
  1296. TheTiers = Tiers.by_id(entity_id)
  1297. if TheTiers is None:
  1298. raise HTTPNotFound()
  1299. else:
  1300. TheTiers = Tiers.by_slug(entity_id)
  1301. if TheTiers is None:
  1302. raise HTTPNotFound()
  1303. form = UpdateTiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
  1304. UserOptions = DBSession.query(TiersOpt)\
  1305. .filter(TiersOpt.entity_type==TheTiers.tiers_type)\
  1306. .all()
  1307. form.tiers_type.choices = TargetList
  1308. else:
  1309. TheTiers = Tiers()
  1310. # prepare the form for creation
  1311. form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
  1312. form.tiers_type.choices = TargetList
  1313. UserOptions = list()
  1314. #test_form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
  1315. if request.method == 'POST' and form.validate():
  1316. ToDelete = list()
  1317. ToDeleteR = list()
  1318. # First, we remove entries no more present
  1319. for obj in form.membership.object_data:
  1320. MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
  1321. form.membership.entries )
  1322. if not MatchEntry:
  1323. ToDelete.append(obj)
  1324. # For roles too
  1325. for obj in form.roles.object_data:
  1326. MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
  1327. form.roles.entries )
  1328. if not MatchEntry:
  1329. ToDeleteR.append(obj)
  1330. # We should remove it as it's not in original data
  1331. for obj in ToDelete:
  1332. TheTiers.membership.remove(obj)
  1333. DBSession.delete(obj)
  1334. # For roles too
  1335. for obj in ToDeleteR:
  1336. TheTiers.roles.remove(obj)
  1337. DBSession.delete(obj)
  1338. # Then, it's time to consider new entries
  1339. for entry in form.membership.entries:
  1340. if entry.object_data is None:
  1341. TmpUser = User_Tiers()
  1342. entry.object_data = TmpUser
  1343. TheTiers.membership.append(TmpUser)
  1344. form.membership.object_data = TheTiers.membership
  1345. # For roles too
  1346. for entry in form.roles.entries:
  1347. if entry.object_data is None:
  1348. TmpRole = Role_Tiers()
  1349. entry.object_data = TmpRole
  1350. TheTiers.roles.append(TmpRole)
  1351. form.roles.object_data = TheTiers.roles
  1352. form.populate_obj(TheTiers)
  1353. # Handle Remove of accents
  1354. TheTiers.slug = slugify(form.name.data)
  1355. if not form._fields.has_key('uid'):
  1356. TheTiers.creator_id = request.user.uid
  1357. DBSession.add(TheTiers)
  1358. DBSession.flush()
  1359. return HTTPFound(location=request.route_url('edit_entity', sep='/',
  1360. entity_id=str(TheTiers.slug), tiers_type=TheTiers.get_entity_type.entity_type))
  1361. DBSession.merge(TheTiers)
  1362. return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug,
  1363. tiers_type=TheTiers.get_entity_type.slug_entity_type))
  1364. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1365. 'form':form, 'DBUser':User, 'UserOptions':UserOptions,
  1366. 'logged_in':request.authenticated_userid }
  1367. return MainTab
  1368. @view_config(route_name='edit_entity_cat', renderer="jm2l:templates/edit_tiers_categ.mako")
  1369. def edit_tiers_category(request):
  1370. if request.user is None:
  1371. # Don't answer to users that aren't logged
  1372. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1373. DicResult = dict()
  1374. ListChanges = list()
  1375. if request.method == 'POST':
  1376. # Reformat data
  1377. RegExist = re.compile('collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[(?P<id>\d+)\]')
  1378. RegTitle = re.compile('collection\[(?P<slug>[\w-]+)\]\[title]')
  1379. RegNew = re.compile('collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[id\]')
  1380. for key, value in request.POST.iteritems():
  1381. regN= RegNew.match(key)
  1382. regT= RegTitle.match(key)
  1383. reg = RegExist.match(key)
  1384. if reg:
  1385. if not DicResult.has_key(reg.group('slug')):
  1386. DicResult[reg.group('slug')] = dict()
  1387. if DicResult[reg.group('slug')].has_key('items'):
  1388. DicResult[reg.group('slug')]['items'].append( ( int(reg.group('id')), value ) )
  1389. else:
  1390. DicResult[reg.group('slug')]['items'] = [ ( int(reg.group('id')), value ) ]
  1391. elif regN:
  1392. if not DicResult.has_key(regN.group('slug')):
  1393. DicResult[regN.group('slug')] = dict()
  1394. if DicResult[regN.group('slug')].has_key('items'):
  1395. DicResult[regN.group('slug')]['items'].append( ( 'id', value ) )
  1396. else:
  1397. DicResult[regN.group('slug')]['items'] = [ ( 'id', value ) ]
  1398. ListChanges.append(('add', 0, DicResult[regN.group('slug')]['title'], value))
  1399. elif regT:
  1400. if not DicResult.has_key(regT.group('slug')):
  1401. DicResult[regT.group('slug')] = dict()
  1402. DicResult[regT.group('slug')]['title'] = value
  1403. else:
  1404. raise
  1405. for opt in DBSession.query(TiersOpt).all():
  1406. if DicResult.has_key(opt.slug_entity_type):
  1407. found = filter( lambda (x,y): opt.uid==x,
  1408. DicResult[opt.slug_entity_type].get('items', []))
  1409. if not found:
  1410. ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
  1411. else:
  1412. for tst in found:
  1413. # Check changes on Cat Name
  1414. if DicResult[opt.slug_entity_type]['title']!=opt.entity_type or \
  1415. tst[1]!=opt.entity_subtype:
  1416. ListChanges.append(('changed', opt.uid,
  1417. DicResult[opt.slug_entity_type]['title'],
  1418. tst[1]))
  1419. else:
  1420. ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
  1421. # Do The change
  1422. for action, uid, entity, subentity in ListChanges:
  1423. if action=="changed":
  1424. opt = TiersOpt.by_id(uid)
  1425. opt.entity_type = entity
  1426. opt.entity_subtype = subentity
  1427. elif action=="remove":
  1428. opt = TiersOpt.by_id(uid)
  1429. DBSession.delete(opt)
  1430. elif action=="add":
  1431. opt = TiersOpt()
  1432. opt.entity_type = entity
  1433. opt.entity_subtype = subentity
  1434. DBSession.add(opt)
  1435. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1436. 'logged_in':request.authenticated_userid, 'TiersOpt':TiersOpt }
  1437. return MainTab
  1438. @view_config(route_name='show_user', renderer="jm2l:templates/view_user.mako")
  1439. def show_user(request):
  1440. user_slug = request.matchdict.get('user_slug', None)
  1441. if user_slug is None or len(user_slug)==0:
  1442. raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
  1443. # Query database
  1444. DispUser = User.by_slug(user_slug)
  1445. if DispUser is None:
  1446. raise HTTPNotFound()
  1447. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1448. 'DispUser':DispUser, 'logged_in':request.authenticated_userid }
  1449. return MainTab
  1450. #@view_config(route_name='link_user_entity')
  1451. def link_user_entity(request):
  1452. if request.user is None:
  1453. # Don't answer to users that aren't logged
  1454. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1455. uid = int(request.matchdict.get('uid', -1))
  1456. year = int(request.matchdict.get('year', -1))
  1457. user_id = int(request.matchdict.get('uid', -1))
  1458. TheTiers = Tiers.by_id(uid)
  1459. if TheTiers is None:
  1460. raise HTTPNotFound()
  1461. return HTTPFound(location=request.route_url('edit_entity', uid=uid) )
  1462. #@view_config(route_name='link_role_entity')
  1463. def link_role_entity(request):
  1464. if request.user is None:
  1465. # Don't answer to users that aren't logged
  1466. raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
  1467. uid = int(request.matchdict.get('uid', -1))
  1468. year = int(request.matchdict.get('year', -1))
  1469. role_id = int(request.matchdict.get('role_id', -1))
  1470. TheTiers = Tiers.by_id(uid)
  1471. if TheTiers is None:
  1472. raise HTTPNotFound()
  1473. return HTTPFound(location=request.route_url('edit_entity', uid=uid) )
  1474. @forbidden_view_config()
  1475. def forbidden(reason, request):
  1476. if 'ident' in reason.detail:
  1477. request.session.flash(('info', reason.detail))
  1478. return HTTPFound(location='/sign/login' )
  1479. else:
  1480. request.response.status = 403
  1481. return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason },
  1482. request=request)
  1483. @notfound_view_config()
  1484. def notfound(reason, request):
  1485. request.response.status = 404
  1486. return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason },
  1487. request=request)