Fix mail from Damien remarks Added room pictures Added tiers deletion Added Redirect to login when not loggedmaster
@@ -67,6 +67,7 @@ def main(global_config, **settings): | |||
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+)}') | |||
# HTML Routes - Public | |||
config.add_route('home', '/{year:(\d+/)?}') | |||
@@ -86,10 +87,10 @@ def main(global_config, **settings): | |||
## Entities | |||
config.add_route('entities', '/entities') #{sep:/*}{Nature:\w+?}') | |||
config.add_route('add_entity', '/entity') | |||
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('edit_entity_cat', '/categorie/entity') | |||
## Users | |||
@@ -260,8 +260,8 @@ class Tiers(Base): | |||
roles = relationship('Role_Tiers', backref="roles_tiers") #secondary='role_tiers_link' ) | |||
@classmethod | |||
def by_id(cls, id): | |||
return DBSession.query(cls).filter(cls.uid == id).first() | |||
def by_id(cls, uid): | |||
return DBSession.query(cls).filter(cls.uid == uid).first() | |||
@classmethod | |||
def by_slug(cls, slug): | |||
@@ -348,6 +348,11 @@ class SallePhy(Base): | |||
@classmethod | |||
def by_id(cls, uid): | |||
return DBSession.query(cls).filter(cls.uid == uid).first() | |||
@property | |||
def PhotosLinks(self): | |||
from .upload import MediaPath | |||
return MediaPath().get_list('salle', self.uid, 'Image') | |||
class Salles(Base): | |||
__tablename__ = 'salle' | |||
@@ -205,8 +205,8 @@ a { | |||
border: 1px solid #d4d4d4; | |||
} | |||
.ShowEntities td img { | |||
width: 100%; | |||
height: 100%; | |||
width: 5em; | |||
height: 5em; | |||
} | |||
.ShowEntities td:hover { | |||
@@ -0,0 +1,2 @@ | |||
<%namespace name="helpers" file="jm2l:templates/helpers.mako"/> | |||
${helpers.show_salles(Salles, IdSalle)} |
@@ -20,6 +20,9 @@ | |||
<div class="row-fluid"> | |||
<div class="span10 offset1"> | |||
<div id="SalleCarousel"> | |||
${helpers.show_salles( Salles, form.salle_uid.data or form.salle_uid.choices[0][0] )} | |||
</div> | |||
% if 'uid' in form._fields: | |||
<div class="borderboxtime"> | |||
@@ -31,6 +34,7 @@ | |||
</div> | |||
%endif | |||
<h3 style="line-height:30px;" class="lowshadow">${form.event_type.data}</h3> | |||
% if 'uid' in form._fields: | |||
<div class="borderbox"> | |||
Intrevenants programmés: | |||
@@ -186,6 +190,20 @@ DicForm = { | |||
} | |||
} | |||
}); | |||
$(document.body).on("change","#salle_uid",function(){ | |||
$.ajax({ | |||
url:'/salle_picture/' + this.value, | |||
success:function(result, status, jqXHR){ | |||
var pictureresult = $('<div />').append(result).find('#MyPictureCarousel').html(); | |||
var picturename = $('<div />').append(result).find('#CarName').html(); | |||
$('#MyPictureCarousel').html(pictureresult); | |||
$('#CarName').html(picturename); | |||
}, | |||
error:function(result, error){ | |||
alert(error); | |||
}, | |||
}); | |||
}); | |||
}); | |||
</script> | |||
</%def> | |||
@@ -12,7 +12,11 @@ | |||
<div class="row-fluid"> | |||
<div class="span10 offset1"> | |||
% if 'uid' in form._fields.keys(): | |||
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('delete_entity', action='delete_entity', entity_id=form.uid.data)}"> | |||
<i class="icon-remove icon-white"></i> Supprimer cette entitée | |||
</a> | |||
%endif | |||
<a class="pull-right" href="/categorie/entity">Editer les catégories</a> | |||
<br> | |||
<form action="" method="POST"> | |||
@@ -196,12 +200,17 @@ DicForm = { | |||
</fieldset> | |||
% endif | |||
<br> | |||
<center> | |||
<button type="submit" class="btn btn-large btn-primary" /> | |||
% if 'uid' in form._fields: | |||
<button class="btn btn-primary" type="submit">Enregistrer</button> | |||
<i class="icon-ok icon-white"></i> Mettre à jour | |||
% else: | |||
<button class="btn btn-primary" type="submit">Proposer</button> | |||
<i class="icon-ok icon-white"></i> Proposer | |||
</button> | |||
% endif | |||
</center> | |||
</form> | |||
% if 'uid' in form._fields: | |||
% if request.user: | |||
@@ -506,6 +506,47 @@ TabJs = {'select':[], 'desc':[]} | |||
</div> | |||
</%def> \ | |||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | |||
<%def name="show_salles(Salles, IdSalle)"> \ | |||
<div class="profile-icon pull-right" style="padding: 0 15px;"> | |||
<% | |||
if not IdSalle: | |||
return "" | |||
SallePhy = Salles.by_id(IdSalle).phy | |||
if not SallePhy: | |||
return "" | |||
photos = SallePhy.PhotosLinks | |||
%> | |||
<div id="CarName" style="text-align: center;line-height:20px;"><strong>Salle</strong>: ${Salles.by_id(IdSalle).name}</div> | |||
<div id="MyPictureCarousel" class="carousel slide"> | |||
% if len(photos)>1: | |||
<!-- Carousel nav --> | |||
<a class="Ucarousel-control left" href="#MyPictureCarousel" data-slide="prev">‹</a> | |||
<a class="Ucarousel-control right" href="#MyPictureCarousel" data-slide="next">›</a> | |||
% endif | |||
<!-- Carousel items --> | |||
<div class="carousel-inner"> | |||
% if len(photos): | |||
% for num, link in enumerate(photos): | |||
<div class="${['','active '][num==0]}item" id="UserPic${num}"> | |||
<div style="margin:auto;"> | |||
<img src="${link}" class="img-polaroid" style="max-height:205px;max-width:235px;" alt="Photo ${SallePhy.name}" /> | |||
</div> | |||
</div> | |||
% endfor | |||
% else: | |||
<div class="active item" id="UserPic0"> | |||
<div style="margin:auto;width:170px;"> | |||
<center> | |||
<img src="/img/no-image.jpg" class="img-polaroid" alt="Photo ${SallePhy.name}" style="max-height:130px;" /> | |||
<center> | |||
</div> | |||
</div> | |||
% endif | |||
</div> | |||
</div> | |||
</div> | |||
</%def> \ | |||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | |||
## Wrapper pour les échanges utilisateurs | |||
## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= | |||
<%def name="show_exchange(Exchange, Asker, Provider)"> \ | |||
@@ -125,6 +125,7 @@ ${helpers.uploader_js()} | |||
% if request.user.Staff: | |||
<li><a href="/Staff">Partie Staff</a></li> | |||
<li><a href="/ListSalles">Gérer les salles</a></li> | |||
<li><a href="/entities">Gérer les entités</a></li> | |||
% endif | |||
<li><a href="/sign/out">Me déconnecter</a></li> | |||
% else: | |||
@@ -5,24 +5,24 @@ Bonjour ${User.prenom},<br> | |||
<br> | |||
Vous venez de vous inscrire sur le site des JM2L et c'est une bonne idée :).<br> | |||
<br> | |||
Pour accéder à votre espace il vous suffit dorénavant de cliquer sur le lien suivant :<br> | |||
Pour accéder à votre espace il vous suffit dorénavant de cliquer sur le lien suivant :<br> | |||
<a href="${request.route_url('bymail', hash=User.my_hash)}">Votre lien !</a> | |||
<br> | |||
À partir de là vous avez la possibilité de : | |||
À partir de là vous avez la possibilité de : | |||
<ul> | |||
<li>inscrire votre stand pour la journée du 28 novembre</li> | |||
<li>inscrire une conférence</li> | |||
<li>inscrire votre stand pour la journée du 28 novembre</li> | |||
<li>inscrire une conférence</li> | |||
<li>inscrire un atelier</li> | |||
<li>chercher/proposer du covoiturage</li> | |||
<li>chercher/proposer un hébergement</li> | |||
<li>chercher/proposer un hébergement</li> | |||
<li>vous faire rembourser vos frais</li> | |||
<li>chercher proposer du matériel (câbles, etc)</li> | |||
<li>chercher proposer du matériel (câbles, etc)</li> | |||
</ul> | |||
<p> | |||
Pour plus d'information vous pouvez vous connectez au site des JM2L : http://jm2l.linux-azur.org ou | |||
nous envoyer un mail à «contact at jm2l.linux-azur.org ». Et si vous êtes vraiment perdu vous pouvez | |||
toujours nous téléphoner au +33 6 52 42 31 37. | |||
toujours nous téléphoner au +33 6 52 42 31 37. | |||
</p> | |||
<p> | |||
Nous vous attendons avec impatience le 28 novembre à Sophia Antipolis pour fêter le libre et partager | |||
@@ -38,29 +38,27 @@ Bonjour ${User.prenom},<br> | |||
<br> | |||
Vous venez de demander le renvoi de vos identifiants sur le site des JM2L.<br> | |||
<br> | |||
Pour accéder à votre espace il vous suffit dorénavant de cliquer sur le lien suivant :<br> | |||
Pour accéder à votre espace il vous suffit dorénavant de cliquer sur le lien suivant :<br> | |||
<a href="${request.route_url('bymail', hash=User.my_hash)}">Votre lien !</a> | |||
<br> | |||
N'hésitez pas à l'ajouter à vos liens favoris. | |||
N'hésitez pas à l'ajouter à vos liens favoris. | |||
<br> | |||
Vos identifiants de connection sont les suivants: | |||
<br> | |||
<b>Login</b>: ${User.slug} | |||
<br> | |||
<b>Password</b>: ${User.password} | |||
<br> | |||
Une fois connecté vous pouvez changer votre mot de passe sur votre fiche. | |||
<b>Login</b>: ${User.slug}<br> | |||
<b>Password</b>: ${User.password}<br> | |||
Une fois connecté vous pouvez changer votre mot de passe sur votre fiche. | |||
<br> | |||
<p> | |||
Pour plus d'information vous pouvez nous envoyer un mail à «contact at jm2l.linux-azur.org ». Et si vous êtes vraiment perdu vous pouvez | |||
toujours nous téléphoner au +33 6 52 42 31 37. | |||
toujours nous téléphoner au +33 6 52 42 31 37. | |||
</p> | |||
<p> | |||
Nous vous attendons avec impatience le 28 novembre 2015 à Sophia Antipolis pour fêter le libre et partager | |||
de la connaissance, de la bonne humeur et du soleil :) | |||
</p> | |||
<br> | |||
L'équipe des <b>JM2L</b> | |||
L'équipe des <b>JM2L</b> | |||
<br> | |||
</%def> \ | |||
% if action=='Welcome': | |||
@@ -8,14 +8,16 @@ | |||
</%def> | |||
<div class="row-fluid"> | |||
<div class="span10 offset1"> | |||
<div id="SalleCarousel"> | |||
${helpers.show_salles( Salles, event.Salle.salle_id )} | |||
</div> | |||
<strong>${event.event_type}</strong>: | |||
<div class="borderboxtime"> | |||
${event.start_time.strftime('%d %b %Y').decode('utf-8')} - | |||
${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} | |||
%if event.Salle: | |||
- <strong>Salle</strong>: ${event.Salle.name} | |||
%endif | |||
##%if event.Salle: | |||
## - <strong>Salle</strong>: ${event.Salle.name} | |||
##%endif | |||
</div> | |||
##%if event.event_uid: | |||
## <a href="http://jm2l.linux-azur.org/node/${event.event_uid}">Link</a> - | |||
@@ -26,7 +28,6 @@ ${event.start_time.strftime('%H:%M')} à ${event.end_time.strftime('%H:%M')} | |||
<a href="/MesJM2L/${event.for_year}/${event.event_type}/${event.slug}">Editer</a> | |||
% endif | |||
<h3 style="line-height:30px;">${event.name}</h3> | |||
% if event.description : | |||
<div class="borderbox"> | |||
${event.description | n} | |||
@@ -17,7 +17,12 @@ ${The_entity_type.entity_subtype} | |||
## <a href="http://jm2l.linux-azur.org/node/${entity.tiers_id}">Link</a> - | |||
##%endif | |||
% if request.user and (request.user.Staff or request.user in entity.members): | |||
<a href="/entity/${entity.get_entity_type.entity_type}/${entity.slug}/edit">Editer</a> | |||
<a href="/entity/${entity.get_entity_type.slug_entity_type}/${entity.slug}/edit">Editer</a> | |||
% endif | |||
% if request.user and (request.user.Staff or request.user in entity.members): | |||
<a class="btn btn-danger btn-mini pull-right" href="${request.route_path('delete_entity', action='delete_entity', entity_id=entity.uid)}"> | |||
<i class="icon-remove icon-white"></i> Supprimer cette entitée | |||
</a> | |||
% endif | |||
<div clear='both'></div> | |||
<div> | |||
@@ -2,6 +2,7 @@ | |||
from pyramid.view import view_config, view_defaults | |||
from pyramid.response import Response | |||
from pyramid.exceptions import NotFound | |||
from pyramid.httpexceptions import HTTPNotFound | |||
from pyramid.request import Request | |||
from PIL import Image | |||
import re, os, shutil | |||
@@ -13,6 +14,7 @@ import cStringIO as StringIO | |||
# Database access imports | |||
from .models import User, Place, Tiers, Event, SallePhy | |||
CurrentYear = 2015 | |||
MIN_FILE_SIZE = 1 # bytes | |||
MAX_FILE_SIZE = 500000000 # bytes | |||
IMAGE_TYPES = re.compile('image/(gif|p?jpeg|(x-)?png)') | |||
@@ -103,15 +105,19 @@ class MediaPath(): | |||
p = IMAGEPATH + [ media_table ] + [ linked_id ] | |||
elif media_table=='tasks': | |||
# Use Current Year | |||
p = IMAGEPATH + [ str(2015), media_table ] + [ linked_id ] | |||
p = IMAGEPATH + [ str(CurrentYear), media_table ] + [ linked_id ] | |||
elif media_table=='poles': | |||
# Use Current Year | |||
p = IMAGEPATH + [ str(2015), media_table ] + [ linked_id ] | |||
p = IMAGEPATH + [ str(CurrentYear), media_table ] + [ linked_id ] | |||
elif media_table in ['RIB', 'Justif']: | |||
slug = User.by_id(linked_id).slug | |||
p = IMAGEPATH + ['users'] + [ slug ] + [ self.media_table ] | |||
elif media_table=='users': | |||
slug = User.by_id(linked_id).slug | |||
user = User.by_id(linked_id) | |||
if not user: | |||
raise HTTPNotFound() | |||
else: | |||
slug = user.slug | |||
p = IMAGEPATH + ['users'] + [ slug ] | |||
elif media_table=='event': | |||
ev = Event.by_id(linked_id) | |||
@@ -911,6 +911,11 @@ def change_year(request): | |||
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)) | |||
@@ -924,7 +929,7 @@ def show_event(request): | |||
if TheEvent is None: | |||
raise HTTPNotFound() | |||
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', | |||
'event':TheEvent, 'logged_in':request.authenticated_userid } | |||
'event':TheEvent, 'logged_in':request.authenticated_userid, "Salles":Salles } | |||
return MainTab | |||
@view_config(route_name='link_event_user') | |||
@@ -1121,6 +1126,7 @@ def edit_event(request): | |||
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', | |||
'event':TheEvent, 'form':form, 'formAdd':formAdd, 'formAddT':formAddT, | |||
'Salles':Salles, | |||
'logged_in':request.authenticated_userid } | |||
return MainTab | |||
@@ -1154,6 +1160,32 @@ def show_tiers(request): | |||
'entity':TheTiers, 'logged_in':request.authenticated_userid } | |||
return MainTab | |||
@view_config(route_name='delete_entity') | |||
def delete_tiers(request): | |||
entity_id = request.matchdict.get('entity_id', None) | |||
if entity_id: | |||
if entity_id.isdigit(): | |||
TheTiers = Tiers.by_id(int(entity_id)) | |||
if TheTiers is None: | |||
raise HTTPNotFound() | |||
else: | |||
TheTiers = Tiers.by_slug(entity_id) | |||
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ée.")) | |||
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ée.")) | |||
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ée a bien été supprimée")) | |||
return HTTPFound(location=request.route_url('entities')) | |||
else: | |||
raise HTTPNotFound() | |||
@view_config(route_name='add_entity', renderer="jm2l:templates/edit_tiers.mako") | |||
@view_config(route_name='edit_entity', renderer="jm2l:templates/edit_tiers.mako") | |||
def edit_tiers(request): | |||
@@ -1241,7 +1273,9 @@ def edit_tiers(request): | |||
return HTTPFound(location=request.route_url('edit_entity', sep='/', | |||
entity_id=str(TheTiers.slug), tiers_type=TheTiers.get_entity_type.entity_type)) | |||
DBSession.merge(TheTiers) | |||
return HTTPFound(location=request.route_url('entities')) | |||
return HTTPFound(location=request.route_url('show_entity', entity_id=TheTiers.slug, | |||
tiers_type=TheTiers.get_entity_type.slug_entity_type)) | |||
MainTab = {'programme':'','presse':'', 'plan':'', 'participer':'', | |||
'form':form, 'DBUser':User, 'UserOptions':UserOptions, | |||
'logged_in':request.authenticated_userid } | |||
@@ -1355,10 +1389,13 @@ def link_role_entity(request): | |||
@forbidden_view_config() | |||
def forbidden(reason, request): | |||
#return Response('forbidden') | |||
request.response.status = 403 | |||
return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason }, | |||
request=request) | |||
if 'ident' in reason.detail: | |||
request.session.flash(('info', reason.detail)) | |||
return HTTPFound(location='/sign/login' ) | |||
else: | |||
request.response.status = 403 | |||
return render_to_response('jm2l:templates/Errors/403.mako', { "reason":reason }, | |||
request=request) | |||
@notfound_view_config() | |||
def notfound(reason, request): | |||