merge branch with rooms features
This commit is contained in:
commit
be6f4dd8d2
@ -17,7 +17,7 @@ from operator import itemgetter
|
|||||||
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import uuid
|
import uuid
|
||||||
|
import re
|
||||||
|
|
||||||
#root = tg.config['application_root_module'].RootController
|
#root = tg.config['application_root_module'].RootController
|
||||||
|
|
||||||
@ -31,18 +31,52 @@ class EditController(AuthenticatedBaseController):
|
|||||||
""" Controller fils wifi pour gérer le wifi """
|
""" Controller fils wifi pour gérer le wifi """
|
||||||
wifi = None
|
wifi = None
|
||||||
|
|
||||||
|
""" Controller fils room pour gérer les chambres """
|
||||||
|
room = None
|
||||||
|
|
||||||
""" Controller fils de gestion des machines """
|
""" Controller fils de gestion des machines """
|
||||||
machine = None
|
machine = None
|
||||||
def __init__(self, new_show):
|
def __init__(self, new_show):
|
||||||
self.show = new_show
|
self.show = new_show
|
||||||
self.wifi = WifiRestController(new_show)
|
self.wifi = WifiRestController(new_show)
|
||||||
self.machine = MachineController()
|
self.machine = MachineController()
|
||||||
|
self.room = RoomController(new_show)
|
||||||
|
|
||||||
|
|
||||||
""" Affiche les détails éditables du membre et de la chambre """
|
""" Affiche les détails éditables du membre et de la chambre """
|
||||||
@expose("brie.templates.edit.member")
|
@expose("brie.templates.edit.member")
|
||||||
def member(self, residence, uid):
|
def member(self, residence, uid):
|
||||||
return self.show.member(residence, uid)
|
|
||||||
|
residence_dn = Residences.get_dn_by_name(self.user, residence)
|
||||||
|
if residence_dn is None:
|
||||||
|
raise Exception("unknown residence")
|
||||||
|
#end if
|
||||||
|
|
||||||
|
member = Member.get_by_uid(self.user, residence_dn, uid)
|
||||||
|
|
||||||
|
if member is None:
|
||||||
|
return self.error_no_entry()
|
||||||
|
|
||||||
|
room = Room.get_by_member_dn(self.user, residence_dn, member.dn)
|
||||||
|
|
||||||
|
machines = Machine.get_machine_tuples_of_member(self.user, member.dn)
|
||||||
|
|
||||||
|
groups = Groupes.get_by_user_dn(self.user, residence_dn, member.dn)
|
||||||
|
|
||||||
|
rooms = Room.get_rooms(self.user, residence_dn)
|
||||||
|
if rooms is None:
|
||||||
|
raise Exception("unable to retrieve rooms")
|
||||||
|
#end if
|
||||||
|
rooms = sorted(rooms, key=lambda t:t.cn.first())
|
||||||
|
return {
|
||||||
|
"residence" : residence,
|
||||||
|
"user" : self.user,
|
||||||
|
"member_ldap" : member,
|
||||||
|
"room_ldap" : room,
|
||||||
|
"machines" : machines,
|
||||||
|
"groups" : groups,
|
||||||
|
"rooms" : rooms
|
||||||
|
}
|
||||||
#end def
|
#end def
|
||||||
|
|
||||||
""" Affiche les détails éditables de la chambre """
|
""" Affiche les détails éditables de la chambre """
|
||||||
@ -79,24 +113,53 @@ class MachineAddController(AuthenticatedRestController):
|
|||||||
def post(self, residence, member_uid, name, mac):
|
def post(self, residence, member_uid, name, mac):
|
||||||
residence_dn = Residences.get_dn_by_name(self.user, residence)
|
residence_dn = Residences.get_dn_by_name(self.user, residence)
|
||||||
|
|
||||||
#TODO : néttoyer mac (utiliser deux-points) et vérifier (regex)
|
#Vérification que l'adresse mac soit correcte
|
||||||
# XX:XX:XX:XX:XX
|
mac_match = re.match('^([0-9A-Fa-f]{2}[:-]?){5}([0-9A-Fa-f]{2})$', mac)
|
||||||
|
if mac_match is None:
|
||||||
|
#TODO : changer l'exception en une page d'erreur
|
||||||
|
raise Exception("mac non valide")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#Remplacement de l'adresse mac non séparée
|
||||||
|
mac_match = re.match('^([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$', mac)
|
||||||
|
if mac_match is not None:
|
||||||
|
mac = mac_match.group(1) + ":" + mac_match.group(2) + ":" + mac_match.group(3) + ":" + mac_match.group(4) + ":" + mac_match.group(5) + ":" + mac_match.group(6)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#Remplacement de l'adresse mac séparée par des tirets
|
||||||
|
mac_match = re.match('^([0-9A-Fa-f]{2})-([0-9A-Fa-f]{2})-([0-9A-Fa-f]{2})-([0-9A-Fa-f]{2})-([0-9A-Fa-f]{2})-([0-9A-Fa-f]{2})$', mac)
|
||||||
|
if mac_match is not None:
|
||||||
|
mac = mac_match.group(1) + ":" + mac_match.group(2) + ":" + mac_match.group(3) + ":" + mac_match.group(4) + ":" + mac_match.group(5) + ":" + mac_match.group(6)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#Passage au format lowercase
|
||||||
|
mac = mac.lower()
|
||||||
|
|
||||||
|
|
||||||
# Vérification que le membre existe
|
# Vérification que le membre existe
|
||||||
member = Member.get_by_uid(self.user, residence_dn, member_uid)
|
member = Member.get_by_uid(self.user, residence_dn, member_uid)
|
||||||
if member is None:
|
if member is None:
|
||||||
#TODO : membre inexistant
|
#TODO : membre inexistant
|
||||||
pass
|
pass
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
# Vérification que l'adresse mac de la machine n'existe pas déjà
|
||||||
|
# Note : on cherche sur toute la résidence (residence_dn)
|
||||||
|
machine = Machine.get_dhcp_by_mac(self.user, residence_dn, mac)
|
||||||
|
if machine is not None:
|
||||||
|
#TODO : gérer l'exception
|
||||||
|
raise Exception("mac address already exist")
|
||||||
|
#endif
|
||||||
|
|
||||||
# Vérification que le nom de machine n'existe pas déjà
|
# Vérification que le nom de machine n'existe pas déjà
|
||||||
# Note : on cherche sur toute la résidence (residence_dn)
|
# Note : on cherche sur toute la résidence (residence_dn)
|
||||||
|
machine = Machine.get_dns_by_name(self.user, residence_dn, name)
|
||||||
# TODO :
|
|
||||||
# machine = Machine.get_machine_by_name(self.user, residence_dn, name)
|
|
||||||
machine = None
|
|
||||||
if machine is not None:
|
if machine is not None:
|
||||||
#TODO : erreur machine existe déjà
|
#TODO : gérer l'exception
|
||||||
pass
|
raise Exception("dns name already exist")
|
||||||
|
#endif
|
||||||
|
|
||||||
# Génération de l'id de la machine et recherche d'une ip libre
|
# Génération de l'id de la machine et recherche d'une ip libre
|
||||||
machine_id = str(uuid.uuid4())
|
machine_id = str(uuid.uuid4())
|
||||||
ip = IpReservation.get_first_free(self.user, residence_dn)
|
ip = IpReservation.get_first_free(self.user, residence_dn)
|
||||||
@ -205,3 +268,132 @@ class WifiRestController(AuthenticatedRestController):
|
|||||||
#end def
|
#end def
|
||||||
#end class
|
#end class
|
||||||
|
|
||||||
|
""" Controller de gestion des rooms """
|
||||||
|
class RoomController(AuthenticatedBaseController):
|
||||||
|
require_group = groups_enum.admin
|
||||||
|
|
||||||
|
""" Controller fils d'ajout de machine """
|
||||||
|
move = None
|
||||||
|
show = None
|
||||||
|
change_member = None
|
||||||
|
def __init__(self, show):
|
||||||
|
self.move = RoomMoveController()
|
||||||
|
self.show = show
|
||||||
|
self.change_member = RoomChangeMemberController()
|
||||||
|
|
||||||
|
|
||||||
|
""" Affiche les détails éditables de la chambre """
|
||||||
|
@expose("brie.templates.edit.room")
|
||||||
|
def index(self, residence, room_id):
|
||||||
|
residence_dn = Residences.get_dn_by_name(self.user, residence)
|
||||||
|
|
||||||
|
room = Room.get_by_uid(self.user, residence_dn, room_id)
|
||||||
|
|
||||||
|
if room is None:
|
||||||
|
raise Exception("no room")
|
||||||
|
|
||||||
|
member = None
|
||||||
|
if room.has("x-memberIn"):
|
||||||
|
member = Member.get_by_dn(self.user, room.get("x-memberIn").first())
|
||||||
|
|
||||||
|
members = Member.get_all(self.user, residence_dn)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"residence" : residence,
|
||||||
|
"user" : self.user,
|
||||||
|
"room_ldap" : room,
|
||||||
|
"member_ldap" : member,
|
||||||
|
"members" : members
|
||||||
|
}
|
||||||
|
#se Exception("tait toi")
|
||||||
|
#end def
|
||||||
|
|
||||||
|
#end class
|
||||||
|
|
||||||
|
""" Controller REST de gestion des ajouts de machines. """
|
||||||
|
class RoomMoveController(AuthenticatedRestController):
|
||||||
|
require_group = groups_enum.admin
|
||||||
|
|
||||||
|
""" Gestion des requêtes post sur ce controller """
|
||||||
|
@expose()
|
||||||
|
def post(self, residence, member_uid, room_uid):
|
||||||
|
residence_dn = Residences.get_dn_by_name(self.user, residence)
|
||||||
|
|
||||||
|
# Récupération du membre et de la machine
|
||||||
|
# Note : on cherche la machine seulement sur le membre (member.dn)
|
||||||
|
member = Member.get_by_uid(self.user, residence_dn, member_uid)
|
||||||
|
room = Room.get_by_uid(self.user, residence_dn, room_uid)
|
||||||
|
|
||||||
|
# Si la machine existe effectivement, on la supprime
|
||||||
|
if room is not None:
|
||||||
|
if room.get("x-memberIn") is not None:
|
||||||
|
raise Exception("chambre de destination non vide")
|
||||||
|
#TODO passer sur une page d'erreur au lieu d'une exception
|
||||||
|
else:
|
||||||
|
old_room = Room.get_by_member_dn(self.user, residence_dn, member.dn)
|
||||||
|
memberIn_attribute = Room.memberIn_attr(str(member.dn))
|
||||||
|
self.user.ldap_bind.delete_attr(old_room.dn, memberIn_attribute)
|
||||||
|
self.user.ldap_bind.add_attr(room.dn, memberIn_attribute)
|
||||||
|
#end if
|
||||||
|
else:
|
||||||
|
old_room = Room.get_by_member_dn(self.user, residence_dn, member.dn)
|
||||||
|
memberIn_attribute = Room.memberIn_attr(str(member.dn))
|
||||||
|
self.user.ldap_bind.delete_attr(old_room.dn, memberIn_attribute)
|
||||||
|
#end if
|
||||||
|
|
||||||
|
#self.user.ldap_bind.delete_entry_subtree(machine.dn)
|
||||||
|
|
||||||
|
#taken_attribute = IpReservation.taken_attr(ip.get("x-taken").first())
|
||||||
|
#self.user.ldap_bind.delete_attr(ip.dn, taken_attribute)
|
||||||
|
#end if
|
||||||
|
|
||||||
|
# On redirige sur la page d'édition du membre
|
||||||
|
redirect("/edit/member/" + residence + "/" + member_uid)
|
||||||
|
#end def
|
||||||
|
#end def
|
||||||
|
|
||||||
|
|
||||||
|
""" Controller REST de gestion des ajouts de machines. """
|
||||||
|
class RoomChangeMemberController(AuthenticatedRestController):
|
||||||
|
require_group = groups_enum.admin
|
||||||
|
|
||||||
|
""" Gestion des requêtes post sur ce controller """
|
||||||
|
@expose()
|
||||||
|
def post(self, residence, member_uid, room_uid):
|
||||||
|
residence_dn = Residences.get_dn_by_name(self.user, residence)
|
||||||
|
|
||||||
|
# Récupération du membre et de la machine
|
||||||
|
# Note : on cherche la machine seulement sur le membre (member.dn)
|
||||||
|
member = Member.get_by_uid(self.user, residence_dn, member_uid)
|
||||||
|
room = Room.get_by_uid(self.user, residence_dn, room_uid)
|
||||||
|
|
||||||
|
if member is None and member_uid != "":
|
||||||
|
raise Exception("member not found")
|
||||||
|
#end if
|
||||||
|
|
||||||
|
if member is not None:
|
||||||
|
old_room_member = Room.get_by_member_dn(self.user, residence_dn, member.dn)
|
||||||
|
|
||||||
|
# Si la machine existe effectivement, on la supprime
|
||||||
|
if old_room_member is not None:
|
||||||
|
raise Exception("le nouveau membre possèdait déjà une chambre. conflit")
|
||||||
|
#end if
|
||||||
|
#end if
|
||||||
|
|
||||||
|
if room is None:
|
||||||
|
raise Exception("room inconnue")
|
||||||
|
|
||||||
|
if room.get("x-memberIn") is not None:
|
||||||
|
memberIn_attribute = Room.memberIn_attr(str(room.get("x-memberIn").first()))
|
||||||
|
self.user.ldap_bind.delete_attr(room.dn, memberIn_attribute)
|
||||||
|
#end if
|
||||||
|
|
||||||
|
if member is not None:
|
||||||
|
memberIn_attribute = Room.memberIn_attr(str(member.dn))
|
||||||
|
self.user.ldap_bind.add_attr(room.dn, memberIn_attribute)
|
||||||
|
#end if
|
||||||
|
|
||||||
|
# On redirige sur la page d'édition du membre
|
||||||
|
redirect("/edit/room/index/" + residence + "/" + room_uid)
|
||||||
|
#end def
|
||||||
|
#end def
|
||||||
|
@ -40,6 +40,14 @@ class Member(object):
|
|||||||
|
|
||||||
class Room(object):
|
class Room(object):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def memberIn_attr(member_dn):
|
||||||
|
return {
|
||||||
|
"x-memberIn" : str(member_dn)
|
||||||
|
}
|
||||||
|
#end def
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_by_name(user_session, residence_dn, name):
|
def get_by_name(user_session, residence_dn, name):
|
||||||
return user_session.ldap_bind.search_first(ldap_config.room_base_dn + residence_dn, "(&(objectClass=pacaterieRoom)(cn=" + name + "))")
|
return user_session.ldap_bind.search_first(ldap_config.room_base_dn + residence_dn, "(&(objectClass=pacaterieRoom)(cn=" + name + "))")
|
||||||
@ -179,6 +187,15 @@ class Machine(object):
|
|||||||
return user_session.ldap_bind.search_first(machine_dn, "(objectClass=dlzAbstractRecord)")
|
return user_session.ldap_bind.search_first(machine_dn, "(objectClass=dlzAbstractRecord)")
|
||||||
#end def
|
#end def
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_dhcp_by_mac(user_session, residence_dn, mac):
|
||||||
|
return user_session.ldap_bind.search_first(residence_dn, "(dhcpHWAddress=ethernet "+mac+")")
|
||||||
|
#end def
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_dns_by_name(user_session, residence_dn, name):
|
||||||
|
return user_session.ldap_bind.search_first(residence_dn, "(dlzHostName="+name+")")
|
||||||
|
#end def
|
||||||
#end class
|
#end class
|
||||||
|
|
||||||
class Groupes(object):
|
class Groupes(object):
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div py:choose="room_ldap">
|
<div py:choose="room_ldap">
|
||||||
<span class="section_name" py:when="None">Pas de chambre associée</span>
|
<span class="section_name" py:when="None">Pas de chambre associée</span>
|
||||||
<div py:otherwise="">${room_view(room_ldap)}</div>
|
<div py:otherwise="">${room_view(room_ldap, rooms, member_ldap)}</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -14,6 +14,14 @@
|
|||||||
<div class="section">
|
<div class="section">
|
||||||
<span class="section_name show_section_name">${member_ldap.cn.first()}</span>
|
<span class="section_name show_section_name">${member_ldap.cn.first()}</span>
|
||||||
<div>
|
<div>
|
||||||
|
<div>
|
||||||
|
<span class="item_name">Prénom</span>
|
||||||
|
<input type="text" value="${member_ldap.givenName.first('')}" />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span class="item_name">Nom</span>
|
||||||
|
<input type="text" value="${member_ldap.sn.first()}" />
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="item_name">Fin de connexion</span>
|
<span class="item_name">Fin de connexion</span>
|
||||||
<span py:choose="member_ldap.get('x-connectionEnd')">
|
<span py:choose="member_ldap.get('x-connectionEnd')">
|
||||||
@ -66,8 +74,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<form action="/edit/machine/add/" method="post">
|
<form action="/edit/machine/add/" method="post">
|
||||||
<input type="text" name="name" class="item_name"/>
|
<input type="text" name="name" placeholder="nom de la machine" class="item_name"/>
|
||||||
<input type="text" name="mac"/>
|
<input type="text" name="mac" placeholder="adresse mac" />
|
||||||
<input type="hidden" name="residence" value="${residence}"/>
|
<input type="hidden" name="residence" value="${residence}"/>
|
||||||
<input type="hidden" name="member_uid" value="${member_ldap.uid.first()}"/>
|
<input type="hidden" name="member_uid" value="${member_ldap.uid.first()}"/>
|
||||||
<input type="submit" value="ajouter" class="button"/>
|
<input type="submit" value="ajouter" class="button"/>
|
||||||
@ -76,15 +84,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</py:def>
|
</py:def>
|
||||||
|
|
||||||
<py:def function="room_view(room, member_in = None)">
|
<py:def function="room_view(room, rooms, member_in)">
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<span class="section_name show_section_name">CHAMBRE ${room.cn.first()}</span>
|
<span class="section_name show_section_name">CHAMBRE ${room.cn.first()}</span>
|
||||||
<div>
|
<div>
|
||||||
<div py:if="member_in is not None">
|
<!-- <div py:if="member_in is not None">
|
||||||
<span class="item_name">Membre</span>
|
<span class="item_name">Membre</span>
|
||||||
<span>
|
<span>
|
||||||
<a href="/show/member/${member_in.uid.first()}">${member_in.cn.first()}</a>
|
<a href="/show/member/${residence}/${member_in.uid.first()}">${member_in.cn.first()}</a>
|
||||||
</span>
|
</span>
|
||||||
|
</div>-->
|
||||||
|
<div py:if="rooms is not None">
|
||||||
|
<form method="post" action="/edit/room/move">
|
||||||
|
<span class="item_name">Changer de chambre</span>
|
||||||
|
<select name="room_uid">
|
||||||
|
<option value=""><vide></option>
|
||||||
|
<py:for each="target_room in rooms">
|
||||||
|
<py:choose test="target_room.cn.first() == room.cn.first()">
|
||||||
|
<option py:when="True" selected="selected" value="${target_room.uid.first()}">${target_room.cn.first()}</option>
|
||||||
|
<option py:when="False" value="${target_room.uid.first()}">${target_room.cn.first()}</option>
|
||||||
|
</py:choose>
|
||||||
|
</py:for>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="residence" value="${residence}"/>
|
||||||
|
<input type="hidden" name="member_uid" value="${member_in.uid.first()}"/>
|
||||||
|
<span>
|
||||||
|
<input type="submit" class="button" value="Envoyer!" />
|
||||||
|
</span>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="item_name"></span>
|
<span class="item_name"></span>
|
||||||
@ -95,5 +122,42 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</py:def>
|
</py:def>
|
||||||
|
<py:def function="room_edit_member(room, members, member_in)">
|
||||||
|
<div class="section">
|
||||||
|
<span class="section_name show_section_name">CHAMBRE ${room.cn.first()}</span>
|
||||||
|
<div>
|
||||||
|
<div py:if="member_in is not None">
|
||||||
|
<span class="item_name">Membre</span>
|
||||||
|
<span>
|
||||||
|
<a href="/show/member/${residence}/${member_in.uid.first()}">${member_in.cn.first()}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<form method="post" action="/edit/room/change_member">
|
||||||
|
<span class="item_name">Changer de propriétaire</span>
|
||||||
|
<select name="member_uid">
|
||||||
|
<option value=""><vide></option>
|
||||||
|
<py:for each="target_member in members">
|
||||||
|
<py:if test="member_in is None">
|
||||||
|
<option value="${target_member.uid.first()}">${target_member.cn.first()}</option>
|
||||||
|
</py:if>
|
||||||
|
<py:if test="member_in is not None">
|
||||||
|
<py:choose test="target_member.cn.first() == member_in.cn.first()">
|
||||||
|
<option py:when="True" selected="selected" value="${target_member.uid.first()}">${target_member.cn.first()}</option>
|
||||||
|
<option py:when="False" value="${target_member.uid.first()}">${target_member.cn.first()}</option>
|
||||||
|
</py:choose>
|
||||||
|
</py:if>
|
||||||
|
</py:for>
|
||||||
|
</select>
|
||||||
|
<input type="hidden" name="residence" value="${residence}"/>
|
||||||
|
<input type="hidden" name="room_uid" value="${room.uid.first()}"/>
|
||||||
|
<span>
|
||||||
|
<input type="submit" class="button" value="Envoyer!" />
|
||||||
|
</span>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</py:def>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
${back_show("room", room_ldap.uid.first())}
|
${back_show("room", room_ldap.uid.first())}
|
||||||
<div py:choose="room_ldap">
|
<div py:choose="room_ldap">
|
||||||
<span class="section_name" py:when="None">Pas de chambre associée</span>
|
<span class="section_name" py:when="None">Pas de chambre associée</span>
|
||||||
<div py:otherwise="">${room_view(room_ldap, member_ldap)}</div>
|
<div py:otherwise="">${room_edit_member(room_ldap, members, member_ldap)}</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<py:def function="back_rooms(preview_room_ldap = None)">
|
<py:def function="back_rooms(preview_room_ldap = None)">
|
||||||
<div py:choose="preview_room_ldap">
|
<div py:choose="preview_room_ldap">
|
||||||
<a py:when="None" href="/rooms/index/${residence}/" class="button">RETOUR LIST</a>
|
<a py:when="None" href="/rooms/index/${residence}/" class="button">RETOUR LIST</a>
|
||||||
<a py:otherwise="" href="/rooms/preview/${residence}/${preview_room_ldap.cn.first()}" class="button">RETOUR PREVIEW</a>
|
<a py:otherwise="" href="/rooms/preview/${residence}/${preview_room_ldap.uid.first()}" class="button">RETOUR PREVIEW</a>
|
||||||
</div>
|
</div>
|
||||||
</py:def>
|
</py:def>
|
||||||
<py:def function="member_view(member_ldap)">
|
<py:def function="member_view(member_ldap)">
|
||||||
@ -83,7 +83,7 @@
|
|||||||
<py:def function="room_view(room, member_in = None)">
|
<py:def function="room_view(room, member_in = None)">
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<span class="section_name show_section_name">CHAMBRE ${room.cn.first()}</span>
|
<span class="section_name show_section_name">CHAMBRE ${room.cn.first()}</span>
|
||||||
<a class="link_button some_margin" href="/edit/room/${residence}/${room.uid.first()}/">éditer</a>
|
<a class="link_button some_margin" href="/edit/room/index/${residence}/${room.uid.first()}/">éditer</a>
|
||||||
<div>
|
<div>
|
||||||
<div py:if="member_in is not None">
|
<div py:if="member_in is not None">
|
||||||
<span class="item_name">Membre</span>
|
<span class="item_name">Membre</span>
|
||||||
|
Loading…
Reference in New Issue
Block a user