chambres_vides: refactoring
This commit is contained in:
parent
871eb7d3c0
commit
7169e50fd2
4 changed files with 114 additions and 110 deletions
|
@ -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
|
|
||||||
if ttl > 0:
|
|
||||||
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:
|
# Date de suppression prévue
|
||||||
for m in machine_liste:
|
date_suppr = date + delai*DAY
|
||||||
|
|
||||||
|
if date_suppr < now: # A expiré
|
||||||
|
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())
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{to}}
|
"{{adh|name}}" <{{to}}>
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue