Files
jm2l/jm2l/views.py
T
2020-09-29 01:14:11 +02:00

2113 lines
91 KiB
Python
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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
from .security import check_staff, check_logged
# Then, standard libs
import csv
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import io
import 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 = "<video controls='controls' preload='metadata' style='width:60%'>"
Container += "<source type='%s' " % mime_type
Container += "src='%s' />" % link
Container += "</video>"
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 -=-=
def url_maker(page_number):
query = request.GET
query["page"] = str(page_number)
return request.current_route_url(_query=query)
@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
page_size = request.params.get('pageSize', "8")
current_page = request.params.get('pageNum', "1")
user_query = 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 constancy of parameters
if page_size.isdigit() and current_page.isdigit():
current_page = int(current_page)
page_size = int(page_size)
else:
return HTTPBadRequest('pageSize and pageNum accept only digits.')
# Query database
part = remove_accents(user_query)
users_set = DBSession.query(User.uid, User.nom, User.prenom) \
.filter(User.slug.contains(part.decode("utf-8"))).all()
records = paginate.Page(users_set, current_page, url_maker=url_maker, items_per_page=page_size)
list_match_user = list(map(lambda u: {"id": u.uid, "text": "%s %s" % (u.prenom, u.nom)}, records))
return {"Results": list_match_user, "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
part = remove_accents(TiersQuery)
j_tiers = DBSession.query(Tiers.uid, Tiers.name) \
.filter(Tiers.slug.contains(part.decode("utf-8"))).all()
records = paginate.Page(j_tiers, current_page, url_maker=url_maker, items_per_page=pageSize)
list_match_tiers = list(map(lambda t: {"id": t.uid, "text": t.name}, records.items))
return {"Results": list_match_tiers, "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
dic_result = 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 is not 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)
list_ev = []
for ev in events:
if ev.event_type:
list_ev.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
})
dic_result[Day.day] = list_ev
return {'all': dic_result}
@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 = "<video controls='controls' preload='metadata' style='width:60%'>"
Container += "<source type='%s' " % CurMedia.mime_type
Container += "src='%s' />" % CurMedia.get_path
Container += "</video>"
else:
Container = ""
ListEv.append({
# "uid":"%d/%d" % ( year, ev.uid ),
"headline": '<a href="/event/%s/%s">%s</a>' % (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 == 2020:
DicResult = {
"lang": "fr",
"headline": "JM2L 2020",
"type": "default",
"startDate": "2020,11,28,10",
"text": "<i><span class='c1'>11ème Édition</span></i>",
"asset":
{
"media": embeed_video("video/ogg", "/resources/2017/Video/JM2L2017_Reportage_FR3.ogv"),
"credit": "Reportage France 3",
"caption": "Dans nos précédentes éditions, une vidéo des JM2L 2017"
}
}
elif year == 2017:
DicResult = {
"lang": "fr",
"headline": "JM2L 2017",
"type": "default",
"startDate": "2017,11,25,10",
"text": "<i><span class='c1'>10ème Édition</span></i>",
"asset":
{
# "media":"https://www.youtube.com/watch?v=91X65eEKxvU&t=6s",
"media": embeed_video("video/ogg", "/resources/2017/Video/JM2L2017_Reportage_PleinSud.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": "<i><span class='c1'>9ème Édition</span></i>",
"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": "<i><span class='c1'>6ème Édition</span></i>",
"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": "<i><span class='c1'>5ème Édition</span></i>",
"asset":
{
"media": embeed_video("video/ogg", "/resources/2010/Video/reportages/JM2L2010-PleinSudTV.ogv"),
"credit": "<a href='http://pleinsudtv.com/index.php/casa/affichage-en-vignettes/93-casa-culture/582-les-jm-du-logiciel-libre-2010'>Le reportage Plein-sud TV</a>",
"caption": "JM2L",
}
}
elif year == 2007:
DicResult = {
"lang": "fr",
"headline": "JM2L 2007",
"type": "default",
"text": "<i><span class='c1'>2ème Édition</span></i>",
"asset":
{
"media": embeed_video("video/ogg", "/resources/2007/Video/20071110-linux.ogv"),
"credit": "<a href='http://pleinsudtv.com/index.php/casa/affichage-en-vignettes/93-casa-culture/245-logiciel-libre-linux-jm2l'>Le reportage Plein-sud TV</a>",
"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 < year <= CurrentYear:
if year == 2006:
return {'year': year, 'content': content, 'edition': u"1<sup>ère</sup>"}
elif year == 2015:
return {'year': year, 'content': content, 'edition': u"9<sup>ème</sup>"}
elif year == 2017:
return {'year': year, 'content': content, 'edition': u"10<sup>ème</sup>"}
elif year == 2018:
return {'year': year, 'content': content, 'edition': u"11<sup>ème</sup>"}
else:
edition = year - 2005
return {'year': year, 'content': content, 'edition': u"%d<sup>ème</sup>" % 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"11<sup>ème</sup>", 'ListPhotos': ListPhotos}
@view_config(route_name='edit_index', renderer="jm2l:templates/Staff/EditIndex.mako")
def edit_index(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
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')
# .decode('utf-8'),
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):
check_staff(request)
year = int(request.matchdict.get('year', None))
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):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
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):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
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):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
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):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
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):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
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):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
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):
check_staff(request)
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):
check_staff(request)
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):
check_staff(request)
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 = tuple(DBSession.query(JM2L_Year.year_uid, JM2L_Year.year_uid).order_by(
sa.desc(JM2L_Year.year_uid)).all())
form.phy_salle_id.choices = 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):
check_staff(request)
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 as 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):
check_staff(request)
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):
check_logged(request)
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):
check_logged(request)
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):
check_logged(request)
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):
check_staff(request)
for_year = int(request.matchdict.get('year', CurrentYear))
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 = io.BytesIO()
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):
check_staff(request)
for_year = int(request.matchdict.get('year', CurrentYear))
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):
check_staff(request)
for_year = int(request.matchdict.get('year', CurrentYear))
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 "Hour_start" in form._fields:
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 "Day_start" in form._fields:
TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week),
int(form.Day_start.data)), "%Y %W %w")
Exch.start_time = TargetTime
if "Hour_end" in form._fields:
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 "Day_end" in form._fields:
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']
mailer = request.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').decode('utf-8')))
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
salle_dispo = 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 "uid" in form._fields:
form.duration.data = 60
salle_dispo = salle_dispo.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')
]
salle_dispo = salle_dispo.filter(Salles.place_type == 'Stand')
elif intervention == "Atelier":
form.duration.choices = list(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: d[0], form.duration.choices):
form.duration.choices.append((duration, u'Atelier (%dh%.2d)' % (duration / 60, duration % 60)))
salle_dispo = salle_dispo.filter(Salles.place_type.in_(['Atelier', 'MAO']))
elif intervention == "Table_ronde":
form.duration.choices = list(map(lambda d: (d, u'Table ronde (%dh%.2d)' % (d / 60, d % 60)),
[60, 90, 120, 150]))
if not duration in map(lambda d: d[0], form.duration.choices):
form.duration.choices.append((duration, u'Table ronde (%dh%.2d)' % (duration / 60, duration % 60)))
salle_dispo = salle_dispo.filter(Salles.place_type == 'Table ronde')
elif intervention == "Concert":
form.duration.choices = list(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: d[0], form.duration.choices):
form.duration.choices.append((duration, u'Concert (%dh%.2d)' % (duration / 60, duration % 60)))
salle_dispo = salle_dispo.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 salle_dispo]
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 "uid" in form._fields:
TheEvent.slug = 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 "uid" in form._fields:
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,'
u'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.')
dic_result = dict()
list_changes = list()
if request.method == 'POST':
#  Reformat data
reg_exist = re.compile(r'collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[(?P<id>\d+)\]')
reg_title = re.compile(r'collection\[(?P<slug>[\w-]+)\]\[title]')
reg_new = re.compile(r'collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[id\]')
for key, value in request.POST.items():
regN = reg_new.match(key)
regT = reg_title.match(key)
reg = reg_exist.match(key)
if reg:
if not reg.group('slug') in dic_result:
dic_result[reg.group('slug')] = dict()
if 'items' in dic_result[reg.group('slug')]:
dic_result[reg.group('slug')]['items'].append((int(reg.group('id')), value))
else:
dic_result[reg.group('slug')]['items'] = [(int(reg.group('id')), value)]
elif regN:
if not regN.group('slug') in dic_result:
dic_result[regN.group('slug')] = dict()
if 'items' in dic_result[regN.group('slug')]:
dic_result[regN.group('slug')]['items'].append(('id', value))
else:
dic_result[regN.group('slug')]['items'] = [('id', value)]
list_changes.append(('add', 0, dic_result[regN.group('slug')]['title'], value))
elif regT:
if not regT.group('slug') in dic_result:
dic_result[regT.group('slug')] = dict()
dic_result[regT.group('slug')]['title'] = value
else:
raise
for opt in DBSession.query(TiersOpt).all():
if opt.slug_entity_type in dic_result:
found = filter(lambda x, y: opt.uid == x,
dic_result[opt.slug_entity_type].get('items', []))
if not found:
list_changes.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
else:
for tst in found:
# Check changes on Cat Name
if dic_result[opt.slug_entity_type]['title'] != opt.entity_type or \
tst[1] != opt.entity_subtype:
list_changes.append(('changed', opt.uid,
dic_result[opt.slug_entity_type]['title'],
tst[1]))
else:
list_changes.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
# Do The change
for action, uid, entity, sub_entity in list_changes:
if action == "changed":
opt = TiersOpt.by_id(uid)
opt.entity_type = entity
opt.entity_subtype = sub_entity
elif action == "remove":
opt = TiersOpt.by_id(uid)
DBSession.delete(opt)
elif action == "add":
opt = TiersOpt()
opt.entity_type = entity
opt.entity_subtype = sub_entity
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)