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.
 
 
 
 
 

1137 lines
49 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. ## =-=- Here, We handle ICal requests -=-=
  37. @view_config(route_name='progr_iCal', renderer="string")
  38. def ICal_Progamme_Request(request):
  39. year = int(request.matchdict.get('year', CurrentYear))
  40. # Initialization
  41. DicResult = dict()
  42. # Query database
  43. # Compute days used by all events matching the specified input year
  44. Events = DBSession.query(Event)\
  45. .filter(Event.for_year == year)\
  46. .filter(Event.event_type != 'Stand')\
  47. .order_by(Event.start_time)
  48. cal = Calendar()
  49. cal.add('prodid', '-//Programme %d//jm2l.linux-azur.org//' % year)
  50. cal.add('version', '2.0')
  51. tz = timezone('Europe/Paris')
  52. for ev in Events:
  53. if ev.event_type:
  54. event = Evt()
  55. event['uid'] = "%d/%d" % ( year, ev.uid )
  56. event.add('summary', ev.name )
  57. event.add('dtstart', ev.start_time.replace(tzinfo=tz) )
  58. event.add('dtend', ev.end_time.replace(tzinfo=tz) )
  59. event.add('created', ev.last_change.replace(tzinfo=tz) )
  60. event.add('description', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) )
  61. event.add('url', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) )
  62. event.add('priority', 5)
  63. cal.add_component(event)
  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('You have to be logged to hope an answer.')
  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('You have to be logged to hope an answer.')
  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. ListEv.append( {
  166. #"uid":"%d/%d" % ( year, ev.uid ),
  167. "headline":ev.name,
  168. "startDate":ev.start_time.strftime('%Y,%m,%d,%H,%M'),
  169. "endDate":ev.end_time.strftime('%Y,%m,%d,%H,%M'),
  170. "text":ev.Salle and (ev.Salle.name or "unk"),
  171. "tags":ev.Salle and (ev.Salle.name or "unk") ,
  172. #"status":ev.event_type,
  173. "asset": {
  174. "media":"", #http://jm2l.linux-azur.org/sites/jm2l.linux-azur.org/files/videos/2012/2012_Introduction_aux_logiciels_libres__Frederic_Couchet.ogv",
  175. "credit":"",
  176. "caption":"" }
  177. } )
  178. break
  179. DicResult = {
  180. "lang":"fr",
  181. "headline":"JM2L 2015",
  182. "type":"default",
  183. "startDate":"2015,11,28,10",
  184. "text":"<i><span class='c1'>9ème Édition</span></i>",
  185. "asset":
  186. {
  187. "media":"https://www.youtube.com/watch?v=DnfjrxVoLao",
  188. "credit":"JM2L",
  189. "caption":""
  190. }
  191. }
  192. DicResult["date"] = ListEv
  193. return { 'timeline':DicResult }
  194. ## =-=- Here, We handle HTTP requests - Public Part -=-=
  195. @view_config(route_name='home', renderer="jm2l:templates/NewIndex.mako")
  196. def index_page(request):
  197. MainTab = {'accueil':'active', "logged_in":request.authenticated_userid }
  198. return MainTab
  199. @view_config(route_name='programme', renderer="jm2l:templates/Public/Programme.mako")
  200. def programme(request):
  201. year = int(request.matchdict.get('year'))
  202. if 2006 > year:
  203. return HTTPBadRequest('The first JM2L event was in 2006.')
  204. # Query database about selected Year.
  205. Events = DBSession.query(Event)\
  206. .filter(Event.for_year == year)\
  207. .order_by(Event.start_time)
  208. Days = DBSession.query(func.strftime('%d-%m-%Y', Event.start_time))\
  209. .filter(Event.for_year == year)\
  210. .filter(Event.event_type != None)\
  211. .group_by(func.strftime('%d', Event.start_time)).all()
  212. ListDay = []
  213. for day in Days:
  214. RefDay = datetime.datetime.strptime(day[0],'%d-%m-%Y')
  215. ListDay.append( ( RefDay.strftime('%A %d %b %Y'),
  216. RefDay.strftime('%d') ) )
  217. MainTab = {'programme':'active','DisplayYear':year, \
  218. 'Events':Events, 'Event':Event, 'Days':ListDay, "logged_in":request.authenticated_userid }
  219. return MainTab
  220. @view_config(route_name='presse', renderer="jm2l:templates/Public/Presse.mako")
  221. def static_presse(request):
  222. year = int(request.matchdict.get('year', None))
  223. content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
  224. MainTab = {'presse':'active', "logged_in":request.authenticated_userid, 'content':content, 'DisplayYear':year}
  225. return MainTab
  226. @view_config(route_name='edit_presse', renderer="jm2l:templates/Staff/EditPresse.mako")
  227. def edit_presse(request):
  228. year = int(request.matchdict.get('year', None))
  229. content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
  230. form = DossPresse(request.POST, content, meta={'csrf_context': request.session})
  231. if request.method == 'POST' and form.validate():
  232. form.populate_obj(content)
  233. MainTab = {'presse':'active', "logged_in":request.authenticated_userid, 'form':form, 'DisplayYear':year}
  234. return MainTab
  235. @view_config(route_name='plan', renderer="jm2l:templates/Public/Plan.mako")
  236. def static_plan(request):
  237. MainTab = {'plan':'active', "logged_in":request.authenticated_userid }
  238. return MainTab
  239. ## =-=- Here, We handle HTTP requests - Staff Logged Part -=-=
  240. @view_config(route_name='list_task', renderer='jm2l:templates/Staff/list.mako')
  241. def list_view(request):
  242. DicTask = {}
  243. taskgroup = DBSession.query( TasksArea ).all()
  244. for grp in taskgroup:
  245. tasks = DBSession.query( Tasks )\
  246. .filter( Tasks.area_uid==grp.uid )\
  247. .order_by(Tasks.closed, Tasks.due_date).all()
  248. DicTask[grp] = tasks
  249. return {'tasks': DicTask }
  250. @view_config(route_name='handle_task', renderer='jm2l:templates/Staff/tasks.mako')
  251. def tasks(request):
  252. task_id = request.matchdict.get('task_id')
  253. # Convert the pole_id GET parameter to int or 0
  254. try:
  255. pole_id = int(request.params.get('pole_id'))
  256. except (ValueError, TypeError):
  257. pole_id = 0
  258. # Get areas from db
  259. Areas = DBSession.query(TasksArea.uid, TasksArea.name)\
  260. .order_by('name').all()
  261. # Get users from db
  262. Users = DBSession.query(User)\
  263. .filter(User.Staff==1)\
  264. .order_by('nom').all()
  265. if task_id:
  266. Task = Tasks.by_id(int(task_id))
  267. if not Task:
  268. raise HTTPNotFound()
  269. form = EditStaffTasks(request.POST, Task, meta={'csrf_context': request.session})
  270. else:
  271. Task = Tasks()
  272. # Check if the supplied pole_id is in the Areas' range
  273. Task.area_uid = pole_id if 1 < pole_id <= len(Areas) else 1
  274. form = StaffTasks(request.POST, Task, meta={'csrf_context': request.session})
  275. # Put some areas on form
  276. form.area_uid.choices = Areas
  277. # Put some users on form
  278. form.closed_by.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
  279. for u in Users]
  280. form.due_date.type = "date"
  281. if request.method == 'POST' and form.validate():
  282. form.populate_obj(Task)
  283. Task.closed = False
  284. if 'uid' in form._fields.keys():
  285. DBSession.merge(Task)
  286. else:
  287. DBSession.add(Task)
  288. DBSession.flush()
  289. return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name))
  290. return {'form':form, 'area':slugify(Areas[Task.area_uid-1].name)}
  291. @view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako')
  292. def tasks_area(request):
  293. pole_id = request.matchdict.get('pole_id')
  294. if pole_id:
  295. Pole = TasksArea.by_id(int(pole_id))
  296. if not Pole:
  297. raise HTTPNotFound()
  298. form = EditStaffArea(request.POST, Pole, meta={'csrf_context': request.session})
  299. else:
  300. Pole = TasksArea()
  301. form = StaffArea(request.POST, Pole, meta={'csrf_context': request.session})
  302. if request.method == 'POST' and form.validate():
  303. form.populate_obj(Pole)
  304. if 'uid' in form._fields.keys():
  305. DBSession.merge(Pole)
  306. else:
  307. DBSession.add(Pole)
  308. return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Pole.name))
  309. return {'form':form }
  310. @view_config(route_name='action_task')
  311. def action_task(request):
  312. action = request.matchdict.get('action')
  313. task_id = request.matchdict.get('task_id')
  314. Task = Tasks.by_id(int(task_id))
  315. if action=='close':
  316. Task.closed = True
  317. request.session.flash(('info', u'La tâche a été fermé, Félicitations !'))
  318. DBSession.merge(Task)
  319. if action=='open':
  320. Task.closed = False
  321. request.session.flash(('info', u'La tâche a été ré-ouverte !'))
  322. DBSession.merge(Task)
  323. if action=='delete':
  324. request.session.flash(('info', u'La tâche a été supprimée !'))
  325. DBSession.delete(Task)
  326. return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name))
  327. @view_config(route_name='action_task_area')
  328. def action_task_area(request):
  329. action = request.matchdict.get('action')
  330. pole_id = request.matchdict.get('pole_id')
  331. Pole = TasksArea.by_id(int(pole_id))
  332. if not Pole:
  333. raise HTTPNotFound()
  334. if action=='delete':
  335. request.session.flash(('info', u'Le pôle a été supprimé !'))
  336. DBSession.delete(Pole)
  337. return HTTPFound(location=request.route_url('list_task'))
  338. ## =-=- Here, We handle HTTP requests - User Logged Part -=-=
  339. @view_config(route_name='exchange', renderer="jm2l:templates/Logistique/Logistique.mako")
  340. def exchange(request):
  341. modtype = request.matchdict.get('modtype', None)
  342. action = request.matchdict.get('action', None)
  343. uid = int(request.matchdict.get('id', -1))
  344. Exch = Exchange.by_id(uid)
  345. if not Exch:
  346. MainTab = {
  347. 'Exchanges':Exchange,
  348. 'Type':modtype[-1:],
  349. 'reload':True,
  350. 'logged_in':request.authenticated_userid
  351. }
  352. return MainTab
  353. if action in ['delete', 'accept', 'refuse', 'deal']:
  354. if action=='delete': # delete exchange
  355. DBSession.delete(Exch)
  356. elif action=='accept': # accept exchange
  357. Exch.exch_done=True
  358. DBSession.merge(Exch)
  359. elif action=='refuse': # refuse exchange
  360. Exch.exch_done=False
  361. if Exch.exch_state=="Ask":
  362. Exch.provider_id = None
  363. elif Exch.exch_state=="Proposal":
  364. Exch.asker_id = None
  365. DBSession.merge(Exch)
  366. elif action=='deal':
  367. # ask to deal the exchange
  368. if Exch.exch_state=="Ask":
  369. Exch.provider_id = request.user.uid
  370. elif Exch.exch_state=="Proposal":
  371. Exch.asker_id = request.user.uid
  372. # Return javascript to parent page
  373. response = render_to_response('jm2l:templates/modals_js.mako',
  374. {'modtype':modtype, 'action':action},
  375. request=request)
  376. response.content_type = 'text/javascript'
  377. return response
  378. else:
  379. MainTab = {
  380. 'Exchanges':Exchange,
  381. 'Type':modtype[-1:],
  382. 'reload':True,
  383. 'logged_in':request.authenticated_userid
  384. }
  385. return MainTab
  386. @view_config(route_name='sejour')
  387. def sejour(request):
  388. if request.user is None:
  389. # Don't answer to users that aren't logged
  390. raise HTTPForbidden('You have to be logged to hope an answer.')
  391. if request.method == 'POST':
  392. print request.POST
  393. return HTTPFound(location='/MesJM2L#Sejour')
  394. @view_config(route_name='vote_logo')
  395. def vote_logo(request):
  396. if request.user is None:
  397. # Don't answer to users that aren't logged
  398. raise HTTPForbidden('You have to be logged to hope an answer.')
  399. else:
  400. vote = int(request.matchdict.get('num', -1))
  401. come = request.params.get('come_from')
  402. if vote:
  403. request.user.vote_logo=vote
  404. DBSession.merge(request.user)
  405. request.session.flash(('info',u'Votre vote à été pris en compte.'))
  406. return HTTPFound('/')
  407. else:
  408. request.session.flash(('warning',u"Votre vote n'a été pris en compte."))
  409. if come:
  410. return HTTPFound(location=come)
  411. raise HTTPForbidden('You have to be logged to hope an answer.')
  412. @view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako")
  413. def jm2l_page(request):
  414. if request.user is None:
  415. # Don't answer to users that aren't logged
  416. raise HTTPForbidden('You have to be logged to hope an answer.')
  417. page = int(request.params.get('page', 1))
  418. UserNum = request.params.get('user')
  419. if UserNum:
  420. profil = User.by_id(int(UserNum))
  421. if not profil:
  422. raise HTTPNotFound()
  423. else:
  424. profil = request.user
  425. # Build Form
  426. profil_form = ProfilForm(request.POST, profil, meta={'csrf_context': request.session})
  427. if request.method == 'POST' and profil_form.validate():
  428. ToDelete = list()
  429. # First, we remove entries no more present
  430. for obj in profil_form.tiersship.object_data:
  431. MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
  432. profil_form.tiersship.entries )
  433. if not MatchEntry:
  434. ToDelete.append(obj)
  435. # Then, it's time to consider new entries
  436. for entry in profil_form.tiersship.entries:
  437. if entry.object_data is None:
  438. TmpUser = User_Tiers()
  439. entry.object_data = TmpUser
  440. profil.tiersship.append(TmpUser)
  441. profil_form.tiersship.object_data = profil.tiersship
  442. profil_form.populate_obj(profil)
  443. # We should remove it as it's not in original data
  444. for obj in ToDelete:
  445. #profil.tiersship.remove(obj)
  446. DBSession.delete(obj)
  447. profil.last_change = datetime.datetime.utcnow()
  448. profil.slug = slugify(remove_accents('%s %s' % (profil.prenom, profil.nom)).lower().strip())
  449. DBSession.merge(profil)
  450. request.session.flash(('info',u'Votre fiche a été mise à jour avec succès'))
  451. MainTab = {'participer':'active',
  452. 'Places':Place.get_list(False),
  453. 'DBTiers':Tiers,
  454. 'DBTiersOpt':TiersOpt,
  455. 'Exchanges':Exchange,
  456. 'profil_form':profil_form,
  457. 'uprofil':profil,
  458. 'logged_in':request.authenticated_userid
  459. }
  460. return MainTab
  461. @view_config(route_name='modal', renderer="jm2l:templates/modals.mako")
  462. def Modal(request):
  463. year = int(request.matchdict.get('year', None))
  464. modtype = request.matchdict.get('modtype', None)
  465. uid = int(request.matchdict.get('id', -1))
  466. session = request.session
  467. if modtype=='Password':
  468. form = UserPasswordForm(request.POST, request.user, meta={'csrf_context': request.session})
  469. if request.method == 'POST' and form.validate():
  470. response = render_to_response('jm2l:templates/modals_js.mako',
  471. {'modtype':modtype},
  472. request=request)
  473. request.user.password = form.password.data
  474. DBSession.merge(request.user)
  475. response.content_type = 'text/javascript'
  476. return response
  477. if modtype=='UserPicture':
  478. form = None
  479. if request.method == 'POST':
  480. response = render_to_response('jm2l:templates/modals_js.mako',
  481. {'modtype':modtype},
  482. request=request)
  483. response.content_type = 'text/javascript'
  484. return response
  485. if modtype=='Place':
  486. if uid>0:
  487. place = Place.by_id(uid)
  488. if not place:
  489. raise HTTPNotFound()
  490. form = PlaceUpdateForm(request.POST, place, meta={'csrf_context': request.session})
  491. else:
  492. place = Place()
  493. form = PlaceCreateForm(request.POST, meta={'csrf_context': request.session})
  494. if request.method == 'POST' and form.validate():
  495. form.populate_obj(place)
  496. place.created_by=request.user.uid
  497. if uid>0:
  498. DBSession.merge(place)
  499. else:
  500. DBSession.add(place)
  501. response = render_to_response('jm2l:templates/modals_js.mako',
  502. {'modtype':modtype},
  503. request=request)
  504. response.content_type = 'text/javascript'
  505. return response
  506. if modtype in ['AskC', 'AskH', 'AskM', 'PropC', 'PropH', 'PropM']:
  507. if uid>0:
  508. Exch = Exchange.by_id(uid)
  509. if not Exch:
  510. raise HTTPNotFound()
  511. if modtype in ['AskC','PropC']:
  512. form = globals()["Update%sForm" % modtype](request.POST, Exch,
  513. start_place = Exch.Itin.start_place,
  514. arrival_place = Exch.Itin.arrival_place,
  515. Hour_start = Exch.start_time.strftime("%H:%M"),
  516. Day_start = Exch.start_time.strftime("%w"),
  517. exch_id = uid, meta={'csrf_context': request.session}
  518. )
  519. elif modtype in ['AskM','PropM']:
  520. form = globals()["Update%sForm" % modtype](request.POST, Exch,
  521. description = Exch.description,
  522. exch_categ = Exch.exch_categ,
  523. Hour_start = Exch.start_time.strftime("%H:%M"),
  524. Day_start = Exch.start_time.strftime("%w"),
  525. Hour_end = Exch.end_time.strftime("%H:%M"),
  526. Day_end = Exch.end_time.strftime("%w"),
  527. exch_id = uid, meta={'csrf_context': request.session}
  528. )
  529. elif modtype in ['AskH','PropH']:
  530. form = globals()["Update%sForm" % modtype](request.POST, Exch,
  531. description = Exch.description,
  532. exch_categ = Exch.exch_categ,
  533. Day_start = Exch.start_time.strftime("%w"),
  534. exch_id = uid, meta={'csrf_context': request.session}
  535. )
  536. # Itinerary, first get itinerary
  537. if 0:
  538. form.itin.form.start_place.data = Exch.Itin.start_place
  539. form.itin.form.arrival_place.data = Exch.Itin.arrival_place
  540. form.dateform.form.Hour.data = Exch.start_time.strftime("%H:%M")
  541. form.dateform.form.Day.data = Exch.start_time.strftime("%w")
  542. form.exch_id.data = uid
  543. else:
  544. Exch = Exchange()
  545. form = globals()["%sForm" % modtype](request.POST, meta={'csrf_context': request.session})
  546. if modtype in ['AskC', 'PropC']:
  547. # Put some place on form
  548. Places = DBSession.query(Place.place_id, Place.display_name)\
  549. .order_by('name').all()
  550. form.start_place.choices = Places
  551. form.arrival_place.choices = Places
  552. if modtype in ['PropH']:
  553. form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\
  554. .filter( Exchange_Cat.exch_type=='H' ).all()
  555. form.place_id.choices = DBSession.query( Place.place_id, Place.display_name)\
  556. .filter( Place.created_by==request.user.uid ).all()
  557. if modtype in ['AskM', 'PropM']:
  558. form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\
  559. .filter( Exchange_Cat.exch_type=='M' ).all()
  560. if request.method == 'POST' and form.validate():
  561. # Form has been validated, it's time to create our Exchange
  562. Exch.for_year = year
  563. Exch.exch_state = {'Ask':'Ask', 'Prop':'Proposal'}[modtype[:-1]]
  564. Exch.exch_type = modtype[-1:]
  565. if modtype in ['AskC', 'PropC']:
  566. # Itinerary, first Let's see if itinerary exist
  567. Itinerary = DBSession.query(Itineraire)\
  568. .filter(Itineraire.start_place==form.start_place.data) \
  569. .filter(Itineraire.arrival_place==form.arrival_place.data) \
  570. .filter(Itineraire.tr_voiture==True) \
  571. .first()
  572. if not Itinerary: # Not exist yet !
  573. Itinerary = Itineraire(start_place=form.start_place.data, \
  574. arrival_place=form.arrival_place.data, \
  575. tr_voiture=True, \
  576. created_by=1
  577. )
  578. DBSession.add(Itinerary)
  579. DBSession.flush()
  580. Exch.itin_id = Itinerary.itin_id
  581. # Start Time
  582. StartEvent = DBSession.query(JM2L_Year.start_time).filter(JM2L_Year.year_uid==year).first()
  583. Week = StartEvent[0].strftime("%W")
  584. # populate
  585. form.populate_obj(Exch)
  586. if modtype in ['AskC', 'PropC']:
  587. Exch.itin_id = Itinerary.itin_id
  588. if form._fields.has_key("Hour_start"):
  589. TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
  590. int(form.Day_start.data), form.Hour_start.data), "%Y %W %w %H:%M")
  591. Exch.start_time = TargetTime
  592. elif form._fields.has_key("Day_start"):
  593. TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
  594. int(form.Day_start.data)), "%Y %W %w")
  595. Exch.start_time = TargetTime
  596. if form._fields.has_key("Hour_end"):
  597. TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
  598. int(form.Day_end.data), form.Hour_end.data), "%Y %W %w %H:%M")
  599. Exch.end_time = TargetTime
  600. elif form._fields.has_key("Day_end"):
  601. TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
  602. int(form.Day_end.data)), "%Y %W %w")
  603. Exch.end_time = TargetTime
  604. Exch.last_change = datetime.datetime.utcnow()
  605. if Exch.exch_state=='Ask':
  606. Exch.asker_id = request.user.uid
  607. elif Exch.exch_state=='Proposal':
  608. Exch.provider_id = request.user.uid
  609. #print vars(form.itin.form)
  610. if uid>0:
  611. DBSession.merge(Exch)
  612. else:
  613. DBSession.add(Exch)
  614. response = render_to_response('jm2l:templates/modals_js.mako',
  615. {'modtype':modtype},
  616. request=request)
  617. response.content_type = 'text/javascript'
  618. return response
  619. # Fallback to HTML Display with errors
  620. return {'modtype':modtype, 'form':form, 'update':uid>0,
  621. 'logged_in':request.authenticated_userid }
  622. if modtype in ['ShowC', 'ShowH', 'ShowM']:
  623. if uid>0:
  624. Exch = Exchange.by_id(uid)
  625. if not Exch:
  626. raise HTTPNotFound()
  627. else:
  628. raise HTTPNotFound()
  629. # Show Details around the Current Exchange
  630. return {'modtype':modtype, 'Exch':Exch, 'logged_in':request.authenticated_userid }
  631. MainTab = {'modtype':modtype, 'form':form, 'update':uid>0, 'uid':uid,
  632. 'DisplayYear':year, 'session':session,
  633. 'logged_in':request.authenticated_userid }
  634. return MainTab
  635. @view_config(route_name='participer', renderer="jm2l:templates/Participer.mako")
  636. def participer(request):
  637. session = request.session
  638. session['year'] = 2015
  639. TmpUsr = User()
  640. form = UserRegisterForm(request.POST, TmpUsr, meta={'csrf_context': request.session})
  641. MyLink=None
  642. if request.method == 'POST' and form.validate():
  643. # Prepare mailer
  644. form.populate_obj(TmpUsr)
  645. TmpUsr.nom = TmpUsr.nom.capitalize()
  646. TmpUsr.prenom = TmpUsr.prenom.capitalize()
  647. TmpUsr.slug = slugify(remove_accents('%s %s' % (form.prenom.data, form.nom.data)).lower().strip())
  648. TmpUsr.password = TmpUsr.my_hash
  649. if len(TmpUsr.slug):
  650. CheckExist = DBSession.query(User)\
  651. .filter(User.slug==TmpUsr.slug)\
  652. .first()
  653. else:
  654. CheckExist=None
  655. if CheckExist:
  656. MyLink = CheckExist.my_hash
  657. NewUser = CheckExist
  658. else:
  659. DBSession.add(TmpUsr)
  660. DBSession.flush()
  661. MyLink = TmpUsr.my_hash
  662. NewUser = TmpUsr
  663. # Send the Welcome Mail
  664. mailer = request.registry['mailer']
  665. # Prepare Plain Text Message :
  666. Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
  667. mail_plain = Mail_template.render(request=request, User=NewUser, action="Welcome")
  668. body = Attachment(data=mail_plain, transfer_encoding="quoted-printable")
  669. # Prepare HTML Message :
  670. Mail_template = Template(filename='jm2l/templates/mail_html.mako')
  671. mail_html = Mail_template.render(request=request, User=NewUser, action="Welcome")
  672. html = Attachment(data=mail_html, transfer_encoding="quoted-printable")
  673. # Prepare Message
  674. message = Message(subject="[JM2L] Mon inscription au site web JM2L",
  675. sender="contact@jm2l.linux-azur.org",
  676. recipients=[NewUser.mail],
  677. body=body, html=html)
  678. message.add_bcc("spam@style-python.fr")
  679. mailer.send(message)
  680. MainTab = {'programme':'','presse':'', 'plan':'',
  681. 'participer':'active', 'form':form, "link": MyLink,
  682. 'logged_in':request.authenticated_userid }
  683. return MainTab
  684. @view_config(route_name='year')
  685. def change_year(request):
  686. year = int(request.matchdict.get('year', -1))
  687. session = request.session
  688. if year>-1:
  689. session['year'] = year
  690. return HTTPFound(location='/%s/le-programme' % year)
  691. return HTTPFound(location=request.route_url('home'))
  692. @view_config(route_name='pict_user', renderer="jm2l:templates/Profil/pict_user.mako")
  693. def pict_user(request):
  694. return {"uprofil":request.user}
  695. @view_config(route_name='event', renderer="jm2l:templates/view_event.mako")
  696. def show_event(request):
  697. year = int(request.matchdict.get('year', -1))
  698. event_id = request.matchdict.get('event_id')
  699. if event_id.isdigit():
  700. TheEvent = Event.by_id(event_id)
  701. if TheEvent is None:
  702. raise HTTPNotFound()
  703. else:
  704. TheEvent = Event.by_slug(event_id, year)
  705. if TheEvent is None:
  706. raise HTTPNotFound()
  707. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  708. 'event':TheEvent, 'logged_in':request.authenticated_userid }
  709. return MainTab
  710. @view_config(route_name='link_event')
  711. def link_event(request):
  712. """ Create user if not exist, add it to current event """
  713. year = int(request.matchdict.get('year', -1))
  714. form = AddIntervenant(request.POST, meta={'csrf_context': request.session})
  715. intervention = request.matchdict.get('intervention', None)
  716. TargetEvent = Event.by_id(form.event_uid.data)
  717. Exist = User.by_id(form.intervenant.data)
  718. if not Exist:
  719. request.session.flash(('error',u"Une erreur s'est produite lors de l'ajout de votre intervenant !"))
  720. return HTTPFound(location=request.route_url('edit_event', sep='/',
  721. year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
  722. else:
  723. TargetUser = Exist
  724. uev = User_Event(year_uid=year, role=u"Animateur d'un évenement JM2L", user_uid=TargetUser.uid)
  725. TargetEvent.interventions.append( uev )
  726. return HTTPFound(location=request.route_url('edit_event', sep='/',
  727. year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
  728. @view_config(route_name='edit_event', renderer="jm2l:templates/edit_event.mako")
  729. def edit_event(request):
  730. year = int(request.matchdict.get('year', -1))
  731. event_id = request.matchdict.get('event_id')
  732. intervention = request.matchdict.get('intervention', None)
  733. IntervLabel = intervention.replace('_',' ').lower()
  734. if intervention=='Conference':
  735. IntervLabel = u'conférence'
  736. # Check intervention
  737. if not intervention in ['Stand', 'Table ronde', 'Atelier', 'Conference']:
  738. raise HTTPNotFound(u"Ce type d'évenement n'est pas reconnu")
  739. TheYear = DBSession.query(JM2L_Year)\
  740. .filter(JM2L_Year.year_uid==year)\
  741. .first()
  742. # Check year avaibility
  743. if not TheYear:
  744. raise HTTPNotFound(u"Cette année n'est pas pris en charge")
  745. # Generate Timeslots for current year
  746. TimeSlots = list(enumerate( [ x.strftime('%a %d %b %H:%M') for x in
  747. TheYear.AvailableTimeSlots ] ))
  748. if event_id:
  749. # We try to update an existing record
  750. if event_id.isdigit():
  751. TheEvent = Event.by_id(event_id)
  752. if TheEvent is None:
  753. raise HTTPNotFound(u"Cette réference n'existe pas")
  754. else:
  755. TheEvent = Event.by_slug(event_id, year)
  756. if TheEvent is None:
  757. raise HTTPNotFound(u"Cette réference n'existe pas")
  758. if request.user is None or not (request.user.Staff or request.user in TheEvent.intervenants):
  759. return HTTPForbidden(u"Vous n'êtes pas identifié comme étant un participant à cette intervention.")
  760. # Compute some field value from selected event
  761. if TheEvent.start_time in TheYear.AvailableTimeSlots:
  762. start_sel = TheYear.AvailableTimeSlots.index(TheEvent.start_time)
  763. else:
  764. start_sel = len(TimeSlots)
  765. TimeSlots.append( (len(TimeSlots), TheEvent.start_time.strftime('%a %d %b %H:%M')))
  766. duration = (TheEvent.end_time - TheEvent.start_time).total_seconds()/60
  767. end = TheEvent.start_time + datetime.timedelta(minutes=duration)
  768. # prepare the form with update
  769. form = ConfUpdateForm(request.POST, TheEvent, start_sel=start_sel, duration=duration, end_time=end,
  770. meta={'csrf_context': request.session} )
  771. # Customize labels
  772. form.name.label.text += IntervLabel
  773. form.description.label.text += IntervLabel
  774. # Each event can get severals members
  775. formAdd = AddIntervenant(event_uid=TheEvent.uid)
  776. # Build list of intervenant
  777. # Get users from db
  778. Users = DBSession.query(User)\
  779. .filter(User.Staff==1)\
  780. .order_by('nom').all()
  781. # Put some users on form
  782. formAdd.intervenant.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
  783. for u in Users]
  784. else:
  785. TheEvent = Event()
  786. # prepare the form for creation
  787. form = ConfCreateForm(request.POST,
  788. event_type=intervention,
  789. for_year=str(year), meta={'csrf_context': request.session}
  790. )
  791. # Customize labels
  792. form.name.label.text += IntervLabel
  793. form.description.label.text += IntervLabel
  794. duration=60
  795. # No intervenant
  796. formAdd = None
  797. if intervention=="Conference":
  798. form.duration.choices =[
  799. (15,u'Lighting talk ( 5 min)'),
  800. (30,u'Conférence (20 min)'),
  801. (60,u'Conférence (50 min)'),
  802. (90,u'Conférence (75 min)'),
  803. ]
  804. if not duration in [15, 30, 60, 90]:
  805. form.duration.choices.append( (duration,u'Conférence (%d min)' % duration) )
  806. if not form._fields.has_key("uid"):
  807. form.duration.data=60
  808. elif intervention=="Stand":
  809. form.duration.choices =[
  810. (8*60, u'Toute la journée'),
  811. (4*60, u'une demi-journée')
  812. ]
  813. elif intervention=="Atelier":
  814. form.duration.choices = map( lambda d:(d, u'Atelier (%dh%.2d)' % (d/60, d%60) ), \
  815. [60, 90, 120, 150, 180, 210, 240] )
  816. if not duration in map(lambda (d,y): d, form.duration.choices):
  817. form.duration.choices.append( (duration,u'Atelier (%dh%.2d)' % (duration/60, duration%60) ) )
  818. elif intervention=="Table_Ronde":
  819. form.duration.choices = map( lambda d:(d, u'Table ronde (%dh%.2d)' % (d/60, d%60) ), \
  820. [60, 90, 120, 150] )
  821. if not duration in map(lambda (d,y): d, form.duration.choices):
  822. form.duration.choices.append( (duration,u'Table ronde (%dh%.2d)' % (duration/60, duration%60) ) )
  823. else:
  824. return HTTPForbidden(u"Pas encore disponible.")
  825. SalleDispo = DBSession.query(Salles)\
  826. .filter(Salles.year_uid==year)\
  827. .order_by('name')
  828. form.salle_uid.choices = [(s.salle_id, s.name) for s in SalleDispo]
  829. form.start_sel.choices = TimeSlots
  830. if request.method == 'POST' and form.validate():
  831. form.populate_obj(TheEvent)
  832. TheEvent.start_time = TheYear.AvailableTimeSlots[form.start_sel.data]
  833. TheEvent.end_time = TheEvent.start_time + datetime.timedelta(minutes=form.duration.data)
  834. # Ok, time to put in database
  835. if not form._fields.has_key("uid"):
  836. TheEvent.slug = slugify(TheEvent.name)
  837. DBSession.add(TheEvent)
  838. # Append creator by default
  839. if request.user.uid!=1:
  840. uev = User_Event(year_uid=TheYear.year_uid, role="Animateur")
  841. uev.user_uid = request.user.uid
  842. TheEvent.interventions.append( uev )
  843. DBSession.flush()
  844. request.session.flash(('sucess','Votre intervention a été créee !'))
  845. return HTTPFound(location=request.route_url('edit_event', sep='/',
  846. year=str(year), intervention=intervention, event_id=str(TheEvent.slug)))
  847. else:
  848. DBSession.merge(TheEvent)
  849. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  850. 'event':TheEvent, 'form':form, 'formAdd':formAdd,
  851. 'logged_in':request.authenticated_userid }
  852. return MainTab
  853. @view_config(route_name='entities', renderer="jm2l:templates/list_tiers.mako")
  854. def list_tiers(request):
  855. Entities = dict()
  856. EntityType = DBSession.query(TiersOpt.entity_type)\
  857. .group_by(TiersOpt.entity_type).all()
  858. for EType in EntityType:
  859. Entities[EType.entity_type] = DBSession.query(Tiers).join(TiersOpt)\
  860. .filter(TiersOpt.entity_type==EType.entity_type)\
  861. .order_by(TiersOpt.entity_subtype, Tiers.name)
  862. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  863. 'entities':Entities, 'logged_in':request.authenticated_userid }
  864. return MainTab
  865. @view_config(route_name='show_entity', renderer="jm2l:templates/view_tiers.mako")
  866. def show_tiers(request):
  867. tiers_type = request.matchdict.get('tiers_type')
  868. entity_id = request.matchdict.get('entity_id')
  869. if entity_id.isdigit():
  870. TheTiers = Tiers.by_id(entity_id)
  871. if TheTiers is None:
  872. raise HTTPNotFound()
  873. else:
  874. TheTiers = Tiers.by_slug(entity_id)
  875. if TheTiers is None:
  876. raise HTTPNotFound()
  877. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  878. 'entity':TheTiers, 'logged_in':request.authenticated_userid }
  879. return MainTab
  880. @view_config(route_name='add_entity', renderer="jm2l:templates/edit_tiers.mako")
  881. @view_config(route_name='edit_entity', renderer="jm2l:templates/edit_tiers.mako")
  882. def edit_tiers(request):
  883. entity_id = request.matchdict.get('entity_id', None)
  884. TargetList = list()
  885. if request.user is None:
  886. # Don't answer to users that aren't logged
  887. raise HTTPForbidden('You have to be logged to hope an answer.')
  888. entity_types = DBSession.query(TiersOpt.entity_type).group_by(TiersOpt.entity_type).all()
  889. for entity_type in entity_types:
  890. entity_subtypes = DBSession.query(TiersOpt)\
  891. .filter(TiersOpt.entity_type==entity_type.entity_type)\
  892. .group_by(TiersOpt.entity_subtype).all()
  893. ListType = [(i.uid, i.entity_subtype) for i in entity_subtypes]
  894. TargetList.append( (entity_type.entity_type, ListType) )
  895. if entity_id:
  896. if entity_id.isdigit():
  897. TheTiers = Tiers.by_id(entity_id)
  898. if TheTiers is None:
  899. raise HTTPNotFound()
  900. else:
  901. TheTiers = Tiers.by_slug(entity_id)
  902. if TheTiers is None:
  903. raise HTTPNotFound()
  904. form = UpdateTiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
  905. UserOptions = DBSession.query(TiersOpt)\
  906. .filter(TiersOpt.entity_type==TheTiers.tiers_type)\
  907. .all()
  908. form.tiers_type.choices = TargetList
  909. else:
  910. TheTiers = Tiers()
  911. # prepare the form for creation
  912. form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
  913. form.tiers_type.choices = TargetList
  914. UserOptions = list()
  915. #test_form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
  916. if request.method == 'POST' and form.validate():
  917. print request.POST
  918. ToDelete = list()
  919. # First, we remove entries no more present
  920. for obj in form.membership.object_data:
  921. MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
  922. form.membership.entries )
  923. if not MatchEntry:
  924. ToDelete.append(obj)
  925. # We should remove it as it's not in original data
  926. for obj in ToDelete:
  927. TheTiers.membership.remove(obj)
  928. DBSession.delete(obj)
  929. # Then, it's time to consider new entries
  930. for entry in form.membership.entries:
  931. if entry.object_data is None:
  932. TmpUser = User_Tiers()
  933. entry.object_data = TmpUser
  934. TheTiers.membership.append(TmpUser)
  935. form.membership.object_data = TheTiers.membership
  936. form.populate_obj(TheTiers)
  937. # Handle Remove of accents
  938. TheTiers.slug = slugify(form.name.data)
  939. if not form._fields.has_key('uid'):
  940. TheTiers.creator_id = request.user.uid
  941. DBSession.add(TheTiers)
  942. DBSession.flush()
  943. return HTTPFound(location=request.route_url('edit_entity', sep='/',
  944. entity_id=str(TheTiers.slug), tiers_type=TheTiers.get_entity_type.entity_type))
  945. DBSession.merge(TheTiers)
  946. return HTTPFound(location=request.route_url('entities'))
  947. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  948. 'form':form, 'DBUser':User, 'UserOptions':UserOptions,
  949. 'logged_in':request.authenticated_userid }
  950. return MainTab
  951. @view_config(route_name='edit_entity_cat', renderer="jm2l:templates/edit_tiers_categ.mako")
  952. def edit_tiers_category(request):
  953. DicResult = dict()
  954. ListChanges = list()
  955. if request.method == 'POST':
  956. # Reformat data
  957. RegExist = re.compile('collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[(?P<id>\d+)\]')
  958. RegTitle = re.compile('collection\[(?P<slug>[\w-]+)\]\[title]')
  959. RegNew = re.compile('collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[id\]')
  960. for key, value in request.POST.iteritems():
  961. regN= RegNew.match(key)
  962. regT= RegTitle.match(key)
  963. reg = RegExist.match(key)
  964. if reg:
  965. if not DicResult.has_key(reg.group('slug')):
  966. DicResult[reg.group('slug')] = dict()
  967. if DicResult[reg.group('slug')].has_key('items'):
  968. DicResult[reg.group('slug')]['items'].append( ( int(reg.group('id')), value ) )
  969. else:
  970. DicResult[reg.group('slug')]['items'] = [ ( int(reg.group('id')), value ) ]
  971. elif regN:
  972. if not DicResult.has_key(regN.group('slug')):
  973. DicResult[regN.group('slug')] = dict()
  974. if DicResult[regN.group('slug')].has_key('items'):
  975. DicResult[regN.group('slug')]['items'].append( ( 'id', value ) )
  976. else:
  977. DicResult[regN.group('slug')]['items'] = [ ( 'id', value ) ]
  978. ListChanges.append(('add', 0, DicResult[regN.group('slug')]['title'], value))
  979. elif regT:
  980. if not DicResult.has_key(regT.group('slug')):
  981. DicResult[regT.group('slug')] = dict()
  982. DicResult[regT.group('slug')]['title'] = value
  983. else:
  984. raise
  985. for opt in DBSession.query(TiersOpt).all():
  986. if DicResult.has_key(opt.slug_entity_type):
  987. found = filter( lambda (x,y): opt.uid==x,
  988. DicResult[opt.slug_entity_type].get('items', []))
  989. if not found:
  990. ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
  991. else:
  992. for tst in found:
  993. # Check changes on Cat Name
  994. if DicResult[opt.slug_entity_type]['title']!=opt.entity_type or \
  995. tst[1]!=opt.entity_subtype:
  996. ListChanges.append(('changed', opt.uid,
  997. DicResult[opt.slug_entity_type]['title'],
  998. tst[1]))
  999. else:
  1000. ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
  1001. # Do The change
  1002. for action, uid, entity, subentity in ListChanges:
  1003. if action=="changed":
  1004. opt = TiersOpt.by_id(uid)
  1005. opt.entity_type = entity
  1006. opt.entity_subtype = subentity
  1007. elif action=="remove":
  1008. opt = TiersOpt.by_id(uid)
  1009. DBSession.delete(opt)
  1010. elif action=="add":
  1011. opt = TiersOpt()
  1012. opt.entity_type = entity
  1013. opt.entity_subtype = subentity
  1014. DBSession.add(opt)
  1015. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1016. 'logged_in':request.authenticated_userid, 'TiersOpt':TiersOpt }
  1017. return MainTab
  1018. @view_config(route_name='show_user', renderer="jm2l:templates/view_user.mako")
  1019. def show_user(request):
  1020. user_slug = request.matchdict.get('user_slug', None)
  1021. if user_slug is None or len(user_slug)==0:
  1022. raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
  1023. # Query database
  1024. DispUser = User.by_slug(user_slug)
  1025. if DispUser is None:
  1026. raise HTTPNotFound()
  1027. MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
  1028. 'DispUser':DispUser, 'logged_in':request.authenticated_userid }
  1029. return MainTab
  1030. #@view_config(route_name='link_user_entity')
  1031. def link_user_entity(request):
  1032. uid = int(request.matchdict.get('uid', -1))
  1033. year = int(request.matchdict.get('year', -1))
  1034. user_id = int(request.matchdict.get('uid', -1))
  1035. TheTiers = Tiers.by_id(uid)
  1036. if TheTiers is None:
  1037. raise HTTPNotFound()
  1038. return HTTPFound(location=request.route_url('edit_entity', uid=uid) )
  1039. #@view_config(route_name='link_role_entity')
  1040. def link_role_entity(request):
  1041. uid = int(request.matchdict.get('uid', -1))
  1042. year = int(request.matchdict.get('year', -1))
  1043. role_id = int(request.matchdict.get('role_id', -1))
  1044. TheTiers = Tiers.by_id(uid)
  1045. if TheTiers is None:
  1046. raise HTTPNotFound()
  1047. return HTTPFound(location=request.route_url('edit_entity', uid=uid) )
  1048. @forbidden_view_config()
  1049. def forbidden(reason, request):
  1050. #return Response('forbidden')
  1051. request.response.status = 403
  1052. return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason },
  1053. request=request)
  1054. @notfound_view_config()
  1055. def notfound(reason, request):
  1056. request.response.status = 404
  1057. return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason },
  1058. request=request)