| @@ -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 }, | ||||