Le repo des sources pour le site web des JM2L
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1600 lines
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)