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): | |||