Passage aux adhésions glissantes (partie 2/2, lc_ldap)
This commit is contained in:
parent
6880051943
commit
7f1ffbeed5
7 changed files with 180 additions and 30 deletions
79
attributs.py
79
attributs.py
|
@ -48,6 +48,7 @@ import random
|
|||
import string
|
||||
from unicodedata import normalize
|
||||
from crans_utils import format_tel, format_mac, mailexist, validate_name, ip4_of_rid, ip6_of_mac, fetch_cert_info
|
||||
from crans_utils import toGeneralizedTimeFormat, fromGeneralizedTimeFormat, extractTz
|
||||
import itertools
|
||||
|
||||
sys.path.append("/usr/scripts")
|
||||
|
@ -557,12 +558,86 @@ class derniereConnexion(intAttr):
|
|||
can_modify = [nounou, cableur, soi] # il faut bien pouvoir le modifier pour le mettre à jour
|
||||
ldap_name = "derniereConnexion"
|
||||
|
||||
class generalizedTimeFormat(Attr):
|
||||
"""Classe définissant un ensemble de données pour manipuler
|
||||
une donnée de temps suivant la RFC 4517
|
||||
|
||||
"""
|
||||
default = "19700101000000Z"
|
||||
|
||||
def __float__(self):
|
||||
return self._stamp
|
||||
|
||||
def __int__(self):
|
||||
return int(self._stamp)
|
||||
|
||||
def __eq__(self, othertime):
|
||||
if isinstance(self, othertime):
|
||||
return self._stamp == othertime._stamp
|
||||
else:
|
||||
resource = generalizedTimeFormat(othertime, conn=None, Parent=None)
|
||||
return self._stamp == resource._stamp
|
||||
|
||||
def __neq__(self, othertime):
|
||||
return not (self == othertime)
|
||||
|
||||
def __lt__(self, othertime):
|
||||
if isinstance(othertime, generalizedTimeFormat):
|
||||
return self._stamp < othertime._stamp
|
||||
else:
|
||||
resource = generalizedTimeFormat(othertime, conn=None, Parent=None)
|
||||
return self._stamp < resource._stamp
|
||||
|
||||
def __gt__(self, othertime):
|
||||
return not (self < othertime) and not (self == othertime)
|
||||
|
||||
def parse_value(self, gtf):
|
||||
if isinstance(gtf, str) or isinstance(gtf, unicode):
|
||||
if not ('Z' in gtf or '+' in gtf or '-' in gtf):
|
||||
self._stamp = gtf
|
||||
self.value = toGeneralizedTimeFormat(float(gtf))
|
||||
else:
|
||||
self._stamp = fromGeneralizedTimeFormat(gtf)
|
||||
self.value = gtf
|
||||
elif isinstance(gtf, float):
|
||||
self._stamp = gtf
|
||||
self.value = toGeneralizedTimeFormat(gtf)
|
||||
|
||||
@crans_attribute
|
||||
class debutAdhesion(generalizedTimeFormat):
|
||||
legend = u"Date de début de l'adhésion"
|
||||
category = 'Adh'
|
||||
can_modify = [cableur, nounou]
|
||||
ldap_name = 'debutAdhesion'
|
||||
|
||||
|
||||
@crans_attribute
|
||||
class finAdhesion(generalizedTimeFormat):
|
||||
legend = u"Date de fin de l'adhésion"
|
||||
category = 'Adh'
|
||||
can_modify = [cableur, nounou]
|
||||
ldap_name = 'finAdhesion'
|
||||
|
||||
@crans_attribute
|
||||
class debutConnexion(generalizedTimeFormat):
|
||||
legend = u"Date de début de la connexion"
|
||||
category = 'Adh'
|
||||
can_modify = [cableur, nounou]
|
||||
ldap_name = 'debutConnexion'
|
||||
|
||||
@crans_attribute
|
||||
class finConnexion(generalizedTimeFormat):
|
||||
legend = u"Date de fin de la connexion"
|
||||
category = 'Adh'
|
||||
can_modify = [cableur, nounou]
|
||||
ldap_name = 'finConnexion'
|
||||
|
||||
@crans_attribute
|
||||
class mail(Attr):
|
||||
singlevalue = False
|
||||
optional = False
|
||||
unique = True
|
||||
legend = "Adresse mail de l'adhérent"
|
||||
legend = u"Adresse mail de l'adhérent"
|
||||
can_modify = [soi, nounou, cableur]
|
||||
category = 'mail'
|
||||
ldap_name = "mail"
|
||||
|
@ -1446,7 +1521,7 @@ class controle(Attr):
|
|||
ldap_name = "controle"
|
||||
|
||||
def parse_value(self, ctrl):
|
||||
if ctrl not in [u"", u"c", u"p", u"cp", u"pc"]:
|
||||
if ctrl not in [u"", u"c", u"p", u"cp", u"pc", u"TRUE", u"FALSE"]:
|
||||
raise ValueError("Contrôle peut prendre les valeurs [c][p]")
|
||||
self.value = ctrl
|
||||
|
||||
|
|
|
@ -306,3 +306,29 @@ def ip4_addresses():
|
|||
ip_list.append(link['addr'])
|
||||
return ip_list
|
||||
|
||||
def extractTz(thetz):
|
||||
abstz = 100*abs(thetz)
|
||||
if thetz == 0:
|
||||
return "Z"
|
||||
else:
|
||||
return "%s%04d" % ("+"*(thetz < 0) + "-"*(thetz > 0), abstz)
|
||||
|
||||
def toGeneralizedTimeFormat(stamp):
|
||||
"""Converts a timestamp (local) in a generalized time format
|
||||
for LDAP.
|
||||
|
||||
* stamp : float value
|
||||
* output : a string without the dot second
|
||||
|
||||
"""
|
||||
|
||||
return "%s%s" % (time.strftime("%Y%m%d%H%M%S", time.localtime(stamp)), extractTz(time.altzone/3600))
|
||||
|
||||
def fromGeneralizedTimeFormat(gtf):
|
||||
"""Converts a GTF stamp to unix timestamp
|
||||
|
||||
* gtf : a generalized time format resource without dotsecond
|
||||
* output : a float value
|
||||
|
||||
"""
|
||||
return time.mktime(time.strptime(gtf.split("-", 1)[0].split("+", 1)[0].split('Z', 1)[0], "%Y%m%d%H%M%S"))
|
||||
|
|
27
objets.py
27
objets.py
|
@ -713,10 +713,13 @@ class proprio(CransLdapObject):
|
|||
u""" Un propriétaire de machine (adhérent, club…) """
|
||||
can_be_by = { variables.created: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||
variables.modified: [attributs.nounou, attributs.bureau, attributs.soi, attributs.cableur],
|
||||
variables.deleted: [attributs.nounou, attributs.bureau],
|
||||
variables.deleted: [attributs.nounou, attributs.bureau,],
|
||||
}
|
||||
|
||||
attribs = [attributs.nom, attributs.chbre, attributs.paiement, attributs.info, attributs.blacklist, attributs.controle, attributs.historique]
|
||||
attribs = [attributs.nom, attributs.chbre, attributs.paiement, attributs.info,
|
||||
attributs.blacklist, attributs.controle, attributs.historique,
|
||||
attributs.debutAdhesion, attributs.finAdhesion, attributs.debutConnexion,
|
||||
attributs.finConnexion]
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.__class__) + " : nom=" + str(self['nom'][0])
|
||||
|
@ -857,6 +860,14 @@ class proprio(CransLdapObject):
|
|||
u"""Renvoie si le propriétaire a payé et donné sa carte pour l'année en cours"""
|
||||
return self.paiement_ok() and self.carte_ok()
|
||||
|
||||
def fin_adhesion(self):
|
||||
"""Retourne la date de fin d'adhésion"""
|
||||
return max([float(facture.get('finAdhesion', [crans_utils.fromGeneralizedTimeFormat(attributs.finAdhesion.default)])[0]) for facture in self.factures() if facture.get('controle', [''])[0] != u"FALSE"] + [0.0])
|
||||
|
||||
def fin_connexion(self):
|
||||
"""Retourne la date de fin de connexion"""
|
||||
return max([float(facture.get('finConnexion', [crans_utils.fromGeneralizedTimeFormat(attributs.finConnexion.default)])[0]) for facture in self.factures() if facture.get('controle', [''])[0] != u"FALSE"] + [0.0])
|
||||
|
||||
def paiement_ok(self, no_bl=False):
|
||||
u"""
|
||||
Renvoie si le propriétaire a payé pour l'année en cours, en prenant en compte les périodes de transition et les blacklistes.
|
||||
|
@ -868,7 +879,13 @@ class proprio(CransLdapObject):
|
|||
for bl in self.blacklist_actif():
|
||||
if bl['type'] == 'paiement':
|
||||
return False
|
||||
return config.ann_scol in self['paiement'] or (config.periode_transitoire and (config.ann_scol - 1) in self['paiement'])
|
||||
old_style_paiement = config.ann_scol in self['paiement'] or (config.periode_transitoire and (config.ann_scol - 1) in self['paiement'])
|
||||
if isinstance(self, adherent):
|
||||
fin_paiement = min(self.fin_adhesion(), self.fin_connexion())
|
||||
else:
|
||||
fin_paiement = self.fin_adhesion()
|
||||
new_style_paiement = time.time() < fin_paiement or (config.periode_transitoire and config.debut_periode_transitoire <= fin_paiement <= config.fin_periode_transitoire)
|
||||
return (old_style_paiement or new_style_paiement)
|
||||
|
||||
def carte_ok(self):
|
||||
u"""Renvoie si le propriétaire a donné sa carte pour l'année en cours, en prenant en compte les periode transitoires et le sursis carte"""
|
||||
|
@ -1251,7 +1268,9 @@ class facture(CransLdapObject):
|
|||
variables.deleted: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||
}
|
||||
attribs = [attributs.fid, attributs.modePaiement, attributs.recuPaiement,
|
||||
attributs.historique, attributs.article, attributs.info]
|
||||
attributs.historique, attributs.article, attributs.info,
|
||||
attributs.debutAdhesion, attributs.finAdhesion, attributs.debutConnexion,
|
||||
attributs.finConnexion, attributs.controle ]
|
||||
ldap_name = "facture"
|
||||
|
||||
_proprio = None
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#!/bin/bash /usr/scripts/python.sh
|
||||
# -*- coding: utf-8 -*-
|
||||
from gestion.affich_tools import coul, tableau
|
||||
from gestion.affichage import style, tableau
|
||||
import importlib
|
||||
import time
|
||||
import ldap
|
||||
import sys
|
||||
import gestion.config as config
|
||||
|
||||
# Import inutile, mais on en a besoin pour que le
|
||||
# script continue à fonctionner.
|
||||
|
@ -35,9 +36,9 @@ def prise_etat(chbre):
|
|||
# fonction prise_etat propre à lc_ldap, pour
|
||||
# ne plus en avoir besoin ci-après.
|
||||
gestion.whos = try_import(u"gestion.whos")
|
||||
gestion.whos.coul = coul
|
||||
gestion.whos.style = style
|
||||
if chbre=="????":
|
||||
return coul("Chambre invalide", "violet")
|
||||
return style("Chambre invalide", "violet")
|
||||
return gestion.whos.prise_etat(chbre)[0]
|
||||
|
||||
def timeformat(t, format):
|
||||
|
@ -50,13 +51,13 @@ def blacklists(l):
|
|||
fin=b['fin'] if b['fin'] == '-' else time.strftime("%d/%m/%Y %H:%M", time.localtime(b['fin']))
|
||||
couleur='rouge' if b['actif'] else None
|
||||
if debut != '-' and fin !='-':
|
||||
bl.append(coul(u"du %s au %s : %s [%s]" % (debut, fin, b['type'], b['comm']), couleur))
|
||||
bl.append(style(u"du %s au %s : %s [%s]" % (debut, fin, b['type'], b['comm']), couleur))
|
||||
elif debut != '-':
|
||||
bl.append(coul(u"À partir du %s : %s [%s]" % (debut, b['type'], b['comm']), couleur))
|
||||
bl.append(style(u"À partir du %s : %s [%s]" % (debut, b['type'], b['comm']), couleur))
|
||||
elif fin != '-':
|
||||
bl.append(coul(u"Jusqu'au %s : %s [%s]" % (fin, b['type'], b['comm']), couleur))
|
||||
bl.append(style(u"Jusqu'au %s : %s [%s]" % (fin, b['type'], b['comm']), couleur))
|
||||
else:
|
||||
bl.append(coul(u"%s [%s]" % (b['type'], b['comm']), couleur))
|
||||
bl.append(style(u"%s [%s]" % (b['type'], b['comm']), couleur))
|
||||
return bl
|
||||
|
||||
def split(str, *arg):
|
||||
|
@ -90,19 +91,19 @@ def const_of_mac(mac):
|
|||
|
||||
templateEnv=None
|
||||
def template(dialog=False):
|
||||
global templateEnv, coul, tableau
|
||||
global templateEnv, style, tableau
|
||||
if not templateEnv:
|
||||
# un import paresseux, comme ça, pas la peine d'installer jinja2 sur les machines où il n'y en a pas besoin
|
||||
import jinja2
|
||||
oldcoul = coul
|
||||
oldstyle = style
|
||||
oldtableau = tableau
|
||||
tableau = lambda *args,**kwargs: oldtableau(*args,dialog=dialog,**kwargs)
|
||||
coul = lambda *args,**kwargs:oldcoul(*args,dialog=dialog,**kwargs)
|
||||
style = lambda *args,**kwargs:oldstyle(*args,dialog=dialog,**kwargs)
|
||||
template_path = '/usr/scripts/lc_ldap/printing/templates/'
|
||||
templateLoader = jinja2.FileSystemLoader( searchpath=["/", template_path] )
|
||||
templateEnv = jinja2.Environment( loader=templateLoader, trim_blocks=True )
|
||||
templateEnv.add_extension('jinja2.ext.do')
|
||||
templateEnv.filters['coul'] = coul
|
||||
templateEnv.filters['coul'] = style
|
||||
templateEnv.filters['blacklists'] = blacklists
|
||||
templateEnv.filters['prise_etat'] = prise_etat
|
||||
templateEnv.filters['timeformat'] = timeformat
|
||||
|
@ -130,7 +131,7 @@ def list_machines(machines, width=None):
|
|||
def list_factures(factures, width=None):
|
||||
return tableau([
|
||||
[f['fid'][0], f['modePaiement'][0],
|
||||
coul("OK", "vert") if f.get('recuPaiement', []) else coul("NON", "rouge"),
|
||||
style("OK", "vert") if f.get('recuPaiement', []) else style("NON", "rouge"),
|
||||
' '.join(attr['code'] for attr in f.get('article',[])),
|
||||
u"%s€" % sum([float(a['pu'])*int(a['nombre']) for a in f.get('article',[])])
|
||||
] for f in factures],
|
||||
|
@ -143,8 +144,8 @@ def list_adherents(adherents, width=None):
|
|||
return tableau([
|
||||
[a['aid'][0],
|
||||
u' '.join(unicode(i) for i in a['prenom'] + a['nom']),
|
||||
a['chbre'][0], coul('o', 'vert') if a.paiement_ok() else coul('n', 'rouge'),
|
||||
coul('o', 'vert') if a.carte_ok() else coul('n', 'rouge'),
|
||||
a['chbre'][0], style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
||||
style('o', 'vert') if a.carte_ok() else style('n', 'rouge'),
|
||||
u', '.join(unicode(m['host'][0]).split('.',1)[0] for m in a.machines())
|
||||
] for a in adherents ],
|
||||
titre = [u'aid', u'Prénom Nom', u'Chbre', u'P', u'C', u'Machines'],
|
||||
|
@ -156,7 +157,7 @@ def list_clubs(clubs, width=None):
|
|||
return tableau([
|
||||
[a['cid'][0],
|
||||
u' '.join(unicode(i) for i in a['nom']),
|
||||
a['chbre'][0], coul('o', 'vert') if a.paiement_ok() else coul('n', 'rouge'),
|
||||
a['chbre'][0], style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
||||
u', '.join(unicode(m['host'][0]).split('.',1)[0] for m in a.machines())
|
||||
] for a in clubs ],
|
||||
titre = [u'cid', u'Nom', u'Chbre', u'P', u'Machines'],
|
||||
|
@ -168,14 +169,39 @@ def proprio(proprio, params):
|
|||
params['o']=proprio
|
||||
etat_administratif=[]
|
||||
if proprio.paiement_ok() and proprio.carte_ok():
|
||||
etat_administratif.append(coul(u"à jour", "vert"))
|
||||
etat_administratif.append(style(u"à jour", "vert"))
|
||||
if not proprio.carte_ok():
|
||||
etat_administratif.append(coul(u"manque carte d'étudiant", "violet"))
|
||||
etat_administratif.append(style(u"manque carte d'étudiant", "violet"))
|
||||
if not proprio.paiement_ok():
|
||||
etat_administratif.append(coul(u"cotisation non réglée", "violet"))
|
||||
etat_administratif.append(style(u"cotisation non réglée", "violet"))
|
||||
if proprio.fin_adhesion() >= time.time():
|
||||
adh = style(u"Adhésion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_adhesion())),), "vert")
|
||||
elif config.ann_scol in proprio['paiement']:
|
||||
adh = style(u"Adhésion pour la période %s-%s ok." % (config.ann_scol, config.ann_scol+1), "vert")
|
||||
elif proprio.paiement_ok():
|
||||
adh = style(u"Adhésion terminée, mais il y a un sursis.", 'orange')
|
||||
else:
|
||||
adh = style(u"Pas adhérent actuellement.", 'rouge')
|
||||
params["adh"] = adh
|
||||
if proprio.fin_connexion() >= time.time():
|
||||
conn = style(u"Connexion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_connexion())),), "vert")
|
||||
elif config.ann_scol in proprio['paiement']:
|
||||
conn = style(u"Connexion pour la période %s-%s ok." % (config.ann_scol, config.ann_scol+1), "vert")
|
||||
elif proprio.paiement_ok():
|
||||
conn = style(u"Connexion terminée, mais il y a un sursis.", 'orange')
|
||||
else:
|
||||
conn = style(u"Pas connecté actuellement.", 'rouge')
|
||||
params["conn"] = conn
|
||||
if proprio.get('carteEtudiant', []):
|
||||
cetud = style(u"Carte d'étudiant fournie.", 'vert')
|
||||
elif proprio.sursis_carte() or proprio.carte_ok():
|
||||
cetud = style(u"Carte d'étudiant non fournie, mais en sursis.", 'orange')
|
||||
else:
|
||||
cetud = style(u"Pas de carte d'étudiant")
|
||||
params["cetud"] = cetud
|
||||
params['etat_administratif']=etat_administratif
|
||||
if proprio["chbre"][0].value not in ["????", "EXT"]:
|
||||
params['brassage'] = coul("Cr@ns", "bleu") if gestion.annuaires_pg.is_crans(proprio["chbre"][0].value[0], proprio["chbre"][0].value[1:]) else coul("CROUS", "jaune")
|
||||
params['brassage'] = style("Cr@ns", "bleu") if gestion.annuaires_pg.is_crans(proprio["chbre"][0].value[0], proprio["chbre"][0].value[1:]) else style("CROUS", "jaune")
|
||||
|
||||
try:
|
||||
if proprio.machines():
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
{{"Chambre : "|coul('gras')}}{{o.chbre.0}} ({{o.chbre.0|string|prise_etat}})
|
||||
{% endif %}
|
||||
{{"Études : "|coul('gras')}}{{o.etudes|join(' ')}}
|
||||
{{"Cotisation payée pour les années : "|coul('gras')}}{{o.paiement|join(' ')}} {% if o.get('controle', []) and 'p' in o.controle.0.value %}{{"(OK)"|coul('vert')}}{% endif %}
|
||||
{{"Carte d'étudiant fournie pour les années : "|coul('gras')}}{{o.carteEtudiant|join(' ')}} {% if o.get('controle', []) and 'c' in o.controle.0.value %}{{"(OK)"|coul('vert')}}{% endif %}
|
||||
{{adh}} {% if o.get('controle', []) and 'p' in o.controle.0.value %}{{"(OK)"|coul('vert')}}{% endif %}
|
||||
|
||||
{{conn}} {% if o.get('controle', []) and 'p' in o.controle.0.value %}{{"(OK)"|coul('vert')}}{% endif %}
|
||||
|
||||
{{cetud}} {% if o.get('controle', []) and 'c' in o.controle.0.value %}{{"(OK)"|coul('vert')}}{% endif %}
|
||||
|
||||
{% endblock%}
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
{{"Imprimeurs : "|coul('gras')}}{% for i in o.imprimeurClub %}{{i.value.prenom|join(' ')}} {{i.value.nom|join(' ')}} ({{i.value.aid|join(' ')}}) {% endfor%}
|
||||
|
||||
{{"Local : "|coul('gras')}}{{o.chbre.0}} ({{o.chbre.0|string|prise_etat}})
|
||||
{{"Charte signée pour les années scolaires : "|coul('gras')}}{{o.paiement|join(' ')}}
|
||||
{{adh}}
|
||||
{% endblock%}
|
||||
|
|
|
@ -16,7 +16,7 @@ import gestion.config as config
|
|||
|
||||
# liste des attributs dont dépend un service
|
||||
services_to_attrs = {}
|
||||
services_to_attrs['macip'] = [ attributs.ipHostNumber, attributs.ip6HostNumber, attributs.macAddress, attributs.paiement, attributs.carteEtudiant ]
|
||||
services_to_attrs['macip'] = [ attributs.ipHostNumber, attributs.ip6HostNumber, attributs.macAddress, attributs.paiement, attributs.carteEtudiant, attributs.finConnexion ]
|
||||
services_to_attrs['dns'] = [ attributs.ipHostNumber, attributs.ip6HostNumber, attributs.sshFingerprint, attributs.host, attributs.hostAlias, attributs.dnsIpv6 , attributs.hostCert, attributs.portTCPin, attributs.portUDPin ]
|
||||
services_to_attrs['blacklist'] = [ attributs.blacklist, attributs.chbre, attributs.mailInvalide ] + services_to_attrs['macip']
|
||||
services_to_attrs['ports'] = [ attributs.portUDPout, attributs.portUDPin, attributs.portTCPout, attributs.portTCPin ]
|
||||
|
@ -319,7 +319,7 @@ def services_to_restart(conn, old_attrs={}, new_attrs={}, created_object=[], del
|
|||
if 'cransAccount' in added_objectClass:
|
||||
arg = services_to_args['home'](added_objectClass[0])
|
||||
service_to_restart(conn, "home", list(arg), 0)
|
||||
|
||||
|
||||
if 'cransAccount' in deleted_objectClass:
|
||||
service_to_restart(conn, "del_user", ["%s,%s" % (old_attrs['uid'][0], old_attrs['homeDirectory'][0])], 0)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue