瀏覽代碼

Merge branch 'tr4ck3ur/various_fixes_2017' of JM2L/jm2l into master

master
JM2L 6 年之前
committed by Gogs
父節點
當前提交
69c15d8b5c
共有 32 個文件被更改,包括 366 次插入267 次删除
  1. +3
    -1
      jm2l/__init__.py
  2. +1
    -1
      jm2l/const.py
  3. +1
    -1
      jm2l/forms.py
  4. +5
    -5
      jm2l/helpers.py
  5. +1
    -1
      jm2l/models.py
  6. +162
    -2
      jm2l/scripts/initializedb.py
  7. +17
    -0
      jm2l/security.py
  8. +1
    -1
      jm2l/templates/Errors/403.mako
  9. +1
    -1
      jm2l/templates/Errors/404.mako
  10. +24
    -24
      jm2l/templates/Interventions/Interventions.mako
  11. +6
    -6
      jm2l/templates/Live.mako
  12. +15
    -15
      jm2l/templates/Logistique/Logistique.mako
  13. +1
    -1
      jm2l/templates/NewIndex.mako
  14. +12
    -12
      jm2l/templates/Profil/Profil.mako
  15. +1
    -1
      jm2l/templates/Profil/Sejour.mako
  16. +33
    -28
      jm2l/templates/Public/Plan.mako
  17. +1
    -1
      jm2l/templates/Public/Presse.mako
  18. +0
    -17
      jm2l/templates/Public/Programme.mako
  19. +2
    -2
      jm2l/templates/Salles/list.mako
  20. +2
    -2
      jm2l/templates/Salles/list_phy.mako
  21. +2
    -2
      jm2l/templates/Salles/salle.mako
  22. +1
    -1
      jm2l/templates/Staff/compta.mako
  23. +2
    -2
      jm2l/templates/Staff/list.mako
  24. +4
    -4
      jm2l/templates/helpers.mako
  25. +1
    -1
      jm2l/templates/index.mako
  26. +5
    -5
      jm2l/templates/jm2l.mako
  27. +9
    -14
      jm2l/templates/layout.mako
  28. +3
    -3
      jm2l/templates/modals.mako
  29. +1
    -0
      jm2l/templates/view_event.mako
  30. +1
    -1
      jm2l/templates/view_tiers.mako
  31. +2
    -1
      jm2l/upload.py
  32. +46
    -111
      jm2l/views.py

+ 3
- 1
jm2l/__init__.py 查看文件

@@ -26,6 +26,7 @@ import logging
def add_renderer_globals(event):
event['mytrip'] = Sejour_helpers(event)
event['myorga'] = Orga_helpers(event)
event['SelectedYear'] = CurrentYear
event['CurrentYear'] = CurrentYear

#@sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=07)
@@ -62,7 +63,8 @@ def mailer_tasks(config):
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8")
#locale.setlocale(locale.LC_ALL, "fr_FR.UTF-8")
locale.setlocale(locale.LC_ALL, "fr_FR.utf8")
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
# Extract secrets from configuration file if any


+ 1
- 1
jm2l/const.py 查看文件

@@ -1 +1 @@
CurrentYear = 2017
CurrentYear = 2018

+ 1
- 1
jm2l/forms.py 查看文件

@@ -189,7 +189,7 @@ class PlaceCreateForm(MyBaseForm):
name = StringField('Nom Complet', [validators.Length(min=1, max=80)],
filters=[strip_filter])
gps_coord = StringField(u'Coordonnées GPS', [validators.Length(max=30),
validators.Regexp( "^[0-9]*\.?[0-9],[0-9]*\.?[0-9]+",
validators.Regexp( "^[0-9]+\.?[0-9]+,[0-9]+\.?[0-9]+$",
message=u"Le GPS devrait être sous la forme 43.6158372,7.0723401")],
filters=[strip_filter])
adresse = TextAreaField('Adresse', [validators.Length(max=100)],


+ 5
- 5
jm2l/helpers.py 查看文件

@@ -42,11 +42,11 @@ class Sejour_helpers(DummySejour):
return TabResult
if self.Sejour:
ArrDate = datetime.strftime(self.Sejour.arrival_time,"%d %B %Y")
DepDate = datetime.strftime(self.Sejour.depart_time,"%d %B %Y")
ArrDate = datetime.strftime(self.Sejour.arrival_time,"%d %B %Y").decode('utf-8')
DepDate = datetime.strftime(self.Sejour.depart_time,"%d %B %Y").decode('utf-8')
else:
ArrDate = datetime.strftime( self.CurrentEventYear.start_time,"%d %B %Y" )
DepDate = datetime.strftime( self.CurrentEventYear.end_time,"%d %B %Y" )
ArrDate = datetime.strftime( self.CurrentEventYear.start_time,"%d %B %Y" ).decode('utf-8')
DepDate = datetime.strftime( self.CurrentEventYear.end_time,"%d %B %Y" ).decode('utf-8')
for oneday in myDayRange:
if arrival:
@@ -55,7 +55,7 @@ class Sejour_helpers(DummySejour):
TmpDay = self.CurrentEventYear.start_time + timedelta(days=oneday)
DayName = datetime.strftime(TmpDay,"%A")
DayNum = datetime.strftime(TmpDay,"%d/%m/%y")
DayString = datetime.strftime(TmpDay,"%d %B %Y")
DayString = datetime.strftime(TmpDay,"%d %B %Y").decode('utf-8')
if arrival and ArrDate==DayString:
TabResult.append((DayNum, DayName, 'selected="selected"'))
elif departure and DepDate==DayString:


+ 1
- 1
jm2l/models.py 查看文件

@@ -102,7 +102,7 @@ class JM2L_Year(Base):
.filter(JM2L_Year.start_time ==
DBSession.query(func.max(JM2L_Year.start_time))
).one()
return last_record.start_time.strftime("%A %d %b %Y")
return last_record.start_time.strftime("%A %d %b %Y").decode('utf-8')

@property
def AvailableTimeSlots(self, TimeStep=30):


+ 162
- 2
jm2l/scripts/initializedb.py 查看文件

@@ -6,12 +6,13 @@ import time
import lxml.etree as ET

from sqlalchemy import engine_from_config
from sqlalchemy import create_engine
from sqlalchemy import create_engine, MetaData, Table
import unicodedata
import urllib
# Usefull tools
from slugify import slugify
from sqlite3 import dbapi2 as sqlite
import sqlite3
from os import path
from pyramid.paster import (
get_appsettings,
@@ -19,7 +20,7 @@ from pyramid.paster import (
)
from string import printable
from random import choice
from sqlalchemy import orm, or_

from jm2l.models import *
from datetime import datetime
@@ -30,8 +31,139 @@ def usage(argv):
'(example: "%s development.ini")' % (cmd, cmd))
sys.exit(1)

def make_session(connection_string):
engine = create_engine(connection_string, echo=False, convert_unicode=True)
Session = sessionmaker(bind=engine)
return Session(), engine

def quick_mapper(table):
Base = declarative_base()
class GenericMapper(Base):
__table__ = table
return GenericMapper

def pull_data(from_db, to_db, tables):
source, sengine = make_session(from_db)
smeta = MetaData(bind=sengine)
destination, dengine = make_session(to_db)

for table_name in tables:
print 'Processing', table_name
print 'Pulling schema from source server'
table = Table(table_name, smeta, autoload=True)
print 'Creating table on destination server'
table.metadata.create_all(dengine)
NewRecord = quick_mapper(table)
columns = table.columns.keys()
print 'Transferring records'
for record in source.query(table).all():
data = dict(
[(str(column), getattr(record, column)) for column in columns]
)
if table_name=='salle':
if data['place_type']=='Ateliers':
data['place_type']='Atelier'
if table_name=='events':
if data['event_type']=='Concert':
data['event_type']='MAO'
try:
destination.merge(NewRecord(**data))
except:
print data
pass
print 'Committing changes'
destination.commit()


def main(argv=sys.argv):
connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"
engine = create_engine(connection_string, echo=False, convert_unicode=True)
DBSession.configure(bind=engine)
Users = DBSession.query(User)
ListUser = filter(lambda x: x.is_Intervenant, Users)
for i in ListUser:
print i.mail

def main4(argv=sys.argv):
import csv
from sqlalchemy import func

connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"

if 1:
conn = sqlite3.connect("/home/tr4ck3ur/Dev/jm2l/JM2L.sqlite")
c = conn.cursor()
try:
c.execute("ALTER TABLE users ADD COLUMN wifi_user VARCHAR(80);")
c.execute("ALTER TABLE users ADD COLUMN wifi_pass VARCHAR(80);")
except:
pass # handle the error
c.close()

engine = create_engine(connection_string, echo=False, convert_unicode=True)
DBSession.configure(bind=engine)

with transaction.manager:
f = open("/home/tr4ck3ur/Dev/jm2l/wifi-11-11-pass.csv", 'rt')
try:
reader = csv.reader(f)
for row in reader:
prenom, nom, w_user, w_pass = row
slug = unicode( slugify(prenom +" "+nom) )
u = DBSession.query(User)\
.filter(User.slug==slug).first()
if u:
u.wifi_user = w_user
u.wifi_pass = w_pass
DBSession.merge(u)
print row, u
finally:
f.close()
if 0:

p0, p1 = orm.aliased(User,name="p0"), orm.aliased(User ,name="p1")
import pprint


def main_3(argv=sys.argv):
connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"
engine = create_engine(connection_string, echo=True, convert_unicode=True)
DBSession.configure(bind=engine)
p0, p1 = orm.aliased(User,name="p0"), orm.aliased(User ,name="p1")
import pprint
## permtation
with transaction.manager:
Datas = DBSession.query(p0, p1)\
.filter(p0.slug==p1.slug)\
.filter(p0.uid!=p1.uid)\
.filter(p0.last_logged<p1.last_logged)\
.with_entities(p0.slug,p0.uid,p1.uid).all()
for slug, idsrc, iddst in Datas:
print slug
# Events
Events = DBSession.query(User_Event)\
.filter(User_Event.user_uid==idsrc)
for uev in Events:
uev.user_uid = iddst
DBSession.merge(uev)
DBSession.flush()
UTiers = DBSession.query(User_Tiers)\
.filter(User_Tiers.user_uid==idsrc)
for ut in UTiers:
ut.user_uid=iddst
DBSession.merge(ut)
DBSession.flush()
orig = DBSession.query(User).filter(User.uid==idsrc).one()
DBSession.delete(orig)
#User_Event.year_uid, Event.name
#pprint.pprint( )
#pprint.pprint( DBSession.query( user_id

def main_(argv=sys.argv):
if len(argv) != 2:
usage(argv)
config_uri = argv[1]
@@ -40,7 +172,35 @@ def main(argv=sys.argv):
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
DBSession.flush()
pull_data("sqlite:////home/tr4ck3ur/Dev/jm2l/PRD_JM2L.sqlite",
"sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite",
['users',
'staff_tasks_area',
'staff_tasks',
'user_event_link',
'jm2l_year',
'users',
'tiers_opt',
'tiers',
'role_tiers_link',
'user_tiers_link',
'medias',
'phy_salle',
'salle',
'place',
'itineraire',
'exchange_category',
'exchanges',
'sejour',
'events',
'entries'
])



def Initialize():
with transaction.manager:
admin = User(nom=u'jm2l', prenom=u'contact',
slug=u'contact jm2l', password=u'jm2l',


+ 17
- 0
jm2l/security.py 查看文件

@@ -1,11 +1,28 @@
# -*- coding: utf8 -*-
from pyramid.security import Allow, Everyone, Authenticated
from pyramid.httpexceptions import HTTPFound, HTTPNotFound, HTTPForbidden
from pyramid.httpexceptions import HTTPBadRequest, HTTPUnauthorized

USERS = { 1:'editor',
'editor':'editor',
'viewer':'viewer'}
GROUPS = {'editor':['group:editors'], 1:['group:editors']}


def check_logged(request):
""" This function is intended to raise an exception if the user is not logged"""
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.')

def check_staff(request):
""" This function is intended to raise an exception if the user is not a Staff member"""
check_logged(request)
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')


def groupfinder(userid, request):
if userid in USERS:
return GROUPS.get(userid, [])


+ 1
- 1
jm2l/templates/Errors/403.mako 查看文件

@@ -58,7 +58,7 @@
% if reason:
<p>${reason}</p>
% else:
<p>Vous n'êtes pas authentifié, ou n'avez pas les autorisations nécessaires.</p>
<p>Vous n'êtes pas authentifi&eacute;, ou n'avez pas les authorisations n&eacute;cessaires.</p>
% endif
</body>
</html>


+ 1
- 1
jm2l/templates/Errors/404.mako 查看文件

@@ -54,7 +54,7 @@
</head>
<body>
<img src="/img/error404.png" width="200px" />
<h1>Page non trouvée</h1>
<h1>Page non trouv&eacute;e</h1>
% if reason:
<p>${reason}</p>
% else:


+ 24
- 24
jm2l/templates/Interventions/Interventions.mako 查看文件

@@ -10,7 +10,7 @@
</thead>
<tbody>
<tr>
<td>Conférences</td> <td style="text-align:center">
<td>Conf&eacute;rences</td> <td style="text-align:center">
% if len( request.user.year_events('Conference') ):
% for evt in request.user.year_events('Conference'):
% endfor
@@ -106,11 +106,11 @@ elif Type=='T':
%>
% if Type!='O':
<fieldset>
<legend class="lowshadow">Vos ${CurTitles} programmés pour ${CurrentYear}</legend>
<legend class="lowshadow">Vos ${CurTitles} programm&eacute;s pour ${CurrentYear}</legend>
<%
Selection = filter(lambda x:(x.event_type==CurEventType and x.for_year==CurrentYear), uprofil.events)
HeadHistTitle = u"L'historique de vos %s ( %d ) " % ( CurTitles, len(Selection) )
NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent
NothingTitle = u"Vous n'avez pas sollicit&eacute; d'intervention %s." % CurEvent
%>
${helpers.show_Interventions(Selection, "Sujet", NothingTitle )}
</fieldset>
@@ -118,31 +118,31 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent

% if Type=='C':
<p>
<strong>Proposer une conférence / un lighting talk</strong><br/>
<strong>Proposer une conf&eacute;rence / un lighting talk</strong><br/>
<ul>
<li>Si vous avez une expérience particulière avec les logiciels libres
<li>Si vous avez une exp&eacute;rience particulière avec les logiciels libres
que vous souhaitez partager.</li>
<li>Si vous êtes acteur d’un des sujets actuels qui menacent ou qui
promeuvent le logiciel libre.</li>
<li>Si vous voulez présenter un logiciel libre dont vous êtes l’auteur.</li>
<li>Si vous voulez pr&eacute;senter un logiciel libre dont vous êtes l’auteur.</li>
</ul>
Nous serons heureux de vous écouter.
Nous serons heureux de vous &eacute;couter.
<br>
Nous souhaitons proposer des conférences pour un public débutant
Nous souhaitons proposer des conf&eacute;rences pour un public d&eacute;butant
autant que pour des visiteurs avertis. Les sujets ne doivent pas
forcément être techniques, mais aussi d’ordre général avec la seule
forc&eacute;ment être techniques, mais aussi d’ordre g&eacute;n&eacute;ral avec la seule
contrainte de traiter de près ou de loin des logiciels libres, de la
communauté ou de vos propres expériences d’utilisateur quotidien. <br>
Le but de ces conférences est double :
communaut&eacute; ou de vos propres exp&eacute;riences d’utilisateur quotidien. <br>
Le but de ces conf&eacute;rences est double :
<ul>
<li>donner confiance aux futurs utilisateurs de logiciels libres</li>
<li>donner matière à réflexion aux auditrices et aux auditeurs expérimentés.</li>
<li>donner matière à r&eacute;flexion aux auditrices et aux auditeurs exp&eacute;riment&eacute;s.</li>
</ul>
Les conférences ont un format défini de 5, 20, 50 ou 70 minutes,
modulable à loisir entre présentation et questions. Vous aideriez l'équipe
d'organisation en essayant au maximum de ne pas dépasser la durée que vous réservez.
Dans tous les cas, 5 minutes supplémentaires vous sont attribuées pour
la mise en place de votre conférence.
Les conf&eacute;rences ont un format d&eacute;fini de 5, 20, 50 ou 70 minutes,
modulable à loisir entre pr&eacute;sentation et questions. Vous aideriez l'&eacute;quipe
d'organisation en essayant au maximum de ne pas d&eacute;passer la dur&eacute;e que vous r&eacute;servez.
Dans tous les cas, 5 minutes suppl&eacute;mentaires vous sont attribu&eacute;es pour
la mise en place de votre conf&eacute;rence.
</p>
% elif Type=='A':
<p>
@@ -154,10 +154,10 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent
l’utilisation de Linux et des logiciels libres standards pour
une utilisation familiale : soyez les bienvenus.

Les ateliers sont organisés dans des salles équipées en matériel
informatique et en vidéo-projecteur. Afin de ne pas perdre de temps,
Les ateliers sont organis&eacute;s dans des salles &eacute;quip&eacute;es en mat&eacute;riel
informatique et en vid&eacute;o-projecteur. Afin de ne pas perdre de temps,
nous avons besoin de connaître les logiciels et installations
spéciales à préparer avant la session de l’atelier.
sp&eacute;ciales à pr&eacute;parer avant la session de l’atelier.
</p>
% endif

@@ -172,8 +172,8 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent
c'est celle où chacun apporte sa contribution.
</p>
<p>
Dans ce genre d'évènement 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
Dans ce genre d'&eacute;vènement nous avons besoin de bras et de bonnes volont&eacute;s.
Vous pouvez nous aider en vous inscrivant en tant que "b&eacute;n&eacute;vole du jour" sur un
certains nombre de missions :
</p>
<p>
@@ -189,7 +189,7 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent
% endfor
</ul>
<p>
Avant l'évènement, et en fonction des cases cochés, les coordinateurs metterons à jour le planning et vous receverez les instructions par mail.
Avant l'&eacute;vènement, et en fonction des cases coch&eacute;s, les coordinateurs metterons à jour le planning et vous receverez les instructions par mail.
</p>
<div class="span2 offset5">
@@ -207,7 +207,7 @@ NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent
<%
Selection = filter(lambda x:(x.event_type==CurEventType and x.for_year!=CurrentYear), uprofil.events)
HeadHistTitle = u"L'historique de vos %s ( %d ) " % ( CurTitles, len(Selection) )
NothingTitle = u"Désolé, Il n'y a rien dans l'historique vous concernant."
NothingTitle = u"D&eacute;sol&eacute;, Il n'y a rien dans l'historique vous concernant."
%>
${helpers.show_Interventions(Selection, HeadHistTitle, NothingTitle )}
</fieldset>


+ 6
- 6
jm2l/templates/Live.mako 查看文件

@@ -17,24 +17,24 @@

<h3>Live JM2L</h3>
<p>
Voici les liens vers les conférences Live:
Voici les liens vers les conf&eacute;rences Live:
<h4>En ce moment:</h4>
</p>
<p>
% for ev in events:
<a href="http://jm2l-bkp.linux-azur.org:8080/${ev.Salle.phy_salle_id}.webm" target="_blank"> Live Vidéo</a> -
## <a href="http://jm2l.linux-azur.org:8081/${ev.Salle.phy_salle_id}.webm" target="_blank"> Live Vidéo</a> -
<a href="http://jm2l-bkp.linux-azur.org:8080/${ev.Salle.phy_salle_id}.webm" target="_blank"> Live Vid&eacute;o</a> -
## <a href="http://jm2l.linux-azur.org:8081/${ev.Salle.phy_salle_id}.webm" target="_blank"> Live Vid&eacute;o</a> -
<a href="http://jm2l.linux-azur.org/event/${ev.for_year}/${ev.slug}"> ${ev.event_type} </a> - ${ev.name}
</br>
% endfor
</p>
<p>
Réalisé avec le concours des admins réseau Polytech'Nice. Encore merci pour leur disponibilité .. <br/>
Rechargez la page pour voir les évenements en cours en fonction de l'heure...<br/>
R&eacute;alis&eacute; avec le concours des admins r&eacute;seau Polytech'Nice. Encore merci pour leur disponibilit&eacute; .. <br/>
Rechargez la page pour voir les &eacute;venements en cours en fonction de l'heure...<br/>
</p>

<p> NB : si vous n'avez pas l'audio à travers votre navigateur...<br>
n'hésitez pas à mettre à contribution votre lecteur de vidéo préféré ( VLC, ffmpeg )<br>
n'h&eacute;sitez pas à mettre à contribution votre lecteur de vid&eacute;o pr&eacute;f&eacute;r&eacute; ( VLC, ffmpeg )<br>
</p>
<p>
Vous avez le droit de vous plaindre, c'est du Do It Yourself ;)


+ 15
- 15
jm2l/templates/Logistique/Logistique.mako 查看文件

@@ -9,10 +9,10 @@ DicExch = Exchanges.get_overview( request.user.uid )
<ul class="nav nav-tabs navbar" style="margin-bottom:0;background-color: #f7f7f7;">
<li class="active"> <a href="#ResumeInt" data-toggle="tab">Resum&eacute;</a> </li>
<li> <a href="#Miam" data-toggle="tab">Miam</a> </li>
<li> <a href="#Covoiturage" data-toggle="tab"><i class="icon-road"></i> Covoiturage</a> </li>
<li> <a href="#Hebergement" data-toggle="tab"><i class="icon-home"></i> H&eacute;bergement</a> </li>
<li> <a href="#Materiel" data-toggle="tab"><i class="icon-shopping-cart"></i> Mat&eacute;riel</a> </li>
<li> <a href="#Miam" data-toggle="tab"><span style="font-size:1.8em;">&#127869;</span> Miam</a> </li>
<li> <a href="#Covoiturage" data-toggle="tab"><span style="font-size:1.8em;">&#128664;</span> Covoiturage</a> </li>
<li> <a href="#Hebergement" data-toggle="tab"><span style="font-size:1.8em;">&#127962;</span> H&eacute;bergement</a> </li>
<li> <a href="#Materiel" data-toggle="tab"><span style="font-size:1.8em;">&#128722;</span> Mat&eacute;riel</a> </li>
</ul>
<div class="tab-content">
@@ -30,7 +30,7 @@ DicExch = Exchanges.get_overview( request.user.uid )
${tables.DoTable(Type, 'Ask', DicExch)}
${tables.DoTable(Type, 'Proposal', DicExch)}
<fieldset>
<legend>Tous les échanges</legend>
<legend>Tous les &eacute;changes</legend>
${Missing(Type, DicExch['Missing'])}
</fieldset>
</%def>
@@ -59,23 +59,23 @@ DicForm = {
</td>
<td>
<p>
Complétez dès à présent votre partie repas afin que l'on puisse faire les réservations nécessaires !
Compl&eacute;tez dès à pr&eacute;sent votre partie repas afin que l'on puisse faire les r&eacute;servations n&eacute;cessaires !
</p>

<u>Vendredi soir :</u>
<p>
Certains conférenciers viennent de très loin et seront présent d&eacute;s le vendredi.<br />
Nous vous proposons de nous retrouver à proximité, à la CASA.<br />
Certains conf&eacute;renciers viennent de très loin et seront pr&eacute;sent d&eacute;s le vendredi.<br />
Nous vous proposons de nous retrouver à proximit&eacute;, à la CASA.<br />
<a href="http://groupelacasa.com/la-carte-et-les-menus-1-2-75"> La carte CASA </a>
le vendredi soir autour d'un verre et d'un bon repas !
</p>
<u>Samedi Midi :</u>
<p>
&Agrave; la pause du midi, nous vous proposons un repas avec le food-truck 'les frères toqués' qui sera présent sur le parking de PolyTech<br />
&Agrave; la pause du midi, nous vous proposons un repas avec le food-truck 'les frères toqu&eacute;s' qui sera pr&eacute;sent sur le parking de PolyTech<br />
</p>
<u>Samedi Soir :</u>
<p>
Pour conclure la journée nous avons l'habitude de nous retrouver au repas de cloture.<br />
Pour conclure la journ&eacute;e nous avons l'habitude de nous retrouver au repas de cloture.<br />
Nous vous proposons de nous retrouver à Antibes au restaurant Les Tonnelles<br />
<a href="https://fr-fr.facebook.com/lestonnellesantibes/?_fb_noscript=1"> Les Tonnelles </a>
</p>
@@ -100,7 +100,7 @@ elif Type=='M':
<thead>
<tr>
<th colspan="5">
Les échanges ${CurTitle}
Les &eacute;changes ${CurTitle}
% if 0:
<span style="float:right;">
<a data-original-title="Afficher les demandes" data-toggle="tooltip" id="${Type}_Demande">
@@ -124,7 +124,7 @@ elif Type=='M':
<tr>
<th style="width:1em;"></th>
<th>Détails</th>
<th>D&eacute;tails</th>
<th style="width:1em;"></th>
<tr>
</thead>
@@ -132,7 +132,7 @@ elif Type=='M':
% if len(Selection)==0:
<tr>
<td colspan="5" style="text-align:center;">
<i>Il n'y a aucun échange ${CurTitle} proposé actuellement...</i>
<i>Il n'y a aucun &eacute;change ${CurTitle} propos&eacute; actuellement...</i>
</td>
</tr>
% else:
@@ -284,7 +284,7 @@ ListWrap = ["Co-voiturage",u"Hébergement","Matos"]
</div>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#AccordionCounter" href="#collapseAll">Les compteur de l´évènement</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#AccordionCounter" href="#collapseAll">Les compteurs de l´&eacute;v&eacute;nement</a>
</div>
<div id="collapseAll" class="accordion-body collapse">
<div class="accordion-inner">
@@ -338,7 +338,7 @@ ListWrap = ["Co-voiturage",u"Hébergement","Matos"]
<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 à :
Pour que tout se passe pour le mieux dans l'organisation de l'&eacute;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>


+ 1
- 1
jm2l/templates/NewIndex.mako 查看文件

@@ -2,7 +2,7 @@
<%def name="jsAddOn()">
<script src="/vendor/timeline/js/timeline-src.js"></script>
<script>
var timeline = new VMM.Timeline("timeline", '95%', '500px');
var timeline = new VMM.Timeline("timeline", '95%', '600px');
var c = {language:{ lang:"fr",api:{wikipedia:"fr"},date:{month:["janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"],month_abbr:["janv.","févr.","mars","avril","mai","juin","juil.","août","sept.","oct.","nov.","dec."],day:["Dimanche","Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi"],day_abbr:["Dim.","Lu.","Ma.","Me.","Jeu.","Vend.","Sam."]},dateformats:{year:"yyyy",month_short:"mmm",month:"mmmm yyyy",full_short:"d mmm",full:"d mmmm yyyy",time_short:"HH:MM:SS",time_no_seconds_short:"HH:MM",time_no_seconds_small_date:"HH:MM'<br/><small>'d mmmm yyyy'</small>'",full_long:"dddd',' d mmm yyyy 'à' HH:MM",full_long_small_date:"HH:MM'<br/><small>'dddd',' d mmm yyyy'</small>'"},messages:{loading_timeline:"Chargement de la frise en cours... ",return_to_title:"Retour à la page d'accueil",expand_timeline:"Elargir la frise",contract_timeline:"Réduire la frise",wikipedia:"Extrait de Wikipedia, l'encyclopédie libre",loading_content:"Chargement",loading:"Chargement",swipe_nav:"Swipe to Navigate"}}};
timeline.init(c, "/${year}/timeline-json");
</script>


+ 12
- 12
jm2l/templates/Profil/Profil.mako 查看文件

@@ -23,12 +23,12 @@
<%
DicFormA = {
'nom': {'PlaceHolder':u"Mon Nom", 'ContainerClass':"span6", 'next':False},
'prenom': {'PlaceHolder':u"Mon Prénom", 'ContainerClass':"span6", 'next':True},
'prenom': {'PlaceHolder':u"Mon Pr&eacute;nom", 'ContainerClass':"span6", 'next':True},
'pseudo': {'PlaceHolder':u"Mon Pseudo", 'ContainerClass':"span6", 'next':False},
'mail': {'PlaceHolder':u"mon.mail@fqdn.tld", 'ContainerClass':"span6", 'next':True},
'phone': {'PlaceHolder':u"0612345678", 'ContainerClass':"span6", 'next':False},
'website': {'PlaceHolder':u"http://ma-page-web.moi",'ContainerClass':"span6", 'next':True},
'gpg_key': {'PlaceHolder':u"Ma clé gpg", 'ContainerClass':"span6", 'next':False},
'gpg_key': {'PlaceHolder':u"Ma cl&eacute; gpg", 'ContainerClass':"span6", 'next':False},
'soc_link':{'PlaceHolder':u"#jm2l sur irc.freenode.org",'ContainerClass':"span6", 'next':True},
'bio': {'Ignore':True},
'tiersship': {'Ignore':True},
@@ -52,12 +52,12 @@ DicFormB = {

DicForm2 = {
'nom': {'PlaceHolder':u"Mon Nom", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"},
'prenom': {'PlaceHolder':u"Mon Prénom", "FieldStyle":"width:16em;"},
'prenom': {'PlaceHolder':u"Mon Pr&eacute;nom", "FieldStyle":"width:16em;"},
'pseudo': {'PlaceHolder':u"Mon Pseudo", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"},
'mail': {'PlaceHolder':u"mon.mail@fqdn.tld", "FieldStyle":"width:16em;"},
'phone': {'PlaceHolder':u"0612345678", "FieldStyle":"width:16em;", 'ContainerStyle':"float:left;"},
'website': {'PlaceHolder':u"http://ma-page-web.moi","FieldStyle":"width:16em;"},
'gpg_key': {'PlaceHolder':u"Ma clé gpg", "FieldStyle":"width:90%;"},
'gpg_key': {'PlaceHolder':u"Ma cl&eacute; gpg", "FieldStyle":"width:90%;"},
'soc_link':{'PlaceHolder':u"#jm2l sur irc.freenode.org","FieldStyle":"width:90%;"},
'bio': {'PlaceHolder':u"Ma Bilibiographie", "FieldStyle":"width:95%;min-height:150px;", "fieldset":True, "ckeditor":1 },
'tiersship': {'Ignore':True}
@@ -84,7 +84,7 @@ DicForm2 = {
<dt>Vos identifiants:</dt>
<dd>Nous n'avons pas encore l'information</dd>
</dl>
<a href="https://wifi.unice.fr/">Plus de détails ...</a>
<a href="https://wifi.unice.fr/">Plus de d&eacute;tails ...</a>
</div>
</div>
@@ -92,21 +92,21 @@ DicForm2 = {
${helpers.DisplayRespForm(profil_form, DicFormB)}
<fieldset>
<legend>Activité</legend>
<legend>Activit&eacute;</legend>
<div class="pull-right">
<a href="/entities" class="add btn btn-block btn-mini btn-info"><i class="icon-list-alt icon-white"> </i> La Liste des entités </a>
<a href="/entity" class="add btn btn-block btn-mini btn-primary"><i class="icon-plus-sign icon-white"> </i> Ajouter une entité </a>
<a href="/entities" class="add btn btn-block btn-mini btn-info"><i class="icon-list-alt icon-white"> </i> La Liste des entit&eacute;s </a>
<a href="/entity" class="add btn btn-block btn-mini btn-primary"><i class="icon-plus-sign icon-white"> </i> Ajouter une entit&eacute; </a>
</div>
Saisissez ci-dessous les entités que vous souhaiter représenter pendant l'événement.
Saisissez ci-dessous les entit&eacute;s que vous souhaiter repr&eacute;senter pendant l'&eacute;v&eacute;nement.
(Association, GULL, Entreprise, Logiciel, ...).<br>
Si elle n'existe pas dans la liste proposée, vous pouvez <a href="/entity"> en ajouter une. </a>
Si elle n'existe pas dans la liste propos&eacute;e, vous pouvez <a href="/entity"> en ajouter une. </a>
<div class="repeat">
<table class="wrapper table" width="100%">
<thead>
<tr class="row">
<th style="width:4em;text-align:center;">Année</th>
<th style="width:19em;text-align:center;">Entité</th>
<th style="width:4em;text-align:center;">Ann&eacute;e</th>
<th style="width:19em;text-align:center;">Entit&eacute;</th>
<th style="text-align:center";>Rôle</th>
<th style="width:6em;text-align:center;">Action</th>
</tr>


+ 1
- 1
jm2l/templates/Profil/Sejour.mako 查看文件

@@ -68,7 +68,7 @@ fieldset:disabled {
</li>
<li><label class="checkbox">
<input id="Cov" ${mytrip.IsCheck("Arrival:Cov")|n} name="Arrival:Cov" title="Covoiturage" type="checkbox">
d'un covoiturage, d'un hébergement...<br>(j'ai rempli/je vais remplir la section Logistique).</input></label>
d'un covoiturage, d'un h&eacute;bergement...<br>(j'ai rempli/je vais remplir la section Logistique).</input></label>
</li>
<li><label class="checkbox">
<input id="Bras" ${mytrip.IsCheck("Arrival:Bras")|n} name="Arrival:Bras" title="Bras" type="checkbox">


+ 33
- 28
jm2l/templates/Public/Plan.mako 查看文件

@@ -1,3 +1,4 @@
## -*- coding: utf-8 -*-
<%inherit file="jm2l:templates/layout.mako"/>
<%def name="jsAddOn_head()">
<script src="/vendor/leaflet/js/leaflet.js"></script>
@@ -28,13 +29,13 @@
<h2 class="shadow">Nous rejoindre ou nous joindre...</h2>

<div class="span10 offset1">
<p>Le ${request.registry['event_date']} d’où que vous veniez, tout est mis en place pour que vous
puissiez vous rendre en toute simplicité sur les lieux de l’événement.
<br> N'hésitez pas à utiliser la section covoiturage de votre profil. Et
<p>Le ${request.registry['event_date']}, d'o&ugrave; que vous veniez, tout est mis en place pour que vous
puissiez vous rendre en toute simplicit&eacute; sur les lieux de l'&eacute;v&eacute;nement.
<br> N'h&eacute;sitez pas à utiliser la section covoiturage de votre profil. Et
pas de panique ! Demain, ce sera pire... </p>
<p>
<b>Si vous désirez devenir sponsor</b> de cet événement du libre
merci de prendre contact avec le staff (par mail de préférence) :
<b>Si vous d&eacute;sirez devenir sponsor</b> de cet &eacute;v&eacute;nement du libre
merci de prendre contact avec le staff (par mail de pr&eacute;f&eacute;rence) :
</p>

</div>
@@ -47,7 +48,7 @@
<dd>» #jm2l@irc.freenode.net</dd>
<dt>par Mail</dt>
<dd>» contact at jm2l.linux-azur.org</dd>
<dt>par Téléphone</dt>
<dt>par T&eacute;l&eacute;phone</dt>
<dd>» +33 6 52 42 31 37</dd>
</dl>
</div>
@@ -85,7 +86,7 @@
if (i==1) {
return L.marker(wp.latLng, {
icon: L.divIcon({ className: 'car_place', iconSize: [30, 30] })
}).bindTooltip('Parking P2 (conseillé)', {direction: 'right'})
}).bindTooltip('Parking P2 (conseill&eacute;)', {direction: 'right'})
} else {
return L.marker(wp.latLng).bindTooltip('Suivre Campus Poly\'tech', {direction: 'bottom'});
}
@@ -119,10 +120,14 @@
<div class="tab-content">
<div class="tab-pane fade active in" id="Trsp">
<h3>Bus</h3>
<h4>Depuis Nice (durée&nbsp;: environ 30')&nbsp;:</h4>
<h4> </h4>
<ul>
<li><a href="https://www.maregionsud.fr/uploads/media/tarif_2018.pdf">Les tarifs du coin</a> (pan) </li>
</ul>
<h4>Depuis Nice (dur&eacute;e&nbsp;: environ 30')&nbsp;:</h4>
<ul>
<li>Trajet sur la ligne Nice-Sophia Express&nbsp;:&nbsp;
<a href="https://www.cg06.fr/documents/A-votre-service/Deplacements/transports-en-commun/cg06-transports_lignes_230.pdf">ligne 230</a>
<a href="https://www.departement06.fr/documents/A-votre-service/Deplacements/transports-en-commun/dpt06-transports_230-2017mars.pdf">ligne 230</a>
</li>
<li>Trajet sur la ligne Cagnes-Villeneuve-Biot-Sophia&nbsp;:&nbsp;
<a href="http://www.cg06.fr/document/?f=servir-les-habitants/fr/231.pdf">ligne 231</a>
@@ -133,22 +138,22 @@
<li>Trajet sur la ligne Vence-StPaul-Valbonne-Sophia&nbsp;:&nbsp;
<a href="https://www.cg06.fr/documents/A-votre-service/Deplacements/transports-en-commun/233.pdf">ligne 233</a>
<ul>
<li>Arrivée&nbsp;: descendre à l’arrêt lesTempliers (à 700m à pied) ou IUT (à 150m à pied)</li>
<li>Arriv&eacute;e&nbsp;: descendre à l’arrêt lesTempliers (à 700m à pied) ou IUT (à 150m à pied)</li>
</ul>
</li>
</ul>
<h4>Depuis Cannes (durée&nbsp;: environ 30')&nbsp;:</h4>
<h4>Depuis Cannes (dur&eacute;e&nbsp;: environ 30')&nbsp;:</h4>
<ul>
<li>Trajet sur la ligne Cannes - Sophia Antipolis&nbsp;:&nbsp;
<a href="https://www.cg06.fr/documents/A-votre-service/Deplacements/transports-en-commun/630.pdf">ligne 630</a>
<ul>
<li>Arrivée&nbsp;: descendre à l’arrêt des LesTempliers (à 700m à pied) ou IUT (à 150m à pied)</li>
<li>Arriv&eacute;e&nbsp;: descendre à l’arrêt des LesTempliers (à 700m à pied) ou IUT (à 150m à pied)</li>
</ul>
</li>
</ul>
<h4>Depuis Antibes (durée&nbsp;: entre 10 et 30')&nbsp;:</h4>
<h4>Depuis Antibes (dur&eacute;e&nbsp;: entre 10 et 30')&nbsp;:</h4>
<ul>
<li>Trajet sur la ligne Express (uniquement pour le vendredi)&nbsp;
<a href="http://www.envibus.fr/ligne_detail.asp?id=79&amp;id_commune=1">ligne 100</a>
@@ -162,48 +167,48 @@
<li>Trajet sur la&nbsp;
<a href="http://www.envibus.fr/ligne_detail.asp?id=14&amp;id_commune=1">ligne 11</a>
<ul>
<li>Arrivée&nbsp;: descendre à l’arrêt Les Templiers (à 700m à pied) ou IUT (à 150m à pied)</li>
<li>Arriv&eacute;e&nbsp;: descendre à l’arrêt Les Templiers (à 700m à pied) ou IUT (à 150m à pied)</li>
</ul>
</li>
</ul>
</div>
<div class="tab-pane fade in" id="Avion">
<h3>Avion</h3>
<p>Des lignes régulières desservent l’aéroport de Nice Côte d’Azur
<p>Des lignes r&eacute;gulières desservent l’a&eacute;roport de Nice Côte d’Azur
depuis les grandes villes de France et d’Europe. Depuis Paris,
la Navette Air France a un départ toutes les heures. Un service
la Navette Air France a un d&eacute;part toutes les heures. Un service
de taxis vous conduira à grands frais jusqu’à Polytech’Nice-Sophia.
Pensez à contacter la communauté pour vous éviter ces frais.
Quelqu’un pourra certainement vous récupérer à l’aéroport et
vous amener à Polytech’Nice-Sophia. Autrement, La société&nbsp;
Pensez à contacter la communaut&eacute; pour vous &eacute;viter ces frais.
Quelqu’un pourra certainement vous r&eacute;cup&eacute;rer à l’a&eacute;roport et
vous amener à Polytech’Nice-Sophia. Autrement, La soci&eacute;t&eacute;&nbsp;
<a href="http://www.nice.aeroport.fr/acces_stationnement/bus/recherche.asp?lign_id=%7B3396BEE2-4ED0-4FAF-8E25-2F031FF4FE7E%7D">STCAR</a>&nbsp;
propose une navette reliant l’aéroport de Nice directement à Sophia Antipolis via la navette.
propose une navette reliant l’a&eacute;roport de Nice directement à Sophia Antipolis via la navette.
</p>
<p><a href="http://www.cg06.fr/fr/servir-les-habitants/deplacements/transport-collectifs/lignes-et-horaires/lignes-et-horaires/">Site transports du conseil général.</a></p>
<p><a href="http://www.cg06.fr/fr/servir-les-habitants/deplacements/transport-collectifs/lignes-et-horaires/lignes-et-horaires/">Site transports du conseil g&eacute;n&eacute;ral.</a></p>
<ul>
<li>Départ&nbsp;: Terminal 1 ou 2</li>
<li>Arrivée&nbsp;: descendre à l’arrêt Templiers (700m à pied) ou IUT (à 150m à pied)</li>
<li>D&eacute;part&nbsp;: Terminal 1 ou 2</li>
<li>Arriv&eacute;e&nbsp;: descendre à l’arrêt Templiers (700m à pied) ou IUT (à 150m à pied)</li>
</ul>
</div>
<div class="tab-pane fade in" id="Train">
<h3>Train</h3>
<p>La gare la plus proche est celle d’Antibes. Les&nbsp;
<a href="http://www.envibus.fr/ligne_detail.asp?id=1&amp;id_commune=1#">lignes de bus numéro 1</a>,&nbsp;
<a href="http://www.envibus.fr/ligne_detail.asp?id=79&amp;id_commune=1">ligne de bus numéro 100 (uniquement le vendredi)&nbsp;</a>
<a href="http://www.envibus.fr/ligne_detail.asp?id=1&amp;id_commune=1#">lignes de bus num&eacute;ro 1</a>,&nbsp;
<a href="http://www.envibus.fr/ligne_detail.asp?id=79&amp;id_commune=1">ligne de bus num&eacute;ro 100 (uniquement le vendredi)&nbsp;</a>
vous emmèneront depuis la gare (arret Passerelle SNCF) jusqu’à l’IUT de Sophia Antipolis.
Polytech’Nice-Sophia partage le site avec l’IUT. Suivez les indications sur place.
</p>
<p>
Attention, des perturbations sont à prévoir !
Attention, des perturbations sont à pr&eacute;voir !
</p>
</div>
<div class="tab-pane fade in" id="Voiture">
<h3>Voiture</h3>
<p>Par l’autoroute, prendre la sortie 44 Antibes ou Sophia, selon le sens de circulation.
Prendre direction Sophia Antipolis (la première route à droite après le péage).</p>
Prendre direction Sophia Antipolis (la première route à droite après le p&eacute;age).</p>
<p>Au rond point en bas de la Route des Chappes, suivre ensuite la direction Sophia Tech.</p>
<p><a href="http://wiki.linux-azur.org/PlanJm2L">http://wiki.linux-azur.org/PlanJm2L</a></p>
<p>Un&nbsp;<strong>flêchage de l’itinéraire</strong>&nbsp;noir sur fond jaune ou orange -
<p>Un&nbsp;<strong>flêchage de l’itin&eacute;raire</strong>&nbsp;noir sur fond jaune ou orange -
JM2L - est en place pour vous guider à partir de la sortie 44 de l’autoroute A8.
</p>
<p>Pensez aussi au co-voiturage&nbsp;:-)&nbsp;


+ 1
- 1
jm2l/templates/Public/Presse.mako 查看文件

@@ -6,7 +6,7 @@ DisplayYear = request.session.get('year',CurrentYear)
% if request.user and request.user.Staff:
<a href="dossier-de-presse/edit">Modifier</a><br>
% endif
<h2 class="shadow">Communiqué de presse ${DisplayYear}</h2>
<h2 class="shadow">Communiqu&eacute; de presse ${DisplayYear}</h2>
<div class="row-fluid">
<div class="span8 offset1">
% if content and content.doss_presse:


+ 0
- 17
jm2l/templates/Public/Programme.mako 查看文件

@@ -21,7 +21,6 @@ TabDisplay = [
}
.SvgBody {
padding: 0px;
/* background-color: transparent; */
}
.EvtBox {
font-size: 0.7em;
@@ -97,16 +96,6 @@ Counter = Events.filter(Event.event_type==EvtType).count()
if Counter==0:
continue
%>

## <div class="accordion-group">
## <div class="accordion-heading">
## <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordionEvent" href="#collapseEvent${num}">
## ${Counter} ${Title}
## </a>
## </div>
## <div id="collapseEvent${num}" class="accordion-body collapse">
## <div class="accordion-inner">

<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
@@ -159,13 +148,7 @@ if Counter==0:
% endfor
</tbody>
</table>
## </div>
## </div>
## </div>
% endfor
##</div>

</div>
</div>

+ 2
- 2
jm2l/templates/Salles/list.mako 查看文件

@@ -37,7 +37,7 @@ from slugify import slugify
% if len(DicSalle[Entity])==0:
<tr>
<td style="text-align:center;">
<i>Il n'y a pas de salle définie pour l'année ${Entity.year_uid}</i>
<i>Il n'y a pas de salle d&eacute;finie pour l'ann&eacute;e ${Entity.year_uid}</i>
</td>
</tr>
% endif
@@ -54,7 +54,7 @@ from slugify import slugify
% if Salle.phy_salle_id:
[ <a href="/PhySalles/${Salle.phy_salle_id}">${Salle.phy.name}</a> ${Salle.phy.nb_places} places ]
% else:
[ <a href="/PhySalles">Créer</a> ]
[ <a href="/PhySalles">Cr&eacute;er</a> ]
% endif
</div>
</td>


+ 2
- 2
jm2l/templates/Salles/list_phy.mako 查看文件

@@ -24,7 +24,7 @@ from slugify import slugify
% if len(DicSallePhy)==0:
<tr>
<td style="text-align:center;">
<i>Il n'y a pas de salle définie pour le moment.</i>
<i>Il n'y a pas de salle d&eacute;finie pour le moment.</i>
</td>
</tr>
% endif
@@ -43,7 +43,7 @@ from slugify import slugify
% if SallePhy.uid:
[ ${SallePhy.nb_places} places ]
% else:
[ <a href="/PhySalles">Créer</a> ]
[ <a href="/PhySalles">Cr&eacute;er</a> ]
% endif
</div>



+ 2
- 2
jm2l/templates/Salles/salle.mako 查看文件

@@ -29,9 +29,9 @@
%endif
<%
DicForm = {
'year_uid': {'PlaceHolder':u"Année", "FieldStyle":"width:7em;", "ContainerStyle":"float:left;" },
'year_uid': {'PlaceHolder':u"Ann&eacute;e", "FieldStyle":"width:7em;", "ContainerStyle":"float:left;" },
'phy_salle_id': {'PlaceHolder':u"Salle Physique", "FieldStyle":"width:20em;", "ContainerStyle":"float:left;" },
'place_type': {'PlaceHolder':u"Type d'évènement","FieldStyle":"width:15em;" },
'place_type': {'PlaceHolder':u"Type d'&eacute;vènement","FieldStyle":"width:15em;" },
'name': {'PlaceHolder':u"Nom de la salle", "FieldStyle":"width:90%;" },
'description': {'PlaceHolder':u"Description", "ContainerStyle":"width:95%;min-height:150px;padding-top: 12px;", "ckeditor":"1" },
}


+ 1
- 1
jm2l/templates/Staff/compta.mako 查看文件

@@ -42,7 +42,7 @@
% if len(found)==0:
<tr>
<td colspan="3" style="text-align:center;">
<i>Aucun justificatif trouvé</i>
<i>Aucun justificatif trouv&eacute;</i>
</td>
</tr>
% endif


+ 2
- 2
jm2l/templates/Staff/list.mako 查看文件

@@ -4,7 +4,7 @@
from slugify import slugify
%>
<a style="float:right;" class="btn btn-mini btn-info" role="button" href="/${year}/Staff/poles">
<i class="icon-plus-sign icon-white"></i> Ajouter un Pôle d'activité
<i class="icon-plus-sign icon-white"></i> Ajouter un Pôle d'activit&eacute;
</a>
<h3>Liste des tâches JM2L Staff</h3>

@@ -70,7 +70,7 @@ from slugify import slugify
<td style="position: relative;width:70px;">
<div class="actions">
% if task.closed:
[ <a href="/${year}/Staff/open/${task.uid}">ré-ouvrir</a> ]
[ <a href="/${year}/Staff/open/${task.uid}">r&eacute;-ouvrir</a> ]
% else:
[ <a href="/${year}/Staff/close/${task.uid}">c'est fait</a> ]
% endif


+ 4
- 4
jm2l/templates/helpers.mako 查看文件

@@ -142,7 +142,7 @@ TabJs = {'select':[], 'desc':[]}
<%def name="sejour_wrapper(Places)">

<div class="form-inline">
Départ :
D&eacute;part :
<select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
% for place in Places:
<option value="${place.place_id}">${place.display_name}</option>
@@ -151,7 +151,7 @@ TabJs = {'select':[], 'desc':[]}
</div>
<br />
<div class="form-inline">
Arrivée :
Arriv&eacute;e :
<select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
% for place in Places:
<option value="${place.place_id}">${place.display_name}</option>
@@ -184,7 +184,7 @@ TabJs = {'select':[], 'desc':[]}
${itin_form.arrival_place(style='width:17em;')}
</div>
<div style="padding:5px;">
<small style="color:#999">Si je n´ai pas trouvé le lieu dont j´ai besoin dans ces listes...</small>
<small style="color:#999">Si je n´ai pas trouv&eacute; le lieu dont j´ai besoin dans ces listes...</small>
<br />
<small style="color:#999">Je peux </small>
<a class="btn btn-mini btn-info" role="button" href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/0');">
@@ -352,7 +352,7 @@ TabJs = {'select':[], 'desc':[]}
% if NotFoundTitle:
<i>${NotFoundTitle}</i>
% else:
<i>Désolé, Il n'y a rien dans l'historique.</i>
<i>D&eacute;sol&eacute;, Il n'y a rien dans l'historique.</i>
% endif
</td>
</tr>


+ 1
- 1
jm2l/templates/index.mako 查看文件

@@ -1,6 +1,6 @@
<%inherit file="jm2l:templates/layout.mako"/>
<p>
Pour que l'&eacute;venement JM2L 2017 se passe dans les meilleures conditions
Pour que l'&eacute;venement JM2L context._kwargs['CurrentYear'] se passe dans les meilleures conditions
possible.
Il s'agit ici pour toi de te connecter et de compl&eacute;ter les formulaires,
d'essayer de les tenir à jour au fur et à meusure, de les compl&eacute;ter


+ 5
- 5
jm2l/templates/jm2l.mako 查看文件

@@ -79,7 +79,7 @@
<div class="tabbable tabs-left" id="Interventions_tab">
<ul class="nav nav-tabs navbar" style="margin-bottom:0;">
<li class="active"> <a href="#ResumePart" data-toggle="tab">Resumé</a> </li>
<li class="active"> <a href="#ResumePart" data-toggle="tab">Resum&eacute;</a> </li>
<li> <a href="#Conference" data-toggle="tab">Conf&eacute;rence</a> </li>
<li> <a href="#Stand" data-toggle="tab">Stand</a> </li>
<li> <a href="#Atelier" data-toggle="tab">Atelier</a> </li>
@@ -118,12 +118,12 @@
<div class="tab-pane fade" id="Frais">
<fieldset>
<legend class="lowshadow">Une participation à mes frais ?</legend>
L'équipe des JM2L participe aux <u>frais de transport</u> des intervenants !<br /><br />
L'&eacute;quipe des JM2L participe aux <u>frais de transport</u> des intervenants !<br /><br />
Et bien oui, mais cette participation ne sera effective que si vous remplissez <u>toutes les conditions</u> suivantes:
<ul style="list-style:circle;">
<li>Vous animez <strong>un atelier, une conférence ou une table ronde</strong> aux JM2L ${CurrentYear}.</li>
<li>Votre fiche est renseignée avec <strong>votre RIB</strong>.</li>
<li>Votre fiche est renseignée avec <strong>les preuves</strong> de vos achats.</li>
<li>Vous animez <strong>un atelier, une conf&eacute;rence ou une table ronde</strong> aux JM2L ${CurrentYear}.</li>
<li>Votre fiche est renseign&eacute;e avec <strong>votre RIB</strong>.</li>
<li>Votre fiche est renseign&eacute;e avec <strong>les preuves</strong> de vos achats.</li>
<li>Vous <strong>présentez l'original de vos tickets</strong> à l'accueil pendant l'évènement.</li>
<li>Tous vos documents sont conformes.</li>
</ul>


+ 9
- 14
jm2l/templates/layout.mako 查看文件

@@ -1,8 +1,12 @@
<!DOCTYPE html>
<html>
<%namespace name="helpers" file="jm2l:templates/helpers.mako"/>
<%
context._kwargs['postpone_js']=[]
DisplayYear = request.session.get('year', 2018)
%>
<head>
<title>JM2L 2017</title>
<title>JM2L ${DisplayYear}</title>
<meta charset="utf-8">
<meta name="keywords" content="python web application" />
<meta name="description" content="jm2l LinuxAzur journée méditéranéenne logiciel libre" />
@@ -26,10 +30,6 @@
${self.jsAddOn_head()}
</head>
<body>
<%
context._kwargs['postpone_js']=[]
DisplayYear = request.session.get('year', 2017)
%>
<%def name="jsAddOn_head()"></%def>
<%def name="jsAddOn()"></%def>
<%def name="cssAddOn()"></%def>
@@ -39,7 +39,7 @@ ${helpers.uploader_js()}
<div id="top">
% if DisplayYear!=2017:
<div class="align-center" style="background: url( ${'/img/%s/headerbg.png' % DisplayYear} ) repeat-x scroll 0 top #ffffff;">
<a href="${"/%s/" % DisplayYear}">
<a href="${'/%s/' % DisplayYear}">
<div style="height:215px;background: url( ${"/img/%s/logo.png" % DisplayYear} ) no-repeat scroll center center transparent">
</div>
</a>
@@ -69,11 +69,11 @@ ${helpers.uploader_js()}
<div class="item active">
<div class="align-center">
<H1>JM2L 2017</H1>
<h3>Choisissez ici votre logo préféré !</h3>
<h3>Choisissez ici votre logo pr&eacute;f&eacute;r&eacute; !</h3>
<p>Utilisez les flèches pour choisir et voter !<br>
Vous pouvez changer à tout moment, mais vous n'aurez droit qu'a un seul choix, le vôtre ;)</p>
<p>Vous souhaitez proposer le vôtre ? <br>
N'hésitez pas à envoyer vos propositions par mail à l'équipe !</p>
N'h&eacute;sitez pas à envoyer vos propositions par mail à l'&eacute;quipe !</p>
</div>
</div>
% endif
@@ -141,11 +141,6 @@ ${helpers.uploader_js()}
<li><a href="/participer-l-evenement#inscription">Je m'inscris</a></li>
<li><a href="/sign/login">Je m'identifie</a></li>
% endif
## <li>Mode
## <span class="visible-phone"> ✔ Phone</span>
## <span class="visible-tablet"> ✔ Tablet</span>
## <span class="visible-desktop"> ✔ Desktop</span>
## </li>
</ul>
</div>
</div>
@@ -189,7 +184,7 @@ ${helpers.uploader_js()}

<footer class="footer">
<div class="container">
<h4>JM2L 2005-2017</h4>
<h4>JM2L 2005-2018</h4>
<p>
Concoct&eacute; par <a href="http://www.linux-azur.org/">Linux Azur</a> ~
<a href="http://creativecommons.org/licenses/by-sa/4.0/">CopyFriendly</a>


+ 3
- 3
jm2l/templates/modals.mako 查看文件

@@ -109,7 +109,7 @@
%else:
<div class="alert">
<button type="button" class="close" data-dismiss="alert">&times;</button>
<strong>Non disponible!</strong> Vous devez d'abord compléter le champ GPS pour activer cette fonctionnalité.
<strong>Non disponible!</strong> Vous devez d'abord compl&eacute;ter le champ GPS pour activer cette fonctionnalit&eacute;.
</div>
%endif
@@ -147,7 +147,7 @@
<div class="modal-body">
<div>
<i class="icon-question-sign"></i>
Les images de taille supérieure à 300x300 pixels seront redimensionnés.
Les images de taille sup&eacute;rieure à 300x300 pixels seront redimensionn&eacute;s.
</div>
${helpers.uploader("users", uid, "une Photo")}
</div>
@@ -174,7 +174,7 @@
${ helpers.DisplayForm(form, {}) }

<div id="pswd_info" style="display: block;">
Pour renforcer la sécurité de votre mot de passe :
Pour renforcer la s&eacute;curit&eacute; de votre mot de passe :
<ul>
<li id="length" class="invalid">Saisissez au moins 6 caractères</li>
<li id="ltrMin" class="invalid">Ajoutez des lettres minuscules</li>


+ 1
- 0
jm2l/templates/view_event.mako 查看文件

@@ -35,6 +35,7 @@
</div>
</div>
<hr/>
<hr/>
% if event.presentation.count() and event.video.count():
<div class="row-fluid">
<div id="pres" class="span6">


+ 1
- 1
jm2l/templates/view_tiers.mako 查看文件

@@ -70,7 +70,7 @@ ${The_entity_type.entity_subtype}
</div>
% endfor
% endif
% for iterv in entity.members:
% for iterv in entity.members[::-1]:
<p>
<div class="titleborderbox">
Intervenant <strong><a href="/user/${iterv.slug}">${iterv.prenom} ${iterv.nom}</a></strong>.


+ 2
- 1
jm2l/upload.py 查看文件

@@ -504,7 +504,8 @@ class MediaUpload(MediaPath):
result['size'] = self.get_file_size(fieldStorage.file)

if self.validate(result, fieldStorage.file):
local_filename = slugify( result['name'] )
filename, file_extension = os.path.splitext( result['name'] )
local_filename = slugify( filename ) + file_extension
# Keep mime-type in .type file
with open( self.mediapath( local_filename ) + '.type', 'w') as f:
f.write(result['type'])


+ 46
- 111
jm2l/views.py 查看文件

@@ -22,6 +22,7 @@ from icalendar import Calendar
from pytz import timezone
from icalendar import Event as Evt
from pyramid_mailer.message import Message
from security import check_staff, check_logged
# Then, standard libs
import csv
import cStringIO as StringIO
@@ -289,7 +290,21 @@ def JSON_TimeLine_Request(request):
"credit": ",".join(["%s %s" % (i.prenom, i.nom) for i in ev.intervenants]),
"caption":"" }
} )
if year==2017:
if year==2018:
DicResult = {
"lang":"fr",
"headline":"JM2L 2018",
"type":"default",
"startDate":"2018,12,15,10",
"text":"<i><span class='c1'>11ème Édition</span></i>",
"asset":
{
"media":embeed_video("video/ogg","/resources/2017/Video/JM2L2017_Reportage_FR3.ogv"),
"credit":"Reportage France 3",
"caption":"JM2L 2018"
}
}
elif year==2017:
DicResult = {
"lang":"fr",
"headline":"JM2L 2017",
@@ -298,7 +313,8 @@ def JSON_TimeLine_Request(request):
"text":"<i><span class='c1'>10ème Édition</span></i>",
"asset":
{
"media":embeed_video("video/ogg","/resources/2017/Video/JM2L2017_Reportage_FR3.ogv"),
#"media":"https://www.youtube.com/watch?v=91X65eEKxvU&t=6s",
"media":embeed_video("video/ogg","/resources/2017/Video/JM2L2017_Reportage_PleinSud.ogv"),
"credit":"Reportage France 3",
"caption":"JM2L 2017"
}
@@ -391,6 +407,8 @@ def index_page(request):
return {'year': year, 'content':content, 'edition':u"9<sup>ème</sup>" }
elif year==2017:
return {'year': year, 'content':content, 'edition':u"10<sup>ème</sup>" }
elif year==2018:
return {'year': year, 'content':content, 'edition':u"11<sup>ème</sup>" }
else:
edition = year - 2005
return {'year': year, 'content':content, 'edition':u"%d<sup>ème</sup>" % edition }
@@ -404,14 +422,12 @@ def index_page(request):
ListPhotos = map(lambda x: TargetUrl + x, listdir(TargetDir))
else:
ListPhotos = []
return {'year': CurrentYear, 'content':content, 'edition':u"10<sup>ème</sup>", 'ListPhotos': ListPhotos}
return {'year': CurrentYear, 'content':content, 'edition':u"11<sup>ème</sup>", 'ListPhotos': ListPhotos}

@view_config(route_name='edit_index', renderer="jm2l:templates/Staff/EditIndex.mako")
def edit_index(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
form = IndexForm(request.POST, content, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
@@ -437,7 +453,7 @@ def programme(request):
ListDay = []
for day in Days:
RefDay = datetime.datetime.strptime(day[0],'%d-%m-%Y')
ListDay.append( ( RefDay.strftime('%A %d %b %Y'),
ListDay.append( ( RefDay.strftime('%A %d %b %Y').decode('utf-8'),
RefDay.strftime('%d') ) )
MainTab = {'programme':'active','DisplayYear':year, \
'Events':Events, 'Event':Event, 'Days':ListDay, "logged_in":request.authenticated_userid }
@@ -452,13 +468,8 @@ def static_presse(request):

@view_config(route_name='edit_presse', renderer="jm2l:templates/Staff/EditPresse.mako")
def edit_presse(request):
check_staff(request)
year = int(request.matchdict.get('year', None))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
content = DBSession.query(JM2L_Year).filter(JM2L_Year.year_uid==year).first()
form = DossPresse(request.POST, content, meta={'csrf_context': request.session})
if request.method == 'POST' and form.validate():
@@ -477,13 +488,8 @@ def static_plan(request):
## =-=- Here, We handle HTTP requests - Staff Logged Part -=-=
@view_config(route_name='list_task', renderer='jm2l:templates/Staff/list.mako')
def list_view(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
DicTask = {}
taskgroup = DBSession.query( TasksArea ).filter( TasksArea.year_uid == year).all()
for grp in taskgroup:
@@ -497,14 +503,8 @@ def list_view(request):

@view_config(route_name='list_expenses', renderer='jm2l:templates/Staff/compta.mako')
def expenses(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')

output = []
dic_out = {}
for name in glob.glob('jm2l/upload/images/users/*/RIB/*'):
@@ -570,13 +570,8 @@ def expenses(request):

@view_config(route_name='handle_task', renderer='jm2l:templates/Staff/tasks.mako')
def tasks(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
task_id = request.matchdict.get('task_id')
# Convert the pole_id GET parameter to int or 0
if request.params.get('pole_id') and request.params.get('pole_id').isdigit():
@@ -631,13 +626,8 @@ def tasks(request):

@view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako')
def tasks_area(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
pole_id = request.matchdict.get('pole_id')
if pole_id:
Pole = TasksArea.by_id(int(pole_id))
@@ -660,13 +650,8 @@ def tasks_area(request):

@view_config(route_name='action_task')
def action_task(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
action = request.matchdict.get('action')
task_id = request.matchdict.get('task_id')
Task = Tasks.by_id(int(task_id))
@@ -685,13 +670,8 @@ def action_task(request):

@view_config(route_name='action_task_area')
def action_task_area(request):
check_staff(request)
year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
action = request.matchdict.get('action')
pole_id = request.matchdict.get('pole_id')
Pole = TasksArea.by_id(int(pole_id))
@@ -704,12 +684,7 @@ def action_task_area(request):

@view_config(route_name='list_salles', renderer='jm2l:templates/Salles/list.mako')
def list_salles(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
check_staff(request)
DicSalle = {}
years = DBSession.query( JM2L_Year ).all()
for year in years:
@@ -722,12 +697,7 @@ def list_salles(request):

@view_config(route_name='list_salles_phy', renderer='jm2l:templates/Salles/list_phy.mako')
def list_salles_phy(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
check_staff(request)
salles_phy = DBSession.query( SallePhy )\
.order_by(SallePhy.name).all()
return {'DicSallePhy': salles_phy }
@@ -735,12 +705,7 @@ def list_salles_phy(request):

@view_config(route_name='handle_salle', renderer='jm2l:templates/Salles/salle.mako')
def handle_salle(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
check_staff(request)
salle_id = request.matchdict.get('salle_id')
if salle_id:
Salle = Salles.by_id(int(salle_id))
@@ -750,7 +715,7 @@ def handle_salle(request):
else:
Salle = Salles()
form = SalleForm(request.POST, Salle, meta={'csrf_context': request.session})
form.year_uid.choices = map(tuple, DBSession.query(JM2L_Year.year_uid, JM2L_Year.year_uid).all())
form.year_uid.choices = map(tuple, DBSession.query(JM2L_Year.year_uid, JM2L_Year.year_uid).order_by(sa.desc(JM2L_Year.year_uid)).all())
form.phy_salle_id.choices = map(tuple, DBSession.query(SallePhy.uid, SallePhy.name).all())
if request.method == 'POST' and form.validate():
form.populate_obj(Salle)
@@ -763,12 +728,7 @@ def handle_salle(request):

@view_config(route_name='handle_salle_phy', renderer='jm2l:templates/Salles/salle_phy.mako')
def handle_salle_phy(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
check_staff(request)
salle_id = request.matchdict.get('salle_id')
if salle_id:
Salle = SallePhy.by_id(int(salle_id))
@@ -802,12 +762,7 @@ def handle_salle_phy(request):
@view_config(route_name='action_salle')
def action_salle(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
check_staff(request)
action = request.matchdict.get('action')
salle_id = request.matchdict.get('salle_id')
Salle = Salles.by_id(int(salle_id))
@@ -870,10 +825,7 @@ def exchange(request):

@view_config(route_name='miam')
def miam(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
check_logged(request)
miam_form = MiamForm(request.POST, request.user, meta={'csrf_context': request.session})
if request.method == 'POST' and miam_form.validate():
FicheSejour = Sejour.by_user(request.user.uid, CurrentYear)
@@ -904,9 +856,7 @@ def miam(request):

@view_config(route_name='sejour')
def sejour(request):
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
check_logged(request)
if request.method == 'POST':
FicheSejour = Sejour.by_user(request.user.uid, CurrentYear)
if FicheSejour:
@@ -953,9 +903,7 @@ def sejour(request):

@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.')
check_logged(request)
if request.method == 'POST':
FicheSejour = Sejour.by_user(request.user.uid, CurrentYear)
UpdateOrga=False
@@ -1013,13 +961,8 @@ def vote_logo(request):

@view_config(route_name='list_users_csv', renderer="string")
def list_users_csv(request):
check_staff(request)
for_year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')

stmt = (DBSession.query(Sejour).filter(Sejour.for_year==for_year)).subquery()
# stmt_event = (DBSession.query(User_Event).filter()
adalias = aliased(Sejour, stmt)
@@ -1049,13 +992,8 @@ def list_users_csv(request):

@view_config(route_name='list_users', renderer="jm2l:templates/Participant/list_users.mako")
def list_users(request):
check_staff(request)
for_year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')

stmt = (DBSession.query(Sejour).filter(Sejour.for_year==for_year)).subquery()
adalias = aliased(Sejour, stmt)
Data = DBSession.query(User, adalias ) \
@@ -1077,12 +1015,8 @@ def list_users(request):

@view_config(route_name='list_orga', renderer="jm2l:templates/Participant/list_orga.mako")
def list_orga(request):
check_staff(request)
for_year = int(request.matchdict.get('year', CurrentYear))
if request.user is None:
# Don't answer to users that aren't logged
raise HTTPForbidden(u'Vous devez vous identifier pour obtenir une réponse.')
if not request.user.Staff:
raise HTTPForbidden(u'Vous n\'avez pas l\'autorité suffisante pour effectuer cette action.')
Data = DBSession.query(User, Sejour)\
.outerjoin(Sejour)\
.filter(Sejour.for_year == for_year)\
@@ -1630,7 +1564,7 @@ def edit_event(request):
if not TheYear:
raise HTTPNotFound(u"Cette année n'est pas pris en charge")
# Generate Timeslots for current year
TimeSlots = list(enumerate( [ x.strftime('%a %d %b %H:%M') for x in
TimeSlots = list(enumerate( [ x.strftime('%a %d %b %H:%M').decode('utf-8') for x in
TheYear.AvailableTimeSlots ] ))

if event_id:
@@ -1651,7 +1585,7 @@ def edit_event(request):
start_sel = TheYear.AvailableTimeSlots.index(TheEvent.start_time)
else:
start_sel = len(TimeSlots)
TimeSlots.append( (len(TimeSlots), TheEvent.start_time.strftime('%a %d %b %H:%M')))
TimeSlots.append( (len(TimeSlots), TheEvent.start_time.strftime('%a %d %b %H:%M').decode('utf-8')))
duration = (TheEvent.end_time - TheEvent.start_time).total_seconds()/60
end = TheEvent.start_time + datetime.timedelta(minutes=duration)
# prepare the form with update
@@ -1940,7 +1874,8 @@ def edit_tiers(request):
# 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.'))
request.session.flash(('warning',u'Attention, Choisissez un autre titre pour votre entitée,'
u'elle est en conflit avec une autre.'))
DBSession.rollback()
return HTTPFound(location=request.route_url('edit_entity', sep='/',
entity_id=str(OriginalSlug), tiers_type=TheTiers.get_entity_type.entity_type))


Loading…
取消
儲存