# -*- coding: utf8 -*-
from pyramid.httpexceptions import HTTPFound, HTTPNotFound, HTTPForbidden
from pyramid.httpexceptions import HTTPBadRequest, HTTPUnauthorized
from pyramid.renderers import render_to_response
from pyramid.view import notfound_view_config, forbidden_view_config
from pyramid.view import view_config
from pyramid.response import Response
from mako.template import Template
from pyramid_mailer.message import Message
from .upload import IMAGEPATH, MediaPath
# Import Web Forms
from .forms import *
# Database access imports
from .models import *
from .helpers import Orga_helpers
from sqlalchemy import func, or_, text, and_
from sqlalchemy.orm import aliased
from os import path, makedirs, listdir
# Usefull tools
from slugify import slugify
from icalendar import Calendar
from pytz import timezone
from icalendar import Event as Evt
from pyramid_mailer.message import Message
# Then, standard libs
import csv
import cStringIO as StringIO
import webhelpers.paginate as paginate
import unicodedata
import datetime
import re
import shutil
import glob
from jm2l.const import CurrentYear
from passlib.hash import argon2
## =-=- Here, We keep some usefull function -=-=
def remove_accents(input_str):
""" This function is intended to remove all accent from input unicode string """
nkfd_form = unicodedata.normalize('NFKD', input_str)
only_ascii = nkfd_form.encode('ASCII', 'ignore')
return only_ascii
def embeed_video(mime_type, link):
Container = ""
return Container
@view_config(route_name='Live', renderer="jm2l:templates/Live.mako")
def Live(request):
year = int(request.matchdict.get('year', CurrentYear))
tz = timezone('Europe/Paris')
curtime = datetime.datetime.now().replace(tzinfo=tz, day=28) #, hour=10, minute=00 )
Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
.filter(Event.event_type != 'Stand')\
.filter(and_(Event.start_time <= curtime, Event.end_time >= curtime) )\
.order_by(Event.start_time)
return {'year': year, "DisplayYear": year, 'events':Events, "logged_in":request.authenticated_userid }
## =-=- Here, We handle ICal requests -=-=
@view_config(route_name='progr_iCal', renderer="string")
def ICal_Progamme_Request(request):
year = int(request.matchdict.get('year', CurrentYear))
# Initialization
# Compute days used by all events matching the specified input year
Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
.filter(Event.event_type != 'Stand')\
.order_by(Event.start_time)
cal = Calendar()
cal.add('prodid', '-//Programme %d//jm2l.linux-azur.org//' % year)
cal.add('version', '2.0')
tz = timezone('Europe/Paris')
for ev in Events:
if ev.event_type:
event = Evt()
event['uid'] = "%d/%d" % ( year, ev.uid )
event.add('summary', ev.name )
event.add('dtstart', ev.start_time.replace(tzinfo=tz) )
event.add('dtend', ev.end_time.replace(tzinfo=tz) )
event.add('created', ev.last_change.replace(tzinfo=tz) )
event.add('description', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) )
event.add('url', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) )
event.add('priority', 5)
for interv in ev.intervenants:
event.add('organizer',
interv.slug,
parameters={
"CN": "%s %s" % (interv.prenom, interv.nom),
"DIR": "https://jm2l.linux-azur.org/user/%s" % interv.slug
}
)
event.add('location', ev.Salle.name)
event.add('categories', ev.event_type)
cal.add_component(event)
request.response.content_type = "text/calendar"
return cal.to_ical()
## =-=- Here, We handle ICal requests -=-=
@view_config(route_name='progr_dyn_iCal', renderer="string")
def ICal_Progamme_Dyn_Request(request):
year = int(request.matchdict.get('year', CurrentYear))
# Initialization
# Compute days used by all events matching the specified input year
Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
.filter(Event.event_type != 'Stand')\
.order_by(Event.start_time)
cal = Calendar()
cal.add('prodid', '-//Programme %d//jm2l.linux-azur.org//' % year)
cal.add('version', '2.0')
today = datetime.datetime.now()
tz = timezone('Europe/Paris')
event = Evt()
event['uid'] = "%d/%d" % ( year, 100 )
event.add('summary', "Les stands JM2L %s" % year )
event.add('dtstart', datetime.datetime.now().replace(tzinfo=tz, hour=10, minute=00 ) )
event.add('dtend', datetime.datetime.now().replace(tzinfo=tz, hour=18, minute=00 ) )
event.add('created', datetime.datetime.now().replace(tzinfo=tz, hour=10, minute=00 ) )
event.add('description', "https://www.youtube.com/watch?v=91X65eEKxvU&t=6s" )
event.add('location', "http://jm2l.linux-azur.org/img/325.gif" )
event.add('url', "http://jm2l.linux-azur.org/%s/le-programme" % CurrentYear)
event.add('priority', 5)
cal.add_component(event)
TabCorr = {
135:"Koneko",
131:"cam-jm2l-a",
132:"cam-jm2l-b",
115:"cam-jm2l-e",
114:"cam-jm2l-f",
116:"cam-jm2l-g",
139:"cam-jm2l-y"
}
for i, ev in enumerate(Events):
if ev.event_type:
event = Evt()
event['uid'] = "%d/%d" % ( year, ev.uid )
event.add('summary', ev.name )
event.add('dtstart', ev.start_time.replace(tzinfo=tz, day=today.day, month = today.month, hour=(ev.start_time.hour)%24 ) )
event.add('dtend', ev.end_time.replace(tzinfo=tz, day=today.day, month = today.month, hour=(ev.end_time.hour)%24 ) )
event.add('created', ev.last_change.replace(tzinfo=tz) )
event.add('description', "http://jm2l.linux-azur.org:8080/%s.webm" % TabCorr.get(ev.Salle.phy_salle_id, ev.Salle.phy_salle_id) )
event.add('location', "http://jm2l.linux-azur.org/img/%d.gif" % ev.Salle.phy_salle_id )
event.add('url', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug) )
event.add('priority', 5)
cal.add_component(event)
request.response.content_type = "text/calendar"
return cal.to_ical()
## =-=- Here, We handle Json requests -=-=
@view_config(route_name='users_json', renderer="json")
def JSON_User_Request(request):
""" Build a JSON answer with active users and pagination handling """
# Check arguments consitency
pageSize = request.params.get('pageSize',"8")
current_page = request.params.get('pageNum',"1")
UserQuery = request.params.get('searchTerm', u"")
# Don't answer to users that aren't logged
if not request.user:
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
# Check consistancy of parameters
if pageSize.isdigit() and current_page.isdigit():
current_page = int(current_page)
pageSize = int(pageSize)
else:
return HTTPBadRequest('pageSize and pageNum accept only digits.')
# Query database
Users = DBSession.query(User.uid, User.nom, User.prenom)\
.filter(User.slug.contains( remove_accents(UserQuery) ))
page_url = paginate.PageURL_WebOb(request)
records = paginate.Page(Users, current_page, url=page_url, items_per_page=pageSize)
ListMatchUser = map( lambda u:{"id": u.uid, "text":"%s %s" % ( u.prenom, u.nom )}, records )
return { "Results": ListMatchUser, "Total":records.item_count,
"logged_in":request.authenticated_userid }
@view_config(route_name='tiers_json', renderer="json")
def JSON_Tiers_Request(request):
""" Build a JSON answer with active users and pagination handling """
# Check arguments consitency
pageSize = request.params.get('pageSize',"8")
current_page = request.params.get('pageNum',"1")
TiersQuery = request.params.get('searchTerm', u"")
# Don't answer to users that aren't logged
if not request.user:
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
# Check consistancy of parameters
if pageSize.isdigit() and current_page.isdigit():
current_page = int(current_page)
pageSize = int(pageSize)
else:
return HTTPBadRequest('pageSize and pageNum accept only digits.')
# Query database
JTiers = DBSession.query(Tiers.uid, Tiers.name)\
.filter(Tiers.slug.contains( remove_accents(TiersQuery) ))
page_url = paginate.PageURL_WebOb(request)
records = paginate.Page(JTiers, current_page, url=page_url, items_per_page=pageSize)
ListMatchTiers = map( lambda t:{"id": t.uid, "text": t.name }, records )
return { "Results": ListMatchTiers, "Total":records.item_count,
"logged_in":request.authenticated_userid }
@view_config(route_name='progr_json', renderer="json")
def JSON_Progamme_Request(request):
year = int(request.matchdict.get('year', CurrentYear))
# Initialization
DicResult = dict()
# Query database
# Compute days used by all events matching the specified input year
Days = DBSession.query( func.strftime('%d', Event.start_time).label('day') )\
.filter(Event.for_year == year)\
.filter(Event.event_type != None)\
.group_by(func.strftime('%d', Event.start_time)).all()
for Day in Days:
Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
.filter(Event.event_type != 'Stand')\
.filter(text("strftime('%d', start_time) = :dow")).params(dow=Day.day)\
.order_by(Event.start_time)
ListEv = []
for ev in Events:
if ev.event_type:
ListEv.append( {
"uid":"%d/%d" % ( year, ev.uid ),
"desc":ev.name,
"startDate":ev.start_time.strftime('%Y-%m-%dT%H:%M:%S+01:00'),
"endDate":ev.end_time.strftime('%Y-%m-%dT%H:%M:%S+01:00'),
"placeName":ev.Salle and (ev.Salle.name or "unk") ,
"status":ev.event_type
} )
DicResult[Day.day] = ListEv
return { 'all':DicResult }
@view_config(route_name='timeline_json', renderer="json")
def JSON_TimeLine_Request(request):
year = int(request.matchdict.get('year', CurrentYear))
# Initialization
DicResult = dict()
# Query database
# Compute days used by all events matching the specified input year
Days = DBSession.query( func.strftime('%d', Event.start_time).label('day') )\
.filter(Event.for_year == year)\
.filter(Event.event_type != None)\
.group_by(func.strftime('%d', Event.start_time)).all()
ListEv = []
for Day in Days:
Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
.filter(Event.event_type != 'Stand')\
.filter(text("strftime('%d', start_time) = :dow")).params(dow=Day.day)\
.order_by(Event.start_time)
#ListEv = []
for ev in Events:
if ev.event_type:
CurMedia = ev.video.first() or ""
if CurMedia:
Container = ""
else:
Container = ""
ListEv.append( {
#"uid":"%d/%d" % ( year, ev.uid ),
"headline":'%s' % (ev.for_year, ev.slug, ev.name),
"startDate":ev.start_time.strftime('%Y,%m,%d,%H,%M'),
"endDate":ev.end_time.strftime('%Y,%m,%d,%H,%M'),
"text": ev.Salle and (ev.Salle.name or "unk"),
#"text":ev.description[:100],
"tags":ev.Salle and (ev.Salle.salle_id or "unk") ,
#"status":ev.event_type,
"asset": {
"media": Container,
"credit": ",".join(["%s %s" % (i.prenom, i.nom) for i in ev.intervenants]),
"caption":"" }
} )
if year==2017:
DicResult = {
"lang":"fr",
"headline":"JM2L 2017",
"type":"default",
"startDate":"2017,11,25,10",
"text":"10ème Édition",
"asset":
{
"media":embeed_video("video/ogg","/resources/2017/Video/JM2L2017_Reportage_FR3.ogv"),
"credit":"Reportage France 3",
"caption":"JM2L 2017"
}
}
elif year==2015:
DicResult = {
"lang":"fr",
"headline":"JM2L 2015",
"type":"default",
"startDate":"2015,11,28,10",
"text":"9ème Édition",
"asset":
{
#"media":"https://www.youtube.com/watch?v=91X65eEKxvU&t=6s",
"media":embeed_video("video/ogg","/resources/2015/Video/jm2l_france3-2015.ogv"),
"credit":"Reportage France 3",
"caption":"JM2L 2015"
}
}
elif year==2011:
DicResult = {
"lang":"fr",
"headline":"JM2L 2011",
"type":"default",
"startDate":"2011,11,25,10",
"text":"6ème Édition",
"asset":
{
"media":"https://www.youtube.com/embed/rcaNeXuAEhs",
"credit":"JM2L",
"caption":"Reportage FR3"
},
}
elif year==2010:
DicResult = {
"lang":"fr",
"headline":"JM2L 2010",
"type":"default",
"text":"5ème Édition",
"asset":
{
"media":embeed_video("video/ogg","/resources/2010/Video/reportages/JM2L2010-PleinSudTV.ogv"),
"credit":"Le reportage Plein-sud TV",
"caption":"JM2L",
}
}
elif year==2007:
DicResult = {
"lang":"fr",
"headline":"JM2L 2007",
"type":"default",
"text":"2ème Édition",
"asset":
{
"media":embeed_video("video/ogg","/resources/2007/Video/20071110-linux.ogv"),
"credit":"Le reportage Plein-sud TV",
"caption":"JM2L 2007",
}
}
else:
DicResult = {
"lang":"fr",
"headline":"JM2L %d" % year,
"type":"default",
"asset":
{
"media":"",
"credit":"JM2L",
"caption":""
}
}
DicResult["date"] = ListEv
return { 'timeline':DicResult }
## =-=- Here, We handle HTTP requests - Public Part -=-=
@view_config(route_name='home', renderer="jm2l:templates/NewIndex.mako")
def index_page(request):
year = request.matchdict.get('year')
if year:
year=int(year[:-1])
content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
if content:
content = content.description
else:
content = ""
if 2004ère" }
elif year==2015:
return {'year': year, 'content':content, 'edition':u"9ème" }
elif year==2017:
return {'year': year, 'content':content, 'edition':u"10ème" }
else:
edition = year - 2005
return {'year': year, 'content':content, 'edition':u"%dème" % edition }
else:
raise HTTPNotFound()
else:
content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==CurrentYear).first().description
TargetDir = "jm2l/static/img/%s/Photos" % (year or CurrentYear)
TargetUrl = "/static/img/%s/Photos/" % (year or CurrentYear)
if path.isdir(TargetDir):
ListPhotos = map(lambda x: TargetUrl + x, listdir(TargetDir))
else:
ListPhotos = []
return {'year': CurrentYear, 'content':content, 'edition':u"10ème", 'ListPhotos': ListPhotos}
@view_config(route_name='edit_index', renderer="jm2l:templates/Staff/EditIndex.mako")
def edit_index(request):
year = int(request.matchdict.get('year', CurrentYear))
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
form = IndexForm(request.POST, content, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
form.populate_obj(content)
return HTTPFound(location=request.route_url('home', year="%d/" % year))
MainTab = {'home':'active', "logged_in":request.authenticated_userid,
'form':form, 'DisplayYear':year}
return MainTab
@view_config(route_name='programme', renderer="jm2l:templates/Public/Programme.mako")
def programme(request):
year = int(request.matchdict.get('year'))
if 2006 > year:
return HTTPBadRequest('The first JM2L event was in 2006.')
# Query database about selected Year.
Events = DBSession.query(Event)\
.filter(Event.for_year == year)\
.order_by(Event.start_time)
Days = DBSession.query(func.strftime('%d-%m-%Y', Event.start_time))\
.filter(Event.for_year == year)\
.filter(Event.event_type != None)\
.group_by(func.strftime('%d', Event.start_time)).all()
ListDay = []
for day in Days:
RefDay = datetime.datetime.strptime(day[0],'%d-%m-%Y')
ListDay.append( ( RefDay.strftime('%A %d %b %Y'),
RefDay.strftime('%d') ) )
MainTab = {'programme':'active','DisplayYear':year, \
'Events':Events, 'Event':Event, 'Days':ListDay, "logged_in":request.authenticated_userid }
return MainTab
@view_config(route_name='presse', renderer="jm2l:templates/Public/Presse.mako")
def static_presse(request):
year = int(request.matchdict.get('year', None))
content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
MainTab = {'presse':'active', "logged_in":request.authenticated_userid, 'content':content, 'DisplayYear':year}
return MainTab
@view_config(route_name='edit_presse', renderer="jm2l:templates/Staff/EditPresse.mako")
def edit_presse(request):
year = int(request.matchdict.get('year', None))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
form = DossPresse(request.POST, content, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
form.populate_obj(content)
MainTab = {'presse':'active', "logged_in":request.authenticated_userid, 'form':form, 'DisplayYear':year}
return MainTab
@view_config(route_name='plan', renderer="jm2l:templates/Public/Plan.mako")
def static_plan(request):
session = request.session
session['year'] = CurrentYear
MainTab = {'plan':'active', "logged_in":request.authenticated_userid }
return MainTab
## =-=- Here, We handle HTTP requests - Staff Logged Part -=-=
@view_config(route_name='list_task', renderer='jm2l:templates/Staff/list.mako')
def list_view(request):
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
DicTask = {}
taskgroup = DBSession.query( TasksArea ).filter( TasksArea.year_uid == year).all()
for grp in taskgroup:
tasks = DBSession.query( Tasks )\
.filter( Tasks.area_uid==grp.uid ) \
.filter( Tasks.year_uid == year) \
.order_by(Tasks.closed, Tasks.due_date).all()
DicTask[grp] = tasks
return {'tasks': DicTask, 'year':year }
@view_config(route_name='list_expenses', renderer='jm2l:templates/Staff/compta.mako')
def expenses(request):
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
output = []
dic_out = {}
for name in glob.glob('jm2l/upload/images/users/*/RIB/*'):
tab_path = name.split('/')
u = User.by_slug(tab_path[4])
if u is None:
continue
if tab_path[6]=='thumbnails' or tab_path[6].endswith('.type'):
continue
if dic_out.get(tab_path[4]) is None:
dic_out[tab_path[4]] = {}
if dic_out[tab_path[4]].get('RIB') is None:
dic_out[tab_path[4]]['RIB'] = {'files':[], 'thumb':[]}
u = User.by_slug(tab_path[4])
if u is None:
dic_out[tab_path[4]]['User'] = {
'uid':'# NOT FOUND',
'nom':name,
'prenom':'# NOT FOUND',
'slug':'# NOT FOUND'
}
else:
dic_out[tab_path[4]]['User'] = {
'uid':u.uid,
'nom':u.nom,
'prenom':u.prenom,
'slug':u.slug
}
dic_out[tab_path[4]]['RIB']['files'].append( name )
dic_out[tab_path[4]]['RIB']['thumb'].append( name + ".jpg" )
for name in glob.glob('jm2l/upload/images/users/*/Justif/*'):
tab_path = name.split('/')
u = User.by_slug(tab_path[4])
if u is None:
continue
if tab_path[6]=='thumbnails' or tab_path[6].endswith('.type'):
continue
if dic_out.get(tab_path[4]) is None:
dic_out[tab_path[4]] = {}
if dic_out[tab_path[4]].get('Justif') is None:
dic_out[tab_path[4]]['Justif'] = {'files':[], 'thumb':[]}
u = User.by_slug(tab_path[4])
if u is None:
dic_out[tab_path[4]]['User'] = {
'uid':'# NOT FOUND',
'nom':name,
'prenom':'# NOT FOUND',
'slug':'# NOT FOUND'
}
else:
dic_out[tab_path[4]]['User'] = {
'uid':u.uid,
'nom':u.nom,
'prenom':u.prenom,
'slug':u.slug
}
dic_out[tab_path[4]]['Justif']['files'].append( name )
dic_out[tab_path[4]]['Justif']['thumb'].append( name + ".jpg" )
return dict(found=dic_out, year=year )
@view_config(route_name='handle_task', renderer='jm2l:templates/Staff/tasks.mako')
def tasks(request):
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
task_id = request.matchdict.get('task_id')
# Convert the pole_id GET parameter to int or 0
if request.params.get('pole_id') and request.params.get('pole_id').isdigit():
pole_id = int(request.params.get('pole_id'))
else:
pole_id = None
# Get areas from db
Areas = DBSession.query(TasksArea.uid, TasksArea.name) \
.filter(TasksArea.year_uid == year) \
.order_by('name').all()
# Get users from db
Users = DBSession.query(User)\
.filter(User.Staff==1)\
.order_by('nom').all()
if task_id:
TmpTask = Tasks.by_id(int(task_id))
if not TmpTask:
raise HTTPNotFound()
form = EditStaffTasks(request.POST, TmpTask, meta={'csrf_context': request.session})
else:
TmpTask = Tasks()
# Check if the supplied pole_id is in the Areas' range
form = StaffTasks(request.POST, TmpTask, meta={'csrf_context': request.session})
Area = TasksArea.by_id(pole_id)
if Area:
form.area_uid.data = Area.uid
# Put some areas on form
form.area_uid.choices = Areas
# Put some users on form
form.closed_by.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
for u in Users]
form.due_date.type = "date"
if request.method=='POST' and form.validate():
form.populate_obj(TmpTask)
TmpTask.closed = False
if not TmpTask.year_uid:
TmpTask.year_uid = year;
if 'uid' in form._fields.keys():
DBSession.merge(TmpTask)
else:
DBSession.add(TmpTask)
DBSession.flush()
return HTTPFound(location=request.route_url('list_task', year=year)+"#"+slugify(TmpTask.area.name))
return {'form':form, 'area':TmpTask.area and slugify(TmpTask.area.name) or '', 'year':year}
@view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako')
def tasks_area(request):
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
pole_id = request.matchdict.get('pole_id')
if pole_id:
Pole = TasksArea.by_id(int(pole_id))
if not Pole:
raise HTTPNotFound()
form = EditStaffArea(request.POST, Pole, meta={'csrf_context': request.session})
else:
Pole = TasksArea()
form = StaffArea(request.POST, Pole, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
form.populate_obj(Pole)
if not Pole.year_uid:
Pole.year_uid = year;
if 'uid' in form._fields.keys():
DBSession.merge(Pole)
else:
DBSession.add(Pole)
return HTTPFound(location=request.route_url('list_task', year=year)+"#"+slugify(Pole.name))
return {'form':form, 'year':year }
@view_config(route_name='action_task')
def action_task(request):
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
action = request.matchdict.get('action')
task_id = request.matchdict.get('task_id')
Task = Tasks.by_id(int(task_id))
if action=='close':
Task.closed = True
request.session.flash(('info', u'La tâche a été fermé, Félicitations !'))
DBSession.merge(Task)
if action=='open':
Task.closed = False
request.session.flash(('info', u'La tâche a été ré-ouverte !'))
DBSession.merge(Task)
if action=='delete':
request.session.flash(('info', u'La tâche a été supprimée !'))
DBSession.delete(Task)
return HTTPFound(location=request.route_url('list_task', year=year)+"#"+slugify(Task.area.name))
@view_config(route_name='action_task_area')
def action_task_area(request):
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
action = request.matchdict.get('action')
pole_id = request.matchdict.get('pole_id')
Pole = TasksArea.by_id(int(pole_id))
if not Pole:
raise HTTPNotFound()
if action=='delete':
request.session.flash(('info', u'Le pôle a été supprimé !'))
DBSession.delete(Pole)
return HTTPFound(location=request.route_url('list_task', year=year))
@view_config(route_name='list_salles', renderer='jm2l:templates/Salles/list.mako')
def list_salles(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
DicSalle = {}
years = DBSession.query( JM2L_Year ).all()
for year in years:
salles = DBSession.query( Salles )\
.filter( Salles.year_uid==year.year_uid )\
.order_by(Salles.name).all()
DicSalle[year] = salles
return {'DicSalle': DicSalle }
@view_config(route_name='list_salles_phy', renderer='jm2l:templates/Salles/list_phy.mako')
def list_salles_phy(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
salles_phy = DBSession.query( SallePhy )\
.order_by(SallePhy.name).all()
return {'DicSallePhy': salles_phy }
@view_config(route_name='handle_salle', renderer='jm2l:templates/Salles/salle.mako')
def handle_salle(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
salle_id = request.matchdict.get('salle_id')
if salle_id:
Salle = Salles.by_id(int(salle_id))
if not Salle:
raise HTTPNotFound()
form = EditSalleForm(request.POST, Salle, meta={'csrf_context': request.session})
else:
Salle = Salles()
form = SalleForm(request.POST, Salle, meta={'csrf_context': request.session})
form.year_uid.choices = map(tuple, DBSession.query(JM2L_Year.year_uid, JM2L_Year.year_uid).all())
form.phy_salle_id.choices = map(tuple, DBSession.query(SallePhy.uid, SallePhy.name).all())
if request.method == 'POST' and form.validate():
form.populate_obj(Salle)
if 'uid' in form._fields.keys():
DBSession.merge(Salle)
else:
DBSession.add(Salle)
return HTTPFound(location=request.route_url('list_salles'))
return {'form':form }
@view_config(route_name='handle_salle_phy', renderer='jm2l:templates/Salles/salle_phy.mako')
def handle_salle_phy(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
salle_id = request.matchdict.get('salle_id')
if salle_id:
Salle = SallePhy.by_id(int(salle_id))
orig_slug = Salle.slug
if not Salle:
raise HTTPNotFound()
form = EditSallePhyForm(request.POST, Salle, meta={'csrf_context': request.session})
else:
Salle = SallePhy()
orig_slug = None
form = SallePhyForm(request.POST, Salle, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
form.populate_obj(Salle)
dest_slug = slugify(Salle.name)
# Do a check in order to move attached files if any
if orig_slug and orig_slug!=dest_slug:
try:
mp = MediaPath().move_mediapath('salle', orig_slug, dest_slug)
except RuntimeError, err:
request.session.flash(('error', u"Le nom de cette salle est déjà utilisé : " + err.message))
return {'form': form}
Salle.slug = slugify(Salle.name)
if 'uid' in form._fields.keys():
DBSession.merge(Salle)
else:
DBSession.add(Salle)
return HTTPFound(location=request.route_url('list_salles'))
return {'form':form }
@view_config(route_name='action_salle')
def action_salle(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
action = request.matchdict.get('action')
salle_id = request.matchdict.get('salle_id')
Salle = Salles.by_id(int(salle_id))
if not Salle:
raise HTTPNotFound()
if action=='delete':
request.session.flash(('info', u'La Salle a été supprimée !'))
DBSession.delete(Salle)
return HTTPFound(location=request.route_url('list_salles'))
## =-=- Here, We handle HTTP requests - User Logged Part -=-=
@view_config(route_name='exchange', renderer="jm2l:templates/Logistique/Logistique.mako")
def exchange(request):
modtype = request.matchdict.get('modtype', None)
action = request.matchdict.get('action', None)
uid = int(request.matchdict.get('id', -1))
Exch = Exchange.by_id(uid)
if not Exch:
MainTab = {
'Exchanges':Exchange,
'Type':modtype[-1:],
'reload':True,
'logged_in':request.authenticated_userid
}
return MainTab
if action in ['delete', 'accept', 'refuse', 'deal']:
if action=='delete': # delete exchange
DBSession.delete(Exch)
elif action=='accept': # accept exchange
Exch.exch_done=True
DBSession.merge(Exch)
elif action=='refuse': # refuse exchange
Exch.exch_done=False
if Exch.exch_state=="Ask":
Exch.provider_id = None
elif Exch.exch_state=="Proposal":
Exch.asker_id = None
DBSession.merge(Exch)
elif action=='deal':
# ask to deal the exchange
if Exch.exch_state=="Ask":
Exch.provider_id = request.user.uid
elif Exch.exch_state=="Proposal":
Exch.asker_id = request.user.uid
# Return javascript to parent page
response = render_to_response('jm2l:templates/modals_js.mako',
{'modtype':modtype, 'action':action},
request=request)
response.content_type = 'text/javascript'
return response
else:
MainTab = {
'Exchanges':Exchange,
'Type':modtype[-1:],
'reload':True,
'logged_in':request.authenticated_userid
}
return MainTab
@view_config(route_name='miam')
def miam(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
miam_form = MiamForm(request.POST, request.user, meta={'csrf_context': request.session})
if request.method == 'POST' and miam_form.validate():
FicheSejour = Sejour.by_user(request.user.uid, CurrentYear)
if FicheSejour:
Update=True
else:
FicheSejour = Sejour()
FicheSejour.created = datetime.datetime.now()
Update=False
Repas=0
for num, item in enumerate(['RepasVendredi', 'RepasSamediMidi', 'RepasSamediSoir']):
if request.params.get(item)==u"1":
Repas += 2**num
FicheSejour.repas = Repas
FicheSejour.repas_allerg = request.params.get('Allergies')
FicheSejour.repas_contr = request.params.get('Contraintes')
FicheSejour.user_id = request.user.uid
FicheSejour.for_year = CurrentYear
if Update:
DBSession.merge(FicheSejour)
else:
DBSession.add(FicheSejour)
request.session.flash(('info',u'Votre fiche a été mise à jour avec succès'))
else:
request.session.flash(('error',u'Un problème est survenu'))
return HTTPFound(location='/MesJM2L#Miam')
@view_config(route_name='sejour')
def sejour(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if request.method == 'POST':
FicheSejour = Sejour.by_user(request.user.uid, CurrentYear)
if FicheSejour:
Update=True
else:
FicheSejour = Sejour()
FicheSejour.created = datetime.datetime.now()
Update=False
FicheSejour.user_id = request.user.uid
FicheSejour.last_change = datetime.datetime.now()
FicheSejour.for_year = CurrentYear
# Arrival
ArrDate = datetime.datetime.strptime(request.params.get('Arrival:Day'),"%d/%m/%y")
ArrTime = datetime.datetime.strptime(request.params.get('Arrival:Hour'),"%H:%M")
FicheSejour.arrival_time = datetime.datetime.combine(ArrDate.date(), ArrTime.time())
ArrivalCheck=0
for num, item in enumerate(['Arrival:PMR', 'Arrival:Cov', 'Arrival:Bras', 'Arrival:Other']):
if request.params.get(item):
ArrivalCheck += 2**num
FicheSejour.arrival_check = ArrivalCheck
FicheSejour.arrival_text = request.params.get('Arrival:Comment')
FicheSejour.arrival_place = request.params.get('Arrival:Place')
# Departure
DepDate = datetime.datetime.strptime(request.params.get('Departure:Day'),"%d/%m/%y")
DepTime = datetime.datetime.strptime(request.params.get('Departure:Hour'),"%H:%M")
FicheSejour.depart_time = datetime.datetime.combine(DepDate.date(), DepTime.time())
DepartCheck=0
for num, item in enumerate(['Departure:PMR', 'Departure:Cov', 'Departure:Bras', 'Departure:Other']):
if request.params.get(item):
DepartCheck += 2**num
FicheSejour.depart_check = DepartCheck
FicheSejour.depart_text = request.params.get('Departure:Comment')
FicheSejour.depart_place = request.params.get('Departure:Place')
if Update:
DBSession.merge(FicheSejour)
request.session.flash(('info',u'Vos modifications de séjour ont été pris en compte.'))
else:
DBSession.add(FicheSejour)
request.session.flash(('info',u'\\o/ Votre séjour est enregistré ! Complétez la partie Logistique.'))
return HTTPFound(location='/MesJM2L#Sejour')
@view_config(route_name='orga')
def orga(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if request.method == 'POST':
FicheSejour = Sejour.by_user(request.user.uid, CurrentYear)
UpdateOrga=False
if FicheSejour:
Update=True
if FicheSejour.orga_part:
UpdateOrga=True
else:
FicheSejour = Sejour()
FicheSejour.created = datetime.datetime.now()
Update=False
FicheSejour.user_id = request.user.uid
FicheSejour.last_change = datetime.datetime.now()
FicheSejour.for_year = CurrentYear
OrgaPart=0
for item in request.params:
try:
nb = int(item[1:])
except:
continue
OrgaPart += 2**nb
FicheSejour.orga_part = OrgaPart
if UpdateOrga:
request.session.flash(('info',u'Vos modifications de participation à l\'organisation ont été pris en compte.'))
else:
request.session.flash(('info',u'\\o/ Votre participation à l\'organisation est enregistrée !'))
if Update:
DBSession.merge(FicheSejour)
else:
DBSession.add(FicheSejour)
return HTTPFound(location='/MesJM2L#Organisation')
@view_config(route_name='vote_logo')
def vote_logo(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
else:
vote = int(request.matchdict.get('num', -1))
come = request.params.get('come_from')
if vote:
request.user.vote_logo=vote
DBSession.merge(request.user)
request.session.flash(('info',u'Votre vote à été pris en compte.'))
return HTTPFound('/')
else:
request.session.flash(('warning',u"Votre vote n'a été pris en compte."))
if come:
return HTTPFound(location=come)
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
@view_config(route_name='list_users_csv', renderer="string")
def list_users_csv(request):
for_year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
stmt = (DBSession.query(Sejour).filter(Sejour.for_year==for_year)).subquery()
# stmt_event = (DBSession.query(User_Event).filter()
adalias = aliased(Sejour, stmt)
Data = DBSession.query(User, adalias ) \
.outerjoin(adalias)\
.order_by(User.slug)\
.all()
FileHandle = StringIO.StringIO()
fileWriter = csv.writer(FileHandle, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
fileWriter.writerow(["Identifiant_JM2L", "Nom", "Prenom", "Status_%s" % for_year ])
for user, sejour in Data:
tab_identifier = [user.slug, user.nom.encode('utf-8'), user.prenom.encode('utf-8'), '']
if user.is_IntervenantOnYear(CurrentYear):
tab_identifier[3] = "Intervenant"
elif user.Staff:
tab_identifier[3] = "Staff"
elif sejour and sejour.orga_part:
tab_identifier[3] = "Bénévole"
elif sejour:
tab_identifier[3] = "Visiteur"
else:
continue
fileWriter.writerow(tab_identifier)
return Response(app_iter=FileHandle.getvalue(), content_type="text/csv")
@view_config(route_name='list_users', renderer="jm2l:templates/Participant/list_users.mako")
def list_users(request):
for_year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
stmt = (DBSession.query(Sejour).filter(Sejour.for_year==for_year)).subquery()
adalias = aliased(Sejour, stmt)
Data = DBSession.query(User, adalias ) \
.outerjoin(adalias)\
.all()
Repas = DBSession.query(Sejour.repas) \
.filter(Sejour.for_year == for_year ) \
.all()
DicRepas = {"Ven":0, "Midi":0, "Soir":0}
for r in Repas:
if r[0] is None:
continue
if (r[0] & 1 == 1): DicRepas["Ven"]+=1
if (r[0] & 2 == 2): DicRepas["Midi"]+=1
if (r[0] & 4 == 4): DicRepas["Soir"]+=1
return { 'Users':Data, 'UserEvent' : User_Event, "DicRepas":DicRepas, "for_year": for_year }
@view_config(route_name='list_orga', renderer="jm2l:templates/Participant/list_orga.mako")
def list_orga(request):
for_year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
Data = DBSession.query(User, Sejour)\
.outerjoin(Sejour)\
.filter(Sejour.for_year == for_year)\
.all()
return { 'Users':Data }
@view_config(route_name='drop_sejour')
def drop_sejour(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
# Feed FicheSejour if any
FicheSejour = Sejour.by_user(request.user.uid, CurrentYear)
if FicheSejour:
DBSession.delete(FicheSejour)
request.session.flash(('warning', u'Votre participation %s a été supprimé avec succès.' % CurrentYear ))
else:
raise HTTPNotFound()
return HTTPFound(location='/MesJM2L#Sejour')
@view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako")
def jm2l_page(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
UserNum = request.params.get('user')
if UserNum:
profil = User.by_id(int(UserNum))
if not profil:
raise HTTPNotFound()
if not request.user.Staff:
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
else:
profil = request.user
FicheSejour = Sejour()
FicheSejour.created = datetime.datetime.now()
# Build Form
profil_form = ProfilForm(request.POST, profil, meta={'csrf_context': request.session})
miam_form = MiamForm(request.POST, profil, meta={'csrf_context': request.session})
# Feed FicheSejour if any
FicheSejour = Sejour.by_user(profil.uid, CurrentYear)
if FicheSejour:
if FicheSejour.repas is not None:
for num, item in enumerate(['RepasVendredi', 'RepasSamediMidi', 'RepasSamediSoir']):
if FicheSejour.repas & 2**num:
miam_form._fields[item].data = "1"
else:
miam_form._fields[item].data = "0"
miam_form._fields['Allergies'].data = FicheSejour.repas_allerg
miam_form._fields['Contraintes'].data = FicheSejour.repas_contr
if request.method == 'POST' and profil_form.validate():
ToDelete = list()
# First, we remove entries no more present
for obj in profil_form.tiersship.object_data:
MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
profil_form.tiersship.entries )
if not MatchEntry:
ToDelete.append(obj)
# Then, it's time to consider new entries
for entry in profil_form.tiersship.entries:
if entry.object_data is None:
TmpUser = User_Tiers()
entry.object_data = TmpUser
profil.tiersship.append(TmpUser)
profil_form.tiersship.object_data = profil.tiersship
profil_form.populate_obj(profil)
# We should remove it as it's not in original data
for obj in ToDelete:
#profil.tiersship.remove(obj)
DBSession.delete(obj)
profil.last_change = datetime.datetime.utcnow()
profil.slug = slugify(remove_accents('%s %s' % (profil.prenom, profil.nom)).lower().strip())
DBSession.merge(profil)
request.session.flash(('info',u'Votre fiche a été mise à jour avec succès'))
MainTab = {'participer':'active',
'Places':Place.get_list(False),
'DBTiers':Tiers,
'DBTiersOpt':TiersOpt,
'Exchanges':Exchange,
'profil_form':profil_form,
'miam_form':miam_form,
'uprofil':profil,
'logged_in':request.authenticated_userid
}
return MainTab
@view_config(route_name='modal', renderer="jm2l:templates/modals.mako")
def Modal(request):
year = int(request.matchdict.get('year', None))
modtype = request.matchdict.get('modtype', None)
uid = int(request.matchdict.get('id', -1))
session = request.session
if modtype=='Password':
form = UserPasswordForm(request.POST, request.user, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
response = render_to_response('jm2l:templates/modals_js.mako',
{'modtype':modtype},
request=request)
request.user.password = argon2.using(rounds=4).hash(form.password.data)
DBSession.merge(request.user)
response.content_type = 'text/javascript'
return response
if modtype=='UserPicture':
form = None
if request.method == 'POST':
response = render_to_response('jm2l:templates/modals_js.mako',
{'modtype':modtype},
request=request)
response.content_type = 'text/javascript'
return response
if modtype=='Place':
if uid>0:
place = Place.by_id(uid)
if not place:
raise HTTPNotFound()
form = PlaceUpdateForm(request.POST, place, meta={'csrf_context': request.session})
else:
place = Place()
form = PlaceCreateForm(request.POST, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
form.populate_obj(place)
place.created_by=request.user.uid
place.slug = slugify(place.name)
if uid>0:
DBSession.merge(place)
else:
DBSession.add(place)
response = render_to_response('jm2l:templates/modals_js.mako',
{'modtype':modtype},
request=request)
response.content_type = 'text/javascript'
return response
if modtype in ['AskC', 'AskH', 'AskM', 'PropC', 'PropH', 'PropM']:
if uid>0:
Exch = Exchange.by_id(uid)
if not Exch:
raise HTTPNotFound()
if modtype in ['AskC','PropC']:
form = globals()["Update%sForm" % modtype](request.POST, Exch,
start_place = Exch.Itin.start_place,
arrival_place = Exch.Itin.arrival_place,
Hour_start = Exch.start_time.strftime("%H:%M"),
Day_start = Exch.start_time.strftime("%w"),
exch_id = uid, meta={'csrf_context': request.session}
)
elif modtype in ['AskM','PropM']:
form = globals()["Update%sForm" % modtype](request.POST, Exch,
description = Exch.description,
exch_categ = Exch.exch_categ,
Hour_start = Exch.start_time.strftime("%H:%M"),
Day_start = Exch.start_time.strftime("%w"),
Hour_end = Exch.end_time.strftime("%H:%M"),
Day_end = Exch.end_time.strftime("%w"),
exch_id = uid, meta={'csrf_context': request.session}
)
elif modtype in ['AskH','PropH']:
form = globals()["Update%sForm" % modtype](request.POST, Exch,
description = Exch.description,
exch_categ = Exch.exch_categ,
Day_start = Exch.start_time.strftime("%w"),
exch_id = uid, meta={'csrf_context': request.session}
)
# Itinerary, first get itinerary
if 0:
form.itin.form.start_place.data = Exch.Itin.start_place
form.itin.form.arrival_place.data = Exch.Itin.arrival_place
form.dateform.form.Hour.data = Exch.start_time.strftime("%H:%M")
form.dateform.form.Day.data = Exch.start_time.strftime("%w")
form.exch_id.data = uid
else:
Exch = Exchange()
form = globals()["%sForm" % modtype](request.POST, meta={'csrf_context': request.session})
if modtype in ['AskC', 'PropC']:
# Put some place on form
Places = DBSession.query(Place.place_id, Place.display_name)\
.order_by('name').all()
form.start_place.choices = Places
form.arrival_place.choices = Places
if modtype in ['PropH']:
form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\
.filter( Exchange_Cat.exch_type=='H' ).all()
form.place_id.choices = DBSession.query( Place.place_id, Place.display_name)\
.filter( Place.created_by==request.user.uid ).all()
if modtype in ['AskM', 'PropM']:
form.exch_categ.choices = DBSession.query( Exchange_Cat.cat_id, Exchange_Cat.exch_subtype)\
.filter( Exchange_Cat.exch_type=='M' ).all()
if request.method == 'POST' and form.validate():
# Form has been validated, it's time to create our Exchange
Exch.for_year = year
Exch.exch_state = {'Ask':'Ask', 'Prop':'Proposal'}[modtype[:-1]]
Exch.exch_type = modtype[-1:]
if modtype in ['AskC', 'PropC']:
# Itinerary, first Let's see if itinerary exist
Itinerary = DBSession.query(Itineraire)\
.filter(Itineraire.start_place==form.start_place.data) \
.filter(Itineraire.arrival_place==form.arrival_place.data) \
.filter(Itineraire.tr_voiture==True) \
.first()
if not Itinerary: # Not exist yet !
Itinerary = Itineraire(start_place=form.start_place.data, \
arrival_place=form.arrival_place.data, \
tr_voiture=True, \
created_by=1
)
DBSession.add(Itinerary)
DBSession.flush()
Exch.itin_id = Itinerary.itin_id
# Start Time
StartEvent = DBSession.query(JM2L_Year.start_time).filter(JM2L_Year.year_uid==year).first()
Week = StartEvent[0].strftime("%W")
# populate
form.populate_obj(Exch)
if modtype in ['AskC', 'PropC']:
Exch.itin_id = Itinerary.itin_id
if form._fields.has_key("Hour_start"):
TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
int(form.Day_start.data), form.Hour_start.data), "%Y %W %w %H:%M")
Exch.start_time = TargetTime
elif form._fields.has_key("Day_start"):
TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
int(form.Day_start.data)), "%Y %W %w")
Exch.start_time = TargetTime
if form._fields.has_key("Hour_end"):
TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
int(form.Day_end.data), form.Hour_end.data), "%Y %W %w %H:%M")
Exch.end_time = TargetTime
elif form._fields.has_key("Day_end"):
TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
int(form.Day_end.data)), "%Y %W %w")
Exch.end_time = TargetTime
Exch.last_change = datetime.datetime.utcnow()
if Exch.exch_state=='Ask':
Exch.asker_id = request.user.uid
elif Exch.exch_state=='Proposal':
Exch.provider_id = request.user.uid
#print vars(form.itin.form)
if uid>0:
DBSession.merge(Exch)
else:
DBSession.add(Exch)
response = render_to_response('jm2l:templates/modals_js.mako',
{'modtype':modtype},
request=request)
response.content_type = 'text/javascript'
return response
# Fallback to HTML Display with errors
return {'modtype':modtype, 'form':form, 'update':uid>0,
'logged_in':request.authenticated_userid }
if modtype in ['ShowC', 'ShowH', 'ShowM']:
if uid>0:
Exch = Exchange.by_id(uid)
if not Exch:
raise HTTPNotFound()
else:
raise HTTPNotFound()
# Show Details around the Current Exchange
return {'modtype':modtype, 'Exch':Exch, 'logged_in':request.authenticated_userid }
MainTab = {'modtype':modtype, 'form':form, 'update':uid>0, 'uid':uid,
'DisplayYear':year, 'session':session,
'logged_in':request.authenticated_userid }
return MainTab
@view_config(route_name='participer', renderer="jm2l:templates/Participer.mako")
def participer(request):
session = request.session
session['year'] = CurrentYear
TmpUsr = User()
form = UserRegisterForm(request.POST, TmpUsr, meta={'csrf_context': request.session})
MyLink=None
if request.method == 'POST' and form.validate():
# Prepare mailer
form.populate_obj(TmpUsr)
TmpUsr.nom = TmpUsr.nom.capitalize()
TmpUsr.prenom = TmpUsr.prenom.capitalize()
TmpUsr.slug = slugify(remove_accents('%s %s' % (form.prenom.data, form.nom.data)).lower().strip())
TmpUsr.password = TmpUsr.my_hash
if len(TmpUsr.slug):
CheckExist = DBSession.query(User)\
.filter(User.slug==TmpUsr.slug)\
.first()
else:
CheckExist=None
if CheckExist:
MyLink = CheckExist.my_hash
NewUser = CheckExist
else:
DBSession.add(TmpUsr)
DBSession.flush()
MyLink = TmpUsr.my_hash
NewUser = TmpUsr
# Send the Welcome Mail
mailer = request.registry['mailer']
# Prepare Plain Text Message :
Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = Mail_template.render(request=request, User=NewUser, action="Welcome")
# Prepare HTML Message :
Mail_template = Template(filename='jm2l/templates/mail_html.mako')
mail_html = Mail_template.render(request=request, User=NewUser, action="Welcome")
# Prepare Message
message = Message(subject="[JM2L] Mon inscription au site web JM2L",
sender="contact@jm2l.linux-azur.org",
recipients=[NewUser.mail or TmpUsr.mail],
body=mail_plain, html=mail_html)
message.add_bcc("spam@style-python.fr")
mailer.send(message)
request.session.flash(('info',u"Un mail vous a été envoyé afin de continuer votre quête !"))
MainTab = {'programme':'','presse':'', 'plan':'',
'participer':'active', 'form':form, "link": MyLink,
'logged_in':request.authenticated_userid }
return MainTab
@view_config(route_name='year')
def change_year(request):
year = int(request.matchdict.get('year', -1))
session = request.session
if year>-1:
session['year'] = year
return HTTPFound(location='/%s/' % year)
return HTTPFound(location=request.route_url('home', year=''))
@view_config(route_name='pict_user', renderer="jm2l:templates/Profil/pict_user.mako")
def pict_user(request):
return {"uprofil":request.user}
@view_config(route_name='pict_salle', renderer="jm2l:templates/Salles/pict_salle.mako")
def pict_salle(request):
salle_id = int(request.matchdict.get('salle_id', -1))
return {"Salles":Salles, "IdSalle":salle_id}
@view_config(route_name='event', renderer="jm2l:templates/view_event.mako")
def show_event(request):
year = int(request.matchdict.get('year', -1))
event_id = request.matchdict.get('event_id')
if event_id.isdigit():
TheEvent = Event.by_id(event_id)
if TheEvent is None:
raise HTTPNotFound()
else:
TheEvent = Event.by_slug(event_id, year)
if TheEvent is None:
raise HTTPNotFound()
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
'event':TheEvent, 'logged_in':request.authenticated_userid, "Salles":Salles }
return MainTab
@view_config(route_name='link_event_user')
def link_event_user(request):
""" Get user and add it to current event """
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
year = int(request.matchdict.get('year', -1))
form = AddIntervenant(request.POST, meta={'csrf_context': request.session})
intervention = request.matchdict.get('intervention', None)
TargetEvent = Event.by_id(form.event_uid.data)
Exist = User.by_id(form.intervenant.data)
if not Exist:
request.session.flash(('error',u"Une erreur s'est produite lors de l'ajout de votre intervenant !"))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
else:
TargetUser = Exist
uev = User_Event(year_uid=year, role=u"Animateur d'un évènement JM2L", user_uid=TargetUser.uid)
TargetEvent.interventions.append( uev )
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
@view_config(route_name='link_event_tiers')
def link_event_tiers(request):
""" Create user if not exist, add it to current event """
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
year = int(request.matchdict.get('year', -1))
form = AddTiers(request.POST, meta={'csrf_context': request.session})
intervention = request.matchdict.get('intervention', None)
TargetEvent = Event.by_id(form.event_uid.data)
Exist = Tiers.by_id(form.tiers.data)
if not Exist:
request.session.flash(('error',u"Une erreur s'est produite lors de l'ajout de votre entité !"))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
else:
TargetTiers = Exist
Matching = DBSession.query(Role_Tiers)\
.filter(Role_Tiers.year_uid==year)\
.filter(Role_Tiers.tiers_role=="Exposant")\
.filter(Role_Tiers.tiers_uid==TargetTiers.uid)\
.filter(Role_Tiers.event_uid==TargetEvent.uid)\
.all()
if len(Matching)==0:
tev = Role_Tiers(year_uid=year, tiers_role="Exposant", tiers_uid=TargetTiers.uid, event_uid=TargetEvent.uid)
DBSession.add(tev)
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid), _anchor="Tiers"))
@view_config(route_name='delete_link_u')
def delete_link_event_user(request):
""" Create user if not exist, add it to current event """
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
year = int(request.matchdict.get('year', -1))
intervention = request.matchdict.get('intervention', None)
TargetEvent = Event.by_id( request.params.get('eid') )
Exist = User.by_id( request.params.get('uid') )
if not Exist:
request.session.flash(('error',u"Une erreur s'est produite lors de votre suppression !"))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
else:
TargetUser = Exist
Matching = DBSession.query(User_Event)\
.filter(User_Event.year_uid==year)\
.filter(User_Event.user_uid==TargetUser.uid)\
.filter(User_Event.event_uid==TargetEvent.uid)\
.all()
if len(Matching)==0:
request.session.flash(('error',u"Une erreur s'est produite lors de la suppression !"))
else:
for item in Matching:
DBSession.delete(item)
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid), _anchor="Tiers"))
@view_config(route_name='delete_link_t')
def delete_link_event_tiers(request):
""" Create user if not exist, add it to current event """
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
year = int(request.matchdict.get('year', -1))
intervention = request.matchdict.get('intervention', None)
TargetEvent = Event.by_id( request.params.get('uid') )
Exist = Tiers.by_id( request.params.get('tid') )
if not Exist:
request.session.flash(('error',u"Une erreur s'est produite lors de l'ajout de votre entité !"))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
else:
TargetTiers = Exist
Matching = DBSession.query(Role_Tiers)\
.filter(Role_Tiers.year_uid==year)\
.filter(Role_Tiers.tiers_role=="Exposant")\
.filter(Role_Tiers.tiers_uid==TargetTiers.uid)\
.filter(Role_Tiers.event_uid==TargetEvent.uid)\
.all()
if len(Matching)==0:
request.session.flash(('error',u"Une erreur s'est produite lors de la suppression de votre entité !"))
else:
for item in Matching:
DBSession.delete(item)
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid), _anchor="Tiers"))
@view_config(route_name='delete_event')
def delete_event(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
year = int(request.matchdict.get('year', -1))
event_id = request.matchdict.get('event_id')
intervention = request.matchdict.get('intervention', None)
# Check intervention
if not intervention in ['Stand', 'Table_ronde', 'Atelier', 'Conference', 'Concert']:
raise HTTPNotFound(u"Ce type d'évènement n'est pas reconnu")
# We should remove all links before to remove the event
if event_id.isdigit():
TheEvent = Event.by_id(event_id)
if TheEvent is None:
raise HTTPNotFound(u"Cette réference n'existe pas")
else:
TheEvent = Event.by_slug(event_id, year)
if TheEvent is None:
raise HTTPNotFound(u"Cette réference n'existe pas")
# Remove Roles
Roles_Link = DBSession.query(Role_Tiers).filter(Role_Tiers.event_uid==TheEvent.uid).all()
for tmp in Roles_Link:
DBSession.delete(tmp)
# Remove Intervenant
User_Link = DBSession.query(User_Event).filter(User_Event.event_uid==TheEvent.uid).all()
for tmp in User_Link:
DBSession.delete(tmp)
# Remove attachment if any
SRCPath = path.join('jm2l/upload', *(IMAGEPATH + ['event'] + [ str(year) ] + [ TheEvent.slug ]) )
shutil.rmtree(SRCPath, ignore_errors=True)
# Remove Event
DBSession.delete(TheEvent)
return HTTPFound(location=request.route_url('jm2l', _anchor="Interventions"))
@view_config(route_name='edit_event', renderer="jm2l:templates/edit_event.mako")
def edit_event(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
year = int(request.matchdict.get('year', -1))
event_id = request.matchdict.get('event_id')
intervention = request.matchdict.get('intervention', None)
IntervLabel = intervention.replace('_',' ').lower()
if intervention=='Conference':
IntervLabel = u'conférence'
elif intervention=='Table_ronde':
IntervLabel = u'Table ronde'
# Check intervention
if not intervention in ['Stand', 'Table_ronde', 'Atelier', 'Conference', 'Concert']:
raise HTTPNotFound(u"Ce type d'évènement n'est pas reconnu")
TheYear = DBSession.query(JM2L_Year)\
.filter(JM2L_Year.year_uid==year)\
.first()
# Check year avaibility
if not TheYear:
raise HTTPNotFound(u"Cette année n'est pas pris en charge")
# Generate Timeslots for current year
TimeSlots = list(enumerate( [ x.strftime('%a %d %b %H:%M') for x in
TheYear.AvailableTimeSlots ] ))
if event_id:
# We try to update an existing record
if event_id.isdigit():
TheEvent = Event.by_id(event_id)
if TheEvent is None:
raise HTTPNotFound(u"Cette réference n'existe pas")
else:
TheEvent = Event.by_slug(event_id, year)
if TheEvent is None:
raise HTTPNotFound(u"Cette réference n'existe pas")
if request.user is None or not (request.user.Staff or request.user in TheEvent.intervenants):
raise HTTPForbidden(u"Vous n'êtes pas identifié comme étant un participant à cette intervention.")
# Compute some field value from selected event
if TheEvent.start_time in TheYear.AvailableTimeSlots:
start_sel = TheYear.AvailableTimeSlots.index(TheEvent.start_time)
else:
start_sel = len(TimeSlots)
TimeSlots.append( (len(TimeSlots), TheEvent.start_time.strftime('%a %d %b %H:%M')))
duration = (TheEvent.end_time - TheEvent.start_time).total_seconds()/60
end = TheEvent.start_time + datetime.timedelta(minutes=duration)
# prepare the form with update
form = ConfUpdateForm(request.POST, TheEvent, start_sel=start_sel, duration=duration, end_time=end,
meta={'csrf_context': request.session} )
# Customize labels
form.name.label.text += IntervLabel
form.description.label.text += IntervLabel
# Each event can get severals members
formAdd = AddIntervenant(event_uid=TheEvent.uid)
# Build list of intervenant
# Get users from db
Users = DBSession.query(User)\
.filter(User.Staff==1)\
.order_by('nom').all()
# Put some users on form
formAdd.intervenant.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
for u in Users]
# Each event can get severals entities
formAddT = AddTiers(event_uid=TheEvent.uid)
# Build list of entities
# Get entities from db
TmpTiers = DBSession.query(Tiers)\
.order_by('name').limit(10)
# Put some entities on form
formAddT.tiers.choices = [(u.uid, "%s %s" % (u.nom, u.prenom))
for u in Users]
else:
TheEvent = Event()
# prepare the form for creation
form = ConfCreateForm(request.POST,
event_type=intervention,
for_year=str(year), meta={'csrf_context': request.session}
)
# Customize labels
form.name.label.text += IntervLabel
form.description.label.text += IntervLabel
duration=60
# No intervenant
formAdd = None
formAddT = None
SalleDispo = DBSession.query(Salles)\
.filter(Salles.year_uid==year)\
.order_by('name')
if intervention=="Conference":
form.duration.choices =[
(15,u'Lighting talk ( 5 min)'),
(30,u'Conférence (20 min)'),
(60,u'Conférence (50 min)'),
(90,u'Conférence (75 min)'),
]
if not duration in [15, 30, 60, 90]:
form.duration.choices.append( (duration,u'Conférence (%d min)' % duration) )
if not form._fields.has_key("uid"):
form.duration.data=60
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Conference', 'MAO', 'Atelier']))
elif intervention=="Stand":
form.duration.choices =[
(8*60, u'Toute la journée'),
(4*60, u'une demi-journée')
]
SalleDispo = SalleDispo.filter(Salles.place_type=='Stand')
elif intervention=="Atelier":
form.duration.choices = map( lambda d:(d, u'Atelier (%dh%.2d)' % (d/60, d%60) ), \
[60, 90, 120, 150, 180, 210, 240] )
if not duration in map(lambda (d,y): d, form.duration.choices):
form.duration.choices.append( (duration,u'Atelier (%dh%.2d)' % (duration/60, duration%60) ) )
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Atelier', 'MAO']))
elif intervention=="Table_ronde":
form.duration.choices = map( lambda d:(d, u'Table ronde (%dh%.2d)' % (d/60, d%60) ), \
[60, 90, 120, 150] )
if not duration in map(lambda (d,y): d, form.duration.choices):
form.duration.choices.append( (duration,u'Table ronde (%dh%.2d)' % (duration/60, duration%60) ) )
SalleDispo = SalleDispo.filter(Salles.place_type=='Table ronde')
elif intervention=="Concert":
form.duration.choices = map( lambda d:(d, u'Concert (%dh%.2d)' % (d/60, d%60) ), \
[60, 90, 120, 150, 180, 210, 240] )
if not duration in map(lambda (d,y): d, form.duration.choices):
form.duration.choices.append( (duration,u'Concert (%dh%.2d)' % (duration/60, duration%60) ) )
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Stand', 'MAO']))
else:
raise HTTPForbidden(u"Pas encore disponible.")
form.salle_uid.choices = [(s.salle_id, s.name) for s in SalleDispo]
form.start_sel.choices = TimeSlots
if request.method == 'POST' and form.validate():
form.populate_obj(TheEvent)
TheEvent.start_time = TheYear.AvailableTimeSlots[form.start_sel.data]
TheEvent.end_time = TheEvent.start_time + datetime.timedelta(minutes=form.duration.data)
# Ok, time to put in database
if not form._fields.has_key("uid"):
TheEvent.slug = unicode(slugify(TheEvent.name))
if intervention==u"Table_ronde":
TheEvent.event_type = "Table ronde"
DBSession.add(TheEvent)
# Append creator by default
if request.user.uid!=1:
uev = User_Event(year_uid=TheYear.year_uid, role=u"Animateur")
uev.user_uid = request.user.uid
TheEvent.interventions.append( uev )
DBSession.flush()
request.session.flash(('sucess',u'Votre intervention a été créee ! Vous pouvez la compléter à tout moment.'))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TheEvent.slug)))
else:
if slugify(TheEvent.name)!=TheEvent.slug:
# We should move some file as slug have been changed
# First we ensure there is no related event that already exist with that slug
CheckEvent = Event.by_slug( unicode(slugify(TheEvent.name)), year)
if CheckEvent:
request.session.flash(('warning',u'Choisissez un autre titre pour votre évènement, il est en conflit avec un autre.'))
return {'event':TheEvent, 'form':form, 'formAdd':formAdd, 'formAddT':formAddT, 'Salles':Salles }
else:
SRCPath = path.join('jm2l/upload', *(IMAGEPATH + ['event'] + [ str(year) ] + [ TheEvent.slug ]) )
TheEvent.slug=unicode(slugify(TheEvent.name))
DSTPath = path.join('jm2l/upload', *(IMAGEPATH + ['event'] + [ str(year) ] + [ TheEvent.slug ]) )
if not path.isdir(path.dirname(DSTPath)):
makedirs(path.dirname(DSTPath))
# Then we should move event attachments to the new slug (if any)
if path.exists(SRCPath):
shutil.move(SRCPath, DSTPath)
DBSession.merge(TheEvent)
request.session.flash(('sucess',u'Votre intervention a été mis à jour !'))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TheEvent.slug)))
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
'event':TheEvent, 'form':form, 'formAdd':formAdd, 'formAddT':formAddT,
'Salles':Salles }
return MainTab
@view_config(route_name='entities', renderer="jm2l:templates/list_tiers.mako")
def list_tiers(request):
Entities = dict()
EntityType = DBSession.query(TiersOpt.entity_type)\
.group_by(TiersOpt.entity_type).all()
for EType in EntityType:
Entities[EType.entity_type] = DBSession.query(Tiers).join(TiersOpt)\
.filter(TiersOpt.entity_type==EType.entity_type)\
.order_by(TiersOpt.entity_subtype, Tiers.name)
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
'entities':Entities, 'logged_in':request.authenticated_userid }
return MainTab
@view_config(route_name='show_entity', renderer="jm2l:templates/view_tiers.mako")
def show_tiers(request):
tiers_type = request.matchdict.get('tiers_type')
entity_id = request.matchdict.get('entity_id')
if entity_id.isdigit():
TheTiers = Tiers.by_id(entity_id)
if TheTiers is None:
raise HTTPNotFound()
else:
TheTiers = Tiers.by_slug(entity_id)
if TheTiers is None:
raise HTTPNotFound()
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
'entity':TheTiers, 'logged_in':request.authenticated_userid }
return MainTab
@view_config(route_name='delete_entity')
def delete_tiers(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
entity_id = request.matchdict.get('entity_id', None)
if entity_id:
if entity_id.isdigit():
TheTiers = Tiers.by_id(int(entity_id))
if TheTiers is None:
raise HTTPNotFound()
else:
TheTiers = Tiers.by_slug(entity_id)
if TheTiers is None:
raise HTTPNotFound()
if len(TheTiers.membership)!=0:
request.session.flash(('error', u"Vous devez supprimer tous les membres liés avant la suppression d'une entité."))
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, tiers_type=TheTiers.get_entity_type.slug_entity_type))
if len(TheTiers.membership)!=0:
request.session.flash(('error', u"Vous devez supprimer tous les roles liés avant la suppression d'une entité."))
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, tiers_type=TheTiers.get_entity_type.slug_entity_type))
DBSession.delete(TheTiers)
request.session.flash(('info', u"L'entité a bien été supprimée"))
return HTTPFound(location=request.route_url('entities'))
else:
raise HTTPNotFound()
@view_config(route_name='add_entity', renderer="jm2l:templates/edit_tiers.mako")
@view_config(route_name='edit_entity', renderer="jm2l:templates/edit_tiers.mako")
def edit_tiers(request):
entity_id = request.matchdict.get('entity_id', None)
TargetList = list()
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
entity_types = DBSession.query(TiersOpt.entity_type).group_by(TiersOpt.entity_type).all()
for entity_type in entity_types:
entity_subtypes = DBSession.query(TiersOpt)\
.filter(TiersOpt.entity_type==entity_type.entity_type)\
.group_by(TiersOpt.entity_subtype).all()
ListType = [(i.uid, i.entity_subtype) for i in entity_subtypes]
TargetList.append( (entity_type.entity_type, ListType) )
if entity_id:
if entity_id.isdigit():
TheTiers = Tiers.by_id(entity_id)
if TheTiers is None:
raise HTTPNotFound()
else:
TheTiers = Tiers.by_slug(entity_id)
if TheTiers is None:
raise HTTPNotFound()
form = UpdateTiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
UserOptions = DBSession.query(TiersOpt)\
.filter(TiersOpt.entity_type==TheTiers.tiers_type)\
.all()
form.tiers_type.choices = TargetList
else:
TheTiers = Tiers()
# prepare the form for creation
form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
form.tiers_type.choices = TargetList
UserOptions = list()
#test_form = TiersForm(request.POST, TheTiers, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
ToDelete = list()
ToDeleteR = list()
# First, we remove entries no more present
for obj in form.membership.object_data:
MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
form.membership.entries )
if not MatchEntry:
ToDelete.append(obj)
# For roles too
for obj in form.roles.object_data:
MatchEntry = filter( lambda x: x.object_data and x.object_data._sa_instance_state == obj._sa_instance_state,
form.roles.entries )
if not MatchEntry:
ToDeleteR.append(obj)
# We should remove it as it's not in original data
for obj in ToDelete:
TheTiers.membership.remove(obj)
DBSession.delete(obj)
# For roles too
for obj in ToDeleteR:
TheTiers.roles.remove(obj)
DBSession.delete(obj)
# Then, it's time to consider new entries
for entry in form.membership.entries:
if entry.object_data is None:
TmpUser = User_Tiers()
entry.object_data = TmpUser
TheTiers.membership.append(TmpUser)
form.membership.object_data = TheTiers.membership
# For roles too
for entry in form.roles.entries:
if entry.object_data is None:
TmpRole = Role_Tiers()
entry.object_data = TmpRole
TheTiers.roles.append(TmpRole)
form.roles.object_data = TheTiers.roles
form.populate_obj(TheTiers)
# Handle Remove of accents
OriginalSlug = TheTiers.slug
if not form._fields.has_key('uid'):
TheTiers.slug = slugify(form.name.data)
TheTiers.creator_id = request.user.uid
DBSession.add(TheTiers)
DBSession.flush()
return HTTPFound(location=request.route_url('edit_entity', sep='/',
entity_id=str(TheTiers.slug), tiers_type=TheTiers.get_entity_type.entity_type))
else:
if OriginalSlug!=slugify(form.name.data):
# We should move some file as slug have been changed
# First we ensure there is no related event that already exist with that slug
CheckTiers = Tiers.by_slug( slugify(form.name.data) )
if CheckTiers:
request.session.flash(('warning',u'Attention, Choisissez un autre titre pour votre entitée, elle est en conflit avec une autre.'))
DBSession.rollback()
return HTTPFound(location=request.route_url('edit_entity', sep='/',
entity_id=str(OriginalSlug), tiers_type=TheTiers.get_entity_type.entity_type))
else:
TheTiers.slug = slugify(form.name.data)
SRCPath = path.join('jm2l/upload', *(IMAGEPATH + ['tiers'] + [ OriginalSlug ]) )
DSTPath = path.join('jm2l/upload', *(IMAGEPATH + ['tiers'] + [ TheTiers.slug ]) )
if not path.isdir(path.dirname(DSTPath)):
makedirs(path.dirname(DSTPath))
# Then we should move event attachments to the new slug (if any)
if path.exists(SRCPath):
shutil.move(SRCPath, DSTPath)
DBSession.merge(TheTiers)
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug,
tiers_type=TheTiers.get_entity_type.slug_entity_type))
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
'form':form, 'DBUser':User, 'UserOptions':UserOptions,
'logged_in':request.authenticated_userid }
return MainTab
@view_config(route_name='edit_entity_cat', renderer="jm2l:templates/edit_tiers_categ.mako")
def edit_tiers_category(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
DicResult = dict()
ListChanges = list()
if request.method == 'POST':
# Reformat data
RegExist = re.compile('collection\[(?P[\w-]+)\]\[(?P\d+)\]\[(?P\d+)\]')
RegTitle = re.compile('collection\[(?P[\w-]+)\]\[title]')
RegNew = re.compile('collection\[(?P[\w-]+)\]\[(?P\d+)\]\[id\]')
for key, value in request.POST.iteritems():
regN= RegNew.match(key)
regT= RegTitle.match(key)
reg = RegExist.match(key)
if reg:
if not DicResult.has_key(reg.group('slug')):
DicResult[reg.group('slug')] = dict()
if DicResult[reg.group('slug')].has_key('items'):
DicResult[reg.group('slug')]['items'].append( ( int(reg.group('id')), value ) )
else:
DicResult[reg.group('slug')]['items'] = [ ( int(reg.group('id')), value ) ]
elif regN:
if not DicResult.has_key(regN.group('slug')):
DicResult[regN.group('slug')] = dict()
if DicResult[regN.group('slug')].has_key('items'):
DicResult[regN.group('slug')]['items'].append( ( 'id', value ) )
else:
DicResult[regN.group('slug')]['items'] = [ ( 'id', value ) ]
ListChanges.append(('add', 0, DicResult[regN.group('slug')]['title'], value))
elif regT:
if not DicResult.has_key(regT.group('slug')):
DicResult[regT.group('slug')] = dict()
DicResult[regT.group('slug')]['title'] = value
else:
raise
for opt in DBSession.query(TiersOpt).all():
if DicResult.has_key(opt.slug_entity_type):
found = filter( lambda (x,y): opt.uid==x,
DicResult[opt.slug_entity_type].get('items', []))
if not found:
ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
else:
for tst in found:
# Check changes on Cat Name
if DicResult[opt.slug_entity_type]['title']!=opt.entity_type or \
tst[1]!=opt.entity_subtype:
ListChanges.append(('changed', opt.uid,
DicResult[opt.slug_entity_type]['title'],
tst[1]))
else:
ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
# Do The change
for action, uid, entity, subentity in ListChanges:
if action=="changed":
opt = TiersOpt.by_id(uid)
opt.entity_type = entity
opt.entity_subtype = subentity
elif action=="remove":
opt = TiersOpt.by_id(uid)
DBSession.delete(opt)
elif action=="add":
opt = TiersOpt()
opt.entity_type = entity
opt.entity_subtype = subentity
DBSession.add(opt)
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
'logged_in':request.authenticated_userid, 'TiersOpt':TiersOpt }
return MainTab
@view_config(route_name='show_user', renderer="jm2l:templates/view_user.mako")
def show_user(request):
user_slug = request.matchdict.get('user_slug', None)
if user_slug is None or len(user_slug)==0:
raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu")
# Query database
DispUser = User.by_slug(user_slug)
if DispUser is None:
raise HTTPNotFound()
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'',
'DispUser':DispUser, 'logged_in':request.authenticated_userid }
return MainTab
#@view_config(route_name='link_user_entity')
def link_user_entity(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
uid = int(request.matchdict.get('uid', -1))
year = int(request.matchdict.get('year', -1))
user_id = int(request.matchdict.get('uid', -1))
TheTiers = Tiers.by_id(uid)
if TheTiers is None:
raise HTTPNotFound()
return HTTPFound(location=request.route_url('edit_entity', uid=uid) )
#@view_config(route_name='link_role_entity')
def link_role_entity(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
uid = int(request.matchdict.get('uid', -1))
year = int(request.matchdict.get('year', -1))
role_id = int(request.matchdict.get('role_id', -1))
TheTiers = Tiers.by_id(uid)
if TheTiers is None:
raise HTTPNotFound()
return HTTPFound(location=request.route_url('edit_entity', uid=uid) )
@forbidden_view_config()
def forbidden(reason, request):
if 'ident' in reason.detail:
request.session.flash(('info', reason.detail))
return HTTPFound(location='/sign/login?from='+request.environ['PATH_INFO'] )
else:
request.response.status = 403
return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason },
request=request)
@notfound_view_config()
def notfound(reason, request):
request.response.status = 404
return render_to_response('jm2l:templates/Errors/404.mako', { "reason":reason },
request=request)