gestion: vieilleries
This commit is contained in:
parent
d5921db4c7
commit
113eb17c4d
4 changed files with 0 additions and 0 deletions
84
archive/gestion/darcs_pylint_check.py
Normal file
84
archive/gestion/darcs_pylint_check.py
Normal 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 ()
|
359
archive/gestion/darcs_send_changes.py
Executable file
359
archive/gestion/darcs_send_changes.py
Executable 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])
|
32
archive/gestion/liberation_ip.py
Normal file
32
archive/gestion/liberation_ip.py
Normal 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 !"
|
47
archive/gestion/spam_cablages.py
Executable file
47
archive/gestion/spam_cablages.py
Executable 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
|
Loading…
Add table
Add a link
Reference in a new issue