chambres_vides: refactoring

This commit is contained in:
Daniel STAN 2014-11-07 00:16:49 +01:00
parent 871eb7d3c0
commit 7169e50fd2
4 changed files with 114 additions and 110 deletions

View file

@ -1,134 +1,138 @@
#!/bin/bash /usr/scripts/python.sh #!/bin/bash /usr/scripts/python.sh
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
""" Pour détecter les gens en chambre invalide, les prévenir, et supprimer leurs machines """ Pour détecter les gens en chambre invalide, les prévenir, et supprimer leurs
en l'absence de réponse. Récupérer des IPs, c'est cool.""" machines en l'absence de réponse. Récupérer des IPs, c'est cool.
# Codé par b2moo, commenté par 20-100, cr{itiqu|on}é par Nit Codé par b2moo, commenté par 20-100, cr{itiqu|on}é par Nit
# <daniel.stan@crans.org> <daniel.stan@crans.org>
# <legallic@crans.org> <legallic@crans.org>
# <samir@crans.org> <samir@crans.org>
"""
import sys
import os
import datetime import datetime
import time import time
import re import re
import affichage
import lc_ldap.shortcuts import lc_ldap.shortcuts
from lc_ldap.crans_utils import to_generalized_time_format as toGeneralizedTimeFormat from lc_ldap.crans_utils import to_generalized_time_format as to_gtf
conn = lc_ldap.shortcuts.lc_ldap_admin()
import mail as mail_module import mail as mail_module
import sys from config import demenagement_delai as delai, \
#: envoyer un mail à chaque adhérent concerné debut_periode_transitoire, periode_transitoire
sendmails = False
if "--mail-all" in sys.argv:
sendmails = True
from email.header import Header
#: Envoyer un mail à respbats ERASE_DAY = { 'second': 0, 'minute': 0, 'microsecond': 0, 'hour': 0, }
sendmail_respbats = True DAY = datetime.timedelta(days=1)
if "--no-mail" in sys.argv: FORMAT_LDAP = '%Y%m%d%H%M%S%z'
sendmail_respbats = False
DEBUG = False RESP = 'respbats@crans.org'
if "--debug" in sys.argv:
DEBUG = True
import os FILTER = u'''(&
import config (aid=*)
year = config.ann_scol (chbre=????)
delai = config.demenagement_delai (finAdhesion>=%(date)s)
(finConnexion>=%(date)s)
)'''
# On récupère ceux qui n'ont pas payé cette année # On récupère ceux qui n'ont pas payé cette année
now = time.time() now = datetime.datetime.now().replace(**ERASE_DAY)
if config.periode_transitoire:
bad_boys_e_s = conn.search(u'(&(aid=*)(chbre=????)(|(&(paiement=%d)(!(paiement=%d)))(finAdhesion<=%s)(finConnexion<=%s)))' % (year-1, year, toGeneralizedTimeFormat(now), toGeneralizedTimeFormat(now)))
else:
bad_boys_e_s = conn.search(u'(&(aid=*)(chbre=????)(|(paiement=%d)(finAdhesion>=%s)(finConnexion>=%s)))' % (year, toGeneralizedTimeFormat(now), toGeneralizedTimeFormat(now)))
to_print = [] def get_kickout(adh):
to_error = [] """Renvoie la date et la chambre de la dernière expulsion"""
for clandestin in bad_boys_e_s:
# On cherche la dernière fois qu'il s'est retrouvé en chambre ???? # On cherche la dernière fois qu'il s'est retrouvé en chambre ????
for l in clandestin['historique'][::-1]: for l in adh['historique'][::-1]:
# On récupère la date du dernier changement de chambre # On récupère la date du dernier changement de chambre
# (l'historique est enregistré par ordre chronologique) # (l'historique est enregistré par ordre chronologique)
x = re.match("(.*),.* : chbre \((.*) -> \?\?\?\?\)", str(l)) x = re.match("(.*),.* : chbre \((.*) -> \?\?\?\?\)", str(l))
if x <> None: if x <> None:
kickout_date = x.group(1) return (l.get_datetime(), x.group(2))
exchambre = x.group(2) raise IndexError('Adh jamais expulse')
machine_liste = clandestin.machines() def warn_or_delete(smtp, clandestin, fail, done):
# On lui accorde un délai """Avertit l'adhérent ou supprime ses machines si nécessaire"""
kickout_date = time.mktime(time.strptime(kickout_date, "%d/%m/%Y %H:%M")) date, exchambre = get_kickout(clandestin)
delta = now - kickout_date
ttl = delai*86400 - delta # Date de suppression prévue
if ttl > 0: date_suppr = date + delai*DAY
if (sendmails and machine_liste != [] or DEBUG) and (ttl >= (delai - 1)*86400 or 0 < ttl <= 86400):
# On lui envoie un mail pour le prévenir
to = clandestin['mail'][0]
mail = mail_module.generate('demenagement', {"from" : "respbats@crans.org",
"chambre" : exchambre,
"jours" : int(ttl/86400) + 1,
"to" : to,
"prenom" : clandestin["prenom"][0],
"nom" : clandestin["nom"][0],
"lang_info":"English version below"}
).as_string()
if DEBUG:
print mail
mailer = os.popen("/usr/sbin/sendmail -t", "w")
mailer.write(mail + "\n.")
mailer.close()
else: if date_suppr < now: # A expiré
for m in machine_liste: reason = u'Adhérent sans chambre valide depuis %d jours' % delai
for m in clandestin.machines(mode='rw'):
try: try:
reason = u'Adhérent sans chambre valide depuis %d jours' % delai with m:
with conn.search(u'mid=%s' % m['mid'][0], mode='w')[0] as m2: m.delete(reason)
m2.delete(reason) done.append(m)
to_print.append( (clandestin['aid'][0], m['ipHostNumber'][0], m['mid'][0], m['host'][0]) )
except Exception as e: except Exception as e:
to_error.append((clandestin['aid'][0], m['ipHostNumber'][0], m['mid'][0], m['host'][0], e)) fail.append((m, e))
elif date_suppr < now + DAY or now - date < DAY:
# Expire dans un jour ou vient tout juste de se faire virer
mail_addr = clandestin.get_mail()
if not clandestin.machines() or not mail_addr:
return # Si pas de machine, on s'en fout. Si pas de mail, inutile
data = {
"from" : RESP,
"chambre" : exchambre,
"jours" : (date_suppr - now).days+1,
"to" : mail_addr,
"adh": clandestin,
"lang_info": "English version below",
}
mail = mail_module.generate('demenagement', data)
smtp.sendmail(RESP, [mail_addr], mail.as_string())
message = u"" def format_entry(m):
if to_print != []: """Renvoie une ligne de tableau, pour une machine"""
# Il s'est passé quelque chose, donc on envoie un mail return [
# On regarde le plus grand hostname unicode(m['host'][0]),
hostnamemaxsize = max([len(str(i[3])) for i in to_print]) unicode(' '.join(m.dn.split(',')[:2])),
template = u"| %%4s | %%-15s | %%4s | %%-%ss |\n" % (hostnamemaxsize) ]
message += u"\nListe des machines supprimées pour chambre invalide depuis plus de %s jours :\n" % delai
tiret_line = u"+------+-----------------+------+-%s-+\n" % ("-" * hostnamemaxsize)
message += tiret_line
message += template % ("aid", " ip", "mid", (" " * (max((hostnamemaxsize-8)/2,0)) + "hostname"))
message += tiret_line
for aid, ip, mid, hostname in to_print:
message += template % (aid, ip, mid, hostname)
message += tiret_line def spaces(x):
message += u"\nScore de cette nuit : %s" % (len(to_print)) """Ajoute des espaces en plus sur un tableau de tableau de strings"""
if type(x) == list:
if to_error != []: return map(spaces, x)
hostnamemaxsize = max([len(str(i[3])) for i in to_error])
errormaxsize = max([len(str(i[4])) for i in to_error])
template = u"| %%4s | %%-15s | %%4s | %%-%ss | %%-%ss |\n" % (hostnamemaxsize, errormaxsize)
message += u"\n"
tiret_line = u"+------+-----------------+------+-%s-+-%s-+\n" % ("-" * hostnamemaxsize, "-" * errormaxsize)
message += u"\nListe des machines dont la supression à échoué :\n"
message += tiret_line
message += template % ("aid", " ip", "mid", (" " * (max((hostnamemaxsize-8)/2,0)) + "hostname"), (" " * (max((errormaxsize-6)/2,0)) + "erreur"))
for aid, ip, mid, hostname, error in to_error:
message += template % (aid, ip, mid, hostname, error)
message += tiret_line
if to_print != [] or to_error != []:
headers = u"From: respbats@crans.org\nSubject: %s\n" % Header("Machines supprimées pour chambre invalide", "utf8").encode()
headers += u"Content-Type: text/plain; charset=UTF-8\n"
headers += u"X-Mailer: /usr/scripts/gestion/chambres_vides.py\n"
headers += u"To: respbats@crans.org\n"
mail = headers + "\n" + message
if sendmails:
mailer = os.popen("/usr/sbin/sendmail -t", "w")
mailer.write(mail.encode("utf-8") + "\n.")
mailer.close()
else: else:
print mail return u' ' + unicode(x) + u' '
if __name__ == '__main__':
conn = lc_ldap.shortcuts.lc_ldap_admin()
if periode_transitoire:
date = to_gtf(debut_periode_transitoire)
else:
date = now.strftime(FORMAT_LDAP) + 'z'
bad_boys_e_s = conn.search(FILTER % {'date': date})
fail = []
done = []
with mail_module.ServerConnection() as smtp:
for clandestin in bad_boys_e_s:
warn_or_delete(smtp, clandestin, fail, done)
if fail or done:
done = spaces([format_entry(m) for m in done])
fail = spaces([format_entry(m) + [e] for (m,e) in fail])
data = {
'from': RESP,
'to': RESP,
'delai': delai,
'fail': fail,
'done': done,
'done_tab': affichage.tableau(
done,
titre=[u'Hôte', u'Référence'],
alignement=['d', 'd'],
),
'fail_tab': affichage.tableau(
fail,
titre=[u'Hôte', u'Référence', u'Erreurs'],
alignement=['d', 'd', 'd'],
),
}
with mail_module.ServerConnection() as smtp:
mail = mail_module.generate('demenagement_stats', data)
smtp.sendmail(RESP, [RESP], mail.as_string())

View file

@ -1 +1 @@
{{to}} "{{adh|name}}" <{{to}}>

View file

@ -1,4 +1,4 @@
Hi {{prenom}} {{nom}}! Hi {{ adh|name }}!
A new member of Crans has declared to live in the room {{chambre}} you were A new member of Crans has declared to live in the room {{chambre}} you were
previously registered in. This means we do not have your residency information previously registered in. This means we do not have your residency information
@ -10,7 +10,7 @@ campus.
If you do not wish to keep your Crans Internet access, a simple message from If you do not wish to keep your Crans Internet access, a simple message from
you is enough to delete all your computers from our database. This deletion you is enough to delete all your computers from our database. This deletion
will automatically take place in {{jours}} day(s) if you do not answer. will automatically take place in {{jours}} day{% if jours > 1 %}s{%endif%} if you do not answer.
If you do have a Crans account, you will keep an unlimited acces to it, as well If you do have a Crans account, you will keep an unlimited acces to it, as well
as all the associated services such as your email firstname.lastname@crans.org. as all the associated services such as your email firstname.lastname@crans.org.

View file

@ -1,4 +1,4 @@
Bonjour {{prenom}} {{nom}}, Bonjour {{ adh|name }},
Un adhérent du Crans a déclaré résider dans la chambre {{chambre}}, Un adhérent du Crans a déclaré résider dans la chambre {{chambre}},
que tu occupais précédemment. Cela signifie que nous ne disposons que tu occupais précédemment. Cela signifie que nous ne disposons
@ -10,7 +10,7 @@ si tu as quitté le campus.
Si tu ne souhaites pas conserver ton accès Internet, un simple message de Si tu ne souhaites pas conserver ton accès Internet, un simple message de
ta part et nous supprimerons les machines que tu possèdes de notre base de ta part et nous supprimerons les machines que tu possèdes de notre base de
données. Cette suppression aura automatiquement lieu dans {{jours}} jour(s) en données. Cette suppression aura automatiquement lieu dans {{jours}} jour{% if jours > 1%}s{%endif%} en
l'absence de réponse. l'absence de réponse.
Si tu possèdes un compte Crans, tu conserves un accès à celui-ci sans limite de Si tu possèdes un compte Crans, tu conserves un accès à celui-ci sans limite de