@@ -12,7 +12,7 @@ from .security import EntryFactory, groupfinder | |||
from pyramid_mailer import mailer_factory_from_settings | |||
from pyramid_mailer.message import Attachment, Message | |||
import locale | |||
from .helpers import Sejour_helpers | |||
from .helpers import Sejour_helpers, Orga_helpers | |||
from apscheduler.schedulers.background import BackgroundScheduler | |||
# Database access imports | |||
from pyramid.request import Request | |||
@@ -23,6 +23,7 @@ import logging | |||
def add_renderer_globals(event): | |||
event['mytrip'] = Sejour_helpers(event) | |||
event['myorga'] = Orga_helpers(event) | |||
#@sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07) | |||
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('list_users', '/ListParticipant') | |||
config.add_route('list_orga', '/ListOrga') | |||
# HTML Routes - Public | |||
config.add_route('home', '/{year:(\d+/)?}') | |||
@@ -133,8 +135,10 @@ def main(global_config, **settings): | |||
## Events | |||
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_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('delete_event', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete') | |||
## Entities | |||
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('miam', '/MonMiam') | |||
config.add_route('sejour', '/MonSejour') | |||
config.add_route('orga', '/MonOrga') | |||
config.add_route('modal', '/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}') | |||
# Handle exchanges | |||
@@ -11,7 +11,7 @@ import re | |||
@view_config(route_name='auth', match_param="action=login", renderer="jm2l:templates/login.mako") | |||
def login(request): | |||
return {} | |||
return {"comefrom":request.GET.get('from', "")} | |||
@view_config(route_name='auth', match_param="action=forgot", renderer="jm2l:templates/login.mako") | |||
def forgot(request): | |||
@@ -75,6 +75,9 @@ def sign_in_out(request): | |||
user.last_logged=datetime.datetime.now() | |||
DBSession.merge(user) | |||
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'), | |||
headers=headers) | |||
else: | |||
@@ -4,17 +4,19 @@ from pyramid.response import Response | |||
import cStringIO as StringIO | |||
from pyramid.view import view_config | |||
from .models import User | |||
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 subprocess | |||
from .upload import MediaPath | |||
# Create PDF container | |||
EXPIRATION_TIME = 300 # seconds | |||
WIDTH = 85 * mm | |||
HEIGHT = 60 * mm | |||
ICONSIZE = 8 * mm | |||
ICONSIZE = 9 * mm | |||
def Ribbon35(DispUser, canvas): | |||
canvas.saveState() | |||
@@ -140,34 +142,48 @@ def JM2L_Logo(canvas, Position="Up"): | |||
yearobject.textLines("2 0 1 5") | |||
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: | |||
StartPos = ( WIDTH -70, 0 ) | |||
StartPos = ( 30 * mm, 2 ) | |||
StartX, StartY = StartPos | |||
MaxX, MaxY = 34*mm, 18*mm | |||
num = 0 | |||
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: | |||
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.drawImage(ImagePath, | |||
PosX, PosY, ICONSIZE, ICONSIZE,\ | |||
preserveAspectRatio=True, | |||
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 | |||
def QRCode(DispUser): | |||
@@ -183,8 +199,10 @@ def QRCode(DispUser): | |||
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): | |||
isoutpng = request.params.get('png') | |||
user_slug = request.matchdict.get('user_slug', None) | |||
if user_slug is None or len(user_slug)==0: | |||
raise HTTPNotFound(u"Cet utilisateur n'a pas été reconnu") | |||
@@ -200,6 +218,7 @@ def badge_user(request): | |||
pdfmetrics.registerFont(TTFont("Liberation", ttfFile)) | |||
pdf = StringIO.StringIO() | |||
out_img = StringIO.StringIO() | |||
c = canvas.Canvas( pdf, pagesize=(WIDTH, HEIGHT) ) | |||
c.translate(mm, mm) | |||
@@ -215,24 +234,24 @@ def badge_user(request): | |||
if DispUser.Staff: | |||
# Staff | |||
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.setFont('Liberation', 30) | |||
c.drawCentredString(WIDTH/2, HEIGHT-26, "STAFF") | |||
elif DispUser.is_Intervenant: | |||
elif DispUser.is_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.setFont('Liberation', 30) | |||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Intervenant") | |||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Intervenant") | |||
else: | |||
# 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.setFont('Liberation', 30) | |||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Visiteur") | |||
c.drawCentredString(WIDTH/2, HEIGHT-26, "Visiteur") | |||
c.restoreState() | |||
@@ -242,19 +261,19 @@ def badge_user(request): | |||
# Feed Name and SurName | |||
if len(DispUser.prenom) + len(DispUser.nom)>18: | |||
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: | |||
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: | |||
c.drawCentredString(WIDTH/2, HEIGHT/2 + 0 * mm , "%s %s" % (DispUser.prenom, DispUser.nom) ) | |||
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 | |||
c.drawInlineImage(QRCode(DispUser), \ | |||
@@ -263,12 +282,28 @@ def badge_user(request): | |||
preserveAspectRatio=True, \ | |||
anchor='s') | |||
Tiers_Logo(c, DispUser, 4, ( 30 * mm, 2 )) | |||
Tiers_Logo(c, DispUser) | |||
c.showPage() | |||
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') | |||
def badge_user1(request): | |||
@@ -312,27 +347,7 @@ def badge_user1(request): | |||
yearobject.textLines("2 0 1 5") | |||
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: | |||
Ribbon90(DispUser, c) | |||
@@ -454,32 +469,11 @@ def badge_user2(request): | |||
yearobject.setWordSpace(21) | |||
yearobject.textLines("2 0 1 5") | |||
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: | |||
c.rotate(35) | |||
offset_u=0 | |||
c.rotate(-35) | |||
c.translate(-100, -70) | |||
offset_u=0 | |||
if DispUser.Staff: | |||
# Staff | |||
c.setFillColorRGB(1,.2,.2) | |||
@@ -489,7 +483,7 @@ def badge_user2(request): | |||
c.drawCentredString(WIDTH/2-10, HEIGHT/2-offset_u+5, "STAFF") | |||
elif DispUser.is_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.setFillColorRGB(1,1,1) | |||
c.setFont('Liberation', 15) | |||
@@ -501,32 +495,6 @@ def badge_user2(request): | |||
c.setFillColorRGB(0,0,0) | |||
c.setFont('Liberation', 12) | |||
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() | |||
@@ -551,7 +519,8 @@ def badge_user2(request): | |||
c.setFont("Helvetica-Oblique", 14) | |||
c.drawCentredString(WIDTH/2, HEIGHT/2 - 8 * mm , "\"%s\"" % DispUser.pseudo ) | |||
#c.restoreState() | |||
# Put Tiers logos | |||
Tiers_Logo(c, DispUser) | |||
# Put QR code to user profile | |||
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): | |||
year_uid = SelectField(u'Année', 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)], | |||
filters=[strip_filter]) | |||
description = TextAreaField('Description', | |||
@@ -1,8 +1,9 @@ | |||
# -*- coding: utf8 -*- | |||
from .models import DBSession, JM2L_Year, Sejour | |||
from datetime import timedelta, datetime | |||
import itertools | |||
class Sejour_helpers: | |||
class DummySejour(object): | |||
def __init__(self, event): | |||
self.Me = event['request'].user | |||
@@ -13,8 +14,13 @@ class Sejour_helpers: | |||
.filter(Sejour.user_id==self.Me.uid)\ | |||
.filter(Sejour.for_year==self.CurrentEventYear.year_uid)\ | |||
.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): | |||
# This function return the start of the event | |||
@@ -98,4 +104,47 @@ class Sejour_helpers: | |||
else: | |||
return "" | |||
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) \ | |||
.filter(User_Event.user_uid==self.uid) \ | |||
.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 | |||
def my_hash(self): | |||
@@ -308,6 +315,7 @@ class Role_Tiers(Base): | |||
tiers_uid = Column(Integer, ForeignKey('tiers.uid')) | |||
tiers = relationship(Tiers, backref=backref("roles_assoc") ) | |||
tiers_role = Column(Enum('Exposant', 'Sponsor', 'Donateur')) | |||
event_uid = Column(Integer, default=None) # Optionnal link with Event | |||
class User_Tiers(Base): | |||
""" 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')) | |||
year_uid = Column(Integer, ForeignKey('jm2l_year.year_uid'), default=CurrentYear) | |||
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 | |||
created = 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_allerg = 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) | |||
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 | |||
name = Column(Unicode(100), nullable=False) | |||
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) | |||
end_time = Column(DateTime, default=datetime.datetime.now) | |||
description = Column(UnicodeText) | |||
@@ -601,6 +611,13 @@ class Event(Base): | |||
return DBSession.query(cls)\ | |||
.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 | |||
def video(self): | |||
return DBSession.query(Media) \ | |||
@@ -7,22 +7,64 @@ | |||
<th>Section</th> | |||
<th>Statut</th> | |||
</tr> | |||
</thead> | |||
</thead> | |||
<tbody> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
<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> | |||
</tbody> | |||
</table> | |||
@@ -62,6 +104,7 @@ elif Type=='T': | |||
CurEventType = "Table ronde" | |||
CurLink = "Ma_Table_Ronde" | |||
%> | |||
% if Type!='O': | |||
<fieldset> | |||
<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 )} | |||
</fieldset> | |||
% endif | |||
% if Type=='C': | |||
<p> | |||
@@ -118,109 +162,46 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent | |||
% endif | |||
% if Type=='O': | |||
<form id="OrgaForm" action="/MonOrga" method="POST"> | |||
<fieldset> | |||
<legend>Participer à l'organisation</legend> | |||
<strong>Une autre façon de participer !</strong> | |||
<p> | |||
Comme vous vous en doutez, la meilleure organisation qui existe, | |||
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> | |||
Et oui, il existe plein de façon de participer aux JM2L, choisissez : | |||
</p> | |||
</fieldset> | |||
<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> | |||
<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> | |||
</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 | |||
<a href="/MesJM2L/2015/${CurEventType.replace(' ','_')}">Je souhaite ajouter ${CurTitle} pour les JM2L 2015 !</a> | |||
% if Type!='O': | |||
<a href="/MesJM2L/2015/${CurEventType.replace(' ','_')}">Je souhaite ajouter ${CurTitle} pour les JM2L 2015 !</a> | |||
<fieldset> | |||
<legend class="lowshadow">Historique</legend> | |||
<% | |||
@@ -303,6 +303,26 @@ ListWrap = ["Co-voiturage",u"Hébergement","Matos"] | |||
<fieldset> | |||
<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> | |||
</%def> | |||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | |||
@@ -111,139 +111,6 @@ $('table').each(function(){ | |||
}); | |||
</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 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> | |||
% 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: | |||
<div class="borderboxtime"> | |||
${event.start_time.strftime('%d %b %Y').decode('utf-8')} - | |||
@@ -53,7 +57,7 @@ | |||
% endif | |||
</ul> | |||
</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"> | |||
%endif | |||
<fieldset> | |||
@@ -105,12 +109,20 @@ DicForm = { | |||
</p> | |||
% 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: | |||
<fieldset> | |||
<legend>Indiquez l'entité dont vous faites la promotion :</legend> | |||
<legend id="Tiers">Indiquez l'entité dont vous faites la promotion :</legend> | |||
<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} | |||
<input type="hidden" id="tiers" name="tiers" style="width:20em;" | |||
class="form-control select2-offscreen" tabindex="-1"> | |||
@@ -120,27 +132,55 @@ DicForm = { | |||
</button> | |||
</form> | |||
NB : Notez que les entités séléctionnées apparaissent dans les exposants. | |||
</p> | |||
</p> | |||
</fieldset> | |||
<fieldset> | |||
<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> | |||
<div class="clearfix"> </div> | |||
@@ -407,12 +407,15 @@ TabJs = {'select':[], 'desc':[]} | |||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | |||
## Wrapper pour les badges des entités utilisateur | |||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | |||
<%def name="show_SummaryEntities(ListEntities)"> \ | |||
<%def name="show_SummaryEntities(ListEntities, callback=None)"> \ | |||
<ul class="thumbnails"> | |||
% for tiers in ListEntities: | |||
<% Entity = tiers.get_entity_type %> | |||
<li class="span3 tiers"> | |||
<div class="media"> | |||
% if callback: | |||
${callback(tiers)} | |||
% endif | |||
<a class="pull-left" href="/entity/${Entity.entity_type}/${tiers.slug}"> | |||
% if tiers.ThumbLinks: | |||
<img class="media-object" src="${tiers.ThumbLinks.pop()}" alt="${tiers.slug}" /> | |||
@@ -59,7 +59,7 @@ | |||
<div class="row-fluid"> | |||
<div class="span10 offset1"> | |||
<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><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> | |||
@@ -108,7 +108,7 @@ ${helpers.uploader_js()} | |||
<div class="btn-group"> | |||
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#"> | |||
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): | |||
% if tmpyear!=2014: | |||
<li><a href="/year/${tmpyear}">${tmpyear}</a></li> | |||
@@ -126,13 +126,15 @@ ${helpers.uploader_js()} | |||
% endif | |||
<span class="caret"></span> | |||
</a> | |||
<ul class="dropdown-menu"> | |||
<ul class="dropdown-menu pull-right"> | |||
% if request.user: | |||
% if request.user.Staff: | |||
<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="/entities">Gérer les entités</a></li> | |||
<li><a href="/ListOrga">Participations à l'orga</a></li> | |||
<li role="separator" class="divider"></li> | |||
% endif | |||
<li><a href="/sign/out">Me déconnecter</a></li> | |||
% else: | |||
@@ -14,6 +14,7 @@ | |||
<hr> | |||
<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="redirect" type="hidden" value="${comefrom}"> | |||
<div class="center"> | |||
<button class="btn btn-large btn-primary btn-block" type="submit">S'identifier</button> | |||
</div> | |||
@@ -8,24 +8,18 @@ | |||
</%def> | |||
<div class="row-fluid"> | |||
<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>: | |||
<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): | |||
<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: | |||
<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 | |||
<h3 style="line-height:30px;">${event.name}</h3> | |||
% if event.description : | |||
@@ -35,10 +29,12 @@ ${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} | |||
% else: | |||
<p>Cette évenement n'a pas de description.</p> | |||
% endif | |||
<div style="margin-top:10px;"> | |||
${helpers.show_SummaryEntities( event.get_linked_tiers() )} | |||
</div> | |||
</div> | |||
</div> | |||
<hr/> | |||
% if event.presentation.count() and event.video.count(): | |||
<div class="row-fluid"> | |||
<div id="pres" class="span6"> | |||
@@ -120,6 +120,13 @@ class MediaPath(): | |||
else: | |||
slug = user.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': | |||
ev = Event.by_id(linked_id) | |||
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 view_config | |||
from mako.template import Template | |||
from .upload import IMAGEPATH | |||
# Import Web Forms | |||
from .forms import * | |||
# Database access imports | |||
from .models import * | |||
from .helpers import Orga_helpers | |||
from sqlalchemy import func, or_ | |||
from os import path, makedirs | |||
# Usefull tools | |||
from slugify import slugify | |||
from icalendar import Calendar | |||
@@ -20,7 +23,8 @@ from pyramid_mailer.message import Message | |||
import webhelpers.paginate as paginate | |||
import unicodedata | |||
import datetime | |||
import re | |||
import re | |||
import shutil | |||
CurrentYear = 2015 | |||
@@ -390,10 +394,10 @@ def tasks(request): | |||
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.') | |||
task_id = request.matchdict.get('task_id') | |||
# Convert the pole_id GET parameter to int or 0 | |||
try: | |||
if request.params.get('pole_id') and request.params.get('pole_id').isdigit(): | |||
pole_id = int(request.params.get('pole_id')) | |||
except (ValueError, TypeError): | |||
pole_id = 0 | |||
else: | |||
pole_id = None | |||
# Get areas from db | |||
Areas = DBSession.query(TasksArea.uid, TasksArea.name)\ | |||
@@ -404,15 +408,18 @@ def tasks(request): | |||
.order_by('nom').all() | |||
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() | |||
form = EditStaffTasks(request.POST, Task, meta={'csrf_context': request.session}) | |||
form = EditStaffTasks(request.POST, TmpTask, meta={'csrf_context': request.session}) | |||
else: | |||
Task = Tasks() | |||
TmpTask = Tasks() | |||
# 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 | |||
form.area_uid.choices = Areas | |||
@@ -421,16 +428,18 @@ def tasks(request): | |||
for u in Users] | |||
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(): | |||
DBSession.merge(Task) | |||
DBSession.merge(TmpTask) | |||
else: | |||
DBSession.add(Task) | |||
DBSession.add(TmpTask) | |||
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') | |||
def tasks_area(request): | |||
@@ -724,6 +733,47 @@ def sejour(request): | |||
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') | |||
def vote_logo(request): | |||
if request.user is None: | |||
@@ -743,7 +793,7 @@ def vote_logo(request): | |||
return HTTPFound(location=come) | |||
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): | |||
if request.user is None: | |||
# 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 | |||
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") | |||
def jm2l_page(request): | |||
if request.user is None: | |||
@@ -1143,17 +1203,90 @@ def link_event_tiers(request): | |||
else: | |||
TargetTiers = Exist | |||
if len(DBSession.query(Role_Tiers)\ | |||
Matching = DBSession.query(Role_Tiers)\ | |||
.filter(Role_Tiers.year_uid==year)\ | |||
.filter(Role_Tiers.tiers_role=="Exposant")\ | |||
.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) | |||
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") | |||
def edit_event(request): | |||
@@ -1167,7 +1300,7 @@ def edit_event(request): | |||
if intervention=='Conference': | |||
IntervLabel = u'conférence' | |||
# 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") | |||
TheYear = DBSession.query(JM2L_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) ) | |||
if not form._fields.has_key("uid"): | |||
form.duration.data=60 | |||
SalleDispo = SalleDispo.filter(Salles.place_type=='Conference') | |||
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Conference', 'MAO'])) | |||
elif intervention=="Stand": | |||
form.duration.choices =[ | |||
(8*60, u'Toute la journée'), | |||
@@ -1268,19 +1401,19 @@ def edit_event(request): | |||
[60, 90, 120, 150, 180, 210, 240] ) | |||
if not duration in map(lambda (d,y): d, form.duration.choices): | |||
form.duration.choices.append( (duration,u'Atelier (%dh%.2d)' % (duration/60, duration%60) ) ) | |||
SalleDispo = SalleDispo.filter(Salles.place_type=='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) ), \ | |||
[60, 90, 120, 150] ) | |||
if not duration in map(lambda (d,y): d, form.duration.choices): | |||
form.duration.choices.append( (duration,u'Table ronde (%dh%.2d)' % (duration/60, duration%60) ) ) | |||
SalleDispo = SalleDispo.filter(Salles.place_type=='Conference') | |||
SalleDispo = SalleDispo.filter(Salles.place_type=='Table ronde') | |||
elif intervention=="Concert": | |||
form.duration.choices = map( lambda d:(d, u'Concert (%dh%.2d)' % (d/60, d%60) ), \ | |||
[60, 90, 120, 150, 180, 210, 240] ) | |||
if not duration in map(lambda (d,y): d, form.duration.choices): | |||
form.duration.choices.append( (duration,u'Concert (%dh%.2d)' % (duration/60, duration%60) ) ) | |||
SalleDispo = SalleDispo.filter(Salles.place_type=='Stand') | |||
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Stand', 'MAO'])) | |||
else: | |||
raise HTTPForbidden(u"Pas encore disponible.") | |||
@@ -1301,16 +1434,35 @@ def edit_event(request): | |||
uev.user_uid = request.user.uid | |||
TheEvent.interventions.append( uev ) | |||
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='/', | |||
year=str(year), intervention=intervention, event_id=str(TheEvent.slug))) | |||
else: | |||
if slugify(TheEvent.name)!=TheEvent.slug: | |||
# We should move some file as slug have been changed | |||
# First we ensure there is no related event that already exist with that slug | |||
CheckEvent = Event.by_slug( 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) | |||
request.session.flash(('sucess',u'Votre intervention a été mis à jour !')) | |||
return HTTPFound(location=request.route_url('edit_event', sep='/', | |||
year=str(year), intervention=intervention, event_id=str(TheEvent.slug))) | |||
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', | |||
'event':TheEvent, 'form':form, 'formAdd':formAdd, 'formAddT':formAddT, | |||
'Salles':Salles, | |||
'logged_in':request.authenticated_userid } | |||
'Salles':Salles } | |||
return MainTab | |||
@@ -1451,13 +1603,34 @@ def edit_tiers(request): | |||
form.populate_obj(TheTiers) | |||
# Handle Remove of accents | |||
TheTiers.slug = slugify(form.name.data) | |||
OriginalSlug = TheTiers.slug | |||
if not form._fields.has_key('uid'): | |||
TheTiers.slug = slugify(form.name.data) | |||
TheTiers.creator_id = request.user.uid | |||
DBSession.add(TheTiers) | |||
DBSession.flush() | |||
return HTTPFound(location=request.route_url('edit_entity', sep='/', | |||
entity_id=str(TheTiers.slug), tiers_type=TheTiers.get_entity_type.entity_type)) | |||
else: | |||
if OriginalSlug!=slugify(form.name.data): | |||
# We should move some file as slug have been changed | |||
# First we ensure there is no related event that already exist with that slug | |||
CheckTiers = Tiers.by_slug( slugify(form.name.data) ) | |||
if CheckTiers: | |||
request.session.flash(('warning',u'Attention, Choisissez un autre titre pour votre entitée, elle est en conflit avec une autre.')) | |||
DBSession.rollback() | |||
return HTTPFound(location=request.route_url('edit_entity', sep='/', | |||
entity_id=str(OriginalSlug), tiers_type=TheTiers.get_entity_type.entity_type)) | |||
else: | |||
TheTiers.slug = slugify(form.name.data) | |||
SRCPath = path.join('jm2l/upload', *(IMAGEPATH + ['tiers'] + [ OriginalSlug ]) ) | |||
DSTPath = path.join('jm2l/upload', *(IMAGEPATH + ['tiers'] + [ TheTiers.slug ]) ) | |||
if not path.isdir(path.dirname(DSTPath)): | |||
makedirs(path.dirname(DSTPath)) | |||
# Then we should move event attachments to the new slug (if any) | |||
if path.exists(SRCPath): | |||
shutil.move(SRCPath, DSTPath) | |||
DBSession.merge(TheTiers) | |||
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, | |||
tiers_type=TheTiers.get_entity_type.slug_entity_type)) | |||
@@ -1586,7 +1759,7 @@ def link_role_entity(request): | |||
def forbidden(reason, request): | |||
if 'ident' in reason.detail: | |||
request.session.flash(('info', reason.detail)) | |||
return HTTPFound(location='/sign/login' ) | |||
return HTTPFound(location='/sign/login?from='+request.environ['PATH_INFO'] ) | |||
else: | |||
request.response.status = 403 | |||
return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason }, | |||