@@ -12,7 +12,7 @@ from .security import EntryFactory, groupfinder | |||||
from pyramid_mailer import mailer_factory_from_settings | from pyramid_mailer import mailer_factory_from_settings | ||||
from pyramid_mailer.message import Attachment, Message | from pyramid_mailer.message import Attachment, Message | ||||
import locale | import locale | ||||
from .helpers import Sejour_helpers | |||||
from .helpers import Sejour_helpers, Orga_helpers | |||||
from apscheduler.schedulers.background import BackgroundScheduler | from apscheduler.schedulers.background import BackgroundScheduler | ||||
# Database access imports | # Database access imports | ||||
from pyramid.request import Request | from pyramid.request import Request | ||||
@@ -23,6 +23,7 @@ import logging | |||||
def add_renderer_globals(event): | def add_renderer_globals(event): | ||||
event['mytrip'] = Sejour_helpers(event) | event['mytrip'] = Sejour_helpers(event) | ||||
event['myorga'] = Orga_helpers(event) | |||||
#@sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07) | #@sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07) | ||||
def mailer_tasks(config): | def mailer_tasks(config): | ||||
@@ -119,6 +120,7 @@ def main(global_config, **settings): | |||||
config.add_route('pict_salle', '/salle_picture/{salle_id:(\d+)}') | config.add_route('pict_salle', '/salle_picture/{salle_id:(\d+)}') | ||||
config.add_route('list_users', '/ListParticipant') | config.add_route('list_users', '/ListParticipant') | ||||
config.add_route('list_orga', '/ListOrga') | |||||
# HTML Routes - Public | # HTML Routes - Public | ||||
config.add_route('home', '/{year:(\d+/)?}') | config.add_route('home', '/{year:(\d+/)?}') | ||||
@@ -133,8 +135,10 @@ def main(global_config, **settings): | |||||
## Events | ## Events | ||||
config.add_route('event', '/event/{year:\d+}/{event_id:([\w-]+)?}') | config.add_route('event', '/event/{year:\d+}/{event_id:([\w-]+)?}') | ||||
config.add_route('link_event_user', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_user') | config.add_route('link_event_user', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_user') | ||||
config.add_route('link_event_tiers', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers') | |||||
config.add_route('link_event_tiers', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers') | |||||
config.add_route('delete_link', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link') | |||||
config.add_route('edit_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}') | config.add_route('edit_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}') | ||||
config.add_route('delete_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete') | |||||
## Entities | ## Entities | ||||
config.add_route('entities', '/entities') #{sep:/*}{Nature:\w+?}') | config.add_route('entities', '/entities') #{sep:/*}{Nature:\w+?}') | ||||
@@ -156,6 +160,7 @@ def main(global_config, **settings): | |||||
config.add_route('jm2l', '/MesJM2L') | config.add_route('jm2l', '/MesJM2L') | ||||
config.add_route('miam', '/MonMiam') | config.add_route('miam', '/MonMiam') | ||||
config.add_route('sejour', '/MonSejour') | config.add_route('sejour', '/MonSejour') | ||||
config.add_route('orga', '/MonOrga') | |||||
config.add_route('modal', '/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}') | config.add_route('modal', '/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}') | ||||
# Handle exchanges | # Handle exchanges | ||||
@@ -11,7 +11,7 @@ import re | |||||
@view_config(route_name='auth', match_param="action=login", renderer="jm2l:templates/login.mako") | @view_config(route_name='auth', match_param="action=login", renderer="jm2l:templates/login.mako") | ||||
def login(request): | def login(request): | ||||
return {} | |||||
return {"comefrom":request.GET.get('from', "")} | |||||
@view_config(route_name='auth', match_param="action=forgot", renderer="jm2l:templates/login.mako") | @view_config(route_name='auth', match_param="action=forgot", renderer="jm2l:templates/login.mako") | ||||
def forgot(request): | def forgot(request): | ||||
@@ -75,6 +75,9 @@ def sign_in_out(request): | |||||
user.last_logged=datetime.datetime.now() | user.last_logged=datetime.datetime.now() | ||||
DBSession.merge(user) | DBSession.merge(user) | ||||
headers = remember(request, user.uid) | headers = remember(request, user.uid) | ||||
if request.POST.get('redirect'): | |||||
return HTTPFound(location=request.POST.get('redirect'), | |||||
headers=headers) | |||||
return HTTPFound(location=request.route_url('jm2l'), | return HTTPFound(location=request.route_url('jm2l'), | ||||
headers=headers) | headers=headers) | ||||
else: | else: | ||||
@@ -4,17 +4,19 @@ from pyramid.response import Response | |||||
import cStringIO as StringIO | import cStringIO as StringIO | ||||
from pyramid.view import view_config | from pyramid.view import view_config | ||||
from .models import User | from .models import User | ||||
from reportlab.pdfgen import canvas | from reportlab.pdfgen import canvas | ||||
from reportlab.pdfbase import pdfmetrics | |||||
from reportlab.pdfbase.ttfonts import TTFont | |||||
from reportlab.lib.units import mm | |||||
from reportlab.pdfbase import pdfmetrics | |||||
from reportlab.pdfbase.ttfonts import TTFont | |||||
from reportlab.lib.units import mm | |||||
import qrcode | import qrcode | ||||
import subprocess | |||||
from .upload import MediaPath | |||||
# Create PDF container | # Create PDF container | ||||
EXPIRATION_TIME = 300 # seconds | |||||
WIDTH = 85 * mm | WIDTH = 85 * mm | ||||
HEIGHT = 60 * mm | HEIGHT = 60 * mm | ||||
ICONSIZE = 8 * mm | |||||
ICONSIZE = 9 * mm | |||||
def Ribbon35(DispUser, canvas): | def Ribbon35(DispUser, canvas): | ||||
canvas.saveState() | canvas.saveState() | ||||
@@ -140,34 +142,48 @@ def JM2L_Logo(canvas, Position="Up"): | |||||
yearobject.textLines("2 0 1 5") | yearobject.textLines("2 0 1 5") | ||||
canvas.drawText(yearobject) | canvas.drawText(yearobject) | ||||
def Tiers_Logo(canvas, DispUser, LWidth=4, StartPos=None): | |||||
Border = 1 | |||||
def Tiers_Logo(canvas, DispUser, StartPos=None): | |||||
Border = 0 | |||||
if StartPos is None: | if StartPos is None: | ||||
StartPos = ( WIDTH -70, 0 ) | |||||
StartPos = ( 30 * mm, 2 ) | |||||
StartX, StartY = StartPos | StartX, StartY = StartPos | ||||
MaxX, MaxY = 34*mm, 18*mm | |||||
num = 0 | num = 0 | ||||
canvas.setStrokeColorRGB(0.5,0.5,0.5) | canvas.setStrokeColorRGB(0.5,0.5,0.5) | ||||
Logos = filter(lambda x:x.ThumbLinks, DispUser.tiers) | |||||
Logos = filter(lambda x:x.ThumbLinks, DispUser.tiers)[:3] | |||||
# Should We compute a better positionning for logos ? | |||||
DicPos = {} | |||||
DicPos[1] = { 0:(1./2, 1./2) } | |||||
DicPos[2] = { 0:(1./3, 1./2), 1:(2./3, 1./2) } | |||||
DicPos[3] = { 0:(1./2, 1./4), 1:(1./3, 3./4), 2:(2./3, 3./4) } | |||||
DicPos[4] = { 0:(1./3, 1./4), 1:(2./3, 1./4), 2:(1./3, 3./4), | |||||
3:(2./3, 3./4) } | |||||
DicPos[5] = { 0:(1./3, 1./4), 1:(2./3, 1./4), 2:(1./6, 3./4), | |||||
3:(3./6, 3./4), 4:(5./6, 3./4) } | |||||
DicPos[6] = { 0:(1./6, 1./4), 1:(3./6, 1./4), 2:(5./6, 1./4), | |||||
3:(1./6, 3./4), 4:(3./6, 3./4), 5:(5./6, 3./4) } | |||||
DicPos[7] = { 0:(1./6, 1./4), 1:(3./6, 1./4), 2:(5./6, 1./4), | |||||
3:(1./8, 3./4), 4:(3./8, 3./4), 5:(5./8, 3./4), | |||||
6:(7./8, 3./4) } | |||||
DicPos[8] = { 0:(1./8, 1./4), 1:(3./8, 1./4), 2:(5./8, 1./4), | |||||
3:(7./8, 1./4), 4:(1./8, 3./4), 5:(3./8, 3./4), | |||||
6:(5./8, 3./4), 7:(7./8, 3./4) } | |||||
# draw overall border | |||||
# canvas.roundRect(StartX, StartY, MaxX, MaxY, radius=2, stroke=True) | |||||
for tiers in Logos: | for tiers in Logos: | ||||
FileName = tiers.ThumbLinks.pop().split("/")[-1] | FileName = tiers.ThumbLinks.pop().split("/")[-1] | ||||
ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName) | |||||
# Should We compute a better positionning for logos ? | |||||
#PosX = StartX + (( (2.0*num+1) / 2*len(Logos) )*(ICONSIZE+Border) - ((ICONSIZE+Border)/2)) | |||||
PosX = StartX + (num % LWidth) * (ICONSIZE+Border) | |||||
if len(Logos)<=LWidth: | |||||
# Middle of line | |||||
PosY = StartY + 0.5 * (ICONSIZE+Border) | |||||
else: | |||||
# in two or more lines | |||||
PosY = StartY + (num / LWidth) * (ICONSIZE+Border) | |||||
ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName) | |||||
PosX = StartX + DicPos[len(Logos)][num][0] * MaxX - (ICONSIZE+Border)/2 | |||||
PosY = StartY + DicPos[len(Logos)][num][1] * MaxY - (ICONSIZE+Border)/2 | |||||
canvas.setLineWidth(.1) | canvas.setLineWidth(.1) | ||||
canvas.drawImage(ImagePath, | canvas.drawImage(ImagePath, | ||||
PosX, PosY, ICONSIZE, ICONSIZE,\ | PosX, PosY, ICONSIZE, ICONSIZE,\ | ||||
preserveAspectRatio=True, | preserveAspectRatio=True, | ||||
anchor='c', | anchor='c', | ||||
mask=[0,3,0,3,0,3] | |||||
mask='auto' | |||||
) | ) | ||||
canvas.roundRect(PosX, PosY, ICONSIZE, ICONSIZE, radius=2, stroke=True) | |||||
# draw icon border | |||||
# canvas.roundRect(PosX, PosY, ICONSIZE, ICONSIZE, radius=2, stroke=True) | |||||
num+=1 | num+=1 | ||||
def QRCode(DispUser): | def QRCode(DispUser): | ||||
@@ -183,8 +199,10 @@ def QRCode(DispUser): | |||||
return qr.make_image() | return qr.make_image() | ||||
@view_config(route_name='badge_user') | |||||
@view_config(route_name='badge_user', http_cache = (EXPIRATION_TIME, {'public':True})) | |||||
def badge_user(request): | def badge_user(request): | ||||
isoutpng = request.params.get('png') | |||||
user_slug = request.matchdict.get('user_slug', None) | user_slug = request.matchdict.get('user_slug', None) | ||||
if user_slug is None or len(user_slug)==0: | if user_slug is None or len(user_slug)==0: | ||||
raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu") | raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu") | ||||
@@ -200,6 +218,7 @@ def badge_user(request): | |||||
pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) | pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) | ||||
pdf = StringIO.StringIO() | pdf = StringIO.StringIO() | ||||
out_img = StringIO.StringIO() | |||||
c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) ) | c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) ) | ||||
c.translate(mm, mm) | c.translate(mm, mm) | ||||
@@ -215,24 +234,24 @@ def badge_user(request): | |||||
if DispUser.Staff: | if DispUser.Staff: | ||||
# Staff | # Staff | ||||
c.setFillColorRGB(.83,0,.33) | c.setFillColorRGB(.83,0,.33) | ||||
c.rect(-3, HEIGHT-30, WIDTH, HEIGHT, fill=1) | |||||
c.rect(-3, HEIGHT-30, WIDTH, HEIGHT, fill=1, stroke=0) | |||||
c.setFillColorRGB(1,1,1) | c.setFillColorRGB(1,1,1) | ||||
c.setFont('Liberation', 30) | c.setFont('Liberation', 30) | ||||
c.drawCentredString(WIDTH/2, HEIGHT-26, "STAFF") | c.drawCentredString(WIDTH/2, HEIGHT-26, "STAFF") | ||||
elif DispUser.is_Intervenant: | |||||
elif DispUser.is_Intervenant: | |||||
# Intervenant | # Intervenant | ||||
c.setFillColorRGB(.3,.3,1) | |||||
c.rect(-3, HEIGHT-30, WIDTH, HEIGHT, fill=1) | |||||
c.setFillColorRGB(.21,.67,.78) | |||||
c.rect(-3, HEIGHT-30, WIDTH, HEIGHT, fill=1, stroke=0) | |||||
c.setFillColorRGB(1,1,1) | c.setFillColorRGB(1,1,1) | ||||
c.setFont('Liberation', 30) | c.setFont('Liberation', 30) | ||||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Intervenant") | |||||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Intervenant") | |||||
else: | else: | ||||
# Visiteur | # Visiteur | ||||
c.setFillColorRGB(.8,.8,.8) | |||||
c.rect(-3, HEIGHT-30, WIDTH, HEIGHT, fill=1) | |||||
c.setFillColorRGB(.8,.8,.8) | |||||
c.rect(-3, HEIGHT-30, WIDTH, HEIGHT, fill=1, stroke=0) | |||||
c.setFillColorRGB(1,1,1) | c.setFillColorRGB(1,1,1) | ||||
c.setFont('Liberation', 30) | c.setFont('Liberation', 30) | ||||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Visiteur") | |||||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Visiteur") | |||||
c.restoreState() | c.restoreState() | ||||
@@ -242,19 +261,19 @@ def badge_user(request): | |||||
# Feed Name and SurName | # Feed Name and SurName | ||||
if len(DispUser.prenom) + len(DispUser.nom)>18: | if len(DispUser.prenom) + len(DispUser.nom)>18: | ||||
if DispUser.pseudo: | if DispUser.pseudo: | ||||
c.drawCentredString(WIDTH/2, HEIGHT/2 + 4 * mm , "%s" % DispUser.prenom ) | |||||
c.setFont('Courier', 17) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 - 2 * mm , "%s" % DispUser.nom ) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 + 0 * mm , "%s" % DispUser.prenom ) | |||||
c.setFont('Courier', 17) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 - 8 * mm , "%s" % DispUser.nom ) | |||||
else: | else: | ||||
c.drawCentredString(WIDTH/2, HEIGHT/2 + 2 * mm , "%s" % DispUser.prenom ) | |||||
c.setFont('Courier', 17) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 - 6 * mm , "%s" % DispUser.nom ) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 + 4 * mm , "%s" % DispUser.prenom ) | |||||
c.setFont('Courier', 17) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 - 8 * mm , "%s" % DispUser.nom ) | |||||
else: | else: | ||||
c.drawCentredString(WIDTH/2, HEIGHT/2 + 0 * mm , "%s %s" % (DispUser.prenom, DispUser.nom) ) | c.drawCentredString(WIDTH/2, HEIGHT/2 + 0 * mm , "%s %s" % (DispUser.prenom, DispUser.nom) ) | ||||
if DispUser.pseudo: | if DispUser.pseudo: | ||||
c.setFont("Helvetica-Oblique", 14) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 - 8 * mm , "%s" % DispUser.pseudo ) | |||||
c.setFont("Helvetica-Oblique", 18) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2 + 10 * mm , "%s" % DispUser.pseudo ) | |||||
# Put QR code to user profile | # Put QR code to user profile | ||||
c.drawInlineImage(QRCode(DispUser), \ | c.drawInlineImage(QRCode(DispUser), \ | ||||
@@ -263,12 +282,28 @@ def badge_user(request): | |||||
preserveAspectRatio=True, \ | preserveAspectRatio=True, \ | ||||
anchor='s') | anchor='s') | ||||
Tiers_Logo(c, DispUser, 4, ( 30 * mm, 2 )) | |||||
Tiers_Logo(c, DispUser) | |||||
c.showPage() | c.showPage() | ||||
c.save() | c.save() | ||||
pdf.seek(0) | |||||
return Response(app_iter=pdf, content_type = 'application/pdf' ) | |||||
pdf.seek(0) | |||||
if isoutpng: | |||||
OutPDF = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf') | |||||
OutPNG = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png') | |||||
# Let's generate a png file for website | |||||
with open( OutPDF ,'wb') as pdff: | |||||
pdff.write(pdf.read()) | |||||
Command = ["convert","-density","150x150", OutPDF, OutPNG] | |||||
subprocess.call(Command) | |||||
with open( OutPNG, 'rb') as pngfile: | |||||
out_img.write(pngfile.read()) | |||||
out_img.seek(0) | |||||
return Response(app_iter=out_img, content_type = 'image/png' ) | |||||
else: | |||||
return Response(app_iter=pdf, content_type = 'application/pdf' ) | |||||
@view_config(route_name='badge_user1') | @view_config(route_name='badge_user1') | ||||
def badge_user1(request): | def badge_user1(request): | ||||
@@ -312,27 +347,7 @@ def badge_user1(request): | |||||
yearobject.textLines("2 0 1 5") | yearobject.textLines("2 0 1 5") | ||||
c.drawText(yearobject) | c.drawText(yearobject) | ||||
num = 0 | |||||
for tiers in DispUser.tiers: | |||||
if tiers.ThumbLinks: | |||||
FileName = tiers.ThumbLinks.pop().split("/")[-1] | |||||
num+=1 | |||||
ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName) | |||||
if num<6: | |||||
c.drawImage(ImagePath, | |||||
WIDTH -5 - num * (ICONSIZE+5), 5, ICONSIZE, ICONSIZE,\ | |||||
preserveAspectRatio=True, | |||||
anchor='c', | |||||
mask=[0,3,0,3,0,3]) | |||||
else: | |||||
c.drawImage(ImagePath, | |||||
WIDTH -5 - (num-5) * (ICONSIZE+5), 5 + ICONSIZE, ICONSIZE, ICONSIZE,\ | |||||
preserveAspectRatio=True, | |||||
anchor='c', | |||||
mask=[0,3,0,3,0,3]) | |||||
Tiers_Logo(c, DispUser) | |||||
if 1: | if 1: | ||||
Ribbon90(DispUser, c) | Ribbon90(DispUser, c) | ||||
@@ -454,32 +469,11 @@ def badge_user2(request): | |||||
yearobject.setWordSpace(21) | yearobject.setWordSpace(21) | ||||
yearobject.textLines("2 0 1 5") | yearobject.textLines("2 0 1 5") | ||||
c.drawText(yearobject) | c.drawText(yearobject) | ||||
num = 0 | |||||
for tiers in DispUser.tiers: | |||||
if tiers.ThumbLinks: | |||||
FileName = tiers.ThumbLinks.pop().split("/")[-1] | |||||
num+=1 | |||||
ImagePath = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, FileName) | |||||
if num<6: | |||||
c.drawImage(ImagePath, | |||||
WIDTH -5 - num * (ICONSIZE+5), 5, ICONSIZE, ICONSIZE,\ | |||||
preserveAspectRatio=True, | |||||
anchor='c', | |||||
mask=[0,3,0,3,0,3]) | |||||
else: | |||||
c.drawImage(ImagePath, | |||||
WIDTH -5 - (num-5) * (ICONSIZE+5), 5 + ICONSIZE, ICONSIZE, ICONSIZE,\ | |||||
preserveAspectRatio=True, | |||||
anchor='c', | |||||
mask=[0,3,0,3,0,3]) | |||||
if 1: | if 1: | ||||
c.rotate(35) | |||||
offset_u=0 | |||||
c.rotate(-35) | |||||
c.translate(-100, -70) | |||||
offset_u=0 | |||||
if DispUser.Staff: | if DispUser.Staff: | ||||
# Staff | # Staff | ||||
c.setFillColorRGB(1,.2,.2) | c.setFillColorRGB(1,.2,.2) | ||||
@@ -489,7 +483,7 @@ def badge_user2(request): | |||||
c.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+5, "STAFF") | c.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+5, "STAFF") | ||||
elif DispUser.is_Intervenant: | elif DispUser.is_Intervenant: | ||||
# Intervenant | # Intervenant | ||||
c.setFillColorRGB(.3,.3,1) | |||||
c.setFillColorRGB(.21,.3,1) | |||||
c.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | c.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | ||||
c.setFillColorRGB(1,1,1) | c.setFillColorRGB(1,1,1) | ||||
c.setFont('Liberation', 15) | c.setFont('Liberation', 15) | ||||
@@ -501,32 +495,6 @@ def badge_user2(request): | |||||
c.setFillColorRGB(0,0,0) | c.setFillColorRGB(0,0,0) | ||||
c.setFont('Liberation', 12) | c.setFont('Liberation', 12) | ||||
c.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+7, "Visiteur") | c.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+7, "Visiteur") | ||||
if 0: | |||||
c.rotate(90) | |||||
offset_u=111 | |||||
if DispUser.Staff: | |||||
# Staff | |||||
c.setFillColorRGB(1,.2,.2) | |||||
c.rect(-5, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||||
c.setFillColorRGB(1,1,1) | |||||
c.setFont('Liberation', 30) | |||||
c.drawCentredString(WIDTH/2-15, HEIGHT/2-offset_u+5, "STAFF") | |||||
elif DispUser.is_Intervenant: | |||||
# Intervenant | |||||
c.setFillColorRGB(.3,.3,1) | |||||
c.rect(0, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||||
c.setFillColorRGB(1,1,1) | |||||
c.setFont('Liberation', 15) | |||||
c.drawCentredString(WIDTH/2-15, HEIGHT/2-offset_u+10, "Intervenant") | |||||
else: | |||||
# Visiteur | |||||
c.setFillColorRGB(.8,.8,.8) | |||||
c.rect(-5, HEIGHT/2-offset_u, WIDTH, 10*mm, fill=1) | |||||
c.setFillColorRGB(0,0,0) | |||||
c.setFont('Liberation', 19) | |||||
c.drawCentredString(WIDTH/2, HEIGHT/2-offset_u+7, "Visiteur") | |||||
c.restoreState() | c.restoreState() | ||||
@@ -551,7 +519,8 @@ def badge_user2(request): | |||||
c.setFont("Helvetica-Oblique", 14) | c.setFont("Helvetica-Oblique", 14) | ||||
c.drawCentredString(WIDTH/2, HEIGHT/2 - 8 * mm , "\"%s\"" % DispUser.pseudo ) | c.drawCentredString(WIDTH/2, HEIGHT/2 - 8 * mm , "\"%s\"" % DispUser.pseudo ) | ||||
#c.restoreState() | #c.restoreState() | ||||
# Put Tiers logos | |||||
Tiers_Logo(c, DispUser) | |||||
# Put QR code to user profile | # Put QR code to user profile | ||||
c.drawInlineImage(img, WIDTH - 20 * mm - 7, 0, 20 * mm, 20 * mm, preserveAspectRatio=True, anchor='s') | c.drawInlineImage(img, WIDTH - 20 * mm - 7, 0, 20 * mm, 20 * mm, preserveAspectRatio=True, anchor='s') | ||||
@@ -156,8 +156,9 @@ class ConfUpdateForm(ConfCreateForm): | |||||
class SalleForm(MyBaseForm): | class SalleForm(MyBaseForm): | ||||
year_uid = SelectField(u'Année', coerce=int) | year_uid = SelectField(u'Année', coerce=int) | ||||
phy_salle_id = SelectField('Salle Physique', coerce=int) | phy_salle_id = SelectField('Salle Physique', coerce=int) | ||||
place_type = SelectField('Type', choices=[('Conference','Conference'), | |||||
('Stand','Stand'), ('Ateliers','Ateliers'), ('Autres','Autres') ]) | |||||
place_type = SelectField('Type', choices=[('Conference',u'Conférence'), | |||||
('Stand','Stand'), ('Atelier','Atelier'), ('Table ronde','Table ronde'), | |||||
('MAO','MAO'), ('Repas','Repas / Snack'), ('Autres','Autres') ]) | |||||
name = TextField('Nom de la salle', [validators.Length(min=1, max=40)], | name = TextField('Nom de la salle', [validators.Length(min=1, max=40)], | ||||
filters=[strip_filter]) | filters=[strip_filter]) | ||||
description = TextAreaField('Description', | description = TextAreaField('Description', | ||||
@@ -1,8 +1,9 @@ | |||||
# -*- coding: utf8 -*- | |||||
from .models import DBSession, JM2L_Year, Sejour | from .models import DBSession, JM2L_Year, Sejour | ||||
from datetime import timedelta, datetime | from datetime import timedelta, datetime | ||||
import itertools | import itertools | ||||
class Sejour_helpers: | |||||
class DummySejour(object): | |||||
def __init__(self, event): | def __init__(self, event): | ||||
self.Me = event['request'].user | self.Me = event['request'].user | ||||
@@ -13,8 +14,13 @@ class Sejour_helpers: | |||||
.filter(Sejour.user_id==self.Me.uid)\ | .filter(Sejour.user_id==self.Me.uid)\ | ||||
.filter(Sejour.for_year==self.CurrentEventYear.year_uid)\ | .filter(Sejour.for_year==self.CurrentEventYear.year_uid)\ | ||||
.first() | .first() | ||||
if self.Sejour and self.Sejour.arrival_time is None: | |||||
self.Sejour = None | |||||
class Sejour_helpers(DummySejour): | |||||
def __init__(self, event): | |||||
super(Sejour_helpers, self).__init__(event) | |||||
if self.Sejour and self.Sejour.arrival_time is None: | |||||
self.Sejour = None | |||||
def StartEvent(self): | def StartEvent(self): | ||||
# This function return the start of the event | # This function return the start of the event | ||||
@@ -98,4 +104,47 @@ class Sejour_helpers: | |||||
else: | else: | ||||
return "" | return "" | ||||
else: | else: | ||||
return "" | |||||
return "" | |||||
class Orga_helpers(DummySejour): | |||||
def __init__(self, event): | |||||
super(Orga_helpers, self).__init__(event) | |||||
self.Orga_tasks = [ | |||||
u"Participer au fléchage de l'événement.", | |||||
u"Faire les courses.", | |||||
u"Participer à l'accueil des visiteurs.", | |||||
u"Accompagner, Guider les visiteurs.", | |||||
u"Accompagner, Guider les intervenants.", | |||||
u"Déplacer le matériel / le mobilier", | |||||
u"Monter / Démonter les stands", | |||||
u"Participer à la préparation / à vider les poubelles", | |||||
u"Participer à la préparation / à vider les salles de conférence", | |||||
u"Participer à la prise de son/vidéo des conférenciers.", | |||||
u"Participer à poser, à repartir, à enlever les ralonges éléctriques.", | |||||
u"Participer à poser, à repartir, à enlever les câbles réseau / le Wifi.", | |||||
u"Remplir les frigos, s'assurer qu'ils soient toujours pleins. (Boissons)", | |||||
u"Participer à la distribution des repas.", | |||||
u"Faire du café et s'assurer de sa disponibilité.", | |||||
u"Participer à la publication / au montage des vidéos des conférenciers.", | |||||
u"Autres" | |||||
] | |||||
def IsChecked(self, nb): | |||||
nb = 2**nb | |||||
if self.Sejour: | |||||
if self.Sejour.orga_part & nb == nb: | |||||
return "checked=\"checked\"" | |||||
else: | |||||
return "" | |||||
else: | |||||
return "" | |||||
def ChoosedList(self): | |||||
""" Return choice validated by user """ | |||||
ListOrga = [] | |||||
for num in range(0,len(self.Orga_tasks)): | |||||
curs = 2**num | |||||
if self.Sejour.orga_part & curs == curs: | |||||
ListOrga.append(self.Orga_tasks[num]) | |||||
return ListOrga |
@@ -175,6 +175,13 @@ class User(Base): | |||||
return DBSession.query(Event).join(User_Event) \ | return DBSession.query(Event).join(User_Event) \ | ||||
.filter(User_Event.user_uid==self.uid) \ | .filter(User_Event.user_uid==self.uid) \ | ||||
.filter(Event.for_year==year).count() | .filter(Event.for_year==year).count() | ||||
def year_events(self, EventType='All', year=2015): | |||||
if EventType=='All': | |||||
return filter(lambda e: e.for_year==year, self.events) | |||||
else: | |||||
return filter(lambda e: e.for_year==year and e.event_type==EventType, self.events) | |||||
@property | @property | ||||
def my_hash(self): | def my_hash(self): | ||||
@@ -308,6 +315,7 @@ class Role_Tiers(Base): | |||||
tiers_uid = Column(Integer, ForeignKey('tiers.uid')) | tiers_uid = Column(Integer, ForeignKey('tiers.uid')) | ||||
tiers = relationship(Tiers, backref=backref("roles_assoc") ) | tiers = relationship(Tiers, backref=backref("roles_assoc") ) | ||||
tiers_role = Column(Enum('Exposant', 'Sponsor', 'Donateur')) | tiers_role = Column(Enum('Exposant', 'Sponsor', 'Donateur')) | ||||
event_uid = Column(Integer, default=None) # Optionnal link with Event | |||||
class User_Tiers(Base): | class User_Tiers(Base): | ||||
""" Créer le lien entre la personne et le tiers en fonction de l'année""" | """ Créer le lien entre la personne et le tiers en fonction de l'année""" | ||||
@@ -364,7 +372,7 @@ class Salles(Base): | |||||
phy_salle_id = Column(Integer, ForeignKey('phy_salle.uid')) | phy_salle_id = Column(Integer, ForeignKey('phy_salle.uid')) | ||||
year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) | year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) | ||||
name = Column(Unicode(40)) | name = Column(Unicode(40)) | ||||
place_type = Column(Enum('Conference', 'Stand', 'Ateliers', 'Autres')) | |||||
place_type = Column(Enum('Conference', 'Stand', 'Atelier', 'Table ronde', 'MAO', 'Repas', 'Autres')) | |||||
description = Column(UnicodeText) # Description du matériel disponible | description = Column(UnicodeText) # Description du matériel disponible | ||||
created = Column(DateTime, default=datetime.datetime.now) | created = Column(DateTime, default=datetime.datetime.now) | ||||
last_change = Column(DateTime, default=datetime.datetime.now) | last_change = Column(DateTime, default=datetime.datetime.now) | ||||
@@ -557,6 +565,8 @@ class Sejour(Base): | |||||
repas = Column(Integer) | repas = Column(Integer) | ||||
repas_allerg = Column(Unicode(100)) | repas_allerg = Column(Unicode(100)) | ||||
repas_contr = Column(Unicode(100)) | repas_contr = Column(Unicode(100)) | ||||
orga_part = Column(Integer, default=0) | |||||
#travel_detail = Column(UnicodeText) | |||||
created = Column(DateTime, default=datetime.datetime.now) | created = Column(DateTime, default=datetime.datetime.now) | ||||
last_change = Column(DateTime, default=datetime.datetime.now) | last_change = Column(DateTime, default=datetime.datetime.now) | ||||
@@ -572,7 +582,7 @@ class Event(Base): | |||||
for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year | for_year = Column(Integer, ForeignKey('jm2l_year.year_uid')) # link JM2L_Year | ||||
name = Column(Unicode(100), nullable=False) | name = Column(Unicode(100), nullable=False) | ||||
slug = Column(Unicode(100)) | slug = Column(Unicode(100)) | ||||
event_type = Column(Enum('Stand', 'Table ronde', 'Atelier', 'Concert', 'Conference', 'Repas')) | |||||
event_type = Column(Enum('Conference', 'Stand', 'Atelier', 'Table ronde', 'MAO', 'Repas', 'Autres')) | |||||
start_time = Column(DateTime, default=datetime.datetime.now) | start_time = Column(DateTime, default=datetime.datetime.now) | ||||
end_time = Column(DateTime, default=datetime.datetime.now) | end_time = Column(DateTime, default=datetime.datetime.now) | ||||
description = Column(UnicodeText) | description = Column(UnicodeText) | ||||
@@ -601,6 +611,13 @@ class Event(Base): | |||||
return DBSession.query(cls)\ | return DBSession.query(cls)\ | ||||
.filter(cls.slug == slug).first() | .filter(cls.slug == slug).first() | ||||
def get_linked_tiers(self): | |||||
ListLink = DBSession.query(Role_Tiers.tiers_uid) \ | |||||
.filter(Role_Tiers.year_uid==self.for_year) \ | |||||
.filter(Role_Tiers.tiers_role=="Exposant") \ | |||||
.filter(Role_Tiers.event_uid==self.uid) | |||||
return DBSession.query(Tiers).filter( Tiers.uid.in_( ListLink ) ) | |||||
@property | @property | ||||
def video(self): | def video(self): | ||||
return DBSession.query(Media) \ | return DBSession.query(Media) \ | ||||
@@ -7,22 +7,64 @@ | |||||
<th>Section</th> | <th>Section</th> | ||||
<th>Statut</th> | <th>Statut</th> | ||||
</tr> | </tr> | ||||
</thead> | |||||
</thead> | |||||
<tbody> | <tbody> | ||||
<tr> | <tr> | ||||
<td>Conférences</td> <td style="text-align:center">Aucune</td> | |||||
<td>Conférences</td> <td style="text-align:center"> | |||||
% if len( request.user.year_events('Conference') ): | |||||
% for evt in request.user.year_events('Conference'): | |||||
% endfor | |||||
<a href="/MesJM2L/${evt.for_year}/Conference/${evt.slug}">${evt.name} à ${evt.start_time.strftime('%Hh%M')}</a> | |||||
% else: | |||||
Aucune | |||||
% endif | |||||
</td> | |||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td>Stands</td> <td style="text-align:center">Aucune</td> | |||||
<td>Stands</td> <td style="text-align:center"> | |||||
% if len( request.user.year_events('Stand') ): | |||||
% for evt in request.user.year_events('Stand'): | |||||
<a href="/MesJM2L/${evt.for_year}/Stand/${evt.slug}">${evt.name}</a> | |||||
% endfor | |||||
% else: | |||||
Aucune | |||||
% endif | |||||
</td> | |||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td>Ateliers</td> <td style="text-align:center">Aucune</td> | |||||
<td>Ateliers</td> <td style="text-align:center"> | |||||
% if len( request.user.year_events('Atelier') ): | |||||
% for evt in request.user.year_events('Atelier'): | |||||
<a href="/MesJM2L/${evt.for_year}/Atelier/${evt.slug}">${evt.name} à ${evt.start_time.strftime('%Hh%M')}</a> | |||||
% endfor | |||||
% else: | |||||
Aucune | |||||
% endif | |||||
</td> | |||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td>Tables Ronde</td> <td style="text-align:center">Aucune</td> | |||||
<td>Tables Ronde</td> <td style="text-align:center"> | |||||
% if len( request.user.year_events('Table ronde') ): | |||||
% for evt in request.user.year_events('Table ronde'): | |||||
<a href="/MesJM2L/${evt.for_year}/Table_ronde/${evt.slug}">${evt.name} à ${evt.start_time.strftime('%Hh%M')}</a> | |||||
% endfor | |||||
% else: | |||||
Aucune | |||||
% endif | |||||
</td> | |||||
</tr> | </tr> | ||||
<tr> | <tr> | ||||
<td>Organisation</td> <td style="text-align:center">Aucune</td> | |||||
<td>Organisation</td> <td style="text-align:left"> | |||||
% if myorga.Sejour and myorga.Sejour.orga_part: | |||||
<ul> | |||||
% for orga_task in myorga.ChoosedList(): | |||||
<li>${orga_task}</li> | |||||
% endfor | |||||
</ul> | |||||
% else: | |||||
<center>Aucune</center> | |||||
% endif | |||||
</td> | |||||
</tr> | </tr> | ||||
</tbody> | </tbody> | ||||
</table> | </table> | ||||
@@ -62,6 +104,7 @@ elif Type=='T': | |||||
CurEventType = "Table ronde" | CurEventType = "Table ronde" | ||||
CurLink = "Ma_Table_Ronde" | CurLink = "Ma_Table_Ronde" | ||||
%> | %> | ||||
% if Type!='O': | |||||
<fieldset> | <fieldset> | ||||
<legend class="lowshadow">Vos ${CurTitles} programmés pour 2015</legend> | <legend class="lowshadow">Vos ${CurTitles} programmés pour 2015</legend> | ||||
<% | <% | ||||
@@ -71,6 +114,7 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent | |||||
%> | %> | ||||
${helpers.show_Interventions(Selection, "Sujet", NothingTitle )} | ${helpers.show_Interventions(Selection, "Sujet", NothingTitle )} | ||||
</fieldset> | </fieldset> | ||||
% endif | |||||
% if Type=='C': | % if Type=='C': | ||||
<p> | <p> | ||||
@@ -118,109 +162,46 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent | |||||
% endif | % endif | ||||
% if Type=='O': | % if Type=='O': | ||||
<form id="OrgaForm" action="/MonOrga" method="POST"> | |||||
<fieldset> | <fieldset> | ||||
<legend>Participer à l'organisation</legend> | <legend>Participer à l'organisation</legend> | ||||
<strong>Une autre façon de participer !</strong> | <strong>Une autre façon de participer !</strong> | ||||
<p> | <p> | ||||
Comme vous vous en doutez, la meilleure organisation qui existe, | Comme vous vous en doutez, la meilleure organisation qui existe, | ||||
c'est celle où chacun apporte sa contribution. | c'est celle où chacun apporte sa contribution. | ||||
</p> | |||||
</p> | |||||
<p> | |||||
Dans ce genre d'évenement nous avons besoin de bras et de bonnes volontés. | |||||
Vous pouvez nous aider en vous inscrivant en tant que "bénévole du jour" sur un | |||||
certains nombre de missions : | |||||
</p> | |||||
<p> | <p> | ||||
Et oui, il existe plein de façon de participer aux JM2L, choisissez : | Et oui, il existe plein de façon de participer aux JM2L, choisissez : | ||||
</p> | </p> | ||||
</fieldset> | |||||
<ul> | <ul> | ||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer au fléchage de l'événement. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Faire les courses. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer à l'accueil des visiteurs. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Accompagner, Guider les visiteurs. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Accompagner, Guider les intervenants. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Déplacer le matériel / le mobilier | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Monter / Démonter les stands | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer à la préparation / à vider les poubelles | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer à la préparation / à vider les salles de conférence | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer à la prise de son/vidéo des conférenciers. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer à poser, à repartir, à enlever les ralonges éléctriques. | |||||
</label> | |||||
</li> | |||||
% for num, item in enumerate(myorga.Orga_tasks): | |||||
<li> | <li> | ||||
<label class="checkbox"> | <label class="checkbox"> | ||||
<input type="checkbox"> Participer à poser, à repartir, à enlever les câbles réseau / le Wifi. | |||||
<input id="O${num}" ${myorga.IsChecked(num)|n} name="O${num}" type="checkbox"> ${item} | |||||
</label> | </label> | ||||
</li> | </li> | ||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Remplir les frigos, s'assurer qu'ils soient toujours pleins. (Boissons) | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer à la distribution des repas. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Faire du café et s'assurer de sa disponibilité. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Participer à la publication / au montage des vidéos des conférenciers. | |||||
</label> | |||||
</li> | |||||
<li> | |||||
<label class="checkbox"> | |||||
<input type="checkbox"> Autres | |||||
</label> | |||||
</li> | |||||
<ul> | |||||
% endfor | |||||
</ul> | |||||
<p> | |||||
Avant l'évenement, et en fonction des cases cochés, les coordinateurs metterons à jour le planning et vous receverez les instructions par mail. | |||||
</p> | |||||
<div class="span2 offset5"> | |||||
<input class="btn btn-primary" type="submit" value="Enregistrer !" /> | |||||
</div> | |||||
</fieldset> | |||||
</form> | |||||
% endif | % endif | ||||
<a href="/MesJM2L/2015/${CurEventType.replace(' ','_')}">Je souhaite ajouter ${CurTitle} pour les JM2L 2015 !</a> | |||||
% if Type!='O': | % if Type!='O': | ||||
<a href="/MesJM2L/2015/${CurEventType.replace(' ','_')}">Je souhaite ajouter ${CurTitle} pour les JM2L 2015 !</a> | |||||
<fieldset> | <fieldset> | ||||
<legend class="lowshadow">Historique</legend> | <legend class="lowshadow">Historique</legend> | ||||
<% | <% | ||||
@@ -303,6 +303,26 @@ ListWrap = ["Co-voiturage",u"Hébergement","Matos"] | |||||
<fieldset> | <fieldset> | ||||
<legend>Mon Badge</legend> | <legend>Mon Badge</legend> | ||||
<p> | |||||
Rendez-vous à l'accueil pour retirer votre badge ! | |||||
<br> | |||||
Pour que tout se passe pour le mieux dans l'organisation de l'événement, nous vous invitons à : | |||||
<ul> | |||||
<li>Renseigner et valider vos horaires d'arrivée / de départ dans la section "Mon Séjour".</li> | |||||
<li>Procéder à la réservation de vos repas dans la section "Miam" !</li> | |||||
<li>Préparer et réserver vos transports au plus vite dans la section "Mes Frais".</li> | |||||
</ul> | |||||
</p> | |||||
<div class="center"> | |||||
<a href="/user/${request.user.slug}/badge"> Télécharger mon badge (PDF)</a> | |||||
<br> | |||||
</div> | |||||
<br> | |||||
<div align="center"> | |||||
<a href="/user/${request.user.slug}/badge"> | |||||
<img style="border:solid black 1px;" src="/user/${request.user.slug}/badge?png=true" alt="Badge de ${request.user.slug}" /> | |||||
</a> | |||||
</div> | |||||
</fieldset> | </fieldset> | ||||
</%def> | </%def> | ||||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||
@@ -111,139 +111,6 @@ $('table').each(function(){ | |||||
}); | }); | ||||
</script> | </script> | ||||
<% | |||||
import datetime | |||||
import itertools | |||||
now = datetime.datetime.now() | |||||
%> | |||||
<form class="filterform" action="#"> | |||||
<table class="table table-bordered table-hover"> | |||||
<thead> | |||||
<tr> | |||||
<th style="width:7em;text-align:center;"></th> | |||||
<th style="width:5em;text-align:center;">Visite</th> | |||||
<th style="width:7em;text-align:center;">Activité</th> | |||||
<th style="text-align:center;">Arrivée prévue</th> | |||||
<th style="width:5em;text-align:center;">${DicRepas['Ven']} Repas Vendredi</th> | |||||
<th style="width:5em;text-align:center;">${DicRepas['Midi']} Repas Midi </th> | |||||
<th style="width:5em;text-align:center;">${DicRepas['Soir']} Repas Soir</th> | |||||
<th style="text-align:center;">Départ prévu</th> | |||||
<th style="text-align:center;">Notes</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody id="list"> | |||||
% for u, s in Users: | |||||
<tr> | |||||
<td style="text-align:center;"> | |||||
<span class="data">${u.slug}</span> | |||||
<a href="/MesJM2L?user=${u.uid}">${u.nom} ${u.prenom}</a><br /> | |||||
<span style="align:center"> | |||||
${u.vote_logo} | |||||
<a href="mailto:${u.mail}"> | |||||
<i class="icon-envelope"></i> | |||||
</a> | |||||
% if u.Staff==1: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\nStaff JM2L');"> | |||||
<i class="icon-star"></i> | |||||
</a> | |||||
% endif | |||||
% if u.Staff==0: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\nIntervenant');"> | |||||
<i class="icon-user"></i> | |||||
</a> | |||||
% endif | |||||
% if u.active==0: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\nInactive');"> | |||||
<i class="icon-ban-circle"></i> | |||||
</a> | |||||
% endif | |||||
% if u.phone: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\n${u.phone}');"> | |||||
<i class="icon-headphones"></i> | |||||
</a> | |||||
% endif | |||||
<a href="/user/${u.slug}/badge"> | |||||
<i class="icon-qrcode"></i> | |||||
</a> | |||||
</span> | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
<span class="data">${(now - u.last_logged).days}</span>${(now - u.last_logged).days} j | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
% if u.events: | |||||
<span class="data">${len(u.events)}</span> | |||||
<select style="width:7em;"> | |||||
<option><strong>${len(u.events)} Intérv.</strong></option> | |||||
% for y, g in itertools.groupby(sorted(u.events, key=lambda k:k.for_year, reverse=True), key=lambda k:k.for_year): | |||||
<OPTGROUP LABEL="${y}"> | |||||
% for event in g: | |||||
${event.for_year} | |||||
<OPTION onclick="location='/event/${event.for_year}/${event.slug}';">${event.event_type} - ${event.name}</OPTION> | |||||
% endfor | |||||
</OPTGROUP> | |||||
% endfor | |||||
</select> | |||||
%else: | |||||
<span class="data"></span> | |||||
<i> - </i> | |||||
% endif | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
% if s and s.arrival_time: | |||||
<span class="data">${s.arrival_time.strftime('%m/%d/%Y %H:%M:%S')}</span> | |||||
${s.arrival_time.strftime('%a %d <strong>%H:%M</strong>') | n}<br/> | |||||
${s.arrival_place} | |||||
% if s.arrival_text: | |||||
- NB: <strong>${s.arrival_text}</strong> | |||||
% endif | |||||
%else: | |||||
<span class="data"></span> | |||||
<i>Pas d'informations</i> | |||||
% endif | |||||
</td> | |||||
% if s and s.repas: | |||||
% for i, d in enumerate(['Ven Soir', 'Sam midi', 'Sam soir']): | |||||
<td style="text-align:center"> | |||||
% if (s.repas & 2**i): | |||||
<span class="data">Oui</span>Oui | |||||
% else: | |||||
<span class="data">Non</span>Non | |||||
% endif | |||||
</td> | |||||
% endfor | |||||
%else: | |||||
<td style="text-align:center;" colspan="3"> | |||||
<i>Pas d'informations</i> | |||||
</td> | |||||
% endif | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
% if s and s.depart_time: | |||||
<span class="data">${s.depart_time.strftime('%m/%d/%Y %H:%M:%S')}</span> | |||||
${s.depart_time.strftime('%a %d <strong>%H:%M</strong>') | n}<br/> | |||||
${s.depart_place} | |||||
% if s.depart_text: | |||||
- NB: <strong>${s.arrival_text}</strong> | |||||
% endif | |||||
%else: | |||||
<span class="data"></span> | |||||
<i>Pas d'informations</i> | |||||
% endif | |||||
</td> | |||||
<td> | |||||
% if s: | |||||
% if s.repas_allerg: | |||||
<u>Allergies</u> : ${s.repas_allerg}<br/> | |||||
% endif | |||||
% if s.repas_contr: | |||||
<u>Contraintes</u> : ${s.repas_contr}<br/> | |||||
% endif | |||||
% endif | |||||
</td> | |||||
</tr> | |||||
% endfor | |||||
</tbody> | |||||
</table> | |||||
</form> | |||||
${next.body()} | |||||
@@ -0,0 +1,48 @@ | |||||
# -*- coding: utf-8 -*- | |||||
<%inherit file="jm2l:templates/Participant/list.mako"/> | |||||
<% | |||||
import unicodedata | |||||
%> | |||||
<%def name="cssAddOn()"> | |||||
${parent.cssAddOn()} | |||||
<style> | |||||
input[type=text]{width:10em;} | |||||
</style> | |||||
</%def> | |||||
<form class="filterform" action="#"> | |||||
<div style="overflow:auto"> | |||||
<table class="table table-bordered table-hover"> | |||||
<thead> | |||||
<tr> | |||||
<th style="width:10em;text-align:center;"></th> | |||||
% for u, s in Users: | |||||
% if s and s.orga_part and s.orga_part > 0: | |||||
<th style="text-align:center;"><a href="/MesJM2L?user=${u.uid}">${u.nom} ${u.prenom} ${s.orga_part}</a></th> | |||||
% endif | |||||
% endfor | |||||
</tr> | |||||
</thead> | |||||
<tbody id="list"> | |||||
% for i, title in enumerate(myorga.Orga_tasks): | |||||
<tr> | |||||
<td style="text-align:center;"><span class="data">${unicodedata.normalize('NFKD', title).encode('ASCII', 'ignore').lower()}</span>${title}</td> | |||||
% for u, s in Users: | |||||
% if s and s.orga_part and s.orga_part > 0: | |||||
<td style="text-align:center;"> | |||||
% if s and s.orga_part: | |||||
% if (s.orga_part & 2**i): | |||||
Oui | |||||
% endif | |||||
% endif | |||||
</td> | |||||
% endif | |||||
% endfor | |||||
</tr> | |||||
% endfor | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</form> |
@@ -0,0 +1,136 @@ | |||||
# -*- coding: utf-8 -*- | |||||
<%inherit file="jm2l:templates/Participant/list.mako"/> | |||||
<% | |||||
import datetime | |||||
import itertools | |||||
now = datetime.datetime.now() | |||||
%> | |||||
<form class="filterform" action="#"> | |||||
<table class="table table-bordered table-hover"> | |||||
<thead> | |||||
<tr> | |||||
<th style="width:7em;text-align:center;"></th> | |||||
<th style="width:5em;text-align:center;">Visite</th> | |||||
<th style="width:7em;text-align:center;">Activité</th> | |||||
<th style="text-align:center;">Arrivée prévue</th> | |||||
<th style="width:5em;text-align:center;">${DicRepas['Ven']} Repas Vendredi</th> | |||||
<th style="width:5em;text-align:center;">${DicRepas['Midi']} Repas Midi </th> | |||||
<th style="width:5em;text-align:center;">${DicRepas['Soir']} Repas Soir</th> | |||||
<th style="text-align:center;">Départ prévu</th> | |||||
<th style="text-align:center;">Notes</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody id="list"> | |||||
% for u, s in Users: | |||||
<tr> | |||||
<td style="text-align:center;"> | |||||
<span class="data">${u.slug}</span> | |||||
<a href="/MesJM2L?user=${u.uid}">${u.nom} ${u.prenom}</a><br /> | |||||
<span style="align:center"> | |||||
${u.vote_logo} | |||||
<a href="mailto:${u.mail}"> | |||||
<i class="icon-envelope"></i> | |||||
</a> | |||||
% if u.Staff==1: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\nStaff JM2L');"> | |||||
<i class="icon-star"></i> | |||||
</a> | |||||
% endif | |||||
% if u.Staff==0: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\nIntervenant');"> | |||||
<i class="icon-user"></i> | |||||
</a> | |||||
% endif | |||||
% if u.active==0: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\nInactive');"> | |||||
<i class="icon-ban-circle"></i> | |||||
</a> | |||||
% endif | |||||
% if u.phone: | |||||
<a href="javascript:alert('${u.nom}, ${u.prenom}\n${u.phone}');"> | |||||
<i class="icon-headphones"></i> | |||||
</a> | |||||
% endif | |||||
</span> | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
<span class="data">${(now - u.last_logged).days}</span>${(now - u.last_logged).days} j | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
% if u.events: | |||||
<span class="data">${len(u.events)}</span> | |||||
<select style="width:7em;"> | |||||
<option><strong>${len(u.events)} Intérv.</strong></option> | |||||
% for y, g in itertools.groupby(sorted(u.events, key=lambda k:k.for_year, reverse=True), key=lambda k:k.for_year): | |||||
<OPTGROUP LABEL="${y}"> | |||||
% for event in g: | |||||
${event.for_year} | |||||
<OPTION onclick="location='/event/${event.for_year}/${event.slug}';">${event.event_type} - ${event.name}</OPTION> | |||||
% endfor | |||||
</OPTGROUP> | |||||
% endfor | |||||
</select> | |||||
%else: | |||||
<span class="data"></span> | |||||
<i> - </i> | |||||
% endif | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
% if s and s.arrival_time: | |||||
<span class="data">${s.arrival_time.strftime('%m/%d/%Y %H:%M:%S')}</span> | |||||
${s.arrival_time.strftime('%a %d <strong>%H:%M</strong>') | n}<br/> | |||||
${s.arrival_place} | |||||
% if s.arrival_text: | |||||
- NB: <strong>${s.arrival_text}</strong> | |||||
% endif | |||||
%else: | |||||
<span class="data"></span> | |||||
<i>Pas d'informations</i> | |||||
% endif | |||||
</td> | |||||
% if s and s.repas: | |||||
% for i, d in enumerate(['Ven Soir', 'Sam midi', 'Sam soir']): | |||||
<td style="text-align:center"> | |||||
% if (s.repas & 2**i): | |||||
<span class="data">Oui</span>Oui | |||||
% else: | |||||
<span class="data">Non</span>Non | |||||
% endif | |||||
</td> | |||||
% endfor | |||||
%else: | |||||
<td style="text-align:center;" colspan="3"> | |||||
<i>Pas d'informations</i> | |||||
</td> | |||||
% endif | |||||
</td> | |||||
<td style="text-align:center;"> | |||||
% if s and s.depart_time: | |||||
<span class="data">${s.depart_time.strftime('%m/%d/%Y %H:%M:%S')}</span> | |||||
${s.depart_time.strftime('%a %d <strong>%H:%M</strong>') | n}<br/> | |||||
${s.depart_place} | |||||
% if s.depart_text: | |||||
- NB: <strong>${s.arrival_text}</strong> | |||||
% endif | |||||
%else: | |||||
<span class="data"></span> | |||||
<i>Pas d'informations</i> | |||||
% endif | |||||
</td> | |||||
<td> | |||||
% if s: | |||||
% if s.repas_allerg: | |||||
<u>Allergies</u> : ${s.repas_allerg}<br/> | |||||
% endif | |||||
% if s.repas_contr: | |||||
<u>Contraintes</u> : ${s.repas_contr}<br/> | |||||
% endif | |||||
% endif | |||||
</td> | |||||
</tr> | |||||
% endfor | |||||
</tbody> | |||||
</table> | |||||
</form> |
@@ -21,9 +21,13 @@ | |||||
<div class="span10 offset1"> | <div class="span10 offset1"> | ||||
<div id="SalleCarousel"> | <div id="SalleCarousel"> | ||||
${helpers.show_salles( Salles, form.salle_uid.data or form.salle_uid.choices[0][0] )} | |||||
${helpers.show_salles( Salles, form.salle_uid.data or form.salle_uid.choices and form.salle_uid.choices[0][0] )} | |||||
</div> | </div> | ||||
% if event.for_year==2015 and request.user and (request.user.Staff or request.user in event.intervenants): | |||||
<a class="btn btn-danger pull-right" type="button" href="${event.uid}/delete"> | |||||
<i class="icon-remove icon-white"></i> Supprimer | |||||
</a> | |||||
%endif | |||||
% if 'uid' in form._fields: | % if 'uid' in form._fields: | ||||
<div class="borderboxtime"> | <div class="borderboxtime"> | ||||
${event.start_time.strftime('%d %b %Y').decode('utf-8')} - | ${event.start_time.strftime('%d %b %Y').decode('utf-8')} - | ||||
@@ -53,7 +57,7 @@ | |||||
% endif | % endif | ||||
</ul> | </ul> | ||||
</div> | </div> | ||||
<a href="/event/${event.for_year}/${event.slug}" class="pull-right">Voir la version publiée de cet évenement</a> | |||||
<a href="/event/${event.for_year}/${event.slug}" class="pull-right">Voir la version publiée de cet évenement</a> | |||||
<br clear="both"> | <br clear="both"> | ||||
%endif | %endif | ||||
<fieldset> | <fieldset> | ||||
@@ -105,12 +109,20 @@ DicForm = { | |||||
</p> | </p> | ||||
% endif | % endif | ||||
<%def name="callback_Del_Summary(Entity)"> \ | |||||
<a class="btn btn-danger btn-mini pull-right" type="button" href="delete_link?tid=${Entity.uid}&uid=${event.uid}"> | |||||
<i class="icon-remove icon-white"></i> | |||||
</a> | |||||
</%def> | |||||
% if 'uid' in form._fields: | % if 'uid' in form._fields: | ||||
<fieldset> | <fieldset> | ||||
<legend>Indiquez l'entité dont vous faites la promotion :</legend> | |||||
<legend id="Tiers">Indiquez l'entité dont vous faites la promotion :</legend> | |||||
<p> | <p> | ||||
<form action="/MesJM2L/${form.for_year.data}/${form.event_type.data}/link_tiers" method="POST"> | |||||
${helpers.show_SummaryEntities( event.get_linked_tiers(), callback_Del_Summary )} | |||||
<form action="/MesJM2L/${form.for_year.data}/${form.event_type.data.replace(' ', '_')}/link_tiers" method="POST"> | |||||
${formAddT.event_uid} | ${formAddT.event_uid} | ||||
<input type="hidden" id="tiers" name="tiers" style="width:20em;" | <input type="hidden" id="tiers" name="tiers" style="width:20em;" | ||||
class="form-control select2-offscreen" tabindex="-1"> | class="form-control select2-offscreen" tabindex="-1"> | ||||
@@ -120,27 +132,55 @@ DicForm = { | |||||
</button> | </button> | ||||
</form> | </form> | ||||
NB : Notez que les entités séléctionnées apparaissent dans les exposants. | NB : Notez que les entités séléctionnées apparaissent dans les exposants. | ||||
</p> | |||||
</p> | |||||
</fieldset> | </fieldset> | ||||
<fieldset> | <fieldset> | ||||
<legend>Ajouter vos co-intervenants</legend> | <legend>Ajouter vos co-intervenants</legend> | ||||
<p> | |||||
Vous avez la possibilité d'être plusieurs pour un même évenement.<br> | |||||
Chacun des intervenants doit être inscrit sur le site. | |||||
<form action="/MesJM2L/${form.for_year.data}/${form.event_type.data}/link_user" method="POST"> | |||||
${formAdd.event_uid} | |||||
<input type="hidden" id="intervenant" name="intervenant" style="width:20em;" | |||||
class="form-control select2-offscreen" tabindex="-1"> | |||||
</input> | |||||
<button type="submit" class="btn btn-primary" /> | |||||
<i class="icon-plus icon-white"></i> Ajouter cet intervenant | |||||
</button> | |||||
</form> | |||||
NB : Notez que les intervenants d'un même évenement ont tous les droits de modification. | |||||
</p> | |||||
<table> | |||||
<tr> | |||||
<td> | |||||
<p> | |||||
Vous avez la possibilité d'être plusieurs pour un même évenement.<br> | |||||
Chacun des intervenants doit être inscrit sur le site. | |||||
<form action="/MesJM2L/${form.for_year.data}/${form.event_type.data.replace(' ', '_')}/link_user" method="POST"> | |||||
${formAdd.event_uid} | |||||
<input type="hidden" id="intervenant" name="intervenant" style="width:20em;" | |||||
class="form-control select2-offscreen" tabindex="-1"> | |||||
</input> | |||||
<button type="submit" class="btn btn-primary" /> | |||||
<i class="icon-plus icon-white"></i> Ajouter cet intervenant | |||||
</button> | |||||
</form> | |||||
NB : Notez que les intervenants d'un même évenement ont tous les droits de modification. | |||||
</p> | |||||
</td> | |||||
<td> | |||||
<u>Les Intrevenants:</u> | |||||
<ul> | |||||
% if event.intervenants.count()==0: | |||||
<i><b>Aucun</b></i> | |||||
% else: | |||||
% for num, iterv in enumerate(event.intervenants): | |||||
<li style="height:2em"> | |||||
<strong><a href="/user/${iterv.slug}">${iterv.prenom} ${iterv.nom}</a></strong>. | |||||
% if iterv.pseudo: | |||||
(${iterv.pseudo}) | |||||
%endif | |||||
% if iterv!=request.user: | |||||
<a class="btn btn-danger btn-mini" type="button" href="delete_interv?uid=${iterv.uid}&eid=${event.uid}"> | |||||
<i class="icon-remove icon-white"></i> | |||||
</a> | |||||
%endif | |||||
</li> | |||||
% endfor | |||||
% endif | |||||
</ul> | |||||
</td> | |||||
</tr> | |||||
</table> | |||||
</fieldset> | </fieldset> | ||||
<div class="clearfix"> </div> | <div class="clearfix"> </div> | ||||
@@ -407,12 +407,15 @@ TabJs = {'select':[], 'desc':[]} | |||||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||
## Wrapper pour les badges des entités utilisateur | ## Wrapper pour les badges des entités utilisateur | ||||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | ||||
<%def name="show_SummaryEntities(ListEntities)"> \ | |||||
<%def name="show_SummaryEntities(ListEntities, callback=None)"> \ | |||||
<ul class="thumbnails"> | <ul class="thumbnails"> | ||||
% for tiers in ListEntities: | % for tiers in ListEntities: | ||||
<% Entity = tiers.get_entity_type %> | <% Entity = tiers.get_entity_type %> | ||||
<li class="span3 tiers"> | <li class="span3 tiers"> | ||||
<div class="media"> | <div class="media"> | ||||
% if callback: | |||||
${callback(tiers)} | |||||
% endif | |||||
<a class="pull-left" href="/entity/${Entity.entity_type}/${tiers.slug}"> | <a class="pull-left" href="/entity/${Entity.entity_type}/${tiers.slug}"> | ||||
% if tiers.ThumbLinks: | % if tiers.ThumbLinks: | ||||
<img class="media-object" src="${tiers.ThumbLinks.pop()}" alt="${tiers.slug}" /> | <img class="media-object" src="${tiers.ThumbLinks.pop()}" alt="${tiers.slug}" /> | ||||
@@ -59,7 +59,7 @@ | |||||
<div class="row-fluid"> | <div class="row-fluid"> | ||||
<div class="span10 offset1"> | <div class="span10 offset1"> | ||||
<div class="tabbable" id="main_tab"> | <div class="tabbable" id="main_tab"> | ||||
<ul class="nav nav-tabs" style="margin-bottom: 5px;"> | |||||
<ul class="nav nav-tabs nav-pills" style="margin-bottom: 5px;"> | |||||
<li class="active"><a href="#Profil" id="Map_Profil" data-toggle="tab">Mon Profil</a></li> | <li class="active"><a href="#Profil" id="Map_Profil" data-toggle="tab">Mon Profil</a></li> | ||||
<li><a href="#Sejour" id="Map_Sejour" data-toggle="tab">Mon Séjour</a></li> | <li><a href="#Sejour" id="Map_Sejour" data-toggle="tab">Mon Séjour</a></li> | ||||
<li><a href="#Logistique" id="Map_Logistique" data-toggle="tab">Logistique</a></li> | <li><a href="#Logistique" id="Map_Logistique" data-toggle="tab">Logistique</a></li> | ||||
@@ -108,7 +108,7 @@ ${helpers.uploader_js()} | |||||
<div class="btn-group"> | <div class="btn-group"> | ||||
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> | <a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> | ||||
Archives <span class="caret"></span></a> | Archives <span class="caret"></span></a> | ||||
<ul class="dropdown-menu"> | |||||
<ul class="dropdown-menu pull-right" style="min-width:0"> | |||||
% for tmpyear in range(2015, 2005, -1): | % for tmpyear in range(2015, 2005, -1): | ||||
% if tmpyear!=2014: | % if tmpyear!=2014: | ||||
<li><a href="/year/${tmpyear}">${tmpyear}</a></li> | <li><a href="/year/${tmpyear}">${tmpyear}</a></li> | ||||
@@ -126,13 +126,15 @@ ${helpers.uploader_js()} | |||||
% endif | % endif | ||||
<span class="caret"></span> | <span class="caret"></span> | ||||
</a> | </a> | ||||
<ul class="dropdown-menu"> | |||||
<ul class="dropdown-menu pull-right"> | |||||
% if request.user: | % if request.user: | ||||
% if request.user.Staff: | % if request.user.Staff: | ||||
<li><a href="/Staff">Partie Staff</a></li> | <li><a href="/Staff">Partie Staff</a></li> | ||||
<li><a href="/ListParticipant">Gérer les intervenants</a></li> | |||||
<li><a href="/ListParticipant">Gérer les intervenants</a></li> | |||||
<li><a href="/ListSalles">Gérer les salles</a></li> | <li><a href="/ListSalles">Gérer les salles</a></li> | ||||
<li><a href="/entities">Gérer les entités</a></li> | <li><a href="/entities">Gérer les entités</a></li> | ||||
<li><a href="/ListOrga">Participations à l'orga</a></li> | |||||
<li role="separator" class="divider"></li> | |||||
% endif | % endif | ||||
<li><a href="/sign/out">Me déconnecter</a></li> | <li><a href="/sign/out">Me déconnecter</a></li> | ||||
% else: | % else: | ||||
@@ -14,6 +14,7 @@ | |||||
<hr> | <hr> | ||||
<input name="username" type="text" class="input-block-level" placeholder="Nom"> | <input name="username" type="text" class="input-block-level" placeholder="Nom"> | ||||
<input name="password" type="password" class="input-block-level" placeholder="Mot de passe"> | <input name="password" type="password" class="input-block-level" placeholder="Mot de passe"> | ||||
<input name="redirect" type="hidden" value="${comefrom}"> | |||||
<div class="center"> | <div class="center"> | ||||
<button class="btn btn-large btn-primary btn-block" type="submit">S'identifier</button> | <button class="btn btn-large btn-primary btn-block" type="submit">S'identifier</button> | ||||
</div> | </div> | ||||
@@ -8,24 +8,18 @@ | |||||
</%def> | </%def> | ||||
<div class="row-fluid"> | <div class="row-fluid"> | ||||
<div class="span10 offset1"> | <div class="span10 offset1"> | ||||
<div id="SalleCarousel"> | |||||
${helpers.show_salles( Salles, event.Salle.salle_id )} | |||||
</div> | |||||
<div id="SalleCarousel"> | |||||
${helpers.show_salles( Salles, event.Salle.salle_id )} | |||||
</div> | |||||
<strong>${event.event_type}</strong>: | <strong>${event.event_type}</strong>: | ||||
<div class="borderboxtime"> | |||||
${event.start_time.strftime('%d %b %Y').decode('utf-8')} - | |||||
${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} | |||||
##%if event.Salle: | |||||
## - <strong>Salle</strong>: ${event.Salle.name} | |||||
##%endif | |||||
</div> | |||||
##%if event.event_uid: | |||||
## <a href="http://jm2l.linux-azur.org/node/${event.event_uid}">Link</a> - | |||||
##%endif | |||||
<div class="borderboxtime"> | |||||
${event.start_time.strftime('%d %b %Y').decode('utf-8')} - | |||||
${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} | |||||
</div> | |||||
% if event.for_year==2015 and request.user and (request.user.Staff or request.user in event.intervenants): | % if event.for_year==2015 and request.user and (request.user.Staff or request.user in event.intervenants): | ||||
<a href="/MesJM2L/${event.for_year}/${event.event_type}/${event.slug}">Modifier</a> | |||||
<a href="/MesJM2L/${event.for_year}/${event.event_type.replace(' ', '_')}/${event.slug}">Modifier</a> | |||||
% elif request.user and request.user.Staff: | % elif request.user and request.user.Staff: | ||||
<a href="/MesJM2L/${event.for_year}/${event.event_type}/${event.slug}">Editer</a> | |||||
<a href="/MesJM2L/${event.for_year}/${event.event_type.replace(' ', '_')}/${event.slug}">Editer</a> | |||||
% endif | % endif | ||||
<h3 style="line-height:30px;">${event.name}</h3> | <h3 style="line-height:30px;">${event.name}</h3> | ||||
% if event.description : | % if event.description : | ||||
@@ -35,10 +29,12 @@ ${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} | |||||
% else: | % else: | ||||
<p>Cette évenement n'a pas de description.</p> | <p>Cette évenement n'a pas de description.</p> | ||||
% endif | % endif | ||||
<div style="margin-top:10px;"> | |||||
${helpers.show_SummaryEntities( event.get_linked_tiers() )} | |||||
</div> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<hr/> | <hr/> | ||||
% if event.presentation.count() and event.video.count(): | % if event.presentation.count() and event.video.count(): | ||||
<div class="row-fluid"> | <div class="row-fluid"> | ||||
<div id="pres" class="span6"> | <div id="pres" class="span6"> | ||||
@@ -120,6 +120,13 @@ class MediaPath(): | |||||
else: | else: | ||||
slug = user.slug | slug = user.slug | ||||
p = IMAGEPATH + ['users'] + [ slug ] | p = IMAGEPATH + ['users'] + [ slug ] | ||||
elif media_table=='badge': | |||||
user = User.by_id(linked_id) | |||||
if not user: | |||||
raise HTTPNotFound() | |||||
else: | |||||
slug = user.slug | |||||
p = IMAGEPATH + ['badge'] + [ slug ] | |||||
elif media_table=='event': | elif media_table=='event': | ||||
ev = Event.by_id(linked_id) | ev = Event.by_id(linked_id) | ||||
slug = ev.slug | slug = ev.slug | ||||
@@ -5,11 +5,14 @@ from pyramid.renderers import render_to_response | |||||
from pyramid.view import notfound_view_config, forbidden_view_config | from pyramid.view import notfound_view_config, forbidden_view_config | ||||
from pyramid.view import view_config | from pyramid.view import view_config | ||||
from mako.template import Template | from mako.template import Template | ||||
from .upload import IMAGEPATH | |||||
# Import Web Forms | # Import Web Forms | ||||
from .forms import * | from .forms import * | ||||
# Database access imports | # Database access imports | ||||
from .models import * | from .models import * | ||||
from .helpers import Orga_helpers | |||||
from sqlalchemy import func, or_ | from sqlalchemy import func, or_ | ||||
from os import path, makedirs | |||||
# Usefull tools | # Usefull tools | ||||
from slugify import slugify | from slugify import slugify | ||||
from icalendar import Calendar | from icalendar import Calendar | ||||
@@ -20,7 +23,8 @@ from pyramid_mailer.message import Message | |||||
import webhelpers.paginate as paginate | import webhelpers.paginate as paginate | ||||
import unicodedata | import unicodedata | ||||
import datetime | import datetime | ||||
import re | |||||
import re | |||||
import shutil | |||||
CurrentYear = 2015 | CurrentYear = 2015 | ||||
@@ -390,10 +394,10 @@ def tasks(request): | |||||
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.') | raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.') | ||||
task_id = request.matchdict.get('task_id') | task_id = request.matchdict.get('task_id') | ||||
# Convert the pole_id GET parameter to int or 0 | # Convert the pole_id GET parameter to int or 0 | ||||
try: | |||||
if request.params.get('pole_id') and request.params.get('pole_id').isdigit(): | |||||
pole_id = int(request.params.get('pole_id')) | pole_id = int(request.params.get('pole_id')) | ||||
except (ValueError, TypeError): | |||||
pole_id = 0 | |||||
else: | |||||
pole_id = None | |||||
# Get areas from db | # Get areas from db | ||||
Areas = DBSession.query(TasksArea.uid, TasksArea.name)\ | Areas = DBSession.query(TasksArea.uid, TasksArea.name)\ | ||||
@@ -404,15 +408,18 @@ def tasks(request): | |||||
.order_by('nom').all() | .order_by('nom').all() | ||||
if task_id: | if task_id: | ||||
Task = Tasks.by_id(int(task_id)) | |||||
if not Task: | |||||
TmpTask = Tasks.by_id(int(task_id)) | |||||
if not TmpTask: | |||||
raise HTTPNotFound() | raise HTTPNotFound() | ||||
form = EditStaffTasks(request.POST, Task, meta={'csrf_context': request.session}) | |||||
form = EditStaffTasks(request.POST, TmpTask, meta={'csrf_context': request.session}) | |||||
else: | else: | ||||
Task = Tasks() | |||||
TmpTask = Tasks() | |||||
# Check if the supplied pole_id is in the Areas' range | # Check if the supplied pole_id is in the Areas' range | ||||
Task.area_uid = pole_id if 1 < pole_id <= len(Areas) else 1 | |||||
form = StaffTasks(request.POST, Task, meta={'csrf_context': request.session}) | |||||
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 | # Put some areas on form | ||||
form.area_uid.choices = Areas | form.area_uid.choices = Areas | ||||
@@ -421,16 +428,18 @@ def tasks(request): | |||||
for u in Users] | for u in Users] | ||||
form.due_date.type = "date" | form.due_date.type = "date" | ||||
if request.method == 'POST' and form.validate(): | |||||
form.populate_obj(Task) | |||||
Task.closed = False | |||||
if request.method=='POST' and form.validate(): | |||||
form.populate_obj(TmpTask) | |||||
TmpTask.closed = False | |||||
if 'uid' in form._fields.keys(): | if 'uid' in form._fields.keys(): | ||||
DBSession.merge(Task) | |||||
DBSession.merge(TmpTask) | |||||
else: | else: | ||||
DBSession.add(Task) | |||||
DBSession.add(TmpTask) | |||||
DBSession.flush() | DBSession.flush() | ||||
return HTTPFound(location=request.route_url('list_task')+"#"+slugify(Task.area.name)) | |||||
return {'form':form, 'area':slugify(Task.area.name)} | |||||
return HTTPFound(location=request.route_url('list_task')+"#"+slugify(TmpTask.area.name)) | |||||
return {'form':form, 'area':TmpTask.area and slugify(TmpTask.area.name) or ''} | |||||
@view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako') | @view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako') | ||||
def tasks_area(request): | def tasks_area(request): | ||||
@@ -724,6 +733,47 @@ def sejour(request): | |||||
return HTTPFound(location='/MesJM2L#Sejour') | 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) | |||||
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') | @view_config(route_name='vote_logo') | ||||
def vote_logo(request): | def vote_logo(request): | ||||
if request.user is None: | if request.user is None: | ||||
@@ -743,7 +793,7 @@ def vote_logo(request): | |||||
return HTTPFound(location=come) | return HTTPFound(location=come) | ||||
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.') | ||||
@view_config(route_name='list_users', renderer="jm2l:templates/Participant/list.mako") | |||||
@view_config(route_name='list_users', renderer="jm2l:templates/Participant/list_users.mako") | |||||
def list_users(request): | def list_users(request): | ||||
if request.user is None: | if request.user is None: | ||||
# Don't answer to users that aren't logged | # Don't answer to users that aren't logged | ||||
@@ -761,6 +811,16 @@ def list_users(request): | |||||
if (r[0] & 4 == 4): DicRepas["Soir"]+=1 | if (r[0] & 4 == 4): DicRepas["Soir"]+=1 | ||||
return { 'Users':Data, 'UserEvent' : User_Event, "DicRepas":DicRepas } | return { 'Users':Data, 'UserEvent' : User_Event, "DicRepas":DicRepas } | ||||
@view_config(route_name='list_orga', renderer="jm2l:templates/Participant/list_orga.mako") | |||||
def list_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 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).all() | |||||
return { 'Users':Data } | |||||
@view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako") | @view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako") | ||||
def jm2l_page(request): | def jm2l_page(request): | ||||
if request.user is None: | if request.user is None: | ||||
@@ -1143,17 +1203,90 @@ def link_event_tiers(request): | |||||
else: | else: | ||||
TargetTiers = Exist | TargetTiers = Exist | ||||
if len(DBSession.query(Role_Tiers)\ | |||||
Matching = DBSession.query(Role_Tiers)\ | |||||
.filter(Role_Tiers.year_uid==year)\ | .filter(Role_Tiers.year_uid==year)\ | ||||
.filter(Role_Tiers.tiers_role=="Exposant")\ | .filter(Role_Tiers.tiers_role=="Exposant")\ | ||||
.filter(Role_Tiers.tiers_uid==TargetTiers.uid)\ | .filter(Role_Tiers.tiers_uid==TargetTiers.uid)\ | ||||
.all())==0: | |||||
tev = Role_Tiers(year_uid=year, tiers_role="Exposant", 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) | DBSession.add(tev) | ||||
return HTTPFound(location=request.route_url('edit_event', sep='/', | return HTTPFound(location=request.route_url('edit_event', sep='/', | ||||
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid))) | |||||
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid), _anchor="Tiers")) | |||||
@view_config(route_name='delete_link') | |||||
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'évenement 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") | @view_config(route_name='edit_event', renderer="jm2l:templates/edit_event.mako") | ||||
def edit_event(request): | def edit_event(request): | ||||
@@ -1167,7 +1300,7 @@ def edit_event(request): | |||||
if intervention=='Conference': | if intervention=='Conference': | ||||
IntervLabel = u'conférence' | IntervLabel = u'conférence' | ||||
# Check intervention | # Check intervention | ||||
if not intervention in ['Stand', 'Table ronde', 'Atelier', 'Conference', 'Concert']: | |||||
if not intervention in ['Stand', 'Table_ronde', 'Atelier', 'Conference', 'Concert']: | |||||
raise HTTPNotFound(u"Ce type d'évenement n'est pas reconnu") | raise HTTPNotFound(u"Ce type d'évenement n'est pas reconnu") | ||||
TheYear = DBSession.query(JM2L_Year)\ | TheYear = DBSession.query(JM2L_Year)\ | ||||
.filter(JM2L_Year.year_uid==year)\ | .filter(JM2L_Year.year_uid==year)\ | ||||
@@ -1256,7 +1389,7 @@ def edit_event(request): | |||||
form.duration.choices.append( (duration,u'Conférence (%d min)' % duration) ) | form.duration.choices.append( (duration,u'Conférence (%d min)' % duration) ) | ||||
if not form._fields.has_key("uid"): | if not form._fields.has_key("uid"): | ||||
form.duration.data=60 | form.duration.data=60 | ||||
SalleDispo = SalleDispo.filter(Salles.place_type=='Conference') | |||||
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Conference', 'MAO'])) | |||||
elif intervention=="Stand": | elif intervention=="Stand": | ||||
form.duration.choices =[ | form.duration.choices =[ | ||||
(8*60, u'Toute la journée'), | (8*60, u'Toute la journée'), | ||||
@@ -1268,19 +1401,19 @@ def edit_event(request): | |||||
[60, 90, 120, 150, 180, 210, 240] ) | [60, 90, 120, 150, 180, 210, 240] ) | ||||
if not duration in map(lambda (d,y): d, form.duration.choices): | 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) ) ) | form.duration.choices.append( (duration,u'Atelier (%dh%.2d)' % (duration/60, duration%60) ) ) | ||||
SalleDispo = SalleDispo.filter(Salles.place_type=='Ateliers') | |||||
elif intervention=="Table ronde": | |||||
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Ateliers', 'MAO'])) | |||||
elif intervention=="Table_ronde": | |||||
form.duration.choices = map( lambda d:(d, u'Table ronde (%dh%.2d)' % (d/60, d%60) ), \ | form.duration.choices = map( lambda d:(d, u'Table ronde (%dh%.2d)' % (d/60, d%60) ), \ | ||||
[60, 90, 120, 150] ) | [60, 90, 120, 150] ) | ||||
if not duration in map(lambda (d,y): d, form.duration.choices): | 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) ) ) | form.duration.choices.append( (duration,u'Table ronde (%dh%.2d)' % (duration/60, duration%60) ) ) | ||||
SalleDispo = SalleDispo.filter(Salles.place_type=='Conference') | |||||
SalleDispo = SalleDispo.filter(Salles.place_type=='Table ronde') | |||||
elif intervention=="Concert": | elif intervention=="Concert": | ||||
form.duration.choices = map( lambda d:(d, u'Concert (%dh%.2d)' % (d/60, d%60) ), \ | form.duration.choices = map( lambda d:(d, u'Concert (%dh%.2d)' % (d/60, d%60) ), \ | ||||
[60, 90, 120, 150, 180, 210, 240] ) | [60, 90, 120, 150, 180, 210, 240] ) | ||||
if not duration in map(lambda (d,y): d, form.duration.choices): | 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) ) ) | form.duration.choices.append( (duration,u'Concert (%dh%.2d)' % (duration/60, duration%60) ) ) | ||||
SalleDispo = SalleDispo.filter(Salles.place_type=='Stand') | |||||
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Stand', 'MAO'])) | |||||
else: | else: | ||||
raise HTTPForbidden(u"Pas encore disponible.") | raise HTTPForbidden(u"Pas encore disponible.") | ||||
@@ -1301,16 +1434,35 @@ def edit_event(request): | |||||
uev.user_uid = request.user.uid | uev.user_uid = request.user.uid | ||||
TheEvent.interventions.append( uev ) | TheEvent.interventions.append( uev ) | ||||
DBSession.flush() | DBSession.flush() | ||||
request.session.flash(('sucess',u'Votre intervention a été créee !')) | |||||
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='/', | return HTTPFound(location=request.route_url('edit_event', sep='/', | ||||
year=str(year), intervention=intervention, event_id=str(TheEvent.slug))) | year=str(year), intervention=intervention, event_id=str(TheEvent.slug))) | ||||
else: | 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( slugify(TheEvent.name), year) | |||||
if CheckEvent: | |||||
request.session.flash(('warning',u'Choisissez un autre titre pour votre évenement, 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=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) | 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':'', | MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', | ||||
'event':TheEvent, 'form':form, 'formAdd':formAdd, 'formAddT':formAddT, | 'event':TheEvent, 'form':form, 'formAdd':formAdd, 'formAddT':formAddT, | ||||
'Salles':Salles, | |||||
'logged_in':request.authenticated_userid } | |||||
'Salles':Salles } | |||||
return MainTab | return MainTab | ||||
@@ -1451,13 +1603,34 @@ def edit_tiers(request): | |||||
form.populate_obj(TheTiers) | form.populate_obj(TheTiers) | ||||
# Handle Remove of accents | # Handle Remove of accents | ||||
TheTiers.slug = slugify(form.name.data) | |||||
OriginalSlug = TheTiers.slug | |||||
if not form._fields.has_key('uid'): | if not form._fields.has_key('uid'): | ||||
TheTiers.slug = slugify(form.name.data) | |||||
TheTiers.creator_id = request.user.uid | TheTiers.creator_id = request.user.uid | ||||
DBSession.add(TheTiers) | DBSession.add(TheTiers) | ||||
DBSession.flush() | DBSession.flush() | ||||
return HTTPFound(location=request.route_url('edit_entity', sep='/', | return HTTPFound(location=request.route_url('edit_entity', sep='/', | ||||
entity_id=str(TheTiers.slug), tiers_type=TheTiers.get_entity_type.entity_type)) | 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) | DBSession.merge(TheTiers) | ||||
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, | return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, | ||||
tiers_type=TheTiers.get_entity_type.slug_entity_type)) | tiers_type=TheTiers.get_entity_type.slug_entity_type)) | ||||
@@ -1586,7 +1759,7 @@ def link_role_entity(request): | |||||
def forbidden(reason, request): | def forbidden(reason, request): | ||||
if 'ident' in reason.detail: | if 'ident' in reason.detail: | ||||
request.session.flash(('info', reason.detail)) | request.session.flash(('info', reason.detail)) | ||||
return HTTPFound(location='/sign/login' ) | |||||
return HTTPFound(location='/sign/login?from='+request.environ['PATH_INFO'] ) | |||||
else: | else: | ||||
request.response.status = 403 | request.response.status = 403 | ||||
return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason }, | return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason }, | ||||