Compare commits

3 Commits

Author SHA1 Message Date
tr4ck3ur 2b3e8116d5 Fixing python3 issues 2020-08-08 17:02:12 +02:00
tr4ck3ur 588ce76eee Misc Fixes 2020-08-08 01:17:55 +02:00
tr4ck3ur ad9883ae09 Migration to python 3 2020-07-26 17:38:55 +02:00
41 changed files with 2452 additions and 2229 deletions
+11
View File
@@ -36,3 +36,14 @@ If no error occurs, the webserver should be available on http://localhost:8080/
pserve development.ini
Enjoy !
sudo apt install virtualenv git python3-virtualenv imagemagick
sudo mkdir -p /srv/jm2l
cd /srv/jm2l/
cd /srv
sudo chown luna jm2l
cd jm2l/
virtualenv -p python3 .venv_jm2l
-1
View File
@@ -15,7 +15,6 @@ pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_mailer.testing
pyramid_debugtoolbar
pyramid_tm
pyramid_mako
+15 -8
View File
@@ -4,9 +4,11 @@ except ImportError:
from cgi import escape
# from wtforms import widgets
from wtforms.widgets import HTMLString, html_params
from wtforms.widgets import html_params
from wtforms.fields.core import Field
from wtforms.compat import text_type, izip
from markupsafe import Markup
class MySelect(object):
"""
@@ -19,6 +21,7 @@ class MySelect(object):
call on rendering; this method must yield tuples of
`(value, label, selected)`.
"""
def __init__(self, multiple=False):
self.multiple = multiple
@@ -40,7 +43,7 @@ class MySelect(object):
if last_group:
html.append(self.render_optgroup(last_group, None))
html.append('</select>')
return HTMLString(''.join(html))
return Markup(''.join(html))
@classmethod
def render_option(cls, value, label, selected, **kwargs):
@@ -51,17 +54,19 @@ class MySelect(object):
options = dict(kwargs, value=value)
if selected:
options['selected'] = True
return HTMLString('<option %s>%s</option>' % (html_params(**options), escape(text_type(label), quote=False)))
return Markup('<option %s>%s</option>' % (html_params(**options), escape(text_type(label), quote=False)))
@classmethod
def render_optgroup(cls, previous_label, label, **kwargs):
options = dict(kwargs)
if previous_label is None:
return HTMLString('<optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))
return Markup(
'<optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))
elif label is None:
return HTMLString('</optgroup>')
return Markup('</optgroup>')
else:
return HTMLString('</optgroup><optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))
return Markup(
'</optgroup><optgroup %s label="%s">' % (html_params(**options), escape(text_type(label), quote=False)))
class MyOption(object):
@@ -71,6 +76,7 @@ class MyOption(object):
This is just a convenience for various custom rendering situations, and an
option by itself does not constitute an entire field.
"""
def __call__(self, field, **kwargs):
return MySelect.render_option(field._value(), field.label.text, field.checked, **kwargs)
@@ -85,6 +91,7 @@ class MySelectFieldBase(Field):
This isn't a field, but an abstract base class for fields which want to
provide this functionality.
"""
def __init__(self, label=None, validators=None, option_widget=None, **kwargs):
super(MySelectFieldBase, self).__init__(label, validators, **kwargs)
@@ -128,11 +135,11 @@ class MySelectField(MySelectFieldBase):
# We should consider choiceA as an optgroup label
group_label = choiceA
for value, label in choiceB:
yield (group_label, value, label, self.coerce(value) == self.data)
yield group_label, value, label, self.coerce(value) == self.data
else:
value, label = choiceA, choiceB
# Not an optgroup, let's fallback to classic usage
yield (None, value, label, self.coerce(value) == self.data)
yield None, value, label, self.coerce(value) == self.data
def process_data(self, value):
try:
+60 -57
View File
@@ -19,47 +19,49 @@ from pyramid.request import Request
from mako.template import Template
from .models import User
from jm2l.const import CurrentYear
from models import JM2L_Year
from .models import JM2L_Year
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)
# @sched.scheduled_job('cron', day_of_week='sun', hour=22, minute=7)
def mailer_tasks(config):
# Send the Welcome Mail
mailer = config.registry['mailer']
Contact = DBSession.query(User).filter(User.uid==1).one()
contact = DBSession.query(User).filter(User.uid == 1).one()
request = Request.blank('/', base_url='http://jm2l.linux-azur.org')
request.registry = config.registry
for StaffUser in DBSession.query(User).filter(User.Staff == True):
for staff_user in DBSession.query(User).filter(User.Staff is True):
# Skip mail to contact
if StaffUser==Contact:
if staff_user == contact:
continue
# Skip those that have no task assigned
if len(filter(lambda k:not k.closed, StaffUser.task_assoc))==0:
if len(filter(lambda k: not k.closed, staff_user.task_assoc)) == 0:
continue
# Prepare Plain Text Message :
Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks")
mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = mail_template.render(request=request, User=staff_user, Contact=contact, action="Tasks")
# Prepare HTML Message :
Mail_template = Template(filename='jm2l/templates/mail_html.mako')
mail_html = Mail_template.render(request=request, User=StaffUser, Contact=Contact, action="Tasks")
mail_template = Template(filename='jm2l/templates/mail_html.mako')
mail_html = mail_template.render(request=request, User=staff_user, Contact=contact, action="Tasks")
# Prepare Message
message = Message(subject="[JM2L] Le mail de rappel pour les JM2L !",
sender="contact@jm2l.linux-azur.org",
recipients=[StaffUser.mail],
recipients=[staff_user.mail],
body=mail_plain, html=mail_html)
message.add_bcc("spam@style-python.fr")
mailer.send_immediately(message)
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
@@ -79,8 +81,11 @@ def main(global_config, **settings):
authentication_policy=authentication_policy,
authorization_policy=authorization_policy
)
#config.include('pyramid_mailer')
config.include('pyramid_mailer.debug')
config.add_subscriber(add_renderer_globals, BeforeRender)
config.registry['mailer'] = mailer_factory_from_settings(settings)
print(settings)
# config.registry['mailer'] = mailer_factory_from_settings(settings)
config.registry['event_date'] = JM2L_Year.get_latest_jm2l_startdate()
sched = BackgroundScheduler()
sched.add_job(mailer_tasks, 'cron', day_of_week='fri', hour=18, args=[config])
@@ -100,70 +105,70 @@ def main(global_config, **settings):
config.add_static_view('resources', 'resources', cache_max_age=3600)
# ICal Routes
config.add_route('progr_iCal', '/{year:\d+}/JM2L.ics')
config.add_route('progr_dyn_iCal', '/{year:\d+}/JM2L_dyn.ics')
config.add_route('progr_iCal', r'/{year:\d+}/JM2L.ics')
config.add_route('progr_dyn_iCal', r'/{year:\d+}/JM2L_dyn.ics')
# JSON Routes
config.add_route('users_json', '/json-users')
config.add_route('tiers_json', '/json-tiers')
config.add_route('progr_json', '/{year:\d+}/le-prog-json')
config.add_route('timeline_json', '/{year:\d+}/timeline-json')
config.add_route('progr_json', r'/{year:\d+}/le-prog-json')
config.add_route('timeline_json', r'/{year:\d+}/timeline-json')
# Session setting Routes
config.add_route('year', '/year/{year:\d+}')
config.add_route('vote_logo', '/vote_logo/{num:\d+}')
config.add_route('year', r'/year/{year:\d+}')
config.add_route('vote_logo', r'/vote_logo/{num:\d+}')
# HTML Routes - Staff
config.add_route('Live', '/Live')
config.add_route('list_expenses', '/{year:\d+}/Staff/compta')
config.add_route('list_task', '/{year:\d+}/Staff')
config.add_route('handle_pole', '/{year:\d+}/Staff/poles{sep:/*}{pole_id:(\d+)?}')
config.add_route('handle_task', '/{year:\d+}/Staff/tasks{sep:/*}{task_id:(\d+)?}')
config.add_route('action_task', '/{year:\d+}/Staff/{action:(\w+)}/{task_id:(\d+)}')
config.add_route('action_task_area', '/{year:\d+}/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}')
config.add_route('list_expenses', r'/{year:\d+}/Staff/compta')
config.add_route('list_task', r'/{year:\d+}/Staff')
config.add_route('handle_pole', r'/{year:\d+}/Staff/poles{sep:/*}{pole_id:(\d+)?}')
config.add_route('handle_task', r'/{year:\d+}/Staff/tasks{sep:/*}{task_id:(\d+)?}')
config.add_route('action_task', r'/{year:\d+}/Staff/{action:(\w+)}/{task_id:(\d+)}')
config.add_route('action_task_area', r'/{year:\d+}/Staff/pole/{action:(\w+)}/{pole_id:(\d+)}')
config.add_route('list_salles', '/ListSalles')
config.add_route('list_salles_phy', '/ListSallesPhy')
config.add_route('handle_salle', '/Salles{sep:/*}{salle_id:(\d+)?}')
config.add_route('handle_salle_phy', '/PhySalles{sep:/*}{salle_id:(\d+)?}')
config.add_route('action_salle', '/Salles/{action:(\w+)}/{salle_id:(\d+)}')
config.add_route('pict_salle', '/salle_picture/{salle_id:(\d+)}')
config.add_route('handle_salle', r'/Salles{sep:/*}{salle_id:(\d+)?}')
config.add_route('handle_salle_phy', r'/PhySalles{sep:/*}{salle_id:(\d+)?}')
config.add_route('action_salle', r'/Salles/{action:(\w+)}/{salle_id:(\d+)}')
config.add_route('pict_salle', r'/salle_picture/{salle_id:(\d+)}')
config.add_route('list_users', '/{year:\d+}/ListParticipant')
config.add_route('list_users_csv', '/{year:\d+}/ListParticipant.csv')
config.add_route('list_orga', '/{year:\d+}/ListOrga')
config.add_route('list_users', r'/{year:\d+}/ListParticipant')
config.add_route('list_users_csv', r'/{year:\d+}/ListParticipant.csv')
config.add_route('list_orga', r'/{year:\d+}/ListOrga')
# HTML Routes - Public
config.add_route('home', '/{year:(\d+/)?}')
config.add_route('edit_index', '/{year:\d+}/edit')
config.add_route('presse', '/{year:\d+}/dossier-de-presse')
config.add_route('edit_presse', '/{year:\d+}/dossier-de-presse/edit')
config.add_route('programme', '/{year:\d+}/le-programme')
config.add_route('home', r'/{year:(\d+/)?}')
config.add_route('edit_index', r'/{year:\d+}/edit')
config.add_route('presse', r'/{year:\d+}/dossier-de-presse')
config.add_route('edit_presse', r'/{year:\d+}/dossier-de-presse/edit')
config.add_route('programme', r'/{year:\d+}/le-programme')
config.add_route('plan', 'nous-rejoindre')
config.add_route('participer', 'participer-l-evenement')
config.add_route('captcha', '/captcha')
## 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('delete_link_u', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_user')
config.add_route('link_event_tiers', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers')
config.add_route('delete_link_t', '/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_tiers')
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')
config.add_route('event', r'/event/{year:\d+}/{event_id:([\w-]+)?}')
config.add_route('link_event_user', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_user')
config.add_route('delete_link_u', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_user')
config.add_route('link_event_tiers', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/link_tiers')
config.add_route('delete_link_t', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}/delete_link_tiers')
config.add_route('edit_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}')
config.add_route('delete_event', r'/MesJM2L/{year:\d+}/{intervention:[\s\w]+}{sep:/*}{event_id:([\w-]+)?}/delete')
## Entities
# Entities
config.add_route('entities', '/entities') # {sep:/*}{Nature:\w+?}')
config.add_route('add_entity', '/entity')
config.add_route('delete_entity', '/entity/{entity_id:(\d+)}/delete')
config.add_route('show_entity', '/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)?}')
config.add_route('edit_entity', '/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit')
config.add_route('delete_entity', r'/entity/{entity_id:(\d+)}/delete')
config.add_route('show_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)?}')
config.add_route('edit_entity', r'/entity/{tiers_type:(\w+)}/{entity_id:([\w-]+)}/edit')
config.add_route('edit_entity_cat', '/categorie/entity')
## Users
# Users
config.add_route('pict_user', '/user_picture')
config.add_route('show_user', '/user/{user_slug:([\w-]+)?}')
config.add_route('badge_user', '/user/{user_slug:([\w-]+)?}/badge')
config.add_route('show_user', r'/user/{user_slug:([\w-]+)?}')
config.add_route('badge_user', r'/user/{user_slug:([\w-]+)?}/badge')
config.add_route('all_badges', '/badges')
config.add_route('place_print', '/place_print')
config.add_route('stand_print', '/stand_print')
@@ -175,10 +180,10 @@ def main(global_config, **settings):
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+)}')
config.add_route('modal', r'/{year:\d+}/modal/{modtype:\w+}/{id:(\d+)}')
# Handle exchanges
config.add_route('exchange', '/{year:\d+}/exchange/{modtype:\w+}/{id:(\d+)}/{action:\w+}')
config.add_route('exchange', r'/{year:\d+}/exchange/{modtype:\w+}/{id:(\d+)}/{action:\w+}')
# Handle authentication
config.add_route('register', '/register')
@@ -186,10 +191,8 @@ def main(global_config, **settings):
config.add_route('bymail', '/sign/jm2l/{hash}')
# Handle Multimedia and Uploads
config.add_route('media_view', '/image/{media_table:\w+}/{uid:\d+}/{name:.+}')
config.add_route('media_upload', '/uploader/{media_table:\w+}/{uid:\d+}/proceed{sep:/*}{name:.*}')
config.add_route('media_view', r'/image/{media_table:\w+}/{uid:\d+}/{name:.+}')
config.add_route('media_upload', r'/uploader/{media_table:\w+}/{uid:\d+}/proceed{sep:/*}{name:.*}')
config.scan()
return config.make_wsgi_app()
+1 -1
View File
@@ -8,7 +8,7 @@ from pyramid_mailer import get_mailer
from pyramid_mailer.message import Attachment, Message
from .forms import UserPasswordForm
from passlib.hash import argon2
from security import check_logged
from .security import check_logged
import datetime
import re
+90 -77
View File
@@ -1,7 +1,12 @@
# -*- coding: utf8 -*-
from pyramid.httpexceptions import HTTPNotFound, HTTPForbidden
from pyramid.response import Response
import cStringIO as StringIO
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import io
from pyramid.view import view_config
from .models import DBSession, User
from reportlab.pdfgen import canvas
@@ -12,40 +17,47 @@ import qrcode
import subprocess
from .upload import MediaPath
from jm2l.const import CurrentYear
# Create PDF container
EXPIRATION_TIME = 300 # seconds
WIDTH = 85 * mm
HEIGHT = 60 * mm
ICONSIZE = 10 * mm
def JM2L_Logo(canvas, Offset=(0, 0)):
OffX, OffY = Offset
logoobject = canvas.beginText()
logoobject.setFont('Logo', 32)
logoobject.setFillColorRGB(.83,0,.33)
logoobject.setTextOrigin(OffX+5, OffY+17)
logoobject.textLines("JM2L")
canvas.drawText(logoobject)
off_x, off_y = Offset
logo_object = canvas.beginText()
logo_object.setFont('Logo', 32)
logo_object.setFillColorRGB(.83, 0, .33)
logo_object.setTextOrigin(off_x + 5, off_y + 17)
logo_object.textLines("JM2L")
canvas.drawText(logo_object)
yearobject = canvas.beginText()
yearobject.setFont("Helvetica-Bold", 10)
yearobject.setFillColorRGB(1,1,1)
yearobject.setTextRenderMode(0)
yearobject.setTextOrigin(OffX+12 , OffY+35)
yearobject.setWordSpace(13)
yearobject.textLines(" ".join(str(CurrentYear)))
canvas.drawText(yearobject)
year_object = canvas.beginText()
year_object.setFont("Helvetica-Bold", 10)
year_object.setFillColorRGB(1, 1, 1)
year_object.setTextRenderMode(0)
year_object.setTextOrigin(off_x + 12, off_y + 35)
year_object.setWordSpace(13)
year_object.textLines(" ".join(str(CurrentYear)))
canvas.drawText(year_object)
def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0,0)):
Border = 0
OffX, OffY = Offset
if StartPos is None:
StartPos = ( 30 * mm, 2 )
StartX, StartY = StartPos
MaxX, MaxY = 34*mm, 18*mm
def Tiers_Logo(canvas, DispUser, start_pos=None, Offset=(0, 0)):
border = 0
off_x, off_y = Offset
if start_pos is None:
start_pos = (30 * mm, 2)
start_x, start_y = start_pos
max_x, max_y = 34 * mm, 18 * mm
num = 0
canvas.setStrokeColorRGB(0.5, 0.5, 0.5)
Logos = filter(lambda x:x.ThumbLinks, DispUser.tiers)[:3]
list_logos = list()
for thumb in DispUser.tiers:
if thumb.ThumbLinks:
list_logos.append(thumb.ThumbLinks[:3])
# list_logos = list(filter(lambda x: x.ThumbLinks, DispUser.tiers)[:3])
# Should We compute a better positionning for logos ?
DicPos = {}
DicPos[1] = {0: (1. / 2, 1. / 2)}
@@ -64,27 +76,28 @@ def Tiers_Logo(canvas, DispUser, StartPos=None, Offset=(0,0)):
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)
PosX = OffX+StartX + DicPos[len(Logos)][num][0] * MaxX - (ICONSIZE+Border)/2
PosY = OffY+StartY + DicPos[len(Logos)][num][1] * MaxY - (ICONSIZE+Border)/2
# canvas.roundRect(start_x, start_y, max_x, max_y, radius=2, stroke=True)
for tiers in list_logos:
file_name = tiers.ThumbLinks.pop().split("/")[-1]
image_path = "jm2l/upload/images/tiers/%s/%s" % (tiers.slug, file_name)
pos_x = off_x + start_x + DicPos[len(list_logos)][num][0] * max_x - (ICONSIZE + border) / 2
pos_y = off_y + start_y + DicPos[len(list_logos)][num][1] * max_y - (ICONSIZE + border) / 2
canvas.setLineWidth(.1)
if len(Logos)>1:
if len(list_logos) > 1:
size = ICONSIZE
else:
size = ICONSIZE * 1.5
canvas.drawImage(ImagePath,
PosX, PosY, size, size,\
canvas.drawImage(image_path,
pos_x, pos_y, size, size,
preserveAspectRatio=True,
anchor='c',
mask='auto'
)
# draw icon border
# canvas.roundRect(PosX, PosY, ICONSIZE, ICONSIZE, radius=2, stroke=True)
# canvas.roundRect(pos_x, pos_y, ICONSIZE, ICONSIZE, radius=2, stroke=True)
num += 1
def QRCode(DispUser):
qr = qrcode.QRCode(
version=1,
@@ -98,40 +111,41 @@ def QRCode(DispUser):
return qr.make_image()
def one_badge(c, DispUser, Offset=(0, 0)):
# Logo on Top
JM2L_Logo(c, Offset)
OffX, OffY = Offset
off_x, off_y = Offset
c.rect(OffX-3, OffY-3, WIDTH+6, HEIGHT+6, fill=0, stroke=1)
c.rect(off_x - 3, off_y - 3, WIDTH + 6, HEIGHT + 6, fill=0, stroke=1)
if DispUser.Staff:
# Staff
c.setFillColorRGB(.83, 0, .33)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "STAFF")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "STAFF")
elif DispUser.is_Intervenant:
# Intervenant
c.setFillColorRGB(.21, .67, .78)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Intervenant")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Intervenant")
elif DispUser.is_crew:
# Benevole
c.setFillColorRGB(.18, .76, .23)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Bénévole")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Bénévole")
else:
# Visiteur
c.setFillColorRGB(.8, .8, .8)
c.rect(OffX-3, OffY+HEIGHT-30, WIDTH+6, 33, fill=1, stroke=0)
c.rect(off_x - 3, off_y + HEIGHT - 30, WIDTH + 6, 33, fill=1, stroke=0)
c.setFillColorRGB(1, 1, 1)
c.setFont('Liberation', 30)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT-24, "Visiteur")
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT - 24, "Visiteur")
c.restoreState()
@@ -141,31 +155,31 @@ def one_badge(c, DispUser, Offset=(0,0)):
# Feed Name and SurName
if DispUser.prenom and DispUser.nom and len(DispUser.prenom) + len(DispUser.nom) > 18:
if DispUser.pseudo:
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s" % DispUser.prenom )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s" % DispUser.prenom)
# c.setFont('Courier', 17)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
else:
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 4 * mm , "%s" % DispUser.prenom )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 4 * mm, "%s" % DispUser.prenom)
# c.setFont('Courier', 17)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 - 8 * mm , "%s" % DispUser.nom )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 - 8 * mm, "%s" % DispUser.nom)
else:
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 0 * mm , "%s %s" % (DispUser.prenom, DispUser.nom) )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 0 * mm, "%s %s" % (DispUser.prenom, DispUser.nom))
if DispUser.pseudo:
c.setFont("Helvetica-Oblique", 18)
c.drawCentredString(OffX+WIDTH/2, OffY+HEIGHT/2 + 10 * mm , "%s" % DispUser.pseudo )
c.drawCentredString(off_x + WIDTH / 2, off_y + HEIGHT / 2 + 10 * mm, "%s" % DispUser.pseudo)
#  Put QR code to user profile
c.drawInlineImage(QRCode(DispUser), \
OffX+WIDTH - 20 * mm -5, OffY+5, \
20 * mm, 20 * mm, \
preserveAspectRatio=True, \
c.drawInlineImage(QRCode(DispUser),
off_x + WIDTH - 20 * mm - 5, off_y + 5,
20 * mm, 20 * mm,
preserveAspectRatio=True,
anchor='s')
Tiers_Logo(c, DispUser, None, Offset)
@view_config(route_name='badge_user', http_cache = (EXPIRATION_TIME, {'public':True}))
@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)
@@ -179,14 +193,14 @@ def badge_user(request):
# Ok let's generate a PDF Badge
# Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO.StringIO()
out_img = StringIO.StringIO()
pdf = io.BytesIO()
out_img = io.BytesIO()
c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
c.translate(mm, mm)
@@ -198,22 +212,21 @@ def badge_user(request):
c.saveState()
one_badge(c, DispUser)
out_pdf = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
c.showPage()
c.save()
pdf.seek(0)
if isoutpng:
OutPDF = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.pdf')
OutPNG = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
out_png = MediaPath().get_mediapath("badge", DispUser.uid, 'badge.png')
#  Let's generate a png file for website
with open( OutPDF ,'wb') as pdff:
with open("./%s" % out_pdf, 'wb') as pdff:
pdff.write(pdf.read())
Command = ["convert","-density","150x150", OutPDF, OutPNG]
Command = ["convert", "-density", "150x150", out_pdf, out_png]
subprocess.call(Command)
with open( OutPNG, 'rb') as pngfile:
out_img.write(pngfile.read())
with open("./%s" % out_png, 'rb') as pngfile:
out_img.write(pngfile.read()) # pngfile.read(), "utf8"))
out_img.seek(0)
return Response(app_iter=out_img, content_type='image/png')
@@ -232,13 +245,13 @@ def planche_badge(request):
# .filter(User_Event.year_uid == year)
# Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO.StringIO()
pdf = io.BytesIO()
FULLWIDTH = 210 * mm
FULLHEIGHT = 297 * mm
@@ -250,11 +263,11 @@ def planche_badge(request):
c.setCreator("linux-azur.org")
c.setTitle("Badge")
t = 0
ListUser = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
for num, DispUser in enumerate(ListUser):
list_user = filter(lambda x: x.is_Intervenant or x.Staff or x.is_crew, Users)
for num, disp_user in enumerate(list_user):
c.saveState()
Offsets = (((num-t)%2)*(WIDTH+40)+40, ((num-t)/2)*(HEIGHT+25)+40)
one_badge(c, DispUser, Offsets)
offsets = (((num - t) % 2) * (WIDTH + 40) + 40, int(((num - t) / 2)) * (HEIGHT + 25) + 40)
one_badge(c, disp_user, offsets)
if num % 8 == 7:
t = num + 1
c.showPage()
+23 -18
View File
@@ -3,12 +3,14 @@
import random
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import cStringIO as StringIO
import io
# from io import StringIO
import math
from pyramid.view import view_config
from .words import TabMots
from pyramid.response import Response
class Captcha_Img(object):
def __init__(self, width, height):
self.width = width
@@ -33,6 +35,7 @@ class Captcha_Img(object):
self._image = img
return self._image
class _PyCaptcha_WarpBase(object):
"""Abstract base class for image warping. Subclasses define a
function that maps points in the output image to points in the input image.
@@ -55,10 +58,10 @@ class _PyCaptcha_WarpBase(object):
# Create a list of arrays with transformed points
xRows = []
yRows = []
for j in xrange(yPoints):
for j in range(int(yPoints)):
xRow = []
yRow = []
for i in xrange(xPoints):
for i in range(int(xPoints)):
x, y = f(i * r, j * r)
# Clamp the edges so we don't get black undefined areas
@@ -73,8 +76,8 @@ class _PyCaptcha_WarpBase(object):
# Create the mesh list, with a transformation for
# each square between points on the grid
mesh = []
for j in xrange(yPoints-1):
for i in xrange(xPoints-1):
for j in range(int(yPoints - 1)):
for i in range(int(xPoints - 1)):
mesh.append((
# Destination rectangle
(i * r, j * r,
@@ -88,6 +91,7 @@ class _PyCaptcha_WarpBase(object):
return image.transform(image.size, Image.MESH, mesh, self.filtering)
class _PyCaptcha_SineWarp(_PyCaptcha_WarpBase):
"""Warp the image using a random composition of sine waves"""
@@ -108,13 +112,14 @@ class _PyCaptcha_SineWarp(_PyCaptcha_WarpBase):
(math.sin((y + o[0]) * p) * a + x,
math.sin((x + o[1]) * p) * a + y))
@view_config(route_name='captcha')
def DoCaptcha(request):
ImgSize = (230,100)
WorkImg = Image.new( 'RGBA', ImgSize, (255, 255, 255, 0) )
Xmax, Ymax = WorkImg.size
img_size = (230, 100)
work_img = Image.new('RGBA', img_size, (255, 255, 255, 0))
Xmax, Ymax = work_img.size
# Write something on it
draw = ImageDraw.Draw(WorkImg)
draw = ImageDraw.Draw(work_img)
# use a truetype font
# font = ImageFont.truetype("/var/lib/defoma/gs.d/dirs/fonts/LiberationMono-Regular.ttf", 40)
@@ -124,28 +129,28 @@ def DoCaptcha(request):
# Choose a word for captcha
text = random.choice(TabMots)
Xt, Yt = font.getsize(text)
OrX, OrY = (ImgSize[0]-Xt)/2, (ImgSize[1]-Yt)/2
OrX, OrY = (img_size[0] - Xt) / 2, (img_size[1] - Yt) / 2
draw.text((OrX, OrY), text, font=font, fill="#000000")
# Apply a Blur
# WorkImg=WorkImg.filter(ImageFilter.BLUR)
# work_img=work_img.filter(ImageFilter.BLUR)
# Apply a DETAIL
WorkImg=WorkImg.filter(ImageFilter.DETAIL)
work_img = work_img.filter(ImageFilter.DETAIL)
# randomize parameters for perspective
ax, ay = (random.uniform(0.9, 1.2), random.uniform(0.9, 1.2))
tx, ty = (random.uniform(0, 0.0003), random.uniform(0, 0.0003))
bx, by = (random.uniform(0.5, 0.8), random.uniform(0, 0.2))
# Apply perspective to Captcha
WorkImg= WorkImg.transform(ImgSize, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty))
work_img = work_img.transform(img_size, Image.PERSPECTIVE, (ax, bx, -25, by, ay, -10, tx, ty))
# Apply SinWarp to Captcha
tr = Captcha_Img(Xmax, Ymax)
tr._image = WorkImg
WorkImg = tr.render()
tr._image = work_img
work_img = tr.render()
# Apply a Smooth on it
WorkImg=WorkImg.filter(random.choice([ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE]))
work_img = work_img.filter(random.choice([ImageFilter.SMOOTH, ImageFilter.SMOOTH_MORE]))
# Save Result
request.session['Captcha'] = text
# session.save()
ImgHandle = StringIO.StringIO()
WorkImg.save(ImgHandle,'png')
ImgHandle = io.BytesIO()
work_img.save(ImgHandle, 'png')
ImgHandle.seek(0)
return Response(app_iter=ImgHandle, content_type='image/png')
+1 -1
View File
@@ -1 +1 @@
CurrentYear = 2018
CurrentYear = 2020
+103 -32
View File
@@ -1,28 +1,48 @@
# -*- coding: utf8 -*-
import random
import string
from wtforms import Form, BooleanField, StringField, TextAreaField, SelectField
from wtforms import SubmitField, validators, FieldList, PasswordField
# import .ExtWforms
from .ExtWtforms import MySelectField
from wtforms import HiddenField, DecimalField, DateTimeField, FormField, DateField
from wtforms.validators import ValidationError
strip_filter = lambda x: x.strip() if x else None
from wtforms.csrf.session import SessionCSRF
from datetime import timedelta
from jm2l.const import CurrentYear
# What about an helper function
def strip_filter(x):
# strip_filter = lambda x: x.strip() if x else None
if x:
return x.strip()
return None
# get random string password with letters, digits, and symbols
def get_random_string(length):
csrf_characters = string.ascii_letters + string.digits + string.punctuation
csrf = ''.join(random.choice(csrf_characters) for i in range(length))
return bytes(csrf, 'utf8')
class MyBaseForm(Form):
class Meta:
csrf = True
csrf_class = SessionCSRF
csrf_secret = b'lJDQtOAMC2qe89doIn8u3Mch_DgeLSKO'
# csrf_secret = b'lJDQtOAMC2qe89doIn8u3Mch_DgeLSKO'
csrf_secret = get_random_string(32)
csrf_time_limit = timedelta(minutes=60)
class BlogCreateForm(MyBaseForm):
title = StringField('Entry title', [validators.Length(min=1, max=255)],
filters=[strip_filter])
body = TextAreaField('Entry body', [validators.Length(min=1)],
filters=[strip_filter])
class BlogUpdateForm(BlogCreateForm):
id = HiddenField()
@@ -56,9 +76,11 @@ class StaffArea(MyBaseForm):
)
year_uid = HiddenField('year', default=str(CurrentYear))
class EditStaffArea(StaffArea):
uid = HiddenField()
class StaffTasks(MyBaseForm):
name = StringField(u'Nom de la tâche', [validators.Required()])
area_uid = SelectField(u'Pôle concerné', coerce=int)
@@ -68,34 +90,42 @@ class StaffTasks(MyBaseForm):
filters=[strip_filter])
year_uid = HiddenField('year', default=str(CurrentYear))
class EditStaffTasks(StaffTasks):
uid = HiddenField()
class DossPresse(MyBaseForm):
year_uid = HiddenField()
doss_presse = TextAreaField('Dossier de Presse', [validators.optional(), validators.Length(max=1000000)],
filters=[strip_filter])
class IndexForm(MyBaseForm):
year_uid = HiddenField()
description = TextAreaField('Index', [validators.optional(), validators.Length(max=1000000)],
filters=[strip_filter])
class TiersMember(MyBaseForm):
class Meta:
csrf = False
year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,CurrentYear+1),range(2006,CurrentYear+1)))
year_uid = SelectField(u'Année', coerce=int,
choices=zip(range(2006, CurrentYear + 1), range(2006, CurrentYear + 1)))
user_uid = StringField(u'user')
role = StringField(u'Role')
class TiersRole(MyBaseForm):
class Meta:
csrf = False
year_uid = SelectField(u'Année', coerce=int, choices=zip(range(2006,CurrentYear+1),range(2006,CurrentYear+1)))
year_uid = SelectField(u'Année', coerce=int,
choices=zip(range(2006, CurrentYear + 1), range(2006, CurrentYear + 1)))
tiers_role = SelectField(u'Role', choices=TIERS_ROLE)
class TiersChoice(MyBaseForm):
class Meta:
csrf = False
@@ -105,6 +135,7 @@ class TiersChoice(MyBaseForm):
tiers_uid = StringField(u'Entité')
role = StringField(u'Role')
class AddIntervenant(MyBaseForm):
class Meta:
csrf = False
@@ -112,6 +143,7 @@ class AddIntervenant(MyBaseForm):
event_uid = HiddenField()
intervenant = SelectField(u'Intervenant', coerce=int)
class AddTiers(MyBaseForm):
class Meta:
csrf = False
@@ -119,57 +151,68 @@ class AddTiers(MyBaseForm):
event_uid = HiddenField()
tiers = SelectField(u'Entité', coerce=int)
class ConfCreateForm(MyBaseForm):
class ConfCreateForm(MyBaseForm):
event_type = HiddenField()
for_year = HiddenField()
start_time = HiddenField()
end_time = HiddenField()
start_sel = SelectField(u'Début', coerce=int,
description=u"C'est une heure indicative correspondant au mieux à vos préférences "+
start_sel = SelectField(
u'Début', coerce=int,
description=u"C'est une heure indicative correspondant au mieux à vos préférences "
u"personnelles. Vous pouvez prendre un créneau horaire déjà réservé si vous avez des contraintes "
u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. En cas de conflit,"+
u"particulières. L'équipe des JM2L mettra à disposition plus de salle si nécessaire. "
u"En cas de conflit,"
u"l'organisation se réserve le droit de changer la salle et l'heure avec votre accord."
)
duration = SelectField(u'Durée', coerce=int,
description=u"Précisez ici la durée de votre intervention"
duration = SelectField(
u'Durée', coerce=int,
description=u"Précisez ici la durée de votre intervention")
salle_uid = SelectField(
u'Salle', coerce=int,
description=u"Choisissez ici la salle en fonction du nombres de personnes potentiellement "
u"intéressé par votre intervention l'organisation se réserve le droit de changer"
u" la salle (avec votre accord)."
)
salle_uid = SelectField(u'Salle', coerce=int,
description=u"Choisissez ici la salle en fonction "
u"du nombres de personnes potentiellement intéressé par votre intervention "+
u"l'organisation se réserve le droit de changer la salle (avec votre accord)."
)
name = StringField(u'Le nom de votre ',
name = StringField(
u'Le nom de votre ',
[validators.DataRequired(u'Vous devez spécifier un nom pour votre intérvention'),
validators.Length(min=1, max=80, message='entre 1 et 80 car')],
filters=[strip_filter])
filters=[strip_filter]
)
description = TextAreaField(u'Décrivez ici quelques détails à propos de votre intervention ',
description = TextAreaField(
u'Décrivez ici quelques détails à propos de votre intervention ',
[validators.Optional(), validators.Length(max=1000000)],
filters=[strip_filter]
)
class ConfUpdateForm(ConfCreateForm):
uid = HiddenField()
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', u'Conférence'),
('Stand','Stand'), ('Atelier','Atelier'), ('Table ronde','Table ronde'),
('Stand', 'Stand'), ('Atelier', 'Atelier'),
('Table ronde', 'Table ronde'),
('MAO', 'MAO'), ('Repas', 'Repas / Snack'), ('Autres', 'Autres')])
name = StringField('Nom de la salle', [validators.Length(min=1, max=40)],
filters=[strip_filter])
description = TextAreaField('Description',
filters=[strip_filter])
class EditSalleForm(SalleForm):
salle_id = HiddenField()
class SallePhyForm(MyBaseForm):
name = StringField('Nom de la salle', [validators.Length(min=1, max=40)],
filters=[strip_filter])
@@ -177,18 +220,20 @@ class SallePhyForm(MyBaseForm):
description = TextAreaField('Description',
filters=[strip_filter])
class EditSallePhyForm(SallePhyForm):
uid = HiddenField()
class PlaceCreateForm(MyBaseForm):
class PlaceCreateForm(MyBaseForm):
place_type = SelectField('Type', choices=PLACE_TYPE)
display_name = StringField(u'Nom affiché', [validators.Length(min=1, max=20)],
filters=[strip_filter])
name = StringField('Nom Complet', [validators.Length(min=1, max=80)],
filters=[strip_filter])
gps_coord = StringField(u'Coordonnées GPS', [validators.Length(max=30),
gps_coord = StringField(u'Coordonnées GPS',
[validators.Length(max=30),
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])
@@ -205,6 +250,7 @@ class PlaceCreateForm(MyBaseForm):
created_by = HiddenField()
class PlaceUpdateForm(PlaceCreateForm):
place_id = HiddenField()
@@ -213,6 +259,7 @@ def captcha_check(form, field):
if form.meta.csrf_context.get('Captcha') != field.data:
raise ValidationError(u"la vérification captcha est invalide.")
class UserPasswordForm(MyBaseForm):
uid = HiddenField()
password = PasswordField("Mot de passe", [
@@ -223,8 +270,8 @@ class UserPasswordForm(MyBaseForm):
)
confirm = PasswordField('Confirmez')
class UserRegisterForm(MyBaseForm):
class UserRegisterForm(MyBaseForm):
nom = StringField(u'Nom', [
validators.Length(max=80, message=u"80 car. maximum"),
validators.required(message=u"Ce champ est obligatoire")],
@@ -248,6 +295,7 @@ class UserRegisterForm(MyBaseForm):
filters=[strip_filter]
)
class ProfilForm(MyBaseForm):
id = HiddenField()
user_id = HiddenField()
@@ -276,7 +324,8 @@ class ProfilForm(MyBaseForm):
)
phone = StringField(u'Mobile', [validators.optional(), validators.Length(max=10),
validators.Regexp("\d+", message=u"Le numéro de téléphone mobile ne doit contenir que des chiffres")],
validators.Regexp("\d+",
message=u"Le numéro de téléphone mobile ne doit contenir que des chiffres")],
filters=[strip_filter],
description=u"Un numéro de mobile valide. Afin de pouvoir rester en" +
u"contact avec les personne de l'organisation, et pour vos échanges. " +
@@ -359,13 +408,14 @@ class DateStartConfidenceForm(MyBaseForm):
filters=[strip_filter])
start_time = HiddenField()
class ItineraireForm(Form):
start_place = SelectField(u'En partant de', coerce=int)
arrival_place = SelectField(u'et à destination de', coerce=int)
itin_id = HiddenField()
class AddItineraireForm(Form):
class AddItineraireForm(Form):
itin = FormField(ItineraireForm)
distance = DecimalField(u'Distance', [validators.Length(min=1, max=4)],
filters=[strip_filter])
@@ -382,6 +432,7 @@ class AddItineraireForm(Form):
tr_avion = BooleanField(u'en avion')
description = TextAreaField(u'Description de l\'itinéraire')
class AddMember(MyBaseForm):
tiers_uid = HiddenField()
nom = StringField(u'Nom', [validators.Length(max=80)],
@@ -404,6 +455,7 @@ class AddMember(MyBaseForm):
u"son inscription sur le site.")
add = SubmitField('Ajouter des membres')
class TiersForm(MyBaseForm):
name = StringField(u'Nom', [validators.Length(max=100)],
filters=[strip_filter],
@@ -429,6 +481,7 @@ class TiersForm(MyBaseForm):
roles = FieldList(FormField(TiersRole))
class UpdateTiersForm(TiersForm):
uid = HiddenField()
tiers_id = HiddenField()
@@ -443,9 +496,11 @@ class ExchCateg(MyBaseForm):
description = TextAreaField('Description',
filters=[strip_filter])
class UpdateExchangeForm(MyBaseForm):
exch_id = HiddenField()
class AskCForm(ItineraireForm):
ConfidenceLevel = [
("0", u"exactement à"),
@@ -466,8 +521,10 @@ class AskCForm(ItineraireForm):
arrival_place = SelectField(u'et à destination de', coerce=int)
itin_id = HiddenField()
class AskHForm(MyBaseForm):
DayChoice = [("4",u"Jeudi à Vendredi"), ("5",u"Vendredi à Samedi"), ("6",u"Samedi à Dimanche"), ("0",u"Dimanche à Lundi")]
DayChoice = [("4", u"Jeudi à Vendredi"), ("5", u"Vendredi à Samedi"), ("6", u"Samedi à Dimanche"),
("0", u"Dimanche à Lundi")]
Day_start = SelectField(u'Pour la nuit de', choices=DayChoice)
start_time = HiddenField()
description = TextAreaField(u'Description de vos contraintes éventuelles', filters=[strip_filter],
@@ -475,6 +532,7 @@ class AskHForm(MyBaseForm):
+ u"les contraintes à prendre en compte. N'hésitez pas à donner des détails."
)
class AskMForm(MyBaseForm):
DayChoice = [("4", "Jeudi"), ("5", "Vendredi"), ("6", "Samedi"), ("0", "Dimanche"), ("1", "Lundi")]
Day_start = SelectField(u"à partir de", choices=DayChoice)
@@ -499,6 +557,7 @@ class AskMForm(MyBaseForm):
+ u"échanger. N'hésitez pas à donner des détails."
)
class PropCForm(ItineraireForm):
ConfidenceLevel = [
("0", u"exactement à"),
@@ -519,8 +578,10 @@ class PropCForm(ItineraireForm):
arrival_place = SelectField(u'et à destination de', coerce=int)
itin_id = HiddenField()
class PropHForm(MyBaseForm):
DayChoice = [("4",u"Jeudi à Vendredi"), ("5",u"Vendredi à Samedi"), ("6",u"Samedi à Dimanche"), ("0",u"Dimanche à Lundi")]
DayChoice = [("4", u"Jeudi à Vendredi"), ("5", u"Vendredi à Samedi"), ("6", u"Samedi à Dimanche"),
("0", u"Dimanche à Lundi")]
Day_start = SelectField(u'Pour la nuit de', choices=DayChoice)
start_time = HiddenField()
exch_categ = SelectField(u'Type de couchage', coerce=int,
@@ -532,6 +593,7 @@ class PropHForm(MyBaseForm):
place_id = SelectField(u'Emplacement', coerce=int,
description=u"Indiquez ici une des adresses que vous avez proposé")
class PropMForm(MyBaseForm):
DayChoice = [("4", "Jeudi"), ("5", "Vendredi"), ("6", "Samedi"), ("0", "Dimanche"), ("1", "Lundi")]
Day_start = SelectField(u"à partir de", choices=DayChoice)
@@ -548,28 +610,37 @@ class PropMForm(MyBaseForm):
message=u"doit être sous la forme HH:MM")],
filters=[strip_filter])
end_time = HiddenField()
exch_categ = SelectField(u'Catégorie de matériel', coerce=int,
exch_categ = SelectField(
u'Catégorie de matériel', coerce=int,
description=u"Choisissez une catégorie de bien matériel"
)
description = TextAreaField(u'Ajoutez quelques mots autour du matériel que vous proposez', filters=[strip_filter],
description = u"Décrivez ici quelques détails sur le matériel que vous souhaitez "
+ u"proposer. N'hésitez pas à donner des détails."
description = TextAreaField(
u'Ajoutez quelques mots autour du matériel que vous proposez',
filters=[strip_filter],
description=u"Décrivez ici quelques détails sur le matériel "
u"que vous souhaitez proposer. N'hésitez pas à donner des détails."
)
class UpdateAskCForm(AskCForm, UpdateExchangeForm):
pass
class UpdateAskHForm(AskHForm, UpdateExchangeForm):
pass
class UpdateAskMForm(AskMForm, UpdateExchangeForm):
pass
class UpdatePropCForm(PropCForm, UpdateExchangeForm):
pass
class UpdatePropHForm(PropHForm, UpdateExchangeForm):
pass
class UpdatePropMForm(PropMForm, UpdateExchangeForm):
pass
+54 -46
View File
@@ -4,6 +4,12 @@ from datetime import timedelta, datetime
import itertools
from jm2l.const import CurrentYear
def get_current_year():
""" This function is intended to return the year of the next edition """
return CurrentYear
class DummySejour(object):
def __init__(self, event):
@@ -16,6 +22,7 @@ class DummySejour(object):
.filter(Sejour.for_year == self.CurrentEventYear.year_uid) \
.first()
class Sejour_helpers(DummySejour):
def __init__(self, event):
@@ -27,78 +34,78 @@ class Sejour_helpers(DummySejour):
# This function return the start of the event
return self.CurrentYear
def PossibleDate(self, typedate="arrival"):
def PossibleDate(self, type_date="arrival"):
arrival, departure = False, False
TabResult = list()
if typedate == "arrival":
tab_result = list()
if type_date == "arrival":
# Let's say people should arrive until 2 day before
arrival = True
myDayRange = xrange(2,-1,-1)
elif typedate == "departure":
my_day_range = range(2, -1, -1)
elif type_date == "departure":
# Let's say people should go back home until 2 day after
departure = True
myDayRange = xrange(3)
my_day_range = range(3)
else:
return TabResult
return tab_result
if self.Sejour:
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')
arr_date = datetime.strftime(self.Sejour.arrival_time, "%d %B %Y")
dep_date = datetime.strftime(self.Sejour.depart_time, "%d %B %Y")
else:
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')
arr_date = datetime.strftime(self.CurrentEventYear.start_time, "%d %B %Y")
dep_date = datetime.strftime(self.CurrentEventYear.end_time, "%d %B %Y")
for oneday in myDayRange:
for one_day in my_day_range:
if arrival:
TmpDay = self.CurrentEventYear.end_time - timedelta(days=oneday)
tmp_day = self.CurrentEventYear.end_time - timedelta(days=one_day)
elif departure:
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").decode('utf-8')
if arrival and ArrDate==DayString:
TabResult.append((DayNum, DayName, 'selected="selected"'))
elif departure and DepDate==DayString:
TabResult.append((DayNum, DayName, 'selected="selected"'))
tmp_day = self.CurrentEventYear.start_time + timedelta(days=one_day)
day_name = datetime.strftime(tmp_day, "%A")
day_num = datetime.strftime(tmp_day, "%d/%m/%y")
day_string = datetime.strftime(tmp_day, "%d %B %Y")
if arrival and arr_date == day_string:
tab_result.append((day_num, day_name, 'selected="selected"'))
elif departure and dep_date == day_string:
tab_result.append((day_num, day_name, 'selected="selected"'))
else:
TabResult.append((DayNum, DayName, ""))
return TabResult
tab_result.append((day_num, day_name, ""))
return tab_result
def PossibleTime(self, typedate="arrival"):
ArrTime, DepTime = "10:00", "19:00"
TabResult = list()
def PossibleTime(self, type_date="arrival"):
arr_time, dep_time = "10:00", "19:00"
tab_result = list()
if self.Sejour:
ArrTime = datetime.strftime(self.Sejour.arrival_time,"%H:%M")
DepTime = datetime.strftime(self.Sejour.depart_time,"%H:%M")
arr_time = datetime.strftime(self.Sejour.arrival_time, "%H:%M")
dep_time = datetime.strftime(self.Sejour.depart_time, "%H:%M")
for hour in range(24):
for minutes in range(0, 60, 10):
StrTime = "%.2d:%.2d" % (hour, minutes)
DispTime = "%dh%.2d" % (hour, minutes)
if typedate == "arrival" and StrTime==ArrTime:
TabResult.append( (StrTime, DispTime, 'selected="selected"') )
elif typedate == "departure" and StrTime==DepTime:
TabResult.append( (StrTime, DispTime, 'selected="selected"') )
str_time = "%.2d:%.2d" % (hour, minutes)
disp_time = "%dh%.2d" % (hour, minutes)
if type_date == "arrival" and str_time == arr_time:
tab_result.append((str_time, disp_time, 'selected="selected"'))
elif type_date == "departure" and str_time == dep_time:
tab_result.append((str_time, disp_time, 'selected="selected"'))
else:
TabResult.append( (StrTime, DispTime, "") )
return TabResult
tab_result.append((str_time, disp_time, ""))
return tab_result
def IsCheck(self, InputControl):
ListControlA = ['Arrival', 'Departure']
ListControlB = ['PMR', 'Cov', 'Bras', 'Other']
if InputControl not in map(':'.join, itertools.product(ListControlA, ListControlB)):
list_control_a = ['Arrival', 'Departure']
list_control_b = ['PMR', 'Cov', 'Bras', 'Other']
if InputControl not in map(':'.join, itertools.product(list_control_a, list_control_b)):
return ""
if self.Sejour:
if InputControl.startswith('Arrival'):
CtrlVal = 2**ListControlB.index(InputControl[8:])
if self.Sejour.arrival_check & CtrlVal == CtrlVal:
ctrl_val = 2 ** list_control_b.index(InputControl[8:])
if self.Sejour.arrival_check & ctrl_val == ctrl_val:
return "checked=\"checked\""
else:
return ""
elif InputControl.startswith('Departure'):
CtrlVal = 2**ListControlB.index(InputControl[10:])
if self.Sejour.depart_check & CtrlVal == CtrlVal:
ctrl_val = 2 ** list_control_b.index(InputControl[10:])
if self.Sejour.depart_check & ctrl_val == ctrl_val:
return "checked=\"checked\""
else:
return ""
@@ -107,6 +114,7 @@ class Sejour_helpers(DummySejour):
else:
return ""
class Orga_helpers(DummySejour):
def __init__(self, event):
@@ -143,9 +151,9 @@ class Orga_helpers(DummySejour):
def ChoosedList(self):
""" Return choice validated by user """
ListOrga = []
list_orga = []
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
list_orga.append(self.Orga_tasks[num])
return list_orga
+44 -17
View File
@@ -18,10 +18,10 @@ from sqlalchemy import (
)
from slugify import slugify
from webhelpers.text import urlify
from webhelpers.paginate import PageURL_WebOb, Page
from webhelpers.date import time_ago_in_words
# from webhelpers.text import urlify
from paginate import Page # PageURL_WebOb
from webhelpers2.date import time_ago_in_words
from sqlalchemy.ext.declarative import declarative_base
@@ -30,14 +30,24 @@ from sqlalchemy.orm import (
sessionmaker
)
from zope.sqlalchemy import ZopeTransactionExtension
# from zope.sqlalchemy import ZopeTransactionExtension
from zope.sqlalchemy import register
from jm2l.const import CurrentYear
from passlib.hash import argon2
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
def urlify(in_string, in_string_length):
return ''.join('%20' if c == ' ' else c for c in in_string[:in_string_length])
DBSession = scoped_session(sessionmaker(autoflush=False))
register(DBSession)
# DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()
class TasksArea(Base):
__tablename__ = 'staff_tasks_area'
uid = Column(Integer, primary_key=True)
@@ -49,6 +59,7 @@ class TasksArea(Base):
def by_id(cls, uid):
return DBSession.query(cls).filter(cls.uid == uid).first()
class Tasks(Base):
__tablename__ = 'staff_tasks'
uid = Column(Integer, primary_key=True)
@@ -68,6 +79,7 @@ class Tasks(Base):
def by_id(cls, uid):
return DBSession.query(cls).filter(cls.uid == uid).first()
class User_Event(Base):
""" Créer le lien entre la personne et l' évenement en fonction de l'année"""
__tablename__ = 'user_event_link'
@@ -84,6 +96,7 @@ class User_Event(Base):
# user = relationship('User', backref=backref("events_assoc") )
# event = relationship('events', backref=backref("users_assoc") )
class JM2L_Year(Base):
__tablename__ = 'jm2l_year'
year_uid = Column(Integer, primary_key=True)
@@ -102,7 +115,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").decode('utf-8')
return last_record.start_time.strftime("%A %d %B %Y") # .decode('utf-8')
@property
def AvailableTimeSlots(self, TimeStep=30):
@@ -125,6 +138,7 @@ class JM2L_Year(Base):
from .upload import MediaPath
return sorted(MediaPath().get_all('presse', self.year_uid))
class User(Base):
__tablename__ = 'users'
uid = Column(Integer, primary_key=True)
@@ -208,25 +222,23 @@ class User(Base):
else:
return False
def year_events(self, EventType='All', year=CurrentYear):
if EventType == 'All':
return filter(lambda e: e.for_year==year, self.events)
return list(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)
return list(filter(lambda e: e.for_year == year and e.event_type == EventType, self.events))
@property
def my_hash(self):
m = hashlib.sha1()
m.update("Nobody inspects ")
m.update("Nobody inspects ".encode('utf-8'))
if self.nom:
m.update(unicode.encode(self.nom,'utf8'))
m.update(self.nom.encode('utf-8')) # unicode.encode(self.nom, 'utf8'))
if self.pseudo:
m.update(unicode.encode(self.pseudo,'utf8'))
m.update(self.pseudo.encode('utf-8')) # unicode.encode(self.pseudo, 'utf8'))
if self.prenom:
m.update(unicode.encode(self.prenom,'utf8'))
m.update(" the spammish repetition")
m.update(self.prenom.encode('utf-8')) # unicode.encode(self.prenom, 'utf8'))
m.update(" the spammish repetition".encode('utf-8'))
return m.hexdigest()
@property
@@ -253,6 +265,7 @@ class User(Base):
return argon2.verify(password, self.password)
class TiersOpt(Base):
__tablename__ = 'tiers_opt'
uid = Column(Integer, primary_key=True)
@@ -285,6 +298,7 @@ class TiersOpt(Base):
def by_id(cls, uid):
return DBSession.query(cls).filter(cls.uid == uid).first()
class Tiers(Base):
__tablename__ = 'tiers'
uid = Column(Integer, primary_key=True)
@@ -344,6 +358,7 @@ class Tiers(Base):
from .upload import MediaPath
return MediaPath().get_thumb('tiers', self.uid)
class Role_Tiers(Base):
""" Créer le lien entre le tiers et son rôle dans l'évenement en fonction de l'année"""
__tablename__ = 'role_tiers_link'
@@ -354,6 +369,7 @@ class Role_Tiers(Base):
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"""
__tablename__ = 'user_tiers_link'
@@ -365,6 +381,7 @@ class User_Tiers(Base):
user = relationship(User, backref=backref("tiers_assoc"))
role = Column(Unicode(80))
class Media(Base):
__tablename__ = 'medias'
media_id = Column(Integer, primary_key=True)
@@ -385,6 +402,7 @@ class Media(Base):
# return '/upload/%s/%s/%s' % (self.media_type, self.media_table, self.filename)
return '/resources/%s/%s/%s' % (self.for_year, self.media_type, self.filename)
class SallePhy(Base):
""" Représente une salle dans les locaux """
__tablename__ = 'phy_salle'
@@ -403,6 +421,7 @@ class SallePhy(Base):
from .upload import MediaPath
return MediaPath().get_list('salle', self.uid, 'Image')
class Salles(Base):
__tablename__ = 'salle'
salle_id = Column(Integer, primary_key=True)
@@ -415,10 +434,12 @@ class Salles(Base):
last_change = Column(DateTime, default=datetime.datetime.now)
phy = relationship(SallePhy)
@classmethod
def by_id(cls, uid):
return DBSession.query(cls).filter(cls.salle_id == uid).first()
class Place(Base):
__tablename__ = 'place'
place_id = Column(Integer, primary_key=True)
@@ -450,6 +471,7 @@ class Place(Base):
else:
return DBSession.query(cls).filter(cls.usage == True).all()
class Itineraire(Base):
__tablename__ = 'itineraire'
itin_id = Column(Integer, primary_key=True)
@@ -473,6 +495,7 @@ class Itineraire(Base):
start = relationship(Place, foreign_keys=[start_place])
arrival = relationship(Place, foreign_keys=[arrival_place])
class Exchange_Cat(Base):
__tablename__ = 'exchange_category'
cat_id = Column(Integer, primary_key=True)
@@ -480,6 +503,7 @@ class Exchange_Cat(Base):
exch_subtype = Column(Unicode(80))
description = Column(UnicodeText)
class Exchange(Base):
__tablename__ = 'exchanges'
exch_id = Column(Integer, primary_key=True)
@@ -586,6 +610,7 @@ class Exchange(Base):
.order_by(cls.start_time).all()
return DicResult
class Sejour(Base):
__tablename__ = 'sejour'
sej_id = Column(Integer, primary_key=True)
@@ -614,6 +639,7 @@ class Sejour(Base):
.filter(cls.for_year == year) \
.first()
class Event(Base):
__tablename__ = 'events'
uid = Column(Integer, primary_key=True)
@@ -640,7 +666,6 @@ class Event(Base):
return DBSession.query(cls) \
.filter(cls.uid == uid).first()
@classmethod
def by_slug(cls, slug, year=None):
if not year is None:
@@ -676,6 +701,7 @@ class Event(Base):
def created_in_words(self):
return time_ago_in_words(self.created)
class Entry(Base):
__tablename__ = 'entries'
id = Column(Integer, primary_key=True)
@@ -706,6 +732,7 @@ class Entry(Base):
page_url = PageURL_WebOb(request)
return Page(Entry.all(), page, url=page_url, items_per_page=5)
# class Seances(Base):
# __tablename__ = 'seances'
def get_user(request):
@@ -731,6 +758,7 @@ def get_sponsors(request, Year):
.join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid) \
.filter(Role_Tiers.tiers_role == 'Sponsor')
def get_exposants(request, Year):
if Year:
return DBSession.query(Tiers) \
@@ -741,4 +769,3 @@ def get_exposants(request, Year):
return DBSession.query(Tiers) \
.join(Role_Tiers, Role_Tiers.tiers_uid == Tiers.uid) \
.filter(Role_Tiers.tiers_role == 'Exposant')
+11 -12
View File
@@ -48,14 +48,14 @@ def pull_data(from_db, to_db, tables):
destination, dengine = make_session(to_db)
for table_name in tables:
print 'Processing', table_name
print 'Pulling schema from source server'
print('Processing', table_name)
print('Pulling schema from source server')
table = Table(table_name, smeta, autoload=True)
print 'Creating table on destination server'
print('Creating table on destination server')
table.metadata.create_all(dengine)
NewRecord = quick_mapper(table)
columns = table.columns.keys()
print 'Transferring records'
print('Transferring records')
for record in source.query(table).all():
data = dict(
[(str(column), getattr(record, column)) for column in columns]
@@ -69,20 +69,20 @@ def pull_data(from_db, to_db, tables):
try:
destination.merge(NewRecord(**data))
except:
print data
print(data)
pass
print 'Committing changes'
print('Committing changes')
destination.commit()
def main(argv=sys.argv):
connection_string = "sqlite:////home/tr4ck3ur/Dev/jm2l/JM2L.sqlite"
connection_string = "sqlite:////home/tr4ck3ur/git_repository/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
print(i.mail)
def main4(argv=sys.argv):
import csv
@@ -116,7 +116,7 @@ def main4(argv=sys.argv):
u.wifi_user = w_user
u.wifi_pass = w_pass
DBSession.merge(u)
print row, u
print(row, u)
finally:
f.close()
@@ -141,7 +141,7 @@ def main_3(argv=sys.argv):
.filter(p0.last_logged<p1.last_logged)\
.with_entities(p0.slug,p0.uid,p1.uid).all()
for slug, idsrc, iddst in Datas:
print slug
print(slug)
# Events
Events = DBSession.query(User_Event)\
.filter(User_Event.user_uid==idsrc)
@@ -238,5 +238,4 @@ def Initialize():
u.password = password
u.Staff = 0
DBSession.merge(u)
print u.nom, u.prenom, u.Staff
print(u.nom, u.prenom, u.Staff)
+1 -1
View File
@@ -58,7 +58,7 @@
% if reason:
<p>${reason}</p>
% else:
<p>Vous n'êtes pas authentifi&eacute;, ou n'avez pas les authorisations n&eacute;cessaires.</p>
<p>Vous n'êtes pas authentifié, ou n'avez pas les authorisations nécessaires.</p>
% endif
</body>
</html>
+1 -1
View File
@@ -54,7 +54,7 @@
</head>
<body>
<img src="/img/error404.png" width="200px" />
<h1>Page non trouv&eacute;e</h1>
<h1>Page non trouvée</h1>
% if reason:
<p>${reason}</p>
% else:
+12 -12
View File
@@ -10,7 +10,7 @@
</thead>
<tbody>
<tr>
<td>Conf&eacute;rences</td> <td style="text-align:center">
<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
@@ -106,11 +106,11 @@ elif Type=='T':
%>
% if Type!='O':
<fieldset>
<legend class="lowshadow">Vos ${CurTitles} programm&eacute;s pour ${CurrentYear}</legend>
<legend class="lowshadow">Vos ${CurTitles} programmés pour ${CurrentYear}</legend>
<%
Selection = filter(lambda x:(x.event_type==CurEventType and x.for_year==CurrentYear), uprofil.events)
Selection = list(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&eacute; d'intervention %s." % CurEvent
NothingTitle = u"Vous n'avez pas sollicité d'intervention %s." % CurEvent
%>
${helpers.show_Interventions(Selection, "Sujet", NothingTitle )}
</fieldset>
@@ -118,21 +118,21 @@ NothingTitle = u"Vous n'avez pas sollicit&eacute; d'intervention %s." % CurEvent
% if Type=='C':
<p>
<strong>Proposer une conf&eacute;rence / un lighting talk</strong><br/>
<strong>Proposer une conférence / un lighting talk</strong><br/>
<ul>
<li>Si vous avez une exp&eacute;rience particulière avec les logiciels libres
<li>Si vous avez une expérience particulière avec les logiciels libres
que vous souhaitez partager.</li>
<li>Si vous êtes acteur dun des sujets actuels qui menacent ou qui
promeuvent le logiciel libre.</li>
<li>Si vous voulez pr&eacute;senter un logiciel libre dont vous êtes lauteur.</li>
<li>Si vous voulez présenter un logiciel libre dont vous êtes lauteur.</li>
</ul>
Nous serons heureux de vous &eacute;couter.
Nous serons heureux de vous écouter.
<br>
Nous souhaitons proposer des conf&eacute;rences pour un public d&eacute;butant
Nous souhaitons proposer des conférences pour un public débutant
autant que pour des visiteurs avertis. Les sujets ne doivent pas
forc&eacute;ment être techniques, mais aussi dordre g&eacute;n&eacute;ral avec la seule
forcément être techniques, mais aussi dordre général avec la seule
contrainte de traiter de près ou de loin des logiciels libres, de la
communaut&eacute; ou de vos propres exp&eacute;riences dutilisateur quotidien. <br>
communauté ou de vos propres exp&eacute;riences dutilisateur quotidien. <br>
Le but de ces conf&eacute;rences est double :
<ul>
<li>donner confiance aux futurs utilisateurs de logiciels libres</li>
@@ -205,7 +205,7 @@ NothingTitle = u"Vous n'avez pas sollicit&eacute; d'intervention %s." % CurEvent
<fieldset>
<legend class="lowshadow">Historique</legend>
<%
Selection = filter(lambda x:(x.event_type==CurEventType and x.for_year!=CurrentYear), uprofil.events)
Selection = list(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&eacute;sol&eacute;, Il n'y a rien dans l'historique vous concernant."
%>
+1 -1
View File
@@ -30,7 +30,7 @@
</tbody>
</table>
<div class="center">
Pour un co-voiturage le <u>${Exch.start_time.strftime("%a %d %b").decode('utf-8')}</u>
Pour un co-voiturage le <u>${Exch.start_time.strftime("%a %d %b")}</u>
vers <strong>${Exch.start_time.strftime("%H:%M")}</strong>
</div>
Temps de voyage estimé à <span id="summary"></span>
+1 -1
View File
@@ -12,7 +12,7 @@
<dd>Un hébergement</dd>
% endif
<dt>Quand </dt>
<dd>La nuit du ${Exch.start_time.strftime('%A %d %b %Y').decode('utf-8')} jusqu'au lendemain</dd>
<dd>La nuit du ${Exch.start_time.strftime('%A %d %b %Y')} jusqu'au lendemain</dd>
% if Exch.description:
<dt>Détails </dt>
<dd>${Exch.description}</dd>
+2 -2
View File
@@ -8,8 +8,8 @@
<dt>Catégorie</dt>
<dd>${Exch.Category.exch_subtype}</dd>
<dt>Quand </dt>
<dd>de ${Exch.start_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${Exch.start_time.strftime('%Hh%M')}
à ${Exch.end_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${Exch.end_time.strftime('%Hh%M')}
<dd>de ${Exch.start_time.strftime('%A %d %b %Y')} vers ${Exch.start_time.strftime('%Hh%M')}
à ${Exch.end_time.strftime('%A %d %b %Y')} vers ${Exch.end_time.strftime('%Hh%M')}
</dd>
<dt>Détails </dt>
<dd>${Exch.description}</dd>
+17 -17
View File
@@ -8,11 +8,11 @@ DicExch = Exchanges.get_overview( request.user.uid )
<div class="tabbable tabs-left" id="Intendance_tab">
<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 class="active"> <a href="#ResumeInt" data-toggle="tab">Resumé</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>
<li> <a href="#Hebergement" data-toggle="tab"><span style="font-size:1.8em;">&#127962;</span> Hébergement</a> </li>
<li> <a href="#Materiel" data-toggle="tab"><span style="font-size:1.8em;">&#128722;</span> Maté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 &eacute;changes</legend>
<legend>Tous les échanges</legend>
${Missing(Type, DicExch['Missing'])}
</fieldset>
</%def>
@@ -59,23 +59,23 @@ DicForm = {
</td>
<td>
<p>
Compl&eacute;tez dès à pr&eacute;sent votre partie repas afin que l'on puisse faire les r&eacute;servations n&eacute;cessaires !
Complétez dès à présent votre partie repas afin que l'on puisse faire les réservations nécessaires !
</p>
<u>Vendredi soir :</u>
<p>
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 />
Certains conférenciers viennent de très loin et seront présent dés le vendredi.<br />
Nous vous proposons de nous retrouver à proximité, à 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&eacute;s' qui sera pr&eacute;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és' qui sera présent sur le parking de PolyTech<br />
</p>
<u>Samedi Soir :</u>
<p>
Pour conclure la journ&eacute;e nous avons l'habitude de nous retrouver au repas de cloture.<br />
Pour conclure la journé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 &eacute;changes ${CurTitle}
Les é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&eacute;tails</th>
<th>Dé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 &eacute;change ${CurTitle} propos&eacute; actuellement...</i>
<i>Il n'y a aucun échange ${CurTitle} proposé actuellement...</i>
</td>
</tr>
% else:
@@ -155,7 +155,7 @@ elif Type=='M':
<a href="/user/${item.provider.slug}"> ${item.provider.prenom} ${item.provider.nom} </a> offre
% endif
% if item.exch_type=="C":
un co-voiturage le ${item.start_time.strftime('%a %d %b vers %Hh%M').decode('utf-8')}
un co-voiturage le ${item.start_time.strftime('%a %d %b vers %Hh%M')}
de <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.start.place_id}')">${item.Itin.start.display_name}</a>
à <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.arrival.place_id}')">${item.Itin.arrival.display_name}</a>
% elif item.exch_type=="M":
@@ -165,8 +165,8 @@ elif Type=='M':
% if item.description:
${item.description[:30]}
% endif
de ${item.start_time.strftime('%a %d %b %Hh%M').decode('utf-8')}
à ${item.end_time.strftime('%a %d %b %Hh%M').decode('utf-8')}
de ${item.start_time.strftime('%a %d %b %Hh%M')}
à ${item.end_time.strftime('%a %d %b %Hh%M')}
% else:
% if item.Category:
<i>${item.Category.exch_subtype}</i>
@@ -174,7 +174,7 @@ elif Type=='M':
% if item.description:
${item.description[:30]}
% endif
${item.start_time.strftime('%a %d %b').decode('utf-8')} soir
${item.start_time.strftime('%a %d %b')} soir
% endif
</p>
</td>
@@ -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 compteurs de l´&eacute;v&eacute;nement</a>
<a class="accordion-toggle" data-toggle="collapse" data-parent="#AccordionCounter" href="#collapseAll">Les compteurs de l´év&eacute;nement</a>
</div>
<div id="collapseAll" class="accordion-body collapse">
<div class="accordion-inner">
+4 -4
View File
@@ -97,17 +97,17 @@ elif Type=='M':
</td>
<td>
%if Type=='C':
${item.start_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${item.start_time.strftime('%Hh%M')}
${item.start_time.strftime('%A %d %b %Y')} vers ${item.start_time.strftime('%Hh%M')}
de <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.start.place_id}')">${item.Itin.start.display_name}</a>
à <a href="javascript:DoGetLieu('/${CurrentYear}/modal/Place/${item.Itin.arrival.place_id}')">${item.Itin.arrival.display_name}</a>
%elif Type=='H':
% if item.Category:
<i>${item.Category.exch_subtype}</i>,
% endif
La nuit du ${item.start_time.strftime('%A %d %b %Y').decode('utf-8')}<br>
La nuit du ${item.start_time.strftime('%A %d %b %Y')}<br>
%elif Type=='M':
de ${item.start_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${item.start_time.strftime('%Hh%M')}
à ${item.end_time.strftime('%A %d %b %Y').decode('utf-8')} vers ${item.end_time.strftime('%Hh%M')}<br>
de ${item.start_time.strftime('%A %d %b %Y')} vers ${item.start_time.strftime('%Hh%M')}
à ${item.end_time.strftime('%A %d %b %Y')} vers ${item.end_time.strftime('%Hh%M')}<br>
${item.Category.exch_subtype}
%endif
%if item.description:
+4 -4
View File
@@ -23,12 +23,12 @@
<%
DicFormA = {
'nom': {'PlaceHolder':u"Mon Nom", 'ContainerClass':"span6", 'next':False},
'prenom': {'PlaceHolder':u"Mon Pr&eacute;nom", 'ContainerClass':"span6", 'next':True},
'prenom': {'PlaceHolder':u"Mon Pré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&eacute; gpg", 'ContainerClass':"span6", 'next':False},
'gpg_key': {'PlaceHolder':u"Ma clé 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&eacute;nom", "FieldStyle":"width:16em;"},
'prenom': {'PlaceHolder':u"Mon Pré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&eacute; gpg", "FieldStyle":"width:90%;"},
'gpg_key': {'PlaceHolder':u"Ma clé 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}
+13 -13
View File
@@ -14,14 +14,14 @@ fieldset:disabled {
% else:
<legend class="lowshadow">
<img style="max-height:50px;" src="/img/warn.png" alt="Attention !">
Vous n'avez pas confirm&eacute; votre venue aux JM2L ${CurrentYear}
Vous n'avez pas confirmé votre venue aux JM2L ${CurrentYear}
</legend>
<h4 class="lowshadow">Compl&eacute;tez et validez vite ce formulaire !</h4>
<h4 class="lowshadow">Complétez et validez vite ce formulaire !</h4>
% endif
<form id="ProfilForm" action="/MonSejour" method="POST">
<fieldset class="ComeToJM2L">
<legend>Arriv&eacute;e</legend>
<legend>Arrivée</legend>
<div class="form-inline">
J'arrive
<select style="width:12em;" id="Arrival:Place" name="Arrival:Place" title="Lieu">
@@ -63,16 +63,16 @@ fieldset:disabled {
<ul style="list-style-type: none;">
<li><label class="checkbox">
<input id="PMR" ${mytrip.IsCheck("Arrival:PMR")|n} name="Arrival:PMR" title="Assistance Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
d'assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)</input></label>
<input id="PMR" ${mytrip.IsCheck("Arrival:PMR")|n} name="Arrival:PMR" title="Assistance Personne à mobilité réduite (PMR)" type="checkbox">
d'assistance : Personne à mobilité réduite (PMR)</input></label>
</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&eacute;bergement...<br>(j'ai rempli/je vais remplir la section Logistique).</input></label>
d'un covoiturage, d'un hé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">
de bras, car je rapporte plein de mat&eacute;riel. <br>(Je transporte ma maison, mon garage ...)</input></label>
de bras, car je rapporte plein de matériel. <br>(Je transporte ma maison, mon garage ...)</input></label>
</li>
<li>
<div class="form-inline">
@@ -81,7 +81,7 @@ fieldset:disabled {
Autres
</input></label>
<input type="text" style="width:20em;" name="Arrival:Comment"
placeholder="Pr&eacute;cisions à propos de mon arriv&eacute;e…" />
placeholder="Précisions à propos de mon arrivée…" />
</div>
</li>
</ul>
@@ -90,7 +90,7 @@ fieldset:disabled {
</fieldset>
<fieldset class="ComeToJM2L">
<legend>D&eacute;part</legend>
<legend>Départ</legend>
<div class="form-inline">
Je repars
<select style="width:12em;" id="Departure:Place" class="formforform-field" name="Departure:Place" title="Alors, j'arrive">
@@ -130,8 +130,8 @@ fieldset:disabled {
Je vais avoir besoin: &nbsp;&nbsp;<small style="color: #aaa;">(Cochez les cases correspondantes)</small>
<ul style="list-style-type: none;">
<li><label class="checkbox">
<input id="PMR" ${mytrip.IsCheck("Departure:PMR")|n} name="Departure:PMR" title="d'Assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)" type="checkbox">
d'assistance : Personne à mobilit&eacute; r&eacute;duite (PMR)</input>
<input id="PMR" ${mytrip.IsCheck("Departure:PMR")|n} name="Departure:PMR" title="d'Assistance : Personne à mobilité réduite (PMR)" type="checkbox">
d'assistance : Personne à mobilité réduite (PMR)</input>
</label>
</li>
<li><label class="checkbox">
@@ -141,7 +141,7 @@ fieldset:disabled {
</li>
<li><label class="checkbox">
<input id="Bras" ${mytrip.IsCheck("Departure:Bras")|n} name="Departure:Bras" title="de bras" type="checkbox">
de bras, car j'ai en stock plein de mat&eacute;riel (Ma maison).</input>
de bras, car j'ai en stock plein de matériel (Ma maison).</input>
</label>
</li>
<li>
@@ -151,7 +151,7 @@ fieldset:disabled {
Autres
</input></label>
<input type="text" style="width:20em;" name="Departure:Comment"
placeholder="Pr&eacute;cisions à propos de mon d&eacute;part…" />
placeholder="Précisions à propos de mon départ…" />
</div>
</li>
</ul>
+1 -1
View File
@@ -111,7 +111,7 @@ if Counter==0:
vid = event.video.first()
pres = event.presentation.first()
%>
${event.start_time.strftime("%a %d %b").decode('utf-8')}<br>
${event.start_time.strftime("%a %d %b")}<br>
${event.start_time.strftime("%H:%M")} - ${event.end_time.strftime("%H:%M")}
</td>
<td style="position: relative;">
+2 -2
View File
@@ -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&eacute;finie pour le moment.</i>
<i>Il n'y a pas de salle dé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&eacute;er</a> ]
[ <a href="/PhySalles">Créer</a> ]
% endif
</div>
+2 -2
View File
@@ -29,9 +29,9 @@
%endif
<%
DicForm = {
'year_uid': {'PlaceHolder':u"Ann&eacute;e", "FieldStyle":"width:7em;", "ContainerStyle":"float:left;" },
'year_uid': {'PlaceHolder':u"Anné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'&eacute;vènement","FieldStyle":"width:15em;" },
'place_type': {'PlaceHolder':u"Type d'é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
View File
@@ -46,7 +46,7 @@
</td>
</tr>
% endif
% for item, one_dic in found.iteritems():
% for item, one_dic in found.items():
<tr>
<td>
<a href="/user/${item}">
+1 -1
View File
@@ -63,7 +63,7 @@ from slugify import slugify
</a>
<span style="float:right;">
- <a href="/user/${task.assignee.slug}">${task.assignee.pseudo or ' '.join([task.assignee.prenom, task.assignee.nom]) }</a>
- ${task.due_date.strftime("%d %b").decode("utf-8")}
- ${task.due_date.strftime("%d %b")}
</span>
% endif
</td>
+3 -3
View File
@@ -30,7 +30,7 @@
%endif
% if 'uid' in form._fields:
<div class="borderboxtime">
${event.start_time.strftime('%d %b %Y').decode('utf-8')} -
${event.start_time.strftime('%d %b %Y')} -
${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')}
%if event.Salle:
- <strong>Salle</strong>: ${event.Salle.name}
@@ -184,10 +184,10 @@ DicForm = {
</fieldset>
<div class="clearfix">&nbsp;</div>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y')}</p>
%else:
<p style="float:right;">Créé le
${datetime.now().strftime('%d %b %Y').decode('utf-8')}
${datetime.now().strftime('%d %b %Y')}
</p>
% endif
<br/>
+14 -14
View File
@@ -7,7 +7,7 @@ TabJs = {'select':[], 'desc':[]}
%>
<div class="row-fluid">
% for FieldName, Field in form._fields.items():
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("Ignore"):
% if Field.name in DicFormat and DicFormat[Field.name].get("Ignore"):
<% continue %>
% endif
% if Field.type in ['HiddenField', 'CSRFTokenField']:
@@ -27,7 +27,7 @@ TabJs = {'select':[], 'desc':[]}
</a>
% endif
</label>
% if DicFormat.has_key(Field.name):
% if Field.name in DicFormat:
<%
PlaceHolder = DicFormat[Field.name].get("PlaceHolder")
Class = [False,"ckeditor"][ "ckeditor" in DicFormat[Field.name] ]
@@ -49,7 +49,7 @@ TabJs = {'select':[], 'desc':[]}
% endfor
</div>
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("next")==True:
% if Field.name in DicFormat and DicFormat[Field.name].get("next")==True:
</div>
<div class="row-fluid">
% endif
@@ -72,7 +72,7 @@ TabJs = {'select':[], 'desc':[]}
TabJs = {'select':[], 'desc':[]}
%>
% for FieldName, Field in form._fields.items():
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("Ignore"):
% if Field.name in DicFormat and DicFormat[Field.name].get("Ignore"):
<% continue %>
% endif
% if Field.type in ['HiddenField', 'CSRFTokenField']:
@@ -81,11 +81,11 @@ TabJs = {'select':[], 'desc':[]}
% elif Field.type=="SelectField":
<% TabJs['select'].append(Field.label.field_id) %>
% endif
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"):
% if Field.name in DicFormat and DicFormat[Field.name].get("fieldset"):
<fieldset>
<legend>${Field.label.text}</legend>
% else:
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("ContainerStyle"):
% if Field.name in DicFormat and DicFormat[Field.name].get("ContainerStyle"):
<div style="padding-right:5px;${DicFormat[Field.name].get("ContainerStyle")}">
% else:
<div style="padding-right:5px;">
@@ -101,7 +101,7 @@ TabJs = {'select':[], 'desc':[]}
% endif
</label>
% endif
% if DicFormat.has_key(Field.name):
% if Field.name in DicFormat:
<%
PlaceHolder = DicFormat[Field.name].get("PlaceHolder")
FieldStyle = DicFormat[Field.name].get("FieldStyle")
@@ -122,7 +122,7 @@ TabJs = {'select':[], 'desc':[]}
${ error }
</div>
% endfor
% if DicFormat.has_key(Field.name) and DicFormat[Field.name].get("fieldset"):
% if Field.name in DicFormat and DicFormat[Field.name].get("fieldset"):
</fieldset>
% else:
</div>
@@ -142,7 +142,7 @@ TabJs = {'select':[], 'desc':[]}
<%def name="sejour_wrapper(Places)">
<div class="form-inline">
D&eacute;part :
Dé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&eacute;e :
Arrivé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&eacute; le lieu dont j´ai besoin dans ces listes...</small>
<small style="color:#999">Si je n´ai pas trouvé 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');">
@@ -350,9 +350,9 @@ TabJs = {'select':[], 'desc':[]}
<tr>
<td style="text-align:center;" colspan="2">
% if NotFoundTitle:
<i>${NotFoundTitle}</i>
<i>${NotFoundTitle | h}</i>
% else:
<i>D&eacute;sol&eacute;, Il n'y a rien dans l'historique.</i>
<i>Désolé;, Il n'y a rien dans l'historique.</i>
% endif
</td>
</tr>
@@ -366,7 +366,7 @@ TabJs = {'select':[], 'desc':[]}
vid = event.video.first()
pres = event.presentation.first()
%>
${event.start_time.strftime('%d %b %Y').decode('utf-8')}
${event.start_time.strftime('%d %b %Y')}
${start.hour}:${"%.2d" % start.minute}-${end.hour}:${"%.2d" % end.minute}
</td>
<td style="position: relative;">${event.event_type}:
+7 -7
View File
@@ -61,7 +61,7 @@
<div class="tabbable" id="main_tab">
<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&eacute;jour</a></li>
<li><a href="#Sejour" id="Map_Sejour" data-toggle="tab">Mon Séjour</a></li>
<li><a href="#Logistique" id="Map_Logistique" data-toggle="tab">Logistique</a></li>
<li><a href="#Interventions" id="Map_Interventions" data-toggle="tab">Mes Interventions</a></li>
<li><a href="#Frais" id="Map_Frais" data-toggle="tab">Mes Frais</a></li>
@@ -79,8 +79,8 @@
<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&eacute;</a> </li>
<li> <a href="#Conference" data-toggle="tab">Conf&eacute;rence</a> </li>
<li class="active"> <a href="#ResumePart" data-toggle="tab">Resumé</a> </li>
<li> <a href="#Conference" data-toggle="tab">Conférence</a> </li>
<li> <a href="#Stand" data-toggle="tab">Stand</a> </li>
<li> <a href="#Atelier" data-toggle="tab">Atelier</a> </li>
<li> <a href="#TableRonde" data-toggle="tab">Table Ronde</a> </li>
@@ -118,12 +118,12 @@
<div class="tab-pane fade" id="Frais">
<fieldset>
<legend class="lowshadow">Une participation à mes frais ?</legend>
L'&eacute;quipe des JM2L participe aux <u>frais de transport</u> des intervenants !<br /><br />
L'é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&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 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 <strong>présentez l'original de vos tickets</strong> à l'accueil pendant l'évènement.</li>
<li>Tous vos documents sont conformes.</li>
</ul>
+16 -16
View File
@@ -3,7 +3,7 @@
<%namespace name="helpers" file="jm2l:templates/helpers.mako"/>
<%
context._kwargs['postpone_js']=[]
DisplayYear = request.session.get('year', 2018)
DisplayYear = request.session.get('year', 2020)
%>
<head>
<title>JM2L ${DisplayYear}</title>
@@ -68,12 +68,12 @@ ${helpers.uploader_js()}
% if request.user and request.user.vote_logo not in [1,2,3]:
<div class="item active">
<div class="align-center">
<H1>JM2L 2017</H1>
<h3>Choisissez ici votre logo pr&eacute;f&eacute;r&eacute; !</h3>
<H1>JM2L 2020</H1>
<h3>Choisissez ici votre logo préféré !</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&eacute;sitez pas à envoyer vos propositions par mail à l'&eacute;quipe !</p>
N'hésitez pas à envoyer vos propositions par mail à l'équipe !</p>
</div>
</div>
% endif
@@ -105,10 +105,10 @@ ${helpers.uploader_js()}
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
Édition&nbsp;<span class="caret"></span></a>
<ul class="dropdown-menu pull-right" style="min-width:0">
% for tmpyear in range(2018, 2005, -1):
% for tmpyear in range(2020, 2005, -1):
% if tmpyear==DisplayYear:
<li><a style="font-weight: bold;" href="/year/${tmpyear}">${tmpyear}</a></li>
% elif tmpyear!=2014 and tmpyear!=2016:
% elif tmpyear not in [2014, 2016, 2018, 2019]:
<li><a href="/year/${tmpyear}">${tmpyear}</a></li>
% endif
% endfor
@@ -128,17 +128,17 @@ ${helpers.uploader_js()}
% if request.user:
% if request.user.Staff:
<li><a href="/${DisplayYear}/Staff">Partie Staff</a></li>
<li><a href="/${DisplayYear}/ListParticipant">G&eacute;rer les intervenants</a></li>
<li><a href="/ListSalles">G&eacute;rer les salles</a></li>
<li><a href="/entities">G&eacute;rer les entit&eacute;s</a></li>
<li><a href="/${DisplayYear}/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="/${DisplayYear}/ListOrga">Participations &agrave; l'orga</a></li>
<li><a href="/${DisplayYear}/Staff/compta">Comptabilit&eacute;</a></li>
<li><a href="/${DisplayYear}/Staff/compta">Comptabilité</a></li>
<li><a href="/ListSallesPhy">Les salles &agrave; Poly'tech</a></li>
<li role="separator" class="divider"></li>
% endif
<li><a href="/MesJM2L">Mon profil</a></li>
<li><a href="/user/${request.user.slug}">Mon profil public</a></li>
<li><a href="/sign/out">Me d&eacute;connecter</a></li>
<li><a href="/sign/out">Me déconnecter</a></li>
% else:
<li><a href="/participer-l-evenement#inscription">Je m'inscris</a></li>
<li><a href="/sign/login">Je m'identifie</a></li>
@@ -186,9 +186,9 @@ ${helpers.uploader_js()}
<footer class="footer">
<div class="container">
<h4>JM2L 2005-2018</h4>
<h4>JM2L 2005-2020</h4>
<p>
Concoct&eacute; par <a href="http://www.linux-azur.org/">Linux Azur</a> ~
Concocté par <a href="http://www.linux-azur.org/">Linux Azur</a> ~
<a href="http://creativecommons.org/licenses/by-sa/4.0/">CopyFriendly</a>
</p>
<p>
@@ -196,10 +196,10 @@ ${helpers.uploader_js()}
</p>
<p>
Conception et construction en <a href="http://git.linux-azur.org/JM2L/jm2l/src/master">DIY</a> ~
H&eacute;berg&eacute; par <a href="http://www.heberg-24.com/"> Heberg24 </a>
Hébergé par <a href="http://www.heberg-24.com/"> Heberg24 </a>
</p>
<p>
Vous avez trouv&eacute; un bug ? <a href="http://git.linux-azur.org/JM2L/jm2l/issues">Reportez-le ici</a>
Vous avez trouvé un bug ? <a href="http://git.linux-azur.org/JM2L/jm2l/issues">Reportez-le ici</a>
</p>
</div>
</footer>
@@ -245,7 +245,7 @@ function handlevote() {
$('.carousel-vote a').attr('href', "/vote_logo/" + currentIndex )
if (currentIndex==${request.user.vote_logo or 0}) {
$('.carousel-vote a').removeClass('btn-primary').addClass('btn-success')
$('.carousel-vote a').html("<i class='icon-ok icon-white'></i> Mon pr&eacute;f&eacute;r&eacute; ! ");
$('.carousel-vote a').html("<i class='icon-ok icon-white'></i> Mon préféré ! ");
} else {
$('.carousel-vote a').removeClass('btn-success').addClass('btn-primary');
$('.carousel-vote a').html("<i class='icon-star icon-white'></i> Je vote pour ce logo ! ");
+3 -3
View File
@@ -96,7 +96,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:
% for t in sorted(User.task_assoc, key=lambda k:k.due_date):
% if not t.closed:
<tr>
<td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td>
<td>${t.due_date.strftime('%d %B %Y')}</td><td>${t.area.name}</td>
<td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a>
% endif
% endfor
@@ -107,7 +107,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:
% for t in sorted(Contact.task_assoc, key=lambda k:k.due_date):
% if not t.closed:
<tr>
<td>${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')}</td><td>${t.area.name}</td>
<td>${t.due_date.strftime('%d %B %Y')}</td><td>${t.area.name}</td>
<td><a href="http://jm2l.linux-azur.org/2017/Staff/tasks/${t.uid}">${t.name}</a>
% endif
% endfor
@@ -116,7 +116,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:
Pour accéder à ton espace sur le site, il te suffit de cliquer sur le <a href="${request.route_url('bymail', hash=User.my_hash)}">lien suivant.</a>
<br/><br/>
% for t in filter(lambda k:k.uid==51, Contact.task_assoc):
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B').decode('utf-8', 'xmlcharrefreplace')} à 19h30.
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B')} à 19h30.
% endfor
<p>
Bon courage !
+3 -3
View File
@@ -65,7 +65,7 @@ Voici ce qu'il y'a dans la liste des tâches qui te sont assignées:
% for t in sorted(User.task_assoc, key=lambda k:k.due_date):
% if not t.closed:
- Pour le ${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')} - ${t.area.name} tâche ${t.uid}
- Pour le ${t.due_date.strftime('%d %B %Y')} - ${t.area.name} tâche ${t.uid}
=> ${t.name}
% endif
@@ -75,7 +75,7 @@ Et il y'a aussi des tâches communes !
% for t in sorted(Contact.task_assoc, key=lambda k:k.due_date):
% if not t.closed and t.uid!=51:
- Pour le ${t.due_date.strftime('%d %B %Y').decode('utf-8', 'xmlcharrefreplace')} - ${t.area.name} tâche ${t.uid}
- Pour le ${t.due_date.strftime('%d %B %Y')} - ${t.area.name} tâche ${t.uid}
=> ${t.name}
% endif
@@ -85,7 +85,7 @@ Pour accéder à ton espace il te suffit de cliquer sur le lien suivant :
${request.route_url('bymail', hash=User.my_hash)}.
% for t in filter(lambda k:k.uid==51, Contact.task_assoc):
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B').decode('utf-8', 'xmlcharrefreplace')} à 19h30.
Nous avons fixé la prochaine réunion JM2L au ${t.due_date.strftime('%d %B')} à 19h30.
% endfor
+1 -1
View File
@@ -52,7 +52,7 @@
</div>
<br/>
<hr/>
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y')}</p>
</div>
</div>
+2 -2
View File
@@ -13,7 +13,7 @@
</div>
<strong>${event.event_type}</strong>:
<div class="borderboxtime">
${event.start_time.strftime('%d %b %Y').decode('utf-8')} -
${event.start_time.strftime('%d %b %Y')} -
${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')}
</div>
% if event.for_year==CurrentYear and request.user and (request.user.Staff or request.user in event.intervenants):
@@ -116,7 +116,7 @@
</p>
% endfor
<div class="clearfix">&nbsp;</div>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${event.created.strftime('%d %b %Y')}</p>
<br/>
<hr/>
</div>
+1 -1
View File
@@ -103,7 +103,7 @@ ${The_entity_type.entity_subtype}
</p>
% endfor
<br/><br/>
<p style="float:right;">Créé le ${entity.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${entity.created.strftime('%d %b %Y')}</p>
<br/>
<hr/>
+1 -1
View File
@@ -47,7 +47,7 @@
<h4>Ses interventions :</h4>
${helpers.show_Interventions(DispUser.events)}
% endif
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y').decode('utf-8')}</p>
<p style="float:right;">Créé le ${DispUser.created.strftime('%d %b %Y')}</p>
</div>
</div>
+21 -21
View File
@@ -1,6 +1,6 @@
# -*- coding: utf8 -*-
import io
from pyramid.response import Response
import cStringIO as StringIO
from pyramid.view import view_config
from .models import DBSession, Event, Salles
from reportlab.pdfgen import canvas
@@ -25,14 +25,15 @@ def JM2L_large_Logo(canvas, Offset=(0,0)):
canvas.drawCentredString(WIDTH / 2 - OffY, HEIGHT - 100 - OffX, "JM2L")
canvas.setFont("Helvetica-Bold", 30)
yearobject = canvas.beginText()
yearobject.setFillColorRGB(1,1,1)
yearobject.setTextRenderMode(0)
yearobject.setTextOrigin(WIDTH/2-OffY-120, HEIGHT-36-OffX)
yearobject.setWordSpace(48)
yearobject.textLines("2 0 1 5")
yearobject.setWordSpace(1)
canvas.drawText(yearobject)
year_object = canvas.beginText()
year_object.setFillColorRGB(1, 1, 1)
year_object.setTextRenderMode(0)
year_object.setTextOrigin(WIDTH / 2 - OffY - 120, HEIGHT - 36 - OffX)
year_object.setWordSpace(48)
year_object.textLines("2 0 1 5")
year_object.setWordSpace(1)
canvas.drawText(year_object)
def one_time_step(canvas, str, hour, max_size, offset):
max_x, max_y = max_size
@@ -51,13 +52,13 @@ def stand_print(request):
# Ok let's generate a print for place schedule
# Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO.StringIO()
pdf = io.BytesIO()
c = canvas.Canvas(pdf, pagesize=(HEIGHT, WIDTH))
c.translate(mm, mm)
@@ -92,19 +93,18 @@ def stand_print(request):
return Response(app_iter=pdf, content_type='application/pdf')
@view_config(route_name='place_print', http_cache=(EXPIRATION_TIME, {'public': True}))
def place_print(request):
# Ok let's generate a print for place schedule
# Register LiberationMono font
ttfFile = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttfFile))
ttf_file = "jm2l/static/fonts/LiberationMono-Regular.ttf"
pdfmetrics.registerFont(TTFont("Liberation", ttf_file))
#  Import font
ttfFile_Logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttfFile_Logo))
ttf_file_logo = "jm2l/static/fonts/PWTinselLetters.ttf"
pdfmetrics.registerFont(TTFont("Logo", ttf_file_logo))
pdf = StringIO.StringIO()
pdf = io.BytesIO()
c = canvas.Canvas(pdf, pagesize=(WIDTH, HEIGHT))
c.translate(mm, mm)
@@ -165,6 +165,7 @@ def place_print(request):
return Response(app_iter=pdf, content_type='application/pdf')
def place_time(c, ev, max_size, offset):
max_x, max_y = max_size
off_x, off_y = offset
@@ -181,4 +182,3 @@ def place_time(c, ev, max_size, offset):
intervs = ', '.join([x.slug for x in ev.intervenants])
c.setFont('Helvetica', 10)
c.drawCentredString(WIDTH / 2, max_y + off_y - 55 - start_pos_y, intervs, 0)
+12 -8
View File
@@ -9,7 +9,10 @@ from os import path
import mimetypes
import magic
import subprocess
import cStringIO as StringIO
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
# Database access imports
from .models import User, Place, Tiers, Event, SallePhy
from .blenderthumbnailer import blend_extract_thumb, write_png
@@ -32,8 +35,6 @@ ACCEPTED_MIMES = ['application/pdf',
'application/x-blender'
]
ACCEPT_FILE_TYPES = IMAGE_TYPES
THUMBNAIL_SIZE = 80
EXPIRATION_TIME = 300 # seconds
@@ -45,6 +46,7 @@ DELETEMETHOD="DELETE"
mimetypes.init()
class MediaPath():
def get_all(self, media_table, linked_id, MediaType=None):
@@ -73,7 +75,6 @@ class MediaPath():
filelist.append((ress_url, thumb_url))
return filelist
def get_list(self, media_table, linked_id, MediaType=None):
filelist = list()
curpath = self.get_mediapath(media_table, linked_id, None)
@@ -191,7 +192,7 @@ class MediaPath():
if not os.path.isdir(os.path.dirname(TargetPath)):
try:
os.makedirs(os.path.dirname(TargetPath))
except OSError, e:
except OSError as e:
if e.errno != 17:
raise e
return os.path.join('jm2l/upload', *p)
@@ -217,12 +218,12 @@ class MediaPath():
fileobj.seek(0)
# Check if the binary file is a blender file
if ( mimetype == "application/octet-stream" or mimetype == "application/x-gzip" ) and self.check_blend_file(fileobj):
if (mimetype == "application/octet-stream" or mimetype == "application/x-gzip") and self.check_blend_file(
fileobj):
return "application/x-blender", True
else:
return mimetype, False
def get_mimetype(self, name):
""" This function return the mime-type based on .type file """
try:
@@ -232,6 +233,7 @@ class MediaPath():
except IOError:
return None
@view_defaults(route_name='media_upload')
class MediaUpload(MediaPath):
@@ -378,8 +380,9 @@ class MediaUpload(MediaPath):
('Impress', 'odp'),
('Calc', 'ods'),
('Draw', 'odg')]
stampfilename = filter(lambda (x,y): ext.endswith(y), istamp)
stampfilename = filter(lambda x, y: ext.endswith(y), istamp)
stamp = Image.open("jm2l/static/img/%s-icon.png" % stampfilename[0][0])
timage = Image.new('RGBA', (THUMBNAIL_SIZE, THUMBNAIL_SIZE), (255, 255, 255, 0))
# Add thumbnail
timage.paste(
@@ -570,6 +573,7 @@ class MediaUpload(MediaPath):
results.append(result)
return {"files": results}
@view_defaults(route_name='media_view')
class MediaView(MediaPath):
+117 -46
View File
@@ -22,11 +22,15 @@ 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
from .security import check_staff, check_logged
# Then, standard libs
import csv
import cStringIO as StringIO
import webhelpers.paginate as paginate
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import io
import paginate
import unicodedata
import datetime
import re
@@ -36,6 +40,7 @@ from jm2l.const import CurrentYear
from passlib.hash import argon2
## =-=- Here, We keep some usefull function -=-=
def remove_accents(input_str):
""" This function is intended to remove all accent from input unicode string """
@@ -43,6 +48,7 @@ def remove_accents(input_str):
only_ascii = nkfd_form.encode('ASCII', 'ignore')
return only_ascii
def embeed_video(mime_type, link):
Container = "<video controls='controls' preload='metadata' style='width:60%'>"
Container += "<source type='%s' " % mime_type
@@ -63,6 +69,7 @@ def Live(request):
.order_by(Event.start_time)
return {'year': year, "DisplayYear": year, 'events': Events, "logged_in": request.authenticated_userid}
## =-=- Here, We handle ICal requests -=-=
@view_config(route_name='progr_iCal', renderer="string")
def ICal_Progamme_Request(request):
@@ -103,6 +110,7 @@ def ICal_Progamme_Request(request):
request.response.content_type = "text/calendar"
return cal.to_ical()
## =-=- Here, We handle ICal requests -=-=
@view_config(route_name='progr_dyn_iCal', renderer="string")
def ICal_Progamme_Dyn_Request(request):
@@ -147,10 +155,13 @@ def ICal_Progamme_Dyn_Request(request):
event = Evt()
event['uid'] = "%d/%d" % (year, ev.uid)
event.add('summary', ev.name)
event.add('dtstart', ev.start_time.replace(tzinfo=tz, day=today.day, month = today.month, hour=(ev.start_time.hour)%24 ) )
event.add('dtend', ev.end_time.replace(tzinfo=tz, day=today.day, month = today.month, hour=(ev.end_time.hour)%24 ) )
event.add('dtstart', ev.start_time.replace(tzinfo=tz, day=today.day, month=today.month,
hour=(ev.start_time.hour) % 24))
event.add('dtend',
ev.end_time.replace(tzinfo=tz, day=today.day, month=today.month, hour=(ev.end_time.hour) % 24))
event.add('created', ev.last_change.replace(tzinfo=tz))
event.add('description', "http://jm2l.linux-azur.org:8080/%s.webm" % TabCorr.get(ev.Salle.phy_salle_id, ev.Salle.phy_salle_id) )
event.add('description', "http://jm2l.linux-azur.org:8080/%s.webm" % TabCorr.get(ev.Salle.phy_salle_id,
ev.Salle.phy_salle_id))
event.add('location', "http://jm2l.linux-azur.org/img/%d.gif" % ev.Salle.phy_salle_id)
event.add('url', "http://www.linux-azur.org/event/%s/%s" % (ev.for_year, ev.slug))
event.add('priority', 5)
@@ -185,6 +196,7 @@ def JSON_User_Request(request):
return {"Results": ListMatchUser, "Total": records.item_count,
"logged_in": request.authenticated_userid}
@view_config(route_name='tiers_json', renderer="json")
def JSON_Tiers_Request(request):
""" Build a JSON answer with active users and pagination handling """
@@ -210,6 +222,7 @@ def JSON_Tiers_Request(request):
return {"Results": ListMatchTiers, "Total": records.item_count,
"logged_in": request.authenticated_userid}
@view_config(route_name='progr_json', renderer="json")
def JSON_Progamme_Request(request):
year = int(request.matchdict.get('year', CurrentYear))
@@ -242,10 +255,9 @@ def JSON_Progamme_Request(request):
})
DicResult[Day.day] = ListEv
return {'all': DicResult}
@view_config(route_name='timeline_json', renderer="json")
def JSON_TimeLine_Request(request):
year = int(request.matchdict.get('year', CurrentYear))
@@ -389,6 +401,7 @@ def JSON_TimeLine_Request(request):
DicResult["date"] = ListEv
return {'timeline': DicResult}
## =-=- Here, We handle HTTP requests - Public Part -=-=
@view_config(route_name='home', renderer="jm2l:templates/NewIndex.mako")
def index_page(request):
@@ -424,6 +437,7 @@ def index_page(request):
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)
@@ -437,6 +451,7 @@ def edit_index(request):
'form': form, 'DisplayYear': year}
return MainTab
@view_config(route_name='programme', renderer="jm2l:templates/Public/Programme.mako")
def programme(request):
year = int(request.matchdict.get('year'))
@@ -453,12 +468,14 @@ 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').decode('utf-8'),
# .decode('utf-8'),
ListDay.append((RefDay.strftime('%A %d %b %Y'),
RefDay.strftime('%d')))
MainTab = {'programme': 'active', 'DisplayYear': year, \
'Events': Events, 'Event': Event, 'Days': ListDay, "logged_in": request.authenticated_userid}
return MainTab
@view_config(route_name='presse', renderer="jm2l:templates/Public/Presse.mako")
def static_presse(request):
year = int(request.matchdict.get('year', None))
@@ -466,6 +483,7 @@ def static_presse(request):
MainTab = {'presse': 'active', "logged_in": request.authenticated_userid, 'content': content, 'DisplayYear': year}
return MainTab
@view_config(route_name='edit_presse', renderer="jm2l:templates/Staff/EditPresse.mako")
def edit_presse(request):
check_staff(request)
@@ -478,6 +496,7 @@ def edit_presse(request):
return MainTab
@view_config(route_name='plan', renderer="jm2l:templates/Public/Plan.mako")
def static_plan(request):
session = request.session
@@ -485,6 +504,7 @@ def static_plan(request):
MainTab = {'plan': 'active', "logged_in": request.authenticated_userid}
return MainTab
## =-=- Here, We handle HTTP requests - Staff Logged Part -=-=
@view_config(route_name='list_task', renderer='jm2l:templates/Staff/list.mako')
def list_view(request):
@@ -624,6 +644,7 @@ def tasks(request):
return {'form': form, 'area': TmpTask.area and slugify(TmpTask.area.name) or '', 'year': year}
@view_config(route_name='handle_pole', renderer='jm2l:templates/Staff/pole.mako')
def tasks_area(request):
check_staff(request)
@@ -648,6 +669,7 @@ def tasks_area(request):
return HTTPFound(location=request.route_url('list_task', year=year) + "#" + slugify(Pole.name))
return {'form': form, 'year': year}
@view_config(route_name='action_task')
def action_task(request):
check_staff(request)
@@ -668,6 +690,7 @@ def action_task(request):
DBSession.delete(Task)
return HTTPFound(location=request.route_url('list_task', year=year) + "#" + slugify(Task.area.name))
@view_config(route_name='action_task_area')
def action_task_area(request):
check_staff(request)
@@ -682,6 +705,7 @@ def action_task_area(request):
DBSession.delete(Pole)
return HTTPFound(location=request.route_url('list_task', year=year))
@view_config(route_name='list_salles', renderer='jm2l:templates/Salles/list.mako')
def list_salles(request):
check_staff(request)
@@ -715,7 +739,8 @@ 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).order_by(sa.desc(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)
@@ -726,6 +751,7 @@ def handle_salle(request):
return HTTPFound(location=request.route_url('list_salles'))
return {'form': form}
@view_config(route_name='handle_salle_phy', renderer='jm2l:templates/Salles/salle_phy.mako')
def handle_salle_phy(request):
check_staff(request)
@@ -748,7 +774,7 @@ def handle_salle_phy(request):
if orig_slug and orig_slug != dest_slug:
try:
mp = MediaPath().move_mediapath('salle', orig_slug, dest_slug)
except RuntimeError, err:
except RuntimeError as err:
request.session.flash(('error', u"Le nom de cette salle est déjà utilisé : " + err.message))
return {'form': form}
Salle.slug = slugify(Salle.name)
@@ -760,6 +786,7 @@ def handle_salle_phy(request):
return HTTPFound(location=request.route_url('list_salles'))
return {'form': form}
@view_config(route_name='action_salle')
def action_salle(request):
check_staff(request)
@@ -773,6 +800,7 @@ def action_salle(request):
DBSession.delete(Salle)
return HTTPFound(location=request.route_url('list_salles'))
## =-=- Here, We handle HTTP requests - User Logged Part -=-=
@view_config(route_name='exchange', renderer="jm2l:templates/Logistique/Logistique.mako")
def exchange(request):
@@ -823,6 +851,7 @@ def exchange(request):
}
return MainTab
@view_config(route_name='miam')
def miam(request):
check_logged(request)
@@ -901,6 +930,7 @@ def sejour(request):
return HTTPFound(location='/MesJM2L#Sejour')
@view_config(route_name='orga')
def orga(request):
check_logged(request)
@@ -929,7 +959,8 @@ def orga(request):
FicheSejour.orga_part = OrgaPart
if UpdateOrga:
request.session.flash(('info',u'Vos modifications de participation à l\'organisation ont été pris en compte.'))
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 !'))
@@ -940,6 +971,7 @@ def orga(request):
return HTTPFound(location='/MesJM2L#Organisation')
@view_config(route_name='vote_logo')
def vote_logo(request):
if request.user is None:
@@ -959,6 +991,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_csv', renderer="string")
def list_users_csv(request):
check_staff(request)
@@ -970,7 +1003,7 @@ def list_users_csv(request):
.outerjoin(adalias) \
.order_by(User.slug) \
.all()
FileHandle = StringIO.StringIO()
FileHandle = io.BytesIO()
fileWriter = csv.writer(FileHandle, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
fileWriter.writerow(["Identifiant_JM2L", "Nom", "Prenom", "Status_%s" % for_year])
for user, sejour in Data:
@@ -1013,6 +1046,7 @@ def list_users(request):
if (r[0] & 4 == 4): DicRepas["Soir"] += 1
return {'Users': Data, 'UserEvent': User_Event, "DicRepas": DicRepas, "for_year": for_year}
@view_config(route_name='list_orga', renderer="jm2l:templates/Participant/list_orga.mako")
def list_orga(request):
check_staff(request)
@@ -1023,6 +1057,7 @@ def list_orga(request):
.all()
return {'Users': Data}
@view_config(route_name='drop_sejour')
def drop_sejour(request):
if request.user is None:
@@ -1038,6 +1073,7 @@ def drop_sejour(request):
raise HTTPNotFound()
return HTTPFound(location='/MesJM2L#Sejour')
@view_config(route_name='jm2l', renderer="jm2l:templates/jm2l.mako")
def jm2l_page(request):
if request.user is None:
@@ -1061,7 +1097,6 @@ def jm2l_page(request):
profil_form = ProfilForm(request.POST, profil, meta={'csrf_context': request.session})
miam_form = MiamForm(request.POST, profil, meta={'csrf_context': request.session})
# Feed FicheSejour if any
FicheSejour = Sejour.by_user(profil.uid, CurrentYear)
if FicheSejour:
@@ -1110,6 +1145,7 @@ def jm2l_page(request):
}
return MainTab
@view_config(route_name='modal', renderer="jm2l:templates/modals.mako")
def Modal(request):
year = int(request.matchdict.get('year', None))
@@ -1241,7 +1277,8 @@ def Modal(request):
Exch.itin_id = Itinerary.itin_id
if form._fields.has_key("Hour_start"):
TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
int(form.Day_start.data), form.Hour_start.data), "%Y %W %w %H:%M")
int(form.Day_start.data),
form.Hour_start.data), "%Y %W %w %H:%M")
Exch.start_time = TargetTime
elif form._fields.has_key("Day_start"):
TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
@@ -1250,7 +1287,8 @@ def Modal(request):
if form._fields.has_key("Hour_end"):
TargetTime = datetime.datetime.strptime('%d %d %d %s' % (year, int(Week), \
int(form.Day_end.data), form.Hour_end.data), "%Y %W %w %H:%M")
int(form.Day_end.data), form.Hour_end.data),
"%Y %W %w %H:%M")
Exch.end_time = TargetTime
elif form._fields.has_key("Day_end"):
TargetTime = datetime.datetime.strptime('%d %d %d' % (year, int(Week), \
@@ -1290,6 +1328,7 @@ def Modal(request):
'logged_in': request.authenticated_userid}
return MainTab
@view_config(route_name='participer', renderer="jm2l:templates/Participer.mako")
def participer(request):
session = request.session
@@ -1320,7 +1359,8 @@ def participer(request):
NewUser = TmpUsr
# Send the Welcome Mail
mailer = request.registry['mailer']
# mailer = request.registry['mailer']
mailer = request.mailer
# Prepare Plain Text Message :
Mail_template = Template(filename='jm2l/templates/mail_plain.mako')
mail_plain = Mail_template.render(request=request, User=NewUser, action="Welcome")
@@ -1344,6 +1384,7 @@ def participer(request):
'logged_in': request.authenticated_userid}
return MainTab
@view_config(route_name='year')
def change_year(request):
year = int(request.matchdict.get('year', -1))
@@ -1353,15 +1394,18 @@ def change_year(request):
return HTTPFound(location='/%s/' % year)
return HTTPFound(location=request.route_url('home', year=''))
@view_config(route_name='pict_user', renderer="jm2l:templates/Profil/pict_user.mako")
def pict_user(request):
return {"uprofil": request.user}
@view_config(route_name='pict_salle', renderer="jm2l:templates/Salles/pict_salle.mako")
def pict_salle(request):
salle_id = int(request.matchdict.get('salle_id', -1))
return {"Salles": Salles, "IdSalle": salle_id}
@view_config(route_name='event', renderer="jm2l:templates/view_event.mako")
def show_event(request):
year = int(request.matchdict.get('year', -1))
@@ -1378,6 +1422,7 @@ def show_event(request):
'event': TheEvent, 'logged_in': request.authenticated_userid, "Salles": Salles}
return MainTab
@view_config(route_name='link_event_user')
def link_event_user(request):
""" Get user and add it to current event """
@@ -1392,7 +1437,8 @@ def link_event_user(request):
if not Exist:
request.session.flash(('error', u"Une erreur s'est produite lors de l'ajout de votre intervenant !"))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
year=str(year), intervention=intervention,
event_id=str(TargetEvent.uid)))
else:
TargetUser = Exist
@@ -1400,7 +1446,8 @@ def link_event_user(request):
TargetEvent.interventions.append(uev)
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)))
@view_config(route_name='link_event_tiers')
@@ -1417,11 +1464,11 @@ def link_event_tiers(request):
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)))
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") \
@@ -1434,7 +1481,9 @@ def link_event_tiers(request):
DBSession.add(tev)
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid), _anchor="Tiers"))
year=str(year), intervention=intervention,
event_id=str(TargetEvent.uid), _anchor="Tiers"))
@view_config(route_name='delete_link_u')
def delete_link_event_user(request):
@@ -1450,7 +1499,8 @@ def delete_link_event_user(request):
if not Exist:
request.session.flash(('error', u"Une erreur s'est produite lors de votre suppression !"))
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid)))
year=str(year), intervention=intervention,
event_id=str(TargetEvent.uid)))
else:
TargetUser = Exist
@@ -1467,8 +1517,8 @@ def delete_link_event_user(request):
DBSession.delete(item)
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid), _anchor="Tiers"))
year=str(year), intervention=intervention,
event_id=str(TargetEvent.uid), _anchor="Tiers"))
@view_config(route_name='delete_link_t')
@@ -1485,7 +1535,8 @@ def delete_link_event_tiers(request):
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)))
year=str(year), intervention=intervention,
event_id=str(TargetEvent.uid)))
else:
TargetTiers = Exist
@@ -1503,7 +1554,9 @@ def delete_link_event_tiers(request):
DBSession.delete(item)
return HTTPFound(location=request.route_url('edit_event', sep='/',
year=str(year), intervention=intervention, event_id=str(TargetEvent.uid), _anchor="Tiers"))
year=str(year), intervention=intervention,
event_id=str(TargetEvent.uid), _anchor="Tiers"))
@view_config(route_name='delete_event')
def delete_event(request):
@@ -1541,6 +1594,7 @@ def delete_event(request):
DBSession.delete(TheEvent)
return HTTPFound(location=request.route_url('jm2l', _anchor="Interventions"))
@view_config(route_name='edit_event', renderer="jm2l:templates/edit_event.mako")
def edit_event(request):
if request.user is None:
@@ -1654,19 +1708,19 @@ def edit_event(request):
elif intervention == "Atelier":
form.duration.choices = map(lambda d: (d, u'Atelier (%dh%.2d)' % (d / 60, d % 60)), \
[60, 90, 120, 150, 180, 210, 240])
if not duration in map(lambda (d,y): d, form.duration.choices):
if not duration in map(lambda d, y: d, form.duration.choices):
form.duration.choices.append((duration, u'Atelier (%dh%.2d)' % (duration / 60, duration % 60)))
SalleDispo = SalleDispo.filter(Salles.place_type.in_(['Atelier', '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):
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 == '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):
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.in_(['Stand', 'MAO']))
else:
@@ -1691,16 +1745,19 @@ 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 ! Vous pouvez la compléter à tout moment.'))
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)))
year=str(year), intervention=intervention,
event_id=str(TheEvent.slug)))
else:
if slugify(TheEvent.name) != TheEvent.slug:
# We should move some file as slug have been changed
# First we ensure there is no related event that already exist with that slug
CheckEvent = Event.by_slug(unicode(slugify(TheEvent.name)), year)
if CheckEvent:
request.session.flash(('warning',u'Choisissez un autre titre pour votre évènement, il est en conflit avec un autre.'))
request.session.flash(('warning',
u'Choisissez un autre titre pour votre évènement, il est en conflit avec un autre.'))
return {'event': TheEvent, 'form': form, 'formAdd': formAdd, 'formAddT': formAddT, 'Salles': Salles}
else:
SRCPath = path.join('jm2l/upload', *(IMAGEPATH + ['event'] + [str(year)] + [TheEvent.slug]))
@@ -1715,7 +1772,8 @@ def edit_event(request):
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)))
year=str(year), intervention=intervention,
event_id=str(TheEvent.slug)))
MainTab = {'programme': '', 'presse': '', 'plan': '', 'participer': '',
'event': TheEvent, 'form': form, 'formAdd': formAdd, 'formAddT': formAddT,
@@ -1723,6 +1781,7 @@ def edit_event(request):
return MainTab
@view_config(route_name='entities', renderer="jm2l:templates/list_tiers.mako")
def list_tiers(request):
Entities = dict()
@@ -1736,6 +1795,7 @@ def list_tiers(request):
'entities': Entities, 'logged_in': request.authenticated_userid}
return MainTab
@view_config(route_name='show_entity', renderer="jm2l:templates/view_tiers.mako")
def show_tiers(request):
tiers_type = request.matchdict.get('tiers_type')
@@ -1769,11 +1829,15 @@ def delete_tiers(request):
if TheTiers is None:
raise HTTPNotFound()
if len(TheTiers.membership) != 0:
request.session.flash(('error', u"Vous devez supprimer tous les membres liés avant la suppression d'une entité."))
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, tiers_type=TheTiers.get_entity_type.slug_entity_type))
request.session.flash(
('error', u"Vous devez supprimer tous les membres liés avant la suppression d'une entité."))
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug,
tiers_type=TheTiers.get_entity_type.slug_entity_type))
if len(TheTiers.membership) != 0:
request.session.flash(('error', u"Vous devez supprimer tous les roles liés avant la suppression d'une entité."))
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, tiers_type=TheTiers.get_entity_type.slug_entity_type))
request.session.flash(
('error', u"Vous devez supprimer tous les roles liés avant la suppression d'une entité."))
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug,
tiers_type=TheTiers.get_entity_type.slug_entity_type))
DBSession.delete(TheTiers)
request.session.flash(('info', u"L'entité a bien été supprimée"))
return HTTPFound(location=request.route_url('entities'))
@@ -1867,7 +1931,8 @@ def edit_tiers(request):
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))
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
@@ -1878,7 +1943,8 @@ def edit_tiers(request):
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))
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]))
@@ -1898,6 +1964,7 @@ def edit_tiers(request):
'logged_in': request.authenticated_userid}
return MainTab
@view_config(route_name='edit_entity_cat', renderer="jm2l:templates/edit_tiers_categ.mako")
def edit_tiers_category(request):
if request.user is None:
@@ -1910,15 +1977,15 @@ def edit_tiers_category(request):
RegExist = re.compile('collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[(?P<id>\d+)\]')
RegTitle = re.compile('collection\[(?P<slug>[\w-]+)\]\[title]')
RegNew = re.compile('collection\[(?P<slug>[\w-]+)\]\[(?P<num>\d+)\]\[id\]')
for key, value in request.POST.iteritems():
for key, value in request.POST.items():
regN = RegNew.match(key)
regT = RegTitle.match(key)
reg = RegExist.match(key)
if reg:
if not DicResult.has_key(reg.group('slug')):
if not reg.group('slug') in DicResult:
DicResult[reg.group('slug')] = dict()
if DicResult[reg.group('slug')].has_key('items'):
if 'items' in DicResult[reg.group('slug')]:
DicResult[reg.group('slug')]['items'].append((int(reg.group('id')), value))
else:
DicResult[reg.group('slug')]['items'] = [(int(reg.group('id')), value)]
@@ -1939,8 +2006,8 @@ def edit_tiers_category(request):
raise
for opt in DBSession.query(TiersOpt).all():
if DicResult.has_key(opt.slug_entity_type):
found = filter( lambda (x,y): opt.uid==x,
if opt.slug_entity_type in DicResult:
found = filter(lambda x, y: opt.uid == x,
DicResult[opt.slug_entity_type].get('items', []))
if not found:
ListChanges.append(('remove', opt.uid, opt.entity_type, opt.entity_subtype))
@@ -1974,6 +2041,7 @@ def edit_tiers_category(request):
'logged_in': request.authenticated_userid, 'TiersOpt': TiersOpt}
return MainTab
@view_config(route_name='show_user', renderer="jm2l:templates/view_user.mako")
def show_user(request):
user_slug = request.matchdict.get('user_slug', None)
@@ -1987,6 +2055,7 @@ def show_user(request):
'DispUser': DispUser, 'logged_in': request.authenticated_userid}
return MainTab
# @view_config(route_name='link_user_entity')
def link_user_entity(request):
if request.user is None:
@@ -2000,6 +2069,7 @@ def link_user_entity(request):
raise HTTPNotFound()
return HTTPFound(location=request.route_url('edit_entity', uid=uid))
# @view_config(route_name='link_role_entity')
def link_role_entity(request):
if request.user is None:
@@ -2013,6 +2083,7 @@ def link_role_entity(request):
raise HTTPNotFound()
return HTTPFound(location=request.route_url('edit_entity', uid=uid))
@forbidden_view_config()
def forbidden(reason, request):
if 'ident' in reason.detail:
@@ -2023,9 +2094,9 @@ def forbidden(reason, request):
return render_to_response('jm2l:templates/Errors/403.mako', {"reason": reason},
request=request)
@notfound_view_config()
def notfound(reason, request):
request.response.status = 404
return render_to_response('jm2l:templates/Errors/404.mako', {"reason": reason},
request=request)
+8 -3
View File
@@ -11,6 +11,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f:
## Do not forget to run for lxml dependencies
## apt-get install libxml2-dev libxslt1-dev
requires = [
'pyramid',
'pyramid_chameleon',
@@ -28,15 +29,19 @@ requires = [
'python-magic',
'Pillow',
'pyramid_exclog',
'repoze.sendmail==4.1',
'repoze.sendmail',
'pyramid_mailer',
'apscheduler',
'qrcode',
'reportlab',
'passlib',
'argon2_cffi'
'argon2_cffi',
'paginate',
'markupsafe',
'webhelpers2',
'email_validator',
'pyramid-scheduler'
]
setup(name='JM2L',
version='0.1',
description='JM2L',