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