gestion: vieilleries

This commit is contained in:
Daniel STAN 2014-10-24 22:59:52 +02:00
parent d5921db4c7
commit 113eb17c4d
4 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,84 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2009 Antoine Durand-Gasselin
# Author: Antoine Durand-Gasselin <adg@crans.org>
#
import commands, os, sys
from affich_tools import cprint, ERREUR
EXCEPTIONS = ["./gestion/ldap_crans.py"]
def goto_darcs_root ():
while not os.path.exists('_darcs') and os.getcwd() != '/':
os.chdir('..')
if not os.path.exists('_darcs'):
cprint("Pas de dépôt darcs trouvé")
sys.exit(1)
cprint("Dans le repo darcs %s" % os.getcwd(), "bleu")
def darcs_modified ():
ret, msg = commands.getstatusoutput('darcs whatsnew -s')
if ret:
cprint(ERREUR)
print msg
changes = msg.split('\n')
python_files = []
for i in changes:
if i[0] in ['A', 'M'] and i.split()[1][-3:] == '.py':
python_files.append(i[2:].split()[0])
return python_files
def pylint_check ():
files = darcs_modified()
erreurs = ""
will_fail = False
l = len(files)
f = 1
for file in files:
print
cprint (u"[%d/%d] Vérification de %s" % (f, l, file), "gras")
f += 1
ret, output = commands.getstatusoutput('pylint %s' % file)
msg = output.split('\n')
is_fatal = False
fatals = []
has_errors = False
errors = []
for i in msg:
if i[:2] == 'F:' :
is_fatal = True
fatals.append(i)
will_fail = True
if i[:2] == 'E:' :
has_errors = True
errors.append(i)
if is_fatal:
cprint ("%s a des erreurs fatales:" % file, 'rouge')
print '\n'.join([ 4*' '+i for i in fatals])
elif has_errors:
cprint ("%s est sûrement plein d'erreurs" % file, 'jaune')
print '\n'.join([ 4*' '+i for i in errors])
if file not in EXCEPTIONS:
will_fail = True
else:
cprint('Mais on s\'en fout: on sait que %s est trop sale' % file , 'rouge')
else:
cprint (' OK', 'vert')
if not will_fail:
ret, output = commands.getstatusoutput('pylint %s' % ' '.join(files))
print output
else:
sys.exit(1)
if __name__ == '__main__':
goto_darcs_root()
pylint_check ()

View file

@ -0,0 +1,359 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# darcs_send_changes.py
# ---------------------
#
# Copyright (C) 2007 Jeremie Dimino <jeremie@dimino.org>
# Copyright (C) 2007,2008 Nicolas Dandrimont <Nicolas.Dandrimont@crans.org>
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
"""
Envoie un mail détaillant le dernier patch appliqué à un dépot.
"""
print """Nan mais en fait l'envoi par mail des modifications darcs ne marche plus.
Avant les patchs darcs étaient nommés AAAAMMJJHHMMSS-hash mais ce n'est plus le cas.
On n'a même plus ordre alphabétique == ordre chronologique."""
import commands, os, sys, email
try:
from lxml import etree
except ImportError:
try:
import cElementTree as etree
except ImportError:
sys.stderr.write("darcs_send_changes requiert python-lxml ou cElementTree.\n")
sys.stderr.flush()
sys.exit(1)
sys.path.append("/usr/scripts/gestion")
from affich_tools import cprint, encoding
from unicode2ascii import unicode2ascii
from interactive import *
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.Utils import formatdate
from email import Encoders
CONF_PATH = "_darcs/third-party/darcs-send-changes"
DATE_FILE = CONF_PATH + "/date-last-send"
ID_FILE = CONF_PATH + "/id"
def to_utf8(input):
""" Decode un str ou un unicode vers un str en UTF-8. """
if not isinstance(input, basestring):
return input
if isinstance(input, unicode):
return input.encode("UTF-8")
else:
try:
# Si c'est une chaine brute, on commend par essayer
# de la décoder comme une chaine en UTF-8
input.decode("UTF-8")
return input
except UnicodeDecodeError:
try:
return input.decode("ISO-8859-15").encode("UTF-8")
except (UnicodeDecodeError, UnicodeEncodeError):
return input.decode("ascii", "replace").encode("UTF-8")
def darcs(args):
""" Invoque darcs et renvoie sa sortie. """
(s, o) = commands.getstatusoutput("env DARCS_DONT_ESCAPE_8BIT=1 darcs " + args)
o = to_utf8(o)
return (s, o)
def get_patch_properties(hash):
""" Récupère les informations a propos d'un certain patch. """
if hash:
match_cmd = "--match='hash %s'" % hash
else:
match_cmd = "--last 1"
(status, changelog) = darcs("changes %s --xml-output" % match_cmd)
if status != 0 or changelog == "":
return None
prop = etree.XML(changelog)
if len(prop) == 0:
return None
prop = prop[0]
diff = darcs("diff %s --unified" % match_cmd)[1]
diff = diff[diff.find('\ndiff ')+1:]
cwd = os.getcwd()
hostname = commands.getoutput('hostname -s')
shortrepo = os.path.basename(cwd)
if os.path.exists(ID_FILE):
id = file(ID_FILE).read().strip()
else:
# Ne devrait jamais être appelé
import socket
id = "%s:%s" % (socket.gethostname(), shortrepo)
return { 'author': prop.attrib['author'],
'hostname': hostname,
'id': id,
'repo': "%s:%s" % (hostname, cwd),
'shortrepo': shortrepo,
'date': prop.attrib['local_date'],
'hash': prop.attrib['hash'],
'name': prop.findtext('name'),
'comment': prop.findtext('comment'),
'diff': diff,
'changes': darcs("changes %s --summary" % match_cmd)[1] }
def send_changes(smtp, recipient, patch_props):
""" Formate et envoie un mail avec les modifications sur le dernier
patch appliqué au dépot.
recipient est une liste des destinataires du mail.
Les différents templates sont des chaînes de format python qui peuvent
contenir les variables suivantes:
* author, date, hash, name, comment
* repo: le dépot (hote + chemin)
* shortrepo: basename(chemin du dépot)
* changes: la sortie de darcs changes --summary
* diff: la sortie de darcs diff --unified a partir du premier diff
* recipient: les destinataires du mail
"""
from_template = "%(author)s"
subject_template = "Darcs record (%(id)s): %(name)s"
message_template = "%(changes)s"
diff_template = "%(diff)s"
# On met toutes valeurs en string, en UTF-8
for key, val in patch_props.items():
patch_props[key] = to_utf8(val)
mail = MIMEMultipart()
# On met le titre en ascii sinon c'est atroce pour le filtrage
# automatique
subject = subject_template % patch_props
if subject:
subject = unicode2ascii(subject.decode("UTF-8"))
mail['Subject'] = subject
mail['From'] = from_template % patch_props
mail['To'] = ", ".join(recipient)
mail['Date'] = formatdate(localtime=True)
mail['Mail-Followup-To'] = ", ".join(recipient)
mail['Mail-Reply-To'] = from_template % patch_props
mail['X-CVSinfo'] = "CRANS"
mail['X-DarcsInfo'] = "CRANS-%(id)s" % patch_props
texte = MIMEText(message_template % patch_props, "plain")
texte.set_charset("UTF-8")
mail.attach(texte)
patch = MIMEText(diff_template % patch_props, "UTF-8")
patch.set_type('text/x-patch')
patch.set_charset("UTF-8")
patch.add_header('Content-Disposition', 'inline', filename='%(hash)s.diff' % patch_props)
mail.attach(patch)
if not mail['Content-Transfer-Encoding']:
mail['Content-Transfer-Encoding'] = '8bit'
mail.set_charset("UTF-8")
for to in recipient:
smtp.sendmail(patch_props['author'], to, mail.as_string())
def __usage(err=None):
if err: cprint("%s\n" % err)
cprint("""Usage: %(name)s [OPTIONS] destinataires
pour en savoir plus faites « %(name)s --help »
""" % { 'name': os.path.basename(sys.argv[0]) })
sys.exit(2)
def __help():
cprint("""Usage: %(name)s [options] destinataires
Les options disponibles sont:
-h, --help affiche cette aide
-s, --smtp <serveur> spécifie le serveur smtp à utiliser
-r, --repo <chemin> spécifie l'emplacement du dépôt
-f, --from <hash> hash du premier patch de la série a envoyer
-i, --interactive sélectionne les patches en mode interactif
-d, --date <date> ne considérer que les patches depuis <date>,
qui doit être un préfixe d'un date
de la forme AAAAMMJJHHMMSS
Si aucun destinataire n'est donné, roots@crans.org est utilisé.
""" % { 'name': os.path.basename(sys.argv[0]) })
sys.exit(0)
def getnew(lastdate=None):
'''Renvoie les possibles nouveaux patches depuis lastdate,
ou depuis la date retenue par le programme'''
if not lastdate:
if os.access(DATE_FILE, os.R_OK):
lastdate=file(DATE_FILE).read().strip()
else:
lastdate='19700101000000'
files = os.listdir("_darcs/patches")
patches = []
for f in files:
if f.endswith(".gz"):
date = f.split("-", 1)[0]
if date > lastdate:
patches.append(f)
patches.sort()
return patches
def select(patches):
'''Sélection interactive de patches'''
decided = []
while patches:
(status, changelog) = darcs("changes --match='hash %s'" % patches[0])
if status == 0:
print
print changelog
c = ask("Envoyer ce patch ? (%d/%d)" % (len(decided)+1, len(patches) + len(decided)),
[("YO", "envoyer ce patch"),
("n", "ne pas envoyer ce patch"),
("k", "revenir au patch précédent"),
("a", "envoyer tout les patches suivant"),
("d", "n'envoyer aucun des patches suivant"),
("v", "voir le patch"),
Exit])
if c == "y":
decided.append((True, patches.pop(0)))
elif c == "n":
decided.append((False, patches.pop(0)))
elif c == "k":
if decided:
patches.insert(0, decided.pop()[1])
else:
cprint("Déjà au début de la liste!", "rouge")
elif c == "a":
while patches:
decided.append((True, patches.pop(0)))
elif c == "d":
while patches:
decided.append((False, patches.pop(0)))
count = [x[0] for x in decided].count(True)
if count:
ask("%d patches à envoyer, accepter ?" % count,
[("YO", "oui"),
("nq", "non", None, lambda: sys.exit(0))])
for d in decided:
if d[0]:
patches.append(d[1])
return patches
if __name__ == "__main__":
import smtplib, getopt
smtp = 'localhost'
repo = None
from_hash = None
interactive = False
lastdate = None
try:
options, arg = getopt.getopt(sys.argv[1:], 'hs:r:f:id:',
[ 'help', 'smtp=', 'repo=', 'from=',
'interactive', 'date'])
except getopt.error, msg:
__usage(unicode(msg))
for opt, val in options:
if opt in [ '-h', '--help' ]:
__help()
elif opt in [ '-s', '--smtp' ]:
smtp = val
elif opt in [ '-r', '--repo' ]:
repo = val
elif opt in [ '-f', '--from' ]:
from_hash = val
elif opt in [ '-i', '--interactive' ]:
interactive = True
elif opt in [ '-d', '--date' ]:
lastdate = val
if not lastdate.isdigit or len(lastdate) >= 14:
__usage("date invalide")
lastdate += (14 - len(lastdate)) * "0"
else:
__usage("option inconnue « %s »'" % opt)
recipient = arg
if len(recipient) == 0:
recipient = [ 'roots@crans.org' ]
if repo:
os.chdir(repo)
else:
while not os.path.exists('_darcs') and os.getcwd() != '/':
os.chdir('..')
if not os.path.exists('_darcs'):
cprint("Pas de dépôt darcs trouvé")
sys.exit(1)
if not os.path.exists(CONF_PATH):
partial_path = ''
for rep in CONF_PATH.split('/'):
partial_path += rep+'/'
if not os.path.exists(partial_path):
os.mkdir(os.path.realpath(partial_path))
if not os.path.exists(ID_FILE):
import socket
open(ID_FILE, "w" ).write("%s:%s" % (socket.gethostname(), os.path.basename(os.getcwd())))
if not os.path.exists(DATE_FILE):
try:
# Sélection du patch façon darcs
cprint(u"C'est la première fois que vous lancez %s dans ce dépôt." % os.path.basename(sys.argv[0]))
c = ask("Que voulez-vous faire ?",
[("S", "sélectionner les patchs à envoyer/ignorer en mode interactif", "select"),
("a", "tout envoyer", "all"),
("d", "tout ignorer", "none"),
Exit])
patches = getnew(lastdate)
if c == "none":
if patches:
open(DATE_FILE, "w").write(patches[-1].split("-", 1)[0])
patches = []
else:
open(DATE_FILE, "w").write("19700101000000")
elif c == "select":
# On commence par les plus récent
patches.reverse()
patches = select(patches)
patches.reverse()
except OSError, e:
if e.errno == 11:
# Quand c'est darcs qui lance la commande on ne pas lire
# l'entrée standart
print
cprint("Veuillez lancez %s à la main" % os.path.basename(sys.argv[0]), 'rouge')
sys.exit(1)
else:
raise e
else:
patches = getnew(lastdate)
if interactive:
patches = select(patches)
if len(patches) == 0:
sys.exit(0)
for patch in patches:
props = get_patch_properties(patch)
if props:
cprint("Envoi du patch %s a %s." % (props['hash'], ", ".join(recipient)))
send_changes(smtplib.SMTP(smtp), recipient, props)
open(DATE_FILE, "w").write(patch.split("-", 1)[0])

View file

@ -0,0 +1,32 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import sys
sys.path.append('/usr/scripts/gestion')
import config
from ldap_crans import crans_ldap, decode
db = crans_ldap()
annee = config.ann_scol
#suppression des machines
adherents = db.search( 'paiement=%d&paiement!=%d' % (annee - 1, annee), 'w' )['adherent']
for adherent in adherents:
print "suppression des machines de: %(nom)s " % {'nom': adherent.Nom()}
machines = adherent.machines()
for machine in machines:
print "suppression machine: %(nom)s " % {'nom': machine.nom()}
machine.delete('liberation de l\'adresse')
# regeneration du pool d'ip
print "Regeneration du pool d'ip"
import numeros_disponibles
ip_occupees = numeros_disponibles.lister_ip_utilisees()
for net in config.NETs.keys():
numeros_disponibles.update_ip(net, ip_occupees)
print "Fini !"

View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
# -!- encoding: utf-8 -!-
# SPAM_CABLAGES.PY -- Spamme respbats pour rappeler les cablages a effectuer
import psycopg2
from collections import defaultdict
import sys
sys.path.append('/usr/scripts/')
import utils.sendmail
TEMPLATE = u"""
Câblages à effectuer :
%(cablages)s
--\u0020
L'intranet du Cr@ns"""
TEMPLATE_BATIMENT = u"""
Batiment %(batiment)s
%(prises)s"""
def get_cablages():
"""Recupere la liste des cablages a effectuer"""
conn = psycopg2.connect("user=crans dbname=switchs host=pgsql.adm.crans.org")
cur = conn.cursor()
cur.execute("SELECT batiment, chambre, prise_crans FROM prises WHERE cablage_effectue = FALSE")
res = defaultdict(list)
for batiment, chambre, prise_crans in cur.fetchall():
res[batiment].append(chambre)
return res
CABLAGES = get_cablages()
if CABLAGES:
CORPS_BATIMENTS = []
for batiment in sorted(CABLAGES.keys()):
ubatiment = batiment.upper()
prises = ", ".join(["%s%s" % (ubatiment, chambre) for chambre in sorted(CABLAGES[batiment])])
CORPS_BATIMENTS.append(TEMPLATE_BATIMENT % { "prises": prises, "batiment": ubatiment })
message = TEMPLATE % { "cablages": "".join(CORPS_BATIMENTS) }
if "--mail" in sys.argv:
utils.sendmail.sendmail(u"intranet-bugreport@crans.org", u"respbats@lists.crans.org",
u"[Câblage] Résumé des câblages à effectuer", message, more_headers={u"X-Crans-Intranet" : u"cablage", u"X-Mailer" : u"/usr/scripts/spam_cablages.py"})
else:
print message