diff --git a/admin/controle_chartes_MA.py b/admin/controle_chartes_MA.py index 4fde7a22..da57c8c1 100755 --- a/admin/controle_chartes_MA.py +++ b/admin/controle_chartes_MA.py @@ -1,21 +1,21 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -# Copyright (C) Stéphane Glondu, Alexandre Bos, Michel Blockelet +# Copyright (C) Stéphane Glondu, Alexandre Bos, Michel Blockelet # Licence : GPLv2 -u"""Ce script permet au secrétaire de repérer plus facilement les membres -actifs qui n'ont pas signé la charte du même nom. +u"""Ce script permet au secrétaire de repérer plus facilement les membres +actifs qui n'ont pas signé la charte du même nom. Utilisation : %(prog)s {liste|modif|spam} [--debug ] L'unique option est : - --debug envoyer tous les mails à l' indiquée, plutôt + --debug envoyer tous les mails à l' indiquée, plutôt qu'aux vrais destinataires Les commandes sont : - * liste énumérer les membres n'ayant pas signé la charte - * modif modifier les membres actifs n'ayant pas signé la charte + * liste énumérer les membres n'ayant pas signé la charte + * modif modifier les membres actifs n'ayant pas signé la charte * spam envoie des mails de rappel pour les chartes """ @@ -29,7 +29,7 @@ from email_tools import send_email, parse_mail_template # Fonctions d'affichage from affich_tools import coul, tableau, prompt, cprint -# Importation de la base de données +# Importation de la base de données from ldap_crans import crans_ldap, ann_scol db = crans_ldap() @@ -44,12 +44,12 @@ if __name__ == '__main__': sys.argv.pop() if debug: - cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug) + cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug) def _controle_interactif_adherents(liste): """ - Contrôle interactif des adhérents de la liste. + Contrôle interactif des adhérents de la liste. Retourne (nb_OK, nb_pas_OK). """ @@ -57,10 +57,10 @@ def _controle_interactif_adherents(liste): if restant == 0: return 0, 0 - cprint(u'\nContrôle des membre actifs' , 'cyan') - cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).") - cprint(u"Une autre réponse entraîne l'interruption du processus.") - cprint(u"Le format est [nb_restant] Nom, Prénom (aid).") + cprint(u'\nContrôle des membre actifs' , 'cyan') + cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).") + cprint(u"Une autre réponse entraîne l'interruption du processus.") + cprint(u"Le format est [nb_restant] Nom, Prénom (aid).") cprint(u"") nb = 0 @@ -81,7 +81,7 @@ def _controle_interactif_adherents(liste): modifiable.charteMA(True) cprint(modifiable.save()) else: - cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') + cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') elif ok == 'n': if a.charteMA() == True: modifiable = db.search('aid=%s' % a.id(), 'w')['adherent'][0] @@ -89,16 +89,16 @@ def _controle_interactif_adherents(liste): modifiable.charteMA(False) cprint(modifiable.save()) else: - cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') + cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') else: - cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge') + cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge') break return nb, len(liste)-nb def liste_charte_nok(): - """Retourne la liste des membres actifs qui n'ont pas signé la charte.""" + """Retourne la liste des membres actifs qui n'ont pas signé la charte.""" liste_actifs = db.search('droits=*')['adherent'] liste_nok = [] for adh in liste_actifs: @@ -110,25 +110,25 @@ def liste_charte_nok(): def controle_interactif(): """ - Procédure interactive de contrôle des chartes de membres actifs. + Procédure interactive de contrôle des chartes de membres actifs. """ todo_list = liste_charte_nok() - # Tri de la liste des adhérents selon nom, prénom - # Ça peut se faire plus facilement en Python 2.4 avec l'argument key + # Tri de la liste des adhérents selon nom, prénom + # Ça peut se faire plus facilement en Python 2.4 avec l'argument key todo_list.sort(lambda x, y: cmp((x.nom(), x.prenom()), (y.nom(), y.prenom()))) # Zou ! ok, nok = _controle_interactif_adherents(todo_list) - cprint(u'\nRécapitulatif des nouveaux contrôles :', 'violet') + cprint(u'\nRécapitulatif des nouveaux contrôles :', 'violet') liste = [[u'membres actifs', str(ok), str(nok)]] cprint(tableau(liste, - titre = [u'Catégorie', u'OK', u'pas OK'], + titre = [u'Catégorie', u'OK', u'pas OK'], largeur = [15, 10, 10])) def spammer(): - # On envoie un mail à chacun des membres actifs qui n'ont pas donné le papier + # On envoie un mail à chacun des membres actifs qui n'ont pas donné le papier todo_list = liste_charte_nok() if todo_list: @@ -144,10 +144,10 @@ def spammer(): print to if not debug: data = config.mails.txt_charte_MA % {'From' : u"ca@crans.org", 'To' : to} - connexion.sendmail("ca@crans.org",to,data.encode('iso-8859-15')) + connexion.sendmail("ca@crans.org",to,data.encode('utf-8')) def __usage(message=None): - """ Comment ça marche ? """ + """ Comment ça marche ? """ cprint(__doc__ % { 'prog': sys.argv[0] }) if message: cprint(message) @@ -161,7 +161,7 @@ if __name__ == '__main__' : elif sys.argv[1] == 'liste': if len(sys.argv) != 2: __usage(u'Mauvaise utilisation de liste') - print "Liste des membres actifs n'ayant pas signé la charte :" + print "Liste des membres actifs n'ayant pas signé la charte :" for adh in liste_charte_nok(): print adh.Nom() elif sys.argv[1] == 'modif': diff --git a/admin/controle_tresorier.py b/admin/controle_tresorier.py index f857e0f1..82b5781d 100755 --- a/admin/controle_tresorier.py +++ b/admin/controle_tresorier.py @@ -1,43 +1,43 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -# Copyright (C) Stéphane Glondu +# Copyright (C) Stéphane Glondu # Licence : GPLv2 -u"""Ce script permet au trésorier de repérer plus facilement les papiers que -les câbleurs n'ont pas encore rendus. +u"""Ce script permet au trésorier de repérer plus facilement les papiers que +les câbleurs n'ont pas encore rendus. Utilisations possibles : * %(prog)s OPTIONS {paiement|carte|list} * %(prog)s OPTIONS mail Les options sont: - -d, --debug envoyer tous les mails à l' indiquée, plutôt + -d, --debug envoyer tous les mails à l' indiquée, plutôt qu'aux vrais destinataires -h, --help affiche ce message -t, --tri trier suivant ce champ. Les champs possibles sont: - id, nom, cableur ou date. Le défaut est ``nom'' + id, nom, cableur ou date. Le défaut est ``nom'' -i, --inverse trier par ordre inverse Les commandes sont : - * paiement contrôle interactif des nouvelles (ré-)adhésions - * carte contrôle interactif des nouvelles cartes d'étudiant - * list affiche le récapitulatif des papiers manquants - * mail envoyer les mails de rappel aux câbleurs dont le - login est dans la , 'bureau' désignant le mail - récapitulatif envoyé à bureau ; si la liste est vide - tous les mails nécessaires seront envoyés + * paiement contrôle interactif des nouvelles (ré-)adhésions + * carte contrôle interactif des nouvelles cartes d'étudiant + * list affiche le récapitulatif des papiers manquants + * mail envoyer les mails de rappel aux câbleurs dont le + login est dans la , 'bureau' désignant le mail + récapitulatif envoyé à bureau ; si la liste est vide + tous les mails nécessaires seront envoyés * help affiche ce message -Le modèle du mail envoyé aux câbleurs est lu sur l'entrée standard (typiquement -via une redirection). Les trois premières lignes doivent être : +Le modèle du mail envoyé aux câbleurs est lu sur l'entrée standard (typiquement +via une redirection). Les trois premières lignes doivent être : Encoding: Subject: Le reste est le corps du message. Il doit contenir une occurrence de '%%s' qui -sera remplacée par la liste des papiers manquants. +sera remplacée par la liste des papiers manquants. -Le mail récapitulatif envoyé à bureau est immuable.""" +Le mail récapitulatif envoyé à bureau est immuable.""" import sys, os, re, getopt @@ -46,21 +46,21 @@ sys.path.append('/usr/scripts/gestion') # Fonctions d'affichage from affich_tools import coul, tableau, prompt, cprint -# Importation de la base de données +# Importation de la base de données from ldap_crans import crans_ldap, ann_scol db = crans_ldap() -# Détermination de l'uid du câbleur +# Détermination de l'uid du câbleur from user_tests import getuser uid = getuser() if not uid : - cprint(u"Impossible de déterminer l'utilisateur !") + cprint(u"Impossible de déterminer l'utilisateur !") sys.exit(1) cableur = db.search('uid=%s' % uid)['adherent'][0] -# Vérification des droits +# Vérification des droits if u'Tresorier' not in cableur.droits(): - cprint(u"Il faut etre tresorier pour exécuter ce script !") + cprint(u"Il faut etre tresorier pour exécuter ce script !") sys.exit(1) # Lors des tests, on m'envoie tous les mails ! @@ -77,19 +77,19 @@ if gethostname().split(".")[0] == 'egon': def _controle_interactif_adherents(liste, quoi): """ - Contrôle interactif des adhérents de la liste (quoi = p ou c). + Contrôle interactif des adhérents de la liste (quoi = p ou c). Retourne (nb_OK, nb_pas_OK). """ if quoi not in 'pc': raise ValueError - explicite = {'p': u'du paiement', 'c': u"de la carte d'étudiant"}[quoi] + explicite = {'p': u'du paiement', 'c': u"de la carte d'étudiant"}[quoi] restant = len(liste) if restant == 0: return 0, 0 - cprint(u'\nContrôle %s des adhérents' % explicite, 'cyan') - cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).") - cprint(u"Une autre réponse entraîne l'interruption du processus.") - cprint(u"Le format est [nb_restant] Nom, Prénom (aid).") + cprint(u'\nContrôle %s des adhérents' % explicite, 'cyan') + cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).") + cprint(u"Une autre réponse entraîne l'interruption du processus.") + cprint(u"Le format est [nb_restant] Nom, Prénom (aid).") cprint(u"") nb = 0 @@ -104,9 +104,9 @@ def _controle_interactif_adherents(liste, quoi): cprint(modifiable.save()) nb += 1 else: - cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') + cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') elif ok != 'n': - cprint(u'Arrêt du contrôle %s des adhérents' % explicite, 'rouge') + cprint(u'Arrêt du contrôle %s des adhérents' % explicite, 'rouge') break return nb, len(liste)-nb @@ -114,16 +114,16 @@ def _controle_interactif_adherents(liste, quoi): def _controle_interactif_clubs(liste): """ - Contrôle interactif des clubs de la liste (uniquement la charte). + Contrôle interactif des clubs de la liste (uniquement la charte). Retourne (nb_OK, nb_pas_OK). """ restant = len(liste) if restant == 0: return 0, 0 - cprint(u'\nContrôle de la charte des clubs', 'cyan') - cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n'.") - cprint(u"Une autre réponse entraîne l'interruption du processus.") + cprint(u'\nContrôle de la charte des clubs', 'cyan') + cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n'.") + cprint(u"Une autre réponse entraîne l'interruption du processus.") cprint(u"Le format est [nb_restant] Nom (cid).") cprint(u"") @@ -139,17 +139,17 @@ def _controle_interactif_clubs(liste): cprint(modifiable.save()) nb += 1 else: - cprint(u'Club %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') + cprint(u'Club %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') elif ok != 'n': - cprint(u'Arrêt du contrôle de la charte des clubs', 'rouge') + cprint(u'Arrêt du contrôle de la charte des clubs', 'rouge') break return nb, len(liste)-nb def qui(historique, quoi): """ - Recherche le câbleur qui a effectué la dernière modification quoi - dans l'historique, ou qui a inscrit l'adhérent. + Recherche le câbleur qui a effectué la dernière modification quoi + dans l'historique, ou qui a inscrit l'adhérent. Retourne le couple (date, cableur) ou ('_inconnu_', '_inconnu_'). """ regexp = re.compile(r'^([^,]*), ([^ :]*)') @@ -166,13 +166,13 @@ def qui(historique, quoi): def controle_interactif(quoi): """ - Procédure interactive de contrôle des paiements/chartes (quoi=p) et cartes (quoi=c). + Procédure interactive de contrôle des paiements/chartes (quoi=p) et cartes (quoi=c). """ if quoi not in 'pc': raise ValueError todo_list = db.search('%s=%d&controle!=*%s*' % ({'p': 'paiement', 'c': 'carteEtudiant'}[quoi], ann_scol, quoi)) - # Tri de la liste des adhérents selon nom, prénom + # Tri de la liste des adhérents selon nom, prénom todo_list['adherent'].sort(key = lambda x: (x.nom(), x.prenom())) if trier_par == 'id': @@ -183,7 +183,7 @@ def controle_interactif(quoi): champ = { 'date': 0, 'cableur': 1 }[trier_par] todo_list['adherent'].sort(key = lambda x: qui(x.historique(), r'paiement')[champ]) - # Traitement des adhérents + # Traitement des adhérents oka, noka = _controle_interactif_adherents(todo_list['adherent'], quoi) if quoi == 'p': @@ -193,18 +193,18 @@ def controle_interactif(quoi): # Traitement des clubs (uniquement la charte) okc, nokc =_controle_interactif_clubs(todo_list['club']) - cprint(u'\nRécapitulatif des nouveaux contrôles +%s :' % quoi, 'violet') - liste = [[u'adhérents', str(oka), str(noka)]] + cprint(u'\nRécapitulatif des nouveaux contrôles +%s :' % quoi, 'violet') + liste = [[u'adhérents', str(oka), str(noka)]] if quoi == 'p': liste.append([u'clubs', str(okc), str(nokc)]) cprint(tableau(liste, - titre = [u'Catégorie', u'OK', u'pas OK'], + titre = [u'Catégorie', u'OK', u'pas OK'], largeur = [15, 10, 10])) def formater_pour_cableur(liste): """ - Formate la liste d'adhérents ou de clubs avec les dates correspondantes. + Formate la liste d'adhérents ou de clubs avec les dates correspondantes. liste est une liste de couples (date, objet). """ lignes = [] @@ -231,8 +231,8 @@ def formater_pour_cableur(liste): def formater_pour_bureau(dico): """ - Formate la liste d'adhérents ou de clubs avec les câbleurs correspondantes - pour le mail récapitulatif envoyé à bureau. + Formate la liste d'adhérents ou de clubs avec les câbleurs correspondantes + pour le mail récapitulatif envoyé à bureau. """ lignes = [] total = 0 @@ -253,15 +253,15 @@ def formater_pour_bureau(dico): if tri_inverse: lignes.reverse() return tableau(lignes, - titre = [u'id', u'Nom', u'Câbleur', u'Date'], + titre = [u'id', u'Nom', u'Câbleur', u'Date'], largeur = [6, 40, 18, 18], alignement = ['d', 'c', 'c', 'c']) + u'\nTotal : %d' % total def chercher_cableurs(liste, quoi): """ - Renvoie un dictionnaire cableur->adherents à partir de liste, quoi - désigne le champ qui sera recherché dans l'historique. + Renvoie un dictionnaire cableur->adherents à partir de liste, quoi + désigne le champ qui sera recherché dans l'historique. """ resultat = {} @@ -275,21 +275,21 @@ def chercher_cableurs(liste, quoi): from email_tools import send_email, parse_mail_template -# Mise en application du mémorable cours de Fred sur les objets :-) +# Mise en application du mémorable cours de Fred sur les objets :-) class ControleMailer: def __init__(self): - # Recherche des câbleurs possédant des cotisations/chartes + # Recherche des câbleurs possédant des cotisations/chartes todo_list = db.search('paiement=%d&controle!=*p*' % ann_scol) self._paiements = chercher_cableurs(todo_list['adherent'], r'(paiement|controle.*\+k)') self._chartes = chercher_cableurs(todo_list['club'], 'paiement') - # Recherche des câbleurs possédant des cartes d'étudiant + # Recherche des câbleurs possédant des cartes d'étudiant todo_list = db.search('carteEtudiant=%d&controle!=*c*' % ann_scol) self._cartes = chercher_cableurs(todo_list['adherent'], 'carteEtudiant') - # Récupère tous les câbleurs qui doivent quelque chose + # Récupère tous les câbleurs qui doivent quelque chose cableurs = {} for a in self._paiements.keys(): if a != '_inconnu_': cableurs[a] = None @@ -299,14 +299,14 @@ class ControleMailer: if a != '_inconnu_': cableurs[a] = None self._cableurs = cableurs.keys() - # Vérification de l'alias pour l'expéditeur + # Vérification de l'alias pour l'expéditeur if u'tresorier' in cableur.alias(): self._sender = u'%s ' % cableur.Nom() else: self._sender = u'%s <%s@crans.org>' % (cableur.Nom(), cableur.canonical_alias() or cableur.mail()) - # Se connecte au serveur SMTP par défaut + # Se connecte au serveur SMTP par défaut from smtplib import SMTP self._server = SMTP() self._server.connect() @@ -317,47 +317,47 @@ class ControleMailer: def recapitulatif(self): """ - Renvoie le récapitulatif pour le bureau. + Renvoie le récapitulatif pour le bureau. """ msg = u'' if self._paiements: - msg += u"Fiches d'adhésion et cotisations et/ou caution des adhérents :\n" + msg += u"Fiches d'adhésion et cotisations et/ou caution des adhérents :\n" msg += formater_pour_bureau(self._paiements) + '\n\n' if self._chartes: - msg += u"Chartes signées des clubs :\n" + msg += u"Chartes signées des clubs :\n" msg += formater_pour_bureau(self._chartes) + '\n\n' if self._cartes: - msg += u"Carte d'étudiant des adhérents :\n" + msg += u"Carte d'étudiant des adhérents :\n" msg += formater_pour_bureau(self._cartes) + '\n\n' return msg.strip() def mail_bureau(self): """ - Envoie le mail récapitulatif à bureau (s'il y a qqch à envoyer). + Envoie le mail récapitulatif à bureau (s'il y a qqch à envoyer). """ msg = self.recapitulatif() if msg: - msg += u"\n\n-- \nScript exécuté par %s\n" % cableur.Nom() + msg += u"\n\n-- \nScript exécuté par %s\n" % cableur.Nom() send_email(self._sender, u"Bureau ", - u"Récapitulatif des papiers manquants", + u"Récapitulatif des papiers manquants", msg, server = self._server, debug = debug) - return coul(u'Mail envoyé à bureau avec succès !', 'vert') + return coul(u'Mail envoyé à bureau avec succès !', 'vert') else: - return coul(u'Tout est à jour, aucun mail envoyé.', 'vert') + return coul(u'Tout est à jour, aucun mail envoyé.', 'vert') def mail_cableurs(self, subject, body, liste=None): """ - Envoie un mail aux câbleurs concernés qui figurent dans la liste. - Si liste vaut None, envoie un mail à tous les câbleurs concernés. + Envoie un mail aux câbleurs concernés qui figurent dans la liste. + Si liste vaut None, envoie un mail à tous les câbleurs concernés. Les arguments subject, body permettent de personnaliser (un peu) - le mail qui sera envoyé. + le mail qui sera envoyé. """ nb = 0 if liste == None: @@ -367,15 +367,15 @@ class ControleMailer: msg = u'' if self._paiements.has_key(c): - msg += u"Fiches d'adhésion, cotisations et/ou caution des adhérents :\n" + msg += u"Fiches d'adhésion, cotisations et/ou caution des adhérents :\n" msg += formater_pour_cableur(self._paiements[c]) + '\n\n' if self._chartes.has_key(c): - msg += u"Chartes signées des clubs :\n" + msg += u"Chartes signées des clubs :\n" msg += formater_pour_cableur(self._chartes[c]) + '\n\n' if self._cartes.has_key(c): - msg += u"Carte d'étudiant des adhérents :\n" + msg += u"Carte d'étudiant des adhérents :\n" msg += formater_pour_cableur(self._cartes[c]) + '\n\n' if msg: @@ -388,11 +388,11 @@ class ControleMailer: debug = debug) nb += 1 - return coul(u'%d mail(s) envoyé(s) aux câbleurs avec succès !' % nb, 'vert') + return coul(u'%d mail(s) envoyé(s) aux câbleurs avec succès !' % nb, 'vert') def __usage(message=None): - """ Comment ça marche ? """ + """ Comment ça marche ? """ cprint(__doc__ % { 'prog': sys.argv[0] }) if message: cprint(message) @@ -412,7 +412,7 @@ if __name__ == '__main__' : elif opt in [ '-d', '--debug' ]: debug = val - cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug) + cprint(u'Mode debug, tous les mails seront envoyés à %s.' % debug) elif opt in [ '-t', '--tri' ]: if val in [ 'id', 'nom', 'cableur', 'date' ]: @@ -424,7 +424,7 @@ if __name__ == '__main__' : tri_inverse = True else: - __usage("option inconnue « %s »'" % opt) + __usage("option inconnue « %s »'" % opt) if len(arg) == 0 or arg[0] == 'help': __usage() @@ -456,14 +456,14 @@ if __name__ == '__main__' : bureau = True cableurs = mailer._cableurs if cableurs: - cprint(u'Des mails vont être envoyés aux câbleurs, lecture du modèle...') + cprint(u'Des mails vont être envoyés aux câbleurs, lecture du modèle...') subject, body = parse_mail_template(sys.stdin) try: body % u'' except TypeError: - cprint(u"Le format du modèle n'est pas correct, arrêt.") + cprint(u"Le format du modèle n'est pas correct, arrêt.") sys.exit(1) - cprint(u'Modèle OK, on envoie les mails...') + cprint(u'Modèle OK, on envoie les mails...') cprint(mailer.mail_cableurs(subject, body, cableurs)) if bureau: cprint(mailer.mail_bureau()) diff --git a/admin/controle_tresorier2.py b/admin/controle_tresorier2.py index 34e9e638..8f6464d2 100755 --- a/admin/controle_tresorier2.py +++ b/admin/controle_tresorier2.py @@ -47,7 +47,7 @@ if u'Tresorier' not in cableur.droits(): dlg = dialog.Dialog() dlg.setBackgroundTitle('Tresorerie') -encoding = sys.stdin.encoding or 'ISO-8859-15' +encoding = sys.stdin.encoding or 'UTF-8' ######################################################################## # Retrait des accents diff --git a/admin/menage_cableurs.py b/admin/menage_cableurs.py index 169e5528..cf4b3be2 100755 --- a/admin/menage_cableurs.py +++ b/admin/menage_cableurs.py @@ -1,20 +1,20 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys -# Copyright (C) Stéphane Glondu, Alexandre Bos +# Copyright (C) Stéphane Glondu, Alexandre Bos # Licence : GPLv2 -__doc__ = u"""Ce script permet de faire le menages parmis les câbleurs qui ne -sont plus sur le campus, ie ceux qui ne sont plus à jour de cotisation. +__doc__ = u"""Ce script permet de faire le menages parmis les câbleurs qui ne +sont plus sur le campus, ie ceux qui ne sont plus à jour de cotisation. Utilisation : %(prog)s {lister|radier} [--debug ] Les commandes sont : - * lister afficher la liste des câbleurs succeptibles d'être - radiés + * lister afficher la liste des câbleurs succeptibles d'être + radiés * radier selectionner, parmis eux, les cableurs que l'on souhaite radier """ @@ -28,23 +28,23 @@ from email_tools import send_email, parse_mail_template # Fonctions d'affichage from affich_tools import coul, tableau, prompt, cprint -# Importation de la base de données +# Importation de la base de données from ldap_crans import crans_ldap, ann_scol db = crans_ldap() def _controle_interactif_adherents(liste): """ - Demande ce qu'il faut faire à chaque fois + Demande ce qu'il faut faire à chaque fois """ restant = len(liste) if restant == 0: return 0, 0 - cprint(u'\nRadiation des câbleurs fantômes' , 'cyan') - cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).") - cprint(u"Une autre réponse entraîne l'interruption du processus.") - cprint(u"Le format est [nb_restant] Nom, Prénom (aid).") + cprint(u'\nRadiation des câbleurs fantômes' , 'cyan') + cprint(u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n).") + cprint(u"Une autre réponse entraîne l'interruption du processus.") + cprint(u"Le format est [nb_restant] Nom, Prénom (aid).") cprint(u"") nb = 0 @@ -58,9 +58,9 @@ def _controle_interactif_adherents(liste): modifiable.droits([]) cprint(modifiable.save()) else: - cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') + cprint(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge') elif ok != 'n': - cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge') + cprint(u'Arrêt du contrôle %s des membres actifs' % explicite, 'rouge') break def candidats(): @@ -74,10 +74,10 @@ def candidats(): def lister(): """ - Afficher les câbleurs fantômes potentiels. + Afficher les câbleurs fantômes potentiels. """ todo_list = candidats() - print "Liste des câbleur dont la cotisation n'est pas à jour." + print "Liste des câbleur dont la cotisation n'est pas à jour." print for adh in todo_list: print adh.prenom() + " " + adh.nom() @@ -86,7 +86,7 @@ def lister(): def controle_interactif(): """ - Procédure interactive de radiations des câbleurs fantômes. + Procédure interactive de radiations des câbleurs fantômes. """ todo_list = candidats() @@ -94,7 +94,7 @@ def controle_interactif(): _controle_interactif_adherents(todo_list) def __usage(message=None): - """ Comment ça marche ? """ + """ Comment ça marche ? """ cprint(__doc__ % { 'prog': sys.argv[0] }) if message: diff --git a/gestion/affich_tools.py b/gestion/affich_tools.py index 79772419..e4aa0a9a 100755 --- a/gestion/affich_tools.py +++ b/gestion/affich_tools.py @@ -18,11 +18,11 @@ except: pass if not encoding: - encoding = sys.stdin.encoding or "ISO-8859-15" + encoding = sys.stdin.encoding or 'UTF-8' -# Si aucune locale n'est définie, on se met en ISO-8859-15 +# Si aucune locale n'est définie, on se met en... if encoding == "ANSI_X3.4-1968": - encoding = "ISO-8859-15" + encoding = 'UTF-8' if 'TERM' in os.environ and os.environ['TERM'] != 'unknown': el = subprocess.Popen('tput cr ; tput el', shell=True, stdout=subprocess.PIPE).stdout.read() @@ -115,7 +115,7 @@ def to_unicode(txt, enc=encoding): return txt.decode("UTF-8") except: # Sinon c'est surement de l'iso - return txt.decode("ISO8859-15") + return txt.decode("UTF-8") def to_encoding(txt, enc=encoding): return to_unicode(txt).encode(enc, 'ignore') diff --git a/gestion/config/mails/p2p.py b/gestion/config/mails/p2p.py index 9053821f..01d6ad6e 100644 --- a/gestion/config/mails/p2p.py +++ b/gestion/config/mails/p2p.py @@ -6,7 +6,7 @@ #: Envoyé à la ML disconnect@ en cas de déconnexion pour p2p avertissement = u"""From: %(From)s To: %(To)s -Subject: =?iso-8859-1?Q?D=E9tection?= de p2p sur la machine %(hostname)s +Subject: =?utf-8?q?D=C3=A9tection?= de p2p sur la machine %(hostname)s Content-Type: text/plain; charset="utf-8" La machine %(hostname)s a été déconnectée pendant 24h pour @@ -20,7 +20,7 @@ Message créé par deconnexion.py""" #: Envoyé à l'adhérent en cas de déconnexion pour p2p deconnexion = u"""From: %(From)s To: %(To)s -Subject: Avis de =?iso-8859-15?Q?D=E9connexion?= +Subject: Avis de =?utf-8?q?D=C3=A9connexion?= Content-Type: text/plain; charset="utf-8" Bonjour, @@ -81,7 +81,7 @@ Disconnect Team""" #: Envoyé à la ML disconnect@ en cas de déconnexion pour p2p plusieurs fois message_disconnect_multi = u"""From: %(from)s To: %(to)s -Subject: %(proprio)s a =?iso-8859-15?Q?=E9t=E9=20d=E9connect=E9?= %(nbdeco)d fois pour p2p en un an ! +Subject: %(proprio)s a =?utf-8?q?=C3=A9t=C3=A9_d=C3=A9connect=C3=A9?= %(nbdeco)d fois pour p2p en un an ! Content-Type: text/plain; charset="utf-8" L'adhérent %(proprio)s a été déconnecté %(nbdeco)d fois pour p2p en un an ! @@ -90,4 +90,4 @@ Le PS a été généré et se trouve sur zamok : %(ps)s --\u0020 -Message créé par deconnexion.py""" \ No newline at end of file +Message créé par deconnexion.py""" diff --git a/gestion/config/mails/upload.py b/gestion/config/mails/upload.py index 68aaf6a6..72d0e44a 100644 --- a/gestion/config/mails/upload.py +++ b/gestion/config/mails/upload.py @@ -124,7 +124,7 @@ Message créé par deconnexion.py""" #: Envoyé à la ML disconnect@ en cas de dépassement de la limite hard message_disconnect_hard = u"""From: %(from)s To: %(to)s -Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20brid=E9?= +Subject: %(proprio)s a =?utf-8?q?=C3=A9t=C3=A9_brid=C3=A9?= Content-Type: text/plain; charset="utf-8" %(proprio)s (%(id)s) a été limité en débit montant du fait d'un @@ -141,7 +141,7 @@ Message créé par deconnexion.py""" #: Envoyé à la ML disconnect@ en cas de dépassement de la limite hard plusieurs fois message_disconnect_multi = u"""From: %(from)s To: %(to)s -Subject: %(proprio)s a =?iso-8859-1?Q?=E9t=E9=20brid=E9?= +Subject: %(proprio)s a =?utf-8?q?=C3=A9t=C3=A9_brid=C3=A9?= %(nbdeco)d fois pour upload en un mois ! Content-Type: text/plain; charset="utf-8" diff --git a/gestion/email_tools.py b/gestion/email_tools.py index 845ad94d..193ade5f 100644 --- a/gestion/email_tools.py +++ b/gestion/email_tools.py @@ -14,7 +14,7 @@ format_sender et send_email adaptés depuis /usr/scripts/impression/crans_backen import re -def format_sender(sender, header_charset='ISO-8859-15'): +def format_sender(sender, header_charset='utf-8'): """ Check and format sender for header. """ @@ -42,8 +42,8 @@ def send_email(sender, recipient, subject, body, server='localhost', cc=None, de Only the real name part of sender and recipient addresses may contain non-ASCII characters. The email will be properly MIME encoded. - The charset of the email will be the first one out of US-ASCII, ISO-8859-15 - and UTF-8 that can represent all the characters occurring in the email. + The charset of the email will be the first one out of US-ASCII or UTF-8 + that can represent all the characters occurring in the email. Argument server maybe a string, indicating the name of the SMTP server, or directly an instance of smtplib.SMTP. @@ -57,10 +57,10 @@ def send_email(sender, recipient, subject, body, server='localhost', cc=None, de # Header class is smart enough to try US-ASCII, then the charset we # provide, then fall back to UTF-8. - header_charset = 'ISO-8859-15' + header_charset = 'UTF-8' # We must choose the body charset manually - for body_charset in 'US-ASCII', 'ISO-8859-15', 'UTF-8': + for body_charset in 'US-ASCII', 'UTF-8': try: body.encode(body_charset) except UnicodeError: diff --git a/gestion/gen_confs/__init__.py b/gestion/gen_confs/__init__.py old mode 100755 new mode 100644 index b1cfe73a..392dbdc7 --- a/gestion/gen_confs/__init__.py +++ b/gestion/gen_confs/__init__.py @@ -1,9 +1,9 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -""" Package pour la génération des fichiers de conf +""" Package pour la génération des fichiers de conf -Copyright (C) Frédéric Pauget +Copyright (C) Frédéric Pauget Licence : GPLv2 """ @@ -18,11 +18,11 @@ import config from tempfile import NamedTemporaryFile class gen_config : - """ Base pour toutes les classes de génération de fichiers de conf """ + """ Base pour toutes les classes de génération de fichiers de conf """ base = None debug = 0 _locked = 0 - __restore={} # pour restorer la config d'origine en cas d'erreur de génération + __restore={} # pour restorer la config d'origine en cas d'erreur de génération def lockname(self): """Nom du lock""" @@ -39,7 +39,7 @@ class gen_config : if self._locked : remove_lock(self.lockname()) def __del__(self) : - # Au cas où... + # Au cas où... self.unlock() def _restore(self) : @@ -54,12 +54,12 @@ class gen_config : os.system('cp -f %s %s' % ( f.name, nom ) ) def _open_conf(self,nom,comment=None) : - """ Créé un fichier - si comment est fourni, insère une entète qui utilisera le caractère + """ Créé un fichier + si comment est fourni, insère une entète qui utilisera le caractère de commentaire fourni copie l'ancien fichier dans un fichier temporaire pour permettre - la restauration en cas d'échec de la configuration + la restauration en cas d'échec de la configuration Retourne le descripteur du fichier """ @@ -89,15 +89,15 @@ class gen_config : return fd def gen_conf(self) : - """ Génération des fichiers de conf, retourne False si erreur """ + """ Génération des fichiers de conf, retourne False si erreur """ self.lock() - self.anim = anim('\tgénération fichiers') + self.anim = anim('\tgénération fichiers') try : warn = self._gen() if warn : self.anim.reinit() print WARNING - if self.debug : sys.stderr.write(warn.encode("ISO-8859-15")) + if self.debug : sys.stderr.write(warn.encode("UTF-8")) else : self.anim.reinit() print OK @@ -110,7 +110,7 @@ class gen_config : return False def restart(self) : - """ Redémarrage du service concerné """ + """ Redémarrage du service concerné """ if not self.restart_cmd : return self.lock() self.anim = anim('\trestart') @@ -127,8 +127,8 @@ class gen_config : self.unlock() def reconfigure(self) : - """ Génère les fichiers puis redémarre le service - si la génération c'est bien passée """ + """ Génère les fichiers puis redémarre le service + si la génération c'est bien passée """ cprint(u'Reconfiguration %s :' % self.__str__(), 'gras') if self.gen_conf() : return self.restart() diff --git a/gestion/gen_confs/adherents.py b/gestion/gen_confs/adherents.py index e09a2a89..9f059432 100644 --- a/gestion/gen_confs/adherents.py +++ b/gestion/gen_confs/adherents.py @@ -1,7 +1,7 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -# Copyright (C) Frédéric Pauget +# Copyright (C) Frédéric Pauget # Licence : GPLv2 import smtplib, sys, commands, shutil, os, traceback @@ -18,7 +18,7 @@ try: from Mailman.UserDesc import UserDesc from Mailman.Errors import MMAlreadyAMember except: - # Machine sans mailman, les ML ne seront pas reconfigurées + # Machine sans mailman, les ML ne seront pas reconfigurées pass @@ -101,7 +101,7 @@ class home: self.args = args def reconfigure(self): - cprint(u'Création home', 'gras') + cprint(u'Création home', 'gras') for args in self.args: anim('\t' + args) try: @@ -116,11 +116,11 @@ class home: os.mkdir(home, 0755) os.chown(home, int(uid), config.gid) elif os.path.isdir(home): - # Il y un répertoire existant + # Il y un répertoire existant # Bon UID ? stat = os.stat(home) if stat[4] != int(uid) or stat[5] != config.gid: - # Le home n'est pas pas à la bonne personne + # Le home n'est pas pas à la bonne personne raise OSError('home existant') ### Quota @@ -226,7 +226,7 @@ class ML_ens: try: mlist.ApprovedAddMember(UserDesc(mail)) except MMAlreadyAMember: - cprint(u"DÉJÀ INSCRIT", "jaune") + cprint(u"DÉJÀ INSCRIT", "jaune") except: print ERREUR if self.debug: diff --git a/gestion/gen_confs/bind.py b/gestion/gen_confs/bind.py index e32a5353..3463a81f 100755 --- a/gestion/gen_confs/bind.py +++ b/gestion/gen_confs/bind.py @@ -1,9 +1,9 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -""" Génération de la configuration pour bind9 +""" Génération de la configuration pour bind9 -Copyright (C) Frédéric Pauget +Copyright (C) Frédéric Pauget Licence : GPLv2 """ import time, sys, re, hashlib, base64, os @@ -56,36 +56,36 @@ def netv6_to_arpa(net): class dns(gen_config) : """ - Génération des fichiers de configuration de bind9 : - * fichier DNS_CONF qui contient les définitions de zone conformément -à zone_template. Ce fichier doit être inclus à partir de la config statique + Génération des fichiers de configuration de bind9 : + * fichier DNS_CONF qui contient les définitions de zone conformément +à zone_template. Ce fichier doit être inclus à partir de la config statique de bind - * les fichiers de zones, ce sont eux qui contiennent les données du -dns, ils ont appellés par le fichier DNS_CONF et sont générés dans DNS_DIR -Leur entète est générée à partir de zone_entete. + * les fichiers de zones, ce sont eux qui contiennent les données du +dns, ils ont appellés par le fichier DNS_CONF et sont générés dans DNS_DIR +Leur entète est générée à partir de zone_entete. - Les fichiers générés placent bind comme autoritaire sur les noms de -zones_direct et les adresses de zones_reverse. Les données proviennent de + Les fichiers générés placent bind comme autoritaire sur les noms de +zones_direct et les adresses de zones_reverse. Les données proviennent de la base LDAP """ ######################################PARTIE DE CONFIGURATION - ### Fichiers à écrire - # Répertoire d'écriture des fichiers de zone - DNS_DIR = '/etc/bind/generated/' # Avec un / à la fin - DNSSEC_DIR = '/etc/bind/signed/' # Avec un / à la fin - # Fichier de définition des zones pour le maître + ### Fichiers à écrire + # Répertoire d'écriture des fichiers de zone + DNS_DIR = '/etc/bind/generated/' # Avec un / à la fin + DNSSEC_DIR = '/etc/bind/signed/' # Avec un / à la fin + # Fichier de définition des zones pour le maître DNS_CONF = DNS_DIR + 'zones_crans' - # Fichier de définition des zones pour les esclaves géré par BCfg2 + # Fichier de définition des zones pour les esclaves géré par BCfg2 DNS_CONF_BCFG2 = "/var/lib/bcfg2/Cfg/etc/bind/generated/zones_crans/zones_crans" - ### Sur quelles zones on a autorité ? - ## En cas de modification de ces zones penser à regéner le fichier de + ### Sur quelles zones on a autorité ? + ## En cas de modification de ces zones penser à regéner le fichier de ## zone des esclaves (sur le serveur principal de bcfg2 : python /usr/scripts/gestion/gen_confs/bind.py puis lancer bcfg2 sur les miroirs) - # Résolution directe + # Résolution directe zones_direct = config.dns.zones_direct - # Zones signée par opendnssec sur le serveur maitre + # Zones signée par opendnssec sur le serveur maitre zones_dnssec = config.dns.zones_dnssec # Zones alias pour les enregistrement A AAAA CNAME TXT et SSHFP zone_alias = config.dns.zone_alias @@ -97,7 +97,7 @@ la base LDAP 'adm.crans.org': 'adm.v6.crans.org', 'ferme.crans.org': 'ferme.v6.crans.org', } - # Résolution inverse + # Résolution inverse zones_reverse = config.dns.zones_reverse zones_v6_to_net = { 'crans.eu': config.prefix["fil"][0], @@ -105,26 +105,26 @@ la base LDAP 'wifi.crans.org': config.prefix["wifi"][0], 'adm.crans.org': config.prefix["adm"][0], 'ferme.crans.org': config.prefix["fil"][0], - # Hack pour générer un fichier de zone vide + # Hack pour générer un fichier de zone vide '##HACK##': config.prefix["subnet"][0], } ### Liste DNS - # Le premier doit être le maitre + # Le premier doit être le maitre DNSs = ['sable.crans.org', 'freebox.crans.org', 'ovh.crans.org'] DNSs_private = [] ip_master_DNS = config.dns.master zone_multicast = 'tv.crans.org' - ### Liste des délégations de zone - # Pour les demandes de ces zones, le DNS dira d'aller voir les serveurs listés ici + ### Liste des délégations de zone + # Pour les demandes de ces zones, le DNS dira d'aller voir les serveurs listés ici # Pour les noms des serveurs on met l'IP sans point ou le nom avec un point DELEG = { zone_multicast : [ 'sable.crans.org.' , 'mdr.crans.org.', 'freebox.crans.org.', 'ovh.crans.org.'] , } ### Serveurs de mail - # format : [ priorité serveur , .... ] + # format : [ priorité serveur , .... ] MXs = ['10 redisdead.crans.org', '20 ovh.crans.org', '20 freebox.crans.org'] SRVs = [ '_jabber._tcp.crans.org. 86400 IN SRV 5 0 5269 xmpp.crans.org.', @@ -135,7 +135,7 @@ la base LDAP '_sips._tcp.crans.org. 86400 IN SRV 5 0 5061 asterisk.crans.org.', ] - # DS à publier dans zone parentes : { parent : [ zone. TTL IN DS key_id algo_id 1 hash ] } + # DS à publier dans zone parentes : { parent : [ zone. TTL IN DS key_id algo_id 1 hash ] } # ex : { 'crans.eu' : ['wifi.crans.eu. 86400 IN DS 33131 8 1 3B573B0E2712D8A8B1B0C3'] } # /!\ Il faut faire attention au rollback des keys, il faudrait faire quelque chose d'automatique avec opendnssec DS = { @@ -161,7 +161,7 @@ la base LDAP } - ### Entète des fichiers de zone + ### Entète des fichiers de zone zone_entete=""" $ORIGIN %(zone)s. $TTL 3600 @@ -174,14 +174,14 @@ $TTL 3600 ) """ - # Syntaxe utilisée dans le fichier DNS_CONF pour définir une zone sur le maître + # Syntaxe utilisée dans le fichier DNS_CONF pour définir une zone sur le maître zone_template=""" zone "%(NOM_zone)s" { type master; file "%(FICHIER_zone)s"; }; """ - # Syntaxe utilisée dans le fichier DNS_CONF_BCFG2 pour définir une zone sur un esclave + # Syntaxe utilisée dans le fichier DNS_CONF_BCFG2 pour définir une zone sur un esclave zone_template_slave=""" zone "%(NOM_zone)s" { type slave; @@ -190,10 +190,10 @@ zone "%(NOM_zone)s" { }; """ - ### Verbosité - # Si =2, ralera (chaine warnings) si machines hors zone trouvée + ### Verbosité + # Si =2, ralera (chaine warnings) si machines hors zone trouvée # Si =1, comme ci-dessus, mais ne ralera pas pour freebox - # Si =0, ralera seulement contre les machines ne pouvant être classées + # Si =0, ralera seulement contre les machines ne pouvant être classées verbose = 1 hostname = short_name(gethostname()) @@ -208,8 +208,8 @@ zone "%(NOM_zone)s" { return "DNS" def reverse(self, net, ip): - """Renvoie la zone DNS inverse correspondant au réseau et à - l'adresse donnés, ainsi que le nombre d'éléments de l'ip a + """Renvoie la zone DNS inverse correspondant au réseau et à + l'adresse donnés, ainsi que le nombre d'éléments de l'ip a mettre dans le fichier de zone.""" n = netaddr.IPNetwork(net) a = netaddr.IPAddress(ip) @@ -228,7 +228,7 @@ zone "%(NOM_zone)s" { zone_reverse=netv4_to_arpa(config.NETs['multicast'][0])[0] sap=open('/tmp/chaines_recup_sap.txt').readlines() - DNS='; DNS de la zone par ordre de priorité\n' + DNS='; DNS de la zone par ordre de priorité\n' for d in self.DELEG[self.zone_multicast] : DNS += '@\tIN\tNS %s\n' % d DNS += '\n' @@ -238,9 +238,9 @@ zone "%(NOM_zone)s" { lignes_d +='@\tIN\tA\t%s\n' % '138.231.136.243' for line in sap: [nom,ip]=line.split(':') - nom=re.sub('TNT([0-9]*) ','',nom) # on enlève les TNT## des noms - nom=re.sub(' +([^ ])','-\g<1>',nom) # on remplaces les espaces intérieur par un tiret - nom=re.sub('[ .():,"\'+<>]','',nom) # on enlève tous les caractères illégaux + nom=re.sub('TNT([0-9]*) ','',nom) # on enlève les TNT## des noms + nom=re.sub(' +([^ ])','-\g<1>',nom) # on remplaces les espaces intérieur par un tiret + nom=re.sub('[ .():,"\'+<>]','',nom) # on enlève tous les caractères illégaux nom=nom.lower() try: [ip1,ip2,ip3,ip4]=ip.strip().split('.') @@ -248,7 +248,7 @@ zone "%(NOM_zone)s" { lignes_d +='%s\tIN\tA\t%s' % (nom,ip) except: pass - # Écriture de la zone directe + # Écriture de la zone directe file = self.DNS_DIR + 'db.' + self.zone_multicast fd = self._open_conf(file,';') fd.write(self.zone_entete % \ @@ -258,7 +258,7 @@ zone "%(NOM_zone)s" { fd.write(lignes_d) fd.close() - # Écriture du reverse + # Écriture du reverse file = self.DNS_DIR + 'db.' + zone_reverse fd = self._open_conf(file,';') fd.write(self.zone_entete % \ @@ -270,7 +270,7 @@ zone "%(NOM_zone)s" { def gen_slave(self) : - """ Génération du fichier de config de zone pour les esclaves """ + """ Génération du fichier de config de zone pour les esclaves """ zones = self.zones_direct zones.extend(self.zones_v4_to_v6.values()) @@ -297,13 +297,13 @@ zone "%(NOM_zone)s" { fd.close() def _gen(self) : - ### Génération du numéro de série - # Le + 1000.... s'explique pas l'idée précédente et peu pratique d'avoir - # le numéro de série du type AAAAMMJJNN (année, mois, jour, incrément par jour) + ### Génération du numéro de série + # Le + 1000.... s'explique pas l'idée précédente et peu pratique d'avoir + # le numéro de série du type AAAAMMJJNN (année, mois, jour, incrément par jour) serial = time.time() + 1000000000 ### DNS - DNS='; DNS de la zone par ordre de priorité\n' + DNS='; DNS de la zone par ordre de priorité\n' for d in self.DNSs : DNS += '@\tIN\tNS %s.\n' % d DNS += '\n' @@ -311,7 +311,7 @@ zone "%(NOM_zone)s" { ### Serveurs de mail MX='; Serveurs de mails\n' for m in self.MXs : - MX += '%(zone)s.\t' # Sera remplacé par le nom de zone plus tard + MX += '%(zone)s.\t' # Sera remplacé par le nom de zone plus tard MX += 'IN\tMX\t%s.\n' % m MX += '\n' @@ -345,12 +345,12 @@ zone "%(NOM_zone)s" { self.anim.iter=len(self.machines) for machine in self.machines : self.anim.cycle() - # Calculs préliminaires + # Calculs préliminaires try : nom , zone = machine.nom().split('.',1) - zone = zone.encode('iso-8859-1') + zone = zone.encode('utf-8') except : - warnings += u'Machine ignorée (mid=%s) : format nom incorrect (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.nom().encode('iso-8859-1') ) + warnings += u'Machine ignorée (mid=%s) : format nom incorrect (%s)\n' % ( machine.id().encode('utf-8'), machine.nom().encode('utf-8') ) continue # Le direct @@ -359,7 +359,7 @@ zone "%(NOM_zone)s" { # Si la machine est une borne wifi, on ajoute la position if isinstance(machine,ldap_crans.BorneWifi) and machine.position(): ligne +="%s\tIN\tTXT\t\"LOC %s,%s \"\n" % (nom,machine.position()[0],machine.position()[1]) - # Si la machine à des clefs ssh, on ajoute les champs SSFP correspondant + # Si la machine à des clefs ssh, on ajoute les champs SSFP correspondant for sshkey in machine.sshFingerprint(): try: [algo_txt,key]=sshkey.split()[:2] @@ -378,7 +378,7 @@ zone "%(NOM_zone)s" { for alias in self.zone_alias[zone]: direct[alias] = direct.get(alias, "") + ligne elif self.verbose and machine.nom() != "ftp.federez.net": - warnings += u'Résolution directe ignorée (mid=%s) : zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), zone.encode('iso-8859-1') ) + warnings += u'Résolution directe ignorée (mid=%s) : zone non autoritaire (%s)\n' % ( machine.id().encode('utf-8'), zone.encode('utf-8') ) # IPv6 if zone in self.zones_v4_to_v6: @@ -406,23 +406,23 @@ zone "%(NOM_zone)s" { # Le direct avec alias for alias in machine.alias() : - alias = alias.encode('iso-8859-1') + alias = alias.encode('utf-8') # Cas particulier : nom de l'alias = nom de la zone if alias in self.zones_direct : ligne = "@\tIN\tA\t%s\n" % machine.ip() - ligne = ligne.encode('iso-8859-1') + ligne = ligne.encode('utf-8') direct[alias] = direct.get(alias, "") + ligne if alias in self.zone_alias: for alias2 in self.zone_alias[alias]: direct[alias2] = direct.get(alias2, "") + ligne if machine.dnsIpv6(): ligne = "@\tIN\tAAAA\t%s\n" % machine.ipv6() - ligne = ligne.encode('iso-8859-1') + ligne = ligne.encode('utf-8') direct[alias]= direct.get(alias, "") + ligne if alias in self.zone_alias: for alias2 in self.zone_alias[alias]: direct[alias2] = direct.get(alias2, "") + ligne if alias in self.zones_v4_to_v6: ligne = "@\tIN\tAAAA\t%s\n" % machine.ipv6() - ligne = ligne.encode('iso-8859-1') + ligne = ligne.encode('utf-8') zone6 = self.zones_v4_to_v6[alias] direct[zone6] = direct.get(zone6, '') + ligne if alias in self.zone_alias: @@ -445,9 +445,9 @@ zone "%(NOM_zone)s" { ok = 1 break if not ok: - warnings += u'Alias ignoré (mid=%s) : %s\n' % ( machine.id().encode('iso-8859-1'), alias.encode('iso-8859-1') ) + warnings += u'Alias ignoré (mid=%s) : %s\n' % ( machine.id().encode('utf-8'), alias.encode('utf-8') ) continue - zone = zone.encode('iso-8859-1') + zone = zone.encode('utf-8') ligne = "%s\tIN\tCNAME\t%s.\n" % ( nom, machine.nom() ) direct[zone] = direct.get(zone, '') + ligne if zone in self.zones_v4_to_v6: @@ -468,40 +468,40 @@ zone "%(NOM_zone)s" { base_ip = ip.split('.') base_ip.reverse() zone, length = self.reverse(net, ip) - zone = zone.encode('iso-8859-1') + zone = zone.encode('utf-8') ligne = '%s\tIN\tPTR\t%s.\n' % ('.'.join(base_ip[:length]), machine.nom()) try : reverse[zone] += ligne except : reverse[zone] = ligne elif self.verbose >= 2 or machine.nom() not in ('freebox.crans.org', 'ovh.crans.org', 'kokarde.crans.org'): - warnings += u'Résolution inverse ignorée (mid=%s) : ip sur zone non autoritaire (%s)\n' % ( machine.id().encode('iso-8859-1'), machine.ip().encode('iso-8859-1') ) + warnings += u'Résolution inverse ignorée (mid=%s) : ip sur zone non autoritaire (%s)\n' % ( machine.id().encode('utf-8'), machine.ip().encode('utf-8') ) - ### Ajouts pour les fichiers de résolution directs + ### Ajouts pour les fichiers de résolution directs for zone in direct.keys() : # MXs direct[zone] = MX % { 'zone' : zone } + direct[zone] - ### XXX: création de la zone inverse pour le /48 IPv6 complet du Cr@ns + ### XXX: création de la zone inverse pour le /48 IPv6 complet du Cr@ns full_net_v6 = self.zones_v6_to_net["##HACK##"] zone_rev, length = self.reverse(full_net_v6, netaddr.IPNetwork(full_net_v6).first) reverse[zone_rev] = reverse.get(zone_rev, "") - ### Ajout des délégations de zones + ### Ajout des délégations de zones for deleg in self.DELEG.keys(): nom, zone = deleg.split('.',1) if not zone in direct.keys(): - warnings += u'Délégation ignorée %s : on ne génère pas la zone parent\n' % deleg + warnings += u'Délégation ignorée %s : on ne génère pas la zone parent\n' % deleg continue for serv in self.DELEG[deleg]: direct[zone] = direct[zone] + "%s\tIN\tNS\t%s\n" % ( nom, serv ) - ### Ajout d'eventuel champs DS pour les délégation dnssec + ### Ajout d'eventuel champs DS pour les délégation dnssec for zone,ds in self.DS.items(): for s in ds: direct[zone] += s + '\n' direct[zone] += '\n' - ### Ecriture des fichiers de zone et préparation du fichier de définition + ### Ecriture des fichiers de zone et préparation du fichier de définition f = '' for zone, lignes in direct.items() + reverse.items() : if zone in self.zones_dnssec: @@ -523,7 +523,7 @@ zone "%(NOM_zone)s" { else: f += self.zone_template % { 'NOM_zone' : zone, 'FICHIER_zone' : path } - ### Ecriture fichier de définition + ### Ecriture fichier de définition fd = self._open_conf(self.DNS_CONF,'//') fd.write(f) fd.close() @@ -535,13 +535,13 @@ if __name__ == '__main__' : from config import bcfg2_main hostname = short_name(gethostname()) if hostname == short_name(bcfg2_main): - print "Reconfiguration du fichier de BCfg2 pour configurer le bind d'un serveur en esclave (pensez à lancer bcfg2 sur les esclaves)." + print "Reconfiguration du fichier de BCfg2 pour configurer le bind d'un serveur en esclave (pensez à lancer bcfg2 sur les esclaves)." c = dns() c.gen_slave() if hostname == short_name(dns.DNSs[0]): - print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate." + print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate." elif hostname == short_name(dns.DELEG['tv.crans.org'][0][0:-1]): - print "Serveur ma�tre pour tv.crans.org, génération de la zone" + print "Serveur maᅵtre pour tv.crans.org, génération de la zone" c = dns() c.gen_tv() import subprocess @@ -551,10 +551,10 @@ if __name__ == '__main__' : print ret[0].strip() print ret[1].strip() if hostname == short_name(dns.DNSs[0]): - print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate." + print "Ce serveur est également serveur maitre, mais la reconfiguration du DNS maitre se fait par generate." elif hostname == short_name(dns.DNSs[0]): - print "Ce serveur est maître ! Utilisez generate." + print "Ce serveur est maître ! Utilisez generate." elif hostname in map(lambda fullhostname : short_name(fullhostname),dns.DNSs[1:]+dns.DNSs_private): print "Ce serveur est esclave! Lancez ce script sur %s, puis lancez bcfg2 ici" % bcfg2_main else: - print "Ce serveur ne correspond à rien pour la configuration DNS." + print "Ce serveur ne correspond à rien pour la configuration DNS." diff --git a/gestion/gen_confs/dhcpd.py b/gestion/gen_confs/dhcpd.py index 6895c9f9..468bc829 100644 --- a/gestion/gen_confs/dhcpd.py +++ b/gestion/gen_confs/dhcpd.py @@ -1,9 +1,9 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -""" Génération de la configuration pour le dhcp +""" Génération de la configuration pour le dhcp -Copyright (C) Frédéric Pauget +Copyright (C) Frédéric Pauget Licence : GPLv2 """ @@ -12,22 +12,22 @@ from gen_confs import gen_config from ldap_crans import hostname class dhcp(gen_config) : - """ Génération du fichier de configuration pour dhcpd (DHCPD_CONF) - Le fichier comporte une partie par réseau servi, chaque réseau - servi doit être une clef du dictionnaire reseaux, la valeur correspondante - est une chaine décrivant les options spécifiques à ce réseau. + """ Génération du fichier de configuration pour dhcpd (DHCPD_CONF) + Le fichier comporte une partie par réseau servi, chaque réseau + servi doit être une clef du dictionnaire reseaux, la valeur correspondante + est une chaine décrivant les options spécifiques à ce réseau. Les options communes sont celles de base_dhcp. - Chaque machines possède ensuite une entrée de la forme de host_template + Chaque machines possède ensuite une entrée de la forme de host_template """ ######################################PARTIE DE CONFIGURATION - # Fichier à écire + # Fichier à écire if hostname == 'ragnarok' : DHCPD_CONF='/etc/dhcpd.conf' else : DHCPD_CONF = '/etc/dhcp3/dhcpd.conf' -# Hotspot ENS plus utilisé... +# Hotspot ENS plus utilisé... # elif hostname == 'ragnarok' : # On rajoute les IP dynamiques # base_conf = """ @@ -47,7 +47,7 @@ class dhcp(gen_config) : #""" elif hostname == 'sable': - # Options communes à toutes les réseaux servis + # Options communes à toutes les réseaux servis base_conf=""" # VLan accueil subnet 10.51.0.0 netmask 255.255.0.0 { @@ -68,7 +68,7 @@ subnet 10.52.0.0 netmask 255.255.0.0 { else : base_conf = '' - # Réseaux servis avec leurs options spécifiques + # Réseaux servis avec leurs options spécifiques # if hostname == 'zamok': # reseaux = { '138.231.136.0/21' : #"""option routers 138.231.136.4; @@ -110,7 +110,7 @@ subnet 10.52.0.0 netmask 255.255.0.0 { option routers 10.42.0.1; option domain-name-servers 10.42.0.1;""" } - # Options communes à toutes les réseaux servis + # Options communes à toutes les réseaux servis base_dhcp=""" subnet %(network)s netmask %(netmask)s { default-lease-time 86400; @@ -153,9 +153,9 @@ subnet %(network)s netmask %(netmask)s { } """ - ### Verbosité - # Si =1 ralera (chaine warnings) si machines hors zone trouvée - # Si =0 ralera seulement si réseau vide + ### Verbosité + # Si =1 ralera (chaine warnings) si machines hors zone trouvée + # Si =0 ralera seulement si réseau vide verbose = 1 # if hostname == 'zamok': @@ -195,7 +195,7 @@ subnet %(network)s netmask %(netmask)s { fd.write(self.base_conf) for net, options in self.reseaux.items() : if not hosts.has_key(net) : - warnings += u'Réseau %s ignoré : aucune machine à servir\n' % net + warnings += u'Réseau %s ignoré : aucune machine à servir\n' % net continue d = param(net) d['OPTIONS_RESEAU'] = options diff --git a/gestion/gen_confs/dhcpd_new.py b/gestion/gen_confs/dhcpd_new.py index 675f2cce..df2e71e8 100644 --- a/gestion/gen_confs/dhcpd_new.py +++ b/gestion/gen_confs/dhcpd_new.py @@ -1,9 +1,9 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -""" Génération de la configuration pour le dhcp +""" Génération de la configuration pour le dhcp -Copyright (C) Frédéric Pauget +Copyright (C) Frédéric Pauget Licence : GPLv2 """ import os @@ -63,15 +63,15 @@ class dydhcp: conn.close() class dhcp(gen_config) : - """ Génération du fichier de déclaration des hosts. - Chaque réseau servi doit être une clef du dictionnaire reseaux, + """ Génération du fichier de déclaration des hosts. + Chaque réseau servi doit être une clef du dictionnaire reseaux, la valeur correspondante est une chaine contenant le nom du fichier - associé à ce réseau. + associé à ce réseau. - Chaque machine possède ensuite une entrée de la forme de host_template. + Chaque machine possède ensuite une entrée de la forme de host_template. """ ######################################PARTIE DE CONFIGURATION - # Fichier à écire + # Fichier à écire if hostname == 'sable': restart_cmd = '/etc/init.d/isc-dhcp-server restart' reseaux = { '138.231.136.0/21' : '/etc/dhcp3/generated/adherents.liste', @@ -114,9 +114,9 @@ class dhcp(gen_config) : } """ - ### Verbosité - # Si =1 ralera (chaine warnings) si machines hors zone trouvée - # Si =0 ralera seulement si réseau vide + ### Verbosité + # Si =1 ralera (chaine warnings) si machines hors zone trouvée + # Si =0 ralera seulement si réseau vide verbose = 1 ######################################FIN PARTIE DE CONFIGURATION @@ -145,7 +145,7 @@ class dhcp(gen_config) : def _gen(self) : - """Construction de la liste des machines appartenant à un réseau + """Construction de la liste des machines appartenant à un réseau """ warnings = '' diff --git a/gestion/gen_confs/generate.py b/gestion/gen_confs/generate.py index b8a6aef3..31848628 100755 --- a/gestion/gen_confs/generate.py +++ b/gestion/gen_confs/generate.py @@ -1,7 +1,7 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- -# Copyright (C) Frédéric Pauget +# Copyright (C) Frédéric Pauget # Licence : GPLv2 #"""Ce script permet de lancer la reconfiguration des divers services @@ -9,8 +9,8 @@ #Usage: %(prog)s options #Les options possibles sont : #\t%(options)s -#Les options avec = doivent être suivies d'un argument. Plusieurs -#arguments peuvent être founis pour une même option, les séparer par & +#Les options avec = doivent être suivies d'un argument. Plusieurs +#arguments peuvent être founis pour une même option, les séparer par & #""" import sys, signal, os, getopt @@ -68,19 +68,19 @@ class base_reconfigure: def __init__(self, to_do=None): - # On vérifie que l'on est root + # On vérifie que l'on est root if os.getuid() != 0: - sys.stderr.write("Il faut être root\n") + sys.stderr.write("Il faut être root\n") sys.exit(1) if not to_do: if debug: - print 'Lecture des services à redémarrer dans la base LDAP...' + print 'Lecture des services à redémarrer dans la base LDAP...' auto = True to_do = {} - # Création de la liste de ce qu'il y a à faire + # Création de la liste de ce qu'il y a à faire for serv in db.services_to_restart(): - # Services spéciaux portant sur plusieurs machines + # Services spéciaux portant sur plusieurs machines to_add = self.__service_develop.get(serv.nom, []) if to_add: for nom in to_add: @@ -97,13 +97,13 @@ class base_reconfigure: else: auto = False if debug: - print 'Services à redémarrer imposés (non lecture de la base LDAP)' + print 'Services à redémarrer imposés (non lecture de la base LDAP)' for serv, args in to_do.items(): - # Au cas où le service porte sur plusieurs machines + # Au cas où le service porte sur plusieurs machines service = serv.replace('%s-' % hostname, '') if hasattr(self, service): - # Le service est à reconfigurer sur cette machine + # Le service est à reconfigurer sur cette machine db.services_to_restart('-%s' % serv) try: m = getattr(self, service) @@ -125,17 +125,17 @@ class base_reconfigure: if debug: reste = db.services_to_restart() if reste: - print "Reste à faire :" + print "Reste à faire :" for s in reste: try: print '\t%s' % s except UnicodeDecodeError: print '\t%s: non imprimable' % s.nom else: - print "Plus rien à faire" + print "Plus rien à faire" def _machines(self): - """ Retourne les machines de la base étant 'à jour' """ + """ Retourne les machines de la base étant 'à jour' """ return db.all_machines(graphic=True) def _do(self, service, machines=None): @@ -180,8 +180,8 @@ class redisdead(base_reconfigure): def mail_modif(self, trucs): """ - trucs est une liste de recherches à effectuer dans la base - l'affichage des résultats formera le corps du mail + trucs est une liste de recherches à effectuer dans la base + l'affichage des résultats formera le corps du mail """ from supervison import mail self._do(mail(trucs)) @@ -238,7 +238,7 @@ class zbee(base_reconfigure): class komaz(base_reconfigure): - # Mimétisme de ma part -- xhub + # Mimétisme de ma part -- xhub def __fw6(self): if not hasattr(self, '__real_fw6'): from firewall6 import Update @@ -312,7 +312,7 @@ if __name__ == '__main__': classe = eval(hostname) args_autorises = ['quiet', 'remove=', 'add=', 'list', 'help', 'reconnect'] - # Ajout aussi des arguments spécifiques à la machine + # Ajout aussi des arguments spécifiques à la machine for nom in dir(classe): if nom[0] != '_': if len(getargspec(getattr(classe, nom))[0]) > 1: @@ -330,7 +330,7 @@ if __name__ == '__main__': sys.stderr.write('%s\n' % msg) sys.exit(255) - debug = 1 # défaut + debug = 1 # défaut to_do = {} for opt, val in options: @@ -344,7 +344,7 @@ if __name__ == '__main__': sys.exit(0) elif opt == '--list': - print 'Services à redémarrer :' + print 'Services à redémarrer :' for s in db.services_to_restart(): try: print '\t%s' % s @@ -353,7 +353,7 @@ if __name__ == '__main__': sys.exit(0) elif opt == '--reconnect': - # Personnes à reconnecter + # Personnes à reconnecter print 'Recherche des personnes en fin de sanction...' c = db.search('blacklist=*') services = [] @@ -369,7 +369,7 @@ if __name__ == '__main__': sys.exit(0) elif opt == '--add': - # Ajout d'un item dans les services à redémarrer + # Ajout d'un item dans les services à redémarrer for serv in val.split('&'): if serv.find(',') != -1: serv, arg = serv.split(',', 1) @@ -390,5 +390,5 @@ if __name__ == '__main__': to_do[opt[2:]] = val.split('&') - # On fait ce qu'il y a à faire + # On fait ce qu'il y a à faire classe(to_do) diff --git a/gestion/gen_confs/supervison.py b/gestion/gen_confs/supervison.py index 23a5067b..36a6561b 100644 --- a/gestion/gen_confs/supervison.py +++ b/gestion/gen_confs/supervison.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- # Licence : GPLv2 @@ -13,8 +13,8 @@ from email.mime.text import MIMEText class mail: """ - Envoie un mail à toutes les personnes de la liste 'To', avec les - informations détaillées des objets contenus dans 'objets' + Envoie un mail à toutes les personnes de la liste 'To', avec les + informations détaillées des objets contenus dans 'objets' (instances des classes Adherent, Machine ou Club) """ From = 'roots@crans.org' @@ -25,14 +25,14 @@ class mail: To: %(To)s Subject: %(Subject)s Mime-Version: 1.0 -Content-Type: text/plain; charset="iso-8859-1" +Content-Type: text/plain; charset="utf-8" Content-Disposition: inline Content-Transfer-Encoding: 8bit %(Text)s""" - # Avec les caractères d'échappement qui vont bien pour la couleur ? + # Avec les caractères d'échappement qui vont bien pour la couleur ? couleur = False def __init__(self,recherches) : @@ -96,7 +96,7 @@ Subject: %(Subject)s %(Text)s""" - # Avec les caractères d'échappement qui vont bien pour la couleur ? + # Avec les caractères d'échappement qui vont bien pour la couleur ? couleur = False def __init__(self,modifs) : diff --git a/gestion/gen_confs/surveillance.py b/gestion/gen_confs/surveillance.py old mode 100644 new mode 100755 index 4e81a1d7..0f2242ce --- a/gestion/gen_confs/surveillance.py +++ b/gestion/gen_confs/surveillance.py @@ -1,11 +1,11 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- """ Classe de synchronisation entre la base ldap et la base postgresql pour la liste des exemptions et la liste des machines. -Utilisé par generate.py +Utilisé par generate.py """ # importation des fonctions et classes @@ -18,7 +18,7 @@ import psycopg2 db = crans_ldap() -# Génération des la tables d'exemptions +# Génération des la tables d'exemptions ####################################### class exemptions(gen_config) : @@ -49,7 +49,7 @@ class exemptions(gen_config) : pgsql.commit() -# Génération des la liste des machines +# Génération des la liste des machines ###################################### class machines(gen_config) : @@ -70,7 +70,7 @@ class machines(gen_config) : # machines = self.machines # machines = db.search('ip=*')['machine'] - # connexion à la base postgresql + # connexion à la base postgresql import psycopg2 pgsql = psycopg2.connect(database='filtrage', user='crans') curseur = pgsql.cursor() @@ -82,7 +82,7 @@ class machines(gen_config) : ipv6_vu[ipv6] = True return ret - # ajout des entrée + # ajout des entrée for m in machines: if m.proprietaire().__class__ == Club: curseur.execute("INSERT INTO machines (ip, type, id) VALUES (inet'%s','club',%s);"%(m.ip(),m.proprietaire().id())) diff --git a/gestion/gen_confs/switchs.py b/gestion/gen_confs/switchs.py index b963536c..e1402b25 100755 --- a/gestion/gen_confs/switchs.py +++ b/gestion/gen_confs/switchs.py @@ -500,7 +500,7 @@ aaa port-access mac-based %(prise)s unauth-vid 1 return ','.join(result) # Saut de ligne parasite - params['INTERFACES_CONF'] = params['INTERFACES_CONF'][:-1].encode('iso-8859-15') + params['INTERFACES_CONF'] = params['INTERFACES_CONF'][:-1].encode('utf-8') # Conversion des listes for key in [ 'uplinks', 'non_uplinks' ] : diff --git a/gestion/gen_confs/wifi_ng.py b/gestion/gen_confs/wifi_ng.py index ce72ead1..09e3c228 100644 --- a/gestion/gen_confs/wifi_ng.py +++ b/gestion/gen_confs/wifi_ng.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import time, commands from gen_confs import gen_config, ERREUR, OK, anim @@ -9,11 +9,11 @@ sys.path.append('/usr/scripts/gestion') from ldap_crans import crans_ldap, BorneWifi class conf_wifi_ng(gen_config) : - """ Génération de la configuration de isakmpd dans ISAKMPD_CONF - Le fichier est constitué en 5 parties : - 1) Configuration générale insérée telle quelle + """ Génération de la configuration de isakmpd dans ISAKMPD_CONF + Le fichier est constitué en 5 parties : + 1) Configuration générale insérée telle quelle 2) Phase 1 : une ligne par host suivant template - 3) Phase 2 : une entrée par machine + 3) Phase 2 : une entrée par machine 4) Bloc par machine suivant template 5) Ajout de net_crans @@ -21,8 +21,8 @@ class conf_wifi_ng(gen_config) : """ ######################################PARTIE DE CONFIGURATION - # Fichiers à écrire - # Répertoire d'écriture des fichiers de zone + # Fichiers à écrire + # Répertoire d'écriture des fichiers de zone ISAKMPD_CONF='/etc/isakmpd/isakmpd.conf' # Correspondance MAC/IP MACIP='/etc/wifi/wifi-update-ng/common/etc/macip' @@ -57,7 +57,7 @@ class conf_wifi_ng(gen_config) : self.anim=anim('\tfin reconfigurations') def gen_bornes(self, bornes): - """Génération de la configuration des bornes""" + """Génération de la configuration des bornes""" TARGET = "/var/www/wifi-update" WORK = "%s/work" % TARGET @@ -68,20 +68,20 @@ class conf_wifi_ng(gen_config) : if self._bornes and borne.nom().split(".")[0] not in self._bornes: continue self.anim=anim('\treconfiguration de %s' % borne.nom()) - # Il s'agit de faire l'union du répertoire common et du - # répertoire propre (s'il existe) ou alors du répertoire default - # On supprime le répertoire de travail + # Il s'agit de faire l'union du répertoire common et du + # répertoire propre (s'il existe) ou alors du répertoire default + # On supprime le répertoire de travail if os.path.isdir(WORK): shutil.rmtree(WORK) # On copie COMMON shutil.copytree(COMMON, WORK) - # Est-ce qu'un répertoire spécifique existe ? + # Est-ce qu'un répertoire spécifique existe ? top = os.path.join(ROOT, borne.nom()) if not os.path.isdir(top): top = DEFAULT # On en copie aussi le contenu for root, dirs, files in os.walk(top, topdown=True): - # On créé les répertoires + # On créé les répertoires for name in dirs: try: os.mkdir(os.path.join("%s%s" % (WORK, root[len(top):]), @@ -93,7 +93,7 @@ class conf_wifi_ng(gen_config) : shutil.copy(os.path.join(root, name), os.path.join("%s%s" % (WORK, root[len(top):]), name)) - # On créé/complète le fichier /etc/nvram.updates + # On créé/complète le fichier /etc/nvram.updates if isinstance(borne, BorneWifi) and borne.nom() != "non-configure.wifi.crans.org": fd = file(os.path.join(WORK, "etc", "nvram.updates"), "a") data = { 'HOST': borne.nom().split('.')[0], @@ -113,7 +113,7 @@ NVRAM_wl0_radio=%(ON)d NVRAM_crans_hotspot=%(HOTSPOT)d """ % data) - # On complète par les variables de la NVRAM + # On complète par les variables de la NVRAM for info in borne.nvram(): fd.write('variables="${variables} %s"\n' % info.split("=")[0]) fd.write("NVRAM_%s\n" % info) @@ -122,15 +122,15 @@ NVRAM_crans_hotspot=%(HOTSPOT)d # On fait du menage os.system("find %s -name CVS -type d -exec rm -rf {} \\; 2> /dev/null" % WORK) os.system("find %s -name '*~' -type f -exec rm -f {} \\;" % WORK) - # Ensuite, on créé le tar + # Ensuite, on créé le tar os.system("tar zcf %s/%s.tmp.tar.gz -C %s ." % (TARGET, borne.nom(), WORK)) - # Et on le renomme (on espère que c'est atomique) + # Et on le renomme (on espère que c'est atomique) os.rename("%s/%s.tmp.tar.gz" % (TARGET, borne.nom()), "%s/%s.tar.gz" % (TARGET, borne.nom())) print OK def gen_macip(self, clients, bornes): - """Génération de la correspondance MAC/IP""" + """Génération de la correspondance MAC/IP""" self.anim=anim('\r\tFichier MAC/IP',len(clients + bornes)) fd = file(self.MACIP, "w") for machine in clients + bornes: @@ -141,9 +141,9 @@ NVRAM_crans_hotspot=%(HOTSPOT)d print OK def gen_isakmpd(self, clients): - """Génération du fichier pour isakmpd""" + """Génération du fichier pour isakmpd""" - # Config générale de ISAKMPd + # Config générale de ISAKMPd general=""" [General] Listen-on= 138.231.148.1 @@ -202,7 +202,7 @@ Remote-ID= Net-%(HOST)s ID-type= IPV4_ADDR Address= %(IP)s """ - # Dernière partie du fichier + # Dernière partie du fichier net_crans=""" [Net-crans] ID-type= IPV4_ADDR_SUBNET @@ -226,7 +226,7 @@ Netmask= 0.0.0.0 # Phase 2 if blocs != '' : - # Ce n'est pas la première machine, il faut insérer un séparateur + # Ce n'est pas la première machine, il faut insérer un séparateur phase2 += phase2_sep phase2 += phase2_template % data diff --git a/gestion/gest_crans.py b/gestion/gest_crans.py index fb6b0d8a..3fa05767 100755 --- a/gestion/gest_crans.py +++ b/gestion/gest_crans.py @@ -51,7 +51,7 @@ droits = db.search("uid=%s" % script_utilisateur)['adherent'][0].droits() isimprimeur = u"Imprimeur" in droits iscontroleur = u'Tresorier' in droits isbureau = u'Bureau' in droits -encoding = sys.stdin.encoding or 'ISO-8859-15' +encoding = sys.stdin.encoding or 'UTF-8' if u'Nounou' in droits: if os.path.exists(os.path.expanduser('~/.dialogrc')): @@ -1892,7 +1892,7 @@ def select(clas, quoi, mde=''): s= ['', '', '', '', '', '', '', '', '', ''] def f(a): try: - return unicode(a, 'iso-8859-15') + return unicode(a, 'utf-8') except: return a while 1: diff --git a/gestion/ldap_crans.py b/gestion/ldap_crans.py index 745fe600..1db5002e 100755 --- a/gestion/ldap_crans.py +++ b/gestion/ldap_crans.py @@ -182,7 +182,7 @@ def preattr(val): val = str(val).strip() # On passe tout en utf-8 pour ne pas avoir de problèmes # d'accents dans la base - return [len(val), unicode(val, 'iso-8859-1').encode('utf-8')] + return [len(val), val] elif isinstance(val, unicode): val = val.strip() return [len(val), val.encode('utf-8')] @@ -690,8 +690,7 @@ class CransLdap: closelog() if type(expression) == str: - # Transformation de l'expression en utf-8 - expression = unicode(expression, 'iso-8859-15').encode('utf-8') + pass elif type(expression) == unicode: expression = expression.encode('utf-8') else: @@ -1889,7 +1888,7 @@ class BaseProprietaire(BaseClasseCrans): if self.idn !='cid': # Mail de bienvenue - self.services_to_restart('mail_bienvenue', [self.mail().encode('iso-8859-15')], start = time.time() + 660) + self.services_to_restart('mail_bienvenue', [self.mail().encode('utf-8')], start = time.time() + 660) else: ret += coul(u"Modification %s effectuée avec succès." % self.Nom(), 'vert') @@ -2178,7 +2177,7 @@ class Adherent(BaseProprietaire): self.mail_invalide(False) # on renvoie le mail de bienvenue - self.services_to_restart('mail_bienvenue', [new.encode('iso-8859-15')]) + self.services_to_restart('mail_bienvenue', [new.encode('utf-8')]) return new @@ -2876,7 +2875,7 @@ Contactez nounou si la MAC est bien celle d'une carte.""", 3) def __host_alias(self, champ, new): """ Vérification de la validité d'un nom de machine """ # Supression des accents - new = strip_accents(unicode(new, 'iso-8859-15')) + new = strip_accents(unicode(new, 'utf-8')) l, new = preattr(new) new = new.lower() diff --git a/gestion/liberation_ip.py b/gestion/liberation_ip.py index ad4f2e0c..4a202624 100644 --- a/gestion/liberation_ip.py +++ b/gestion/liberation_ip.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys diff --git a/gestion/mail-all.py b/gestion/mail-all.py index 53f28a71..e282d5f2 100755 --- a/gestion/mail-all.py +++ b/gestion/mail-all.py @@ -72,7 +72,7 @@ par le script. s = smtplib.SMTP() s.connect('smtp.crans.org') for adherent in adherents: - mail = adherent.mail().encode("iso-8859-15", "ignore") + mail = adherent.mail().encode("utf-8", "ignore") if "@" not in mail: mail = mail + "@crans.org" cprint(u"Envoi du mail à %s <%s>..." % (adherent.Nom(), mail)) diff --git a/gestion/tools/list_droits.py b/gestion/tools/list_droits.py index f6a567e8..f9382a02 100755 --- a/gestion/tools/list_droits.py +++ b/gestion/tools/list_droits.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys sys.path.append('/usr/scripts/gestion') diff --git a/gestion/tools/list_exempt.py b/gestion/tools/list_exempt.py index 3ee5043c..66ca99b9 100755 --- a/gestion/tools/list_exempt.py +++ b/gestion/tools/list_exempt.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys sys.path.append('/usr/scripts/gestion') @@ -15,7 +15,7 @@ for m in machines : # texte pour la machine txt = u'' - txt += u'Propriétaire : %s\n' % m.proprietaire().Nom() + txt += u'Propriétaire : %s\n' % m.proprietaire().Nom() txt += u'Machine : %s\n' % m.nom() txt += u'destination : %s\n' % ', '.join(m.exempt()) diff --git a/gestion/tools/list_firewall.py b/gestion/tools/list_firewall.py index c69bfb59..39488fdc 100755 --- a/gestion/tools/list_firewall.py +++ b/gestion/tools/list_firewall.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys sys.path.append('/usr/scripts/gestion') @@ -13,7 +13,7 @@ done = [] txts = [] for m in machines : - # on vérifie qu'on l'a pas encore traité + # on vérifie qu'on l'a pas encore traité if m.ip() in done : continue if m.proprietaire().__class__ == AssociationCrans : @@ -22,7 +22,7 @@ for m in machines : # texte pour la machine txt = u'' - txt += u'Propriétaire : %s\n' % m.proprietaire().Nom() + txt += u'Propriétaire : %s\n' % m.proprietaire().Nom() txt += u'Machine : %s\n' % m.nom() if m.portTCPin() : txt += u'ports TCP in : %s\n' % ' '.join(m.portTCPin()) diff --git a/gestion/tools/list_quotas.py b/gestion/tools/list_quotas.py index e0ff2b7f..15b80b6b 100755 --- a/gestion/tools/list_quotas.py +++ b/gestion/tools/list_quotas.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys from commands import getoutput diff --git a/gestion/tools/list_solde.py b/gestion/tools/list_solde.py index c6f4e77e..65e5ab27 100755 --- a/gestion/tools/list_solde.py +++ b/gestion/tools/list_solde.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys sys.path.append('/usr/scripts/gestion') @@ -15,7 +15,7 @@ for a in adherents : if a.solde() == 0 : continue - # texte pour l'adhérent + # texte pour l'adhérent txt = u'' txt += u'Nom : %s\n' % a.Nom() txt += u'Solde : %s\n' % a.solde() diff --git a/gestion/tools/liste_adh.py b/gestion/tools/liste_adh.py index 8a8c1f2a..1e87df2f 100755 --- a/gestion/tools/liste_adh.py +++ b/gestion/tools/liste_adh.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys sys.path.append('/usr/scripts/gestion') @@ -12,11 +12,11 @@ def titre (bat) : if bat == 'P' : return 'Pavillon des jardins' elif bat == '?' : - return 'Autres (extérieurs et chambres invalides)' + return 'Autres (extérieurs et chambres invalides)' else : - return 'Bâtiment %s' % bat + return 'Bâtiment %s' % bat -# création de la liste vide +# création de la liste vide ########################### liste = {} @@ -26,7 +26,7 @@ for bat in bats + '?' : # remplissage de la liste ######################### -# les extérieurs +# les extérieurs adhs = db.search( 'paiement=ok&etudes!=Pers' )['adherent'] for adh in adhs : bat = adh.chbre()[0] @@ -34,7 +34,7 @@ for adh in adhs : bat = '?' liste[bat].append( u'%s %s' % ( adh.nom(), adh.prenom() ) ) -# création du fichier tex +# création du fichier tex ######################### print """\\documentclass[a4paper,11pt]{article} @@ -61,7 +61,7 @@ for bat in bats + '?' : \\hline \\endhead""" % {'bat' : titre(bat) } - # ajout des adhérents + # ajout des adhérents liste[bat].sort() for adh in liste[bat] : print (u'%s& \\\\\n\\hline' % adh).encode('iso 8859-15') diff --git a/gestion/tools/locate-wifi.py b/gestion/tools/locate-wifi.py index b1eec86c..f69a05c4 100755 --- a/gestion/tools/locate-wifi.py +++ b/gestion/tools/locate-wifi.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys sys.path.append('/usr/scripts/gestion') @@ -10,21 +10,21 @@ from affich_tools import coul import threading from os import getuid -# il faut être root +# il faut être root if getuid() : - print 'Il faut être root !' + print 'Il faut être root !' sys.exit(1) -# connexion à la base de données +# connexion à la base de données db = crans_ldap() -# décompostion des arguments +# décompostion des arguments try : mac = ":".join([i.zfill(2) for i in sys.argv[1].split(":")]).upper() except : mac = None -# dit si une mac a déja été traitée +# dit si une mac a déja été traitée mac_done=[] def done (mac) : global mac_done @@ -34,7 +34,7 @@ def done (mac) : mac_done.append(mac) return False -# liste des résultats +# liste des résultats results = [] # classe d'interrogation des bornes diff --git a/gestion/tools/locate_mac.py b/gestion/tools/locate_mac.py index 00729aa4..33f85d61 100755 --- a/gestion/tools/locate_mac.py +++ b/gestion/tools/locate_mac.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- import sys, re from time import sleep @@ -37,11 +37,11 @@ class interroge_switch (threading.Thread) : if (prise != None): nom=sw.nom(None,prise) if self.affiche_uplinks or "uplink" not in nom: - self.reponse = ("%-10s => prise %-2s : %s" % (self.switch.encode('iso-8859-15').replace('.adm.crans.org',''), str(prise), nom)) + self.reponse = ("%-10s => prise %-2s : %s" % (self.switch.encode('utf-8').replace('.adm.crans.org',''), str(prise), nom)) -# Retourne les infos sur la machine (l'équivalent d'un whos, mais renvoie la -# chaîne de caractères) +# Retourne les infos sur la machine (l'équivalent d'un whos, mais renvoie la +# chaîne de caractères) def info_machine(mac): s = [] db = crans_ldap() @@ -52,7 +52,7 @@ def info_machine(mac): r = re.sub('\x1b\[1;([0-9]|[0-9][0-9])m', '', r) s.append(r) if len(machines) == 0: - s.append(u"Recherche LDAP de la MAC %s : aucune machine trouvée\n" % mac) + s.append(u"Recherche LDAP de la MAC %s : aucune machine trouvée\n" % mac) return u"\n".join(s) @@ -66,7 +66,7 @@ def trace_machine(mac, affiche_uplinks=False): for t in tableau: t.join() - resultat = u'Traçage de %s...\n' % mac + resultat = u'Traçage de %s...\n' % mac tracage = u'' for t in tableau: diff --git a/gestion/tools/stats_cableur.py b/gestion/tools/stats_cableur.py index 6f48a355..df687499 100644 --- a/gestion/tools/stats_cableur.py +++ b/gestion/tools/stats_cableur.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- encoding: iso-8859-15 -*- +# -*- encoding: utf-8 -*- # Stats sur les historiques @@ -13,22 +13,22 @@ import re from time import mktime, strptime def plat(chose): - """Applatit une liste de liste. Hautement récursif.""" + """Applatit une liste de liste. Hautement récursif.""" if type(chose) != ListType: return [chose] return sum(map(lambda x: plat(x), chose), []) def hist(): - """Récupère l'historique dans une base SQLite dont la connexion est returnée.""" - # On récupèr les adhérents + """Récupère l'historique dans une base SQLite dont la connexion est returnée.""" + # On récupèr les adhérents adherents = crans_ldap().search("nom=*")['adherent'] - # Et les historiques rattachés à eux et à leurs machines + # Et les historiques rattachés à eux et à leurs machines historiques = map(lambda x: [x.historique(), map(lambda y: y.historique(), x.machines())], adherents) historiques = plat(historiques) # On va maintenant coller les historiques dans une structure plus - # sympa, style une base SQL que l'on garde en mémoire + # sympa, style une base SQL que l'on garde en mémoire con = sqlite.connect("historiques") cur = con.cursor() cur.execute("CREATE TABLE historique (date INTEGER, nom TEXT, action TEXT)") diff --git a/gestion/virtualisation/manage.py b/gestion/virtualisation/manage.py new file mode 100644 index 00000000..f4668289 --- /dev/null +++ b/gestion/virtualisation/manage.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +# -*- coding:utf-8 -*- +# +# High level interface between XEN +# and XEN user diff --git a/impression/cout.py b/impression/cout.py index e74f8394..5f4ed945 100644 --- a/impression/cout.py +++ b/impression/cout.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- # ############################################################# # .. # .... ............ ........ @@ -28,7 +28,7 @@ Copyright (c) 2006 by www.crans.org """ -# Début : Ajout log pour réestimer les coûts +# Début : Ajout log pour réestimer les coûts import time # Fin import sys, tempfile, os, commands, shutil, syslog, stat @@ -48,7 +48,7 @@ COUT_UNITE_NOIRE = config.impression.c_noir COUT_PASSAGE_TAMBOUR_NOIR = config.impression.c_tambour_noir COUT_PASSAGE_TAMBOUR_COULEUR = config.impression.c_tambour_coul -# Début : Ajout log pour réestimer les coûts +# Début : Ajout log pour réestimer les coûts FICHIER_LOG="/var/log/log_couts/estimations" # Fin @@ -88,10 +88,10 @@ def try_command(cmd, tmp_rep, error_msg): def base_prix(path_pdf_file, color=False): u""" Calcul le prix d'une impression couleur ou noir et blanc sur papier A4 """ - # nom_rep seras le dossier dans tmp ou tous les fichier créé par - # convert seront entreposé + # nom_rep seras le dossier dans tmp ou tous les fichier créé par + # convert seront entreposé nom_rep = tempfile.mkdtemp(prefix='tmpimpr') - nom_png = "%s/convert.png" % nom_rep # Nom prefixe et chemin des png créé par convert + nom_png = "%s/convert.png" % nom_rep # Nom prefixe et chemin des png créé par convert escaped_path_pdf_file = escapeForShell(path_pdf_file) escaped_path_ps_file = escapeForShell(path_pdf_file + ".ps") error_msg = "ERREUR %%d : Fichier invalide. Aucun %s cree." @@ -113,14 +113,14 @@ def base_prix(path_pdf_file, color=False): nom_rep, error_msg % "ps") - # Convertit les ps en png (il est néscessaire de passer par un ps + # Convertit les ps en png (il est néscessaire de passer par un ps # car ghostscript refuse certain pdf) try_command("nice -n 5 gs -sDEVICE=%s -r30 -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dGraphicsAlphaBits=4 -dTextAlphaBits=4 -dMaxBitmap=50000000 -sOutputFile=%s%%d -q %s" % (gs_device, nom_png, escaped_path_ps_file), nom_rep, error_msg % "png") - # Récupère la liste des fichiers + # Récupère la liste des fichiers list_filepng=os.listdir(nom_rep) # Calcule le nombre de pixel remplissage = [0] * (nb_composante + 1) # couleurs (N ou CMJN), nombre de pages @@ -146,7 +146,7 @@ def base_prix(path_pdf_file, color=False): c_total = (COUT_PASSAGE_TAMBOUR_NOIR * faces # passage dans les toners + COUT_UNITE_NOIRE * total_noir) # cout encre noire - # Début : Ajout log pour réestimer les coûts + # Début : Ajout log pour réestimer les coûts fichier_log_est=open(FICHIER_LOG,"a") fichier_log_est.write("%d %d %3d %10.3f %10.3f %s\n" % (time.time(), color, faces, total_noir, total_couleur, path_pdf_file) ) fichier_log_est.close() diff --git a/impression/etat_imprimante.py b/impression/etat_imprimante.py index 721d8b85..281af21d 100644 --- a/impression/etat_imprimante.py +++ b/impression/etat_imprimante.py @@ -1,9 +1,9 @@ #!/usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- """ etat_imprimante.py - Récupère, filtre et formate l'état actuel de l'imprimante + Récupère, filtre et formate l'état actuel de l'imprimante Copyright (c) 2006, 2007, 2008, 2009 by Cr@ns (http://www.crans.org) @@ -28,7 +28,7 @@ def etat_canon(): 'printing(4)\nrunning(2)' : u'Impression en cours', 'other(1)\ndown(5)' : u"Imprimante hors-service", 'other(1)\nrunning(2)' : u'Imprimante en veille', - 'warmup(5)\nrunning(2)' : u'Préchauffage', + 'warmup(5)\nrunning(2)' : u'Préchauffage', 'idle(3)\nwarning(3)' : u'Imprimante fonctionnelle', 'printing(4)\nwarning(3)' : u'Impression en cours' } @@ -53,15 +53,15 @@ def etat_canon(): def etat_laserjet(): """ Renvoie une liste des differents ecrans actuels du display de l'imprimante """ _dico = { - u"READY": u"Prête", - u"PrÁt": u"Prêt", + u"READY": u"Prête", + u"PrÃt": u"Prêt", u"Pr menus, appuy \x1e": u"", - u"Powersave activÅ": u"En veille", - u"Verification": u"Vérification imprimante", + u"Powersave activÃ…": u"En veille", + u"Verification": u"Vérification imprimante", u"imprimante": u"", - u"PrÅchauffage": u"Préchauffage", + u"PrÃ…chauffage": u"Préchauffage", u"Traitement de la": u"Impression en cours", - u"tÀche du bac 4": u"", + u"tÀche du bac 4": u"", u"COMMANDER CARTOUCHE": u"", u"COMMANDER KIT NETTOY": u"", u"COMMANDER FOURNIT.": u"", diff --git a/respbats/crans b/respbats/crans index c9f97eb5..a4015cdc 100755 --- a/respbats/crans +++ b/respbats/crans @@ -1,3 +1,3 @@ #! /bin/sh -LANG=fr_FR@euro sudo -u respbats /usr/scripts/gestion/gest_crans.py $* +LANG=fr_FR.UTF-8 sudo -u respbats /usr/scripts/gestion/gest_crans.py $* diff --git a/respbats/locate-mac b/respbats/locate-mac index 9d74c32a..03cb333e 100755 --- a/respbats/locate-mac +++ b/respbats/locate-mac @@ -1,4 +1,4 @@ #!/bin/sh #execution avec des droits suffisants -LANG=fr_FR@euro sudo -u '#120' /usr/scripts/gestion/tools/locate_mac.py $* +LANG=fr_FR.UTF-8 sudo -u '#120' /usr/scripts/gestion/tools/locate_mac.py $* diff --git a/respbats/logread b/respbats/logread index c90bc642..daee807a 100755 --- a/respbats/logread +++ b/respbats/logread @@ -1,4 +1,3 @@ #! /bin/sh -#LANG=fr_FR@euro sudo -u respbats /usr/scripts/gestion/logreader/rsyslog_reader.py $* diff --git a/respbats/ressuscite b/respbats/ressuscite index 16f22e60..1f6c70fb 100755 --- a/respbats/ressuscite +++ b/respbats/ressuscite @@ -1,3 +1,3 @@ #! /bin/sh -LANG=fr_FR@euro sudo -u respbats /usr/scripts/gestion/ressuscite.py $* +LANG=fr_FR.UTF-8 sudo -u respbats /usr/scripts/gestion/ressuscite.py $* diff --git a/respbats/whos b/respbats/whos index ba36163d..d248ecee 100755 --- a/respbats/whos +++ b/respbats/whos @@ -1,3 +1,3 @@ #!/bin/sh -LANG=fr_FR@euro sudo -u respbats /usr/scripts/gestion/whos.py $* +LANG=fr_FR.UTF-8 sudo -u respbats /usr/scripts/gestion/whos.py $* diff --git a/surveillance/arpwatch_sendmail b/surveillance/arpwatch_sendmail index 20ec7109..352ed405 100755 --- a/surveillance/arpwatch_sendmail +++ b/surveillance/arpwatch_sendmail @@ -1,4 +1,4 @@ #!/bin/sh #execution avec des droits suffisants -LANG=fr_FR@euro sudo -u 'arpwatch' /usr/scripts/surveillance/arpwatch_sendmail.py $* +LANG=fr_FR.UTF-8 sudo -u 'arpwatch' /usr/scripts/surveillance/arpwatch_sendmail.py $* diff --git a/surveillance/arpwatch_sendmail.py b/surveillance/arpwatch_sendmail.py index ac7a8f85..b0738412 100755 --- a/surveillance/arpwatch_sendmail.py +++ b/surveillance/arpwatch_sendmail.py @@ -1,49 +1,149 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- - -# Ajout d'un whos et d'un tracage aux mails d'arpwatch -# Auteurs : Stéphane Glondu, Cyril Cohen -# Licence : GPLv2 - -import sys, os, re, smtplib -from commands import getstatusoutput - -sys.path.append('/usr/scripts/gestion/tools') -from locate_mac import trace_machine, format_mac, info_machine - -find_mac = re.compile(r'[0-9A-Fa-f]{1,2}(?::[0-9A-Fa-f]{1,2}){5}') +# -*- encoding: utf-8 -*- -def get_machine(unformated_mac): - mac = format_mac(unformated_mac) - return u"\n" + info_machine(mac) + u"\n" + trace_machine(mac) +########################### +# Import des commmandes : # +########################### + +import commands +import os +# import pg # Import des commandes de postgres +import sys +sys.path.append('/usr/scripts/gestion') +import iptools +import psycopg2 +import re +sys.path.append('/usr/script/surveillance') +import strptime + +# Définition de constantes : +############################ +reseau = ["138.231.136.0/21", "138.231.148.0/22"] + +# Ouverture de la base de données : +################################### +pgsql = psycopg2.connect(host='pgsql.adm.crans.org', database='filtrage', user='crans') +# Ancienne méthode pour faire de l'autocommit. +# Sous wheezy, il faudra remplacer par pgsql.set_session(autocommit=True) !!! +pgsql.set_isolation_level(0) +curseur = pgsql.cursor() -if __name__ == "__main__": - texte = sys.stdin.read() #.decode('ISO-8859-15') - textes = texte.splitlines(True) - i = textes.index(u'\n') - textes[i-1:i-1] = [ - u'MIME-Version: 1.0\n', - u'Content-Type: text/plain; charset=UTF-8\n', - u'Content-Transfer-Encoding: 8bit\n', - ] +########################################### +# Récupération des tables de protocoles : # +########################################### - # On récupère les destinataires dans les arguments (très ad hoc) - recipients = sys.argv[2].split(',') - # On complète le message - try: - macs = find_mac.findall(texte) - for mac in macs: - textes.append(get_machine(mac)) - except: - # En cas d'exception, on envoie le traceback - import traceback - textes.append(u'\n') - textes.append(u''.join(traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))) - textes.append('\n-- \narpwatch_sendmail.py\n') +requete = "SELECT nom,id_p2p from protocole_p2p" +curseur.execute(requete) +curseur.fetchall +tableau = curseur.fetchall() +protocole_p2p = {} +for cellule in tableau: + protocole_p2p[cellule[0]]=cellule[1] - smtp = smtplib.SMTP() - smtp.connect() - smtp.sendmail("arpwatch@crans.org", recipients, u''.join(textes).encode('UTF-8')) - smtp.quit() +requete = "SELECT nom,id from protocole" +curseur.execute(requete) +curseur.fetchall +tableau = curseur.fetchall() +protocole = {} +for cellule in tableau: + protocole[cellule[0]]=cellule[1] + + + +############################################################## +# Parser ler log du firewall: /var/log/firewall/filtre.log : # +############################################################## + +# Définition des motifs des comparaisons : +########################################## +motif_p2p = re.compile("^(.*) komaz .* IPP2P=([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") + +motif_virus = re.compile("^(.*) komaz .* Virus:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") + +motif_flood = re.compile("^(.*) komaz .* Flood:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") + + +# On récupère en continu les log du firewall: +############################################# +filtre = os.popen("tail -F /var/log/firewall/filtre.log 2> /dev/null") + + +# On matche les log du firewall avec les motifs : +################################################# +for log in filtre: + resultat_p2p = motif_p2p.match(log) + resultat_virus = motif_virus.match(log) + resultat_flood = motif_flood.match(log) + + if resultat_p2p : + try: + ip_src = resultat_p2p.group(3) + verif = iptools.AddrInNets (ip_src,reseau) + except ValueError: + continue #IP malformee + if verif : + try: + date = resultat_p2p.group(1) + id_p2p = int(protocole_p2p[resultat_p2p.group(2)]) + ip_src = resultat_p2p.group(3) + ip_dest = resultat_p2p.group(4) + proto = int(protocole[resultat_p2p.group(5)]) #C'est à dire id pour la base + port_src = int(resultat_p2p.group(6)) + port_dest = int(resultat_p2p.group(7)) + date=strptime.syslog2pgsql(date) + except ValueError, KeyError: + continue #mal parse + + # On remplit la base : + ###################### + requete = "INSERT INTO p2p (date,ip_src,ip_dest,id_p2p,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d,%d)" % (date,ip_src,ip_dest,id_p2p,proto,port_src,port_dest) + curseur.execute(requete) + + # On teste si le log contient des virus + ######################################## + elif resultat_virus : + try: + ip_src = resultat_virus.group(3) + verif = iptools.AddrInNets (ip_src,reseau) + except ValueError: + continue + if verif : + try: + date = resultat_virus.group(1) + ip_src = resultat_virus.group(3) + ip_dest = resultat_virus.group(4) + proto = int(protocole[resultat_virus.group(5)]) #C'est à dire id pour la base + port_src = int(resultat_virus.group(6)) + port_dest = int(resultat_virus.group(7)) + # On remplit la base : + ###################### + date=strptime.syslog2pgsql(date) + except ValueError, KeyError: + continue + requete = "INSERT INTO virus (date,ip_src,ip_dest,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d)" % (date,ip_src,ip_dest,proto,port_src,port_dest) + curseur.execute(requete) + + elif resultat_flood : + try: + ip_src = resultat_flood.group(3) + verif = iptools.AddrInNets (ip_src,reseau) + except ValueError: + continue + if verif : + try: + date = resultat_flood.group(1) + ip_src = resultat_flood.group(3) + ip_dest = resultat_flood.group(4) + proto = int(protocole[resultat_flood.group(5)]) #C'est à dire id pour la base + port_src = int(resultat_flood.group(6)) + port_dest = int(resultat_flood.group(7)) + + # On remplit la base : + ###################### + date=strptime.syslog2pgsql(date) + except ValueError, KeyError: + continue + requete = "INSERT INTO flood (date,ip_src,ip_dest,id,port_src,port_dest) VALUES ('%s','%s','%s',%d,%d,%d)" % (date,ip_src,ip_dest,proto,port_src,port_dest) + curseur.execute(requete) diff --git a/surveillance/comptes_inactifs.py b/surveillance/comptes_inactifs.py index 1330ba44..e55832b9 100755 --- a/surveillance/comptes_inactifs.py +++ b/surveillance/comptes_inactifs.py @@ -1,9 +1,9 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- """DESCRIPTION - Ce script repère les comptes inactifs en parsant les logs de dernière - connexion de sshd et dovecot, et en lisant et mettant à jour les champs + Ce script repère les comptes inactifs en parsant les logs de dernière + connexion de sshd et dovecot, et en lisant et mettant à jour les champs derniereConnexion dans la base LDAP. UTILISATION @@ -12,7 +12,7 @@ UTILISATION ACTIONS POSSIBLES %(acts)s""" -# Copyright (C) 2006 Stéphane Glondu +# Copyright (C) 2006 Stéphane Glondu # Licence : GPLv2 @@ -41,8 +41,8 @@ openlog('comptes_inactifs') def nb_mails_non_lus(login): """ - Renvoie le nombre de mails non lus de login, ou None si impossible à - déterminer. + Renvoie le nombre de mails non lus de login, ou None si impossible à + déterminer. """ try: maildir = '/var/mail/%s/new' % login @@ -56,8 +56,8 @@ def nb_mails_non_lus(login): class ComptesInactifs(object): - # liste d'expressions régulières qui seront testées sur les lignes de log - # le premier groupe doit correspondre à la date, le second au login + # liste d'expressions régulières qui seront testées sur les lignes de log + # le premier groupe doit correspondre à la date, le second au login re = [re.compile(r'^(\w+\s+\d+\s+\d+:\d+:\d+).*(?:' r'dovecot.*Login: user=<|' r'sshd.*Accepted.*for ' @@ -70,7 +70,7 @@ class ComptesInactifs(object): self.dic = {} def search(self, query, mode=''): - """ CransLdap.search allégé """ + """ CransLdap.search allégé """ query = '(&(objectClass=cransAccount)(objectClass=adherent)(%s))' % query result = db.conn.search_s(db.base_dn, db.scope['adherent'], query) result = [db.make(x, mode) for x in result] @@ -79,13 +79,13 @@ class ComptesInactifs(object): def commit_to_ldap(self): """ Sauvegarde du dico dans la base LDAP. - Renvoie le nombre d'entrées mises à jour. + Renvoie le nombre d'entrées mises à jour. """ total = 0 for (login, timestamp) in self.dic.items(): a = self.search('uid=%s' % login, 'w') if not a: - # Probablement un adhérent récemment parti + # Probablement un adhérent récemment parti continue a = a[0] if a._modifiable == 'w': @@ -93,7 +93,7 @@ class ComptesInactifs(object): if a.modifs: total += 1 a.save() else: - # on loggue on espérant que les logs seront réinjectés + # on loggue on espérant que les logs seront réinjectés # plus tard syslog("LDAP(lock): derniereConnexion=<%s>, login=<%s>" % (strftime("%b %d %H:%M:%S", localtime(timestamp)), login)) @@ -101,7 +101,7 @@ class ComptesInactifs(object): def update(self, login, timestamp): """ - Met à jour l'entrée correspondant au login donné. + Met à jour l'entrée correspondant au login donné. """ dic = self.dic timestamp = int(timestamp) @@ -110,8 +110,8 @@ class ComptesInactifs(object): def update_from_syslog(self, loglines): """ - Met à jour le dico avec les lignes de syslog données. - Renvoie le nombre de lignes traitées. + Met à jour le dico avec les lignes de syslog données. + Renvoie le nombre de lignes traitées. """ annee = localtime(time())[0] now = time() + 600 @@ -124,8 +124,8 @@ class ComptesInactifs(object): date = list(strptime(m.group(1), "%b %d %H:%M:%S")) date[0] = annee t = mktime(date) - # les lignes de syslog n'indiquent pas l'année - # on suppose qu'une date dans le futur est en fait l'année dernière + # les lignes de syslog n'indiquent pas l'année + # on suppose qu'une date dans le futur est en fait l'année dernière if t > now: date[0] = annee - 1 t = mktime(date) @@ -135,21 +135,21 @@ class ComptesInactifs(object): def do_log(self): """ - Lit des lignes de log sur l'entrée std et met à jour la base LDAP. + Lit des lignes de log sur l'entrée std et met à jour la base LDAP. """ parsed_lines = self.update_from_syslog(sys.stdin) updated_entries = self.commit_to_ldap() - syslog("%(parsed_lines)s ligne(s) traitée(s)" % locals()) - syslog("%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP" % locals()) + syslog("%(parsed_lines)s ligne(s) traitée(s)" % locals()) + syslog("%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP" % locals()) if parsed_lines == 0 or updated_entries == 0: - sys.stderr.write("""Erreur lors de la mise à jour de la base LDAP : -%(parsed_lines)s ligne(s) traitée(s) -%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP + sys.stderr.write("""Erreur lors de la mise à jour de la base LDAP : +%(parsed_lines)s ligne(s) traitée(s) +%(updated_entries)s entrée(s) mise(s) à jour dans la base LDAP """ % locals()) def do_dump(self): """ - Affiche la liste des dernières connexions, triées par date. + Affiche la liste des dernières connexions, triées par date. """ liste = self.search('derniereConnexion=*') liste = [(x.derniereConnexion(), x.compte()) for x in liste] @@ -157,15 +157,15 @@ class ComptesInactifs(object): liste = [(x[1], strftime('%d/%m/%Y %H:%M', localtime(x[0]))) for x in liste] cprint(tableau(liste, - titre = (u'Login', u'Dernière connexion'), + titre = (u'Login', u'Dernière connexion'), largeur = (20, 20))) cprint(u"Total : %d" % len(liste)) def get_idle_accounts(self, since=32*24*3600): """ Renvoie la liste des objets Adherent de ceux qui ne se sont pas - connectés depuis since secondes, par défaut un mois (32 jours, - pour être sûr). + connectés depuis since secondes, par défaut un mois (32 jours, + pour être sûr). """ limit = int(time()) - since liste = self.search("derniereConnexion<=%d" % limit) @@ -176,20 +176,20 @@ class ComptesInactifs(object): def do_summary(self): """ - Envoie à disconnect un résume des comptes inactifs depuis plus d'un + Envoie à disconnect un résume des comptes inactifs depuis plus d'un mois. """ - modele = u"""*Membres inscrits ne s'étant pas connectés depuis plus d'un mois* + modele = u"""*Membres inscrits ne s'étant pas connectés depuis plus d'un mois* %(inscrits)s Total : %(inscrits_total)d -*Anciens membres ne s'étant pas connectés depuis plus d'un mois* +*Anciens membres ne s'étant pas connectés depuis plus d'un mois* %(anciens)s Total : %(anciens_total)d -Légende : +Légende : - F : existence d'un .forward - M : existence de mails non lus @@ -219,7 +219,7 @@ comptes_inactifs.py else: anciens.append(ligne) - titres = (u'aid', u'Login', u'Nom', u'Dernière connexion', u'F', u'M') + titres = (u'aid', u'Login', u'Nom', u'Dernière connexion', u'F', u'M') largeurs = (6, 15, 20, 20, 1, 1) alignements = ('d', 'g', 'c', 'c', 'c', 'c') @@ -237,9 +237,9 @@ comptes_inactifs.py def do_spam(self): """ Envoie un mail explicatif aux possesseurs de compte inactif - (doit être exécuté en tant que root). + (doit être exécuté en tant que root). """ - # Nombre de personnes concernées, en expansant de droite à gauche : + # Nombre de personnes concernées, en expansant de droite à gauche : # inscrit/ancien, avec/sans procmail, avec/sans mail non lu # Voir aussi template_path stats = [0, 0, 0, 0, 0, 0, 0, 0] @@ -262,7 +262,7 @@ comptes_inactifs.py if not os.path.isfile('/home/%s/.forward' % login): i += 2 # a-il-des mails non lus ? if not mail: i += 1 - # on incrémente + # on incrémente stats[i] += 1 if i == 1: # on laisse tranquilles les membres inscrits sans mails non @@ -303,7 +303,7 @@ comptes_inactifs.py """ % total send_email(mail_sender, mail_report, - u"Récapitulatif des comptes inactifs", + u"Récapitulatif des comptes inactifs", recapitulatif, server = smtp, debug = debug) diff --git a/surveillance/comptes_inactifs/comptes_inactifs.0.txt b/surveillance/comptes_inactifs/comptes_inactifs.0.txt index 56a0c1cd..b1beba30 100644 --- a/surveillance/comptes_inactifs/comptes_inactifs.0.txt +++ b/surveillance/comptes_inactifs/comptes_inactifs.0.txt @@ -1,4 +1,4 @@ -Encoding: iso-8859-15 +Encoding: utf-8 Subject: [CRANS] Compte inactif depuis plus d'un mois Bonjour %(nom)s, diff --git a/surveillance/comptes_inactifs/comptes_inactifs.2.txt b/surveillance/comptes_inactifs/comptes_inactifs.2.txt index f403a175..50034680 100644 --- a/surveillance/comptes_inactifs/comptes_inactifs.2.txt +++ b/surveillance/comptes_inactifs/comptes_inactifs.2.txt @@ -1,4 +1,4 @@ -Encoding: iso-8859-15 +Encoding: utf-8 Subject: [CRANS] Compte inactif depuis plus d'un mois Bonjour %(nom)s, diff --git a/surveillance/comptes_inactifs/comptes_inactifs.4.txt b/surveillance/comptes_inactifs/comptes_inactifs.4.txt index e6e42672..81d0f386 100644 --- a/surveillance/comptes_inactifs/comptes_inactifs.4.txt +++ b/surveillance/comptes_inactifs/comptes_inactifs.4.txt @@ -1,4 +1,4 @@ -Encoding: iso-8859-15 +Encoding: utf-8 Subject: [CRANS] Compte inactif depuis plus d'un mois Bonjour %(nom)s, diff --git a/surveillance/comptes_inactifs/comptes_inactifs.5.txt b/surveillance/comptes_inactifs/comptes_inactifs.5.txt index 3632c4ac..fd5c3378 100644 --- a/surveillance/comptes_inactifs/comptes_inactifs.5.txt +++ b/surveillance/comptes_inactifs/comptes_inactifs.5.txt @@ -1,4 +1,4 @@ -Encoding: iso-8859-15 +Encoding: utf-8 Subject: [CRANS] Compte inactif depuis plus d'un mois Bonjour %(nom)s, diff --git a/surveillance/comptes_inactifs/comptes_inactifs.6.txt b/surveillance/comptes_inactifs/comptes_inactifs.6.txt index 827cdf75..dd3f5a5a 100644 --- a/surveillance/comptes_inactifs/comptes_inactifs.6.txt +++ b/surveillance/comptes_inactifs/comptes_inactifs.6.txt @@ -1,4 +1,4 @@ -Encoding: iso-8859-15 +Encoding: utf-8 Subject: [CRANS] Compte inactif depuis plus d'un mois Bonjour %(nom)s, diff --git a/surveillance/deconnexion.py b/surveillance/deconnexion.py index 4824a244..d4951471 100755 --- a/surveillance/deconnexion.py +++ b/surveillance/deconnexion.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- """ Script de déconnection automatique des machines du crans pour les raisons : diff --git a/surveillance/dhcp-detect.py b/surveillance/dhcp-detect.py index 073bb6fa..79ee9f0f 100755 --- a/surveillance/dhcp-detect.py +++ b/surveillance/dhcp-detect.py @@ -1,7 +1,7 @@ #! /usr/bin/env python -# -*- encoding: iso-8859-15 -*- +# -*- encoding: utf-8 -*- -# Utilisation de scappy pour détecter un DHCP pirate. +# Utilisation de scappy pour détecter un DHCP pirate. # $Id: dhcp-detect.py,v 1.3 2006/12/11 23:31:39 glondu Exp $ import sys, os @@ -25,23 +25,23 @@ PIDFILE = "/var/run/dhcp-detect.pid" # dhcp-server attendu DHCPSERVER = '138.231.136.9' -# Interface à surveiller +# Interface à surveiller INTERFACE = "crans" # Adresse MAC mac = os.popen(r"ifconfig | grep '^%s' | awk '{print $(NF)}'" % INTERFACE).readline().strip() -# Paquet à envoyer pour détecter un DHCP (il a été capturé pour avoir la bonne tête) +# Paquet à envoyer pour détecter un DHCP (il a été capturé pour avoir la bonne tête) tosend = Ether("\xff\xff\xff\xff\xff\xff\x00\x80\xc8\xc9\xab\x01\x08\x00E\x10\x01H\x00\x00\x00\x00@\x11y\x96\x00\x00\x00\x00\xff\xff\xff\xff\x00D\x00C\x014\x9aA\x01\x01\x06\x00\xb2\x87\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\xc8\xc9\xab\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x82Sc5\x01\x012\x04R\xe1'67\x07\x01\x1c\x02\x03\x0f\x06\x0c\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") -# On met à jour ce paquet +# On met à jour ce paquet tosend.getlayer(Ether).src = mac tosend.getlayer(IP).chksum = None tosend.getlayer(UDP).chksum = None tosend.getlayer(BOOTP).chaddr = ''.join(map(lambda x: chr(int(x,16)),mac.split(":")+['0']*10)) tosend = Ether(tosend.build()) -# Tableau associatif "mac" - "mailé pour la dernière fois" +# Tableau associatif "mac" - "mailé pour la dernière fois" dejavu = {} @@ -88,7 +88,7 @@ def mail(paquet): print "Envoi d'un mail...", msg = u"""Boujour, -Un DHCP pirate a été découvert sur le réseau. Voici quelques renseignements mineurs à son sujet : +Un DHCP pirate a été découvert sur le réseau. Voici quelques renseignements mineurs à son sujet : Son adresse Ethernet : %s Son adresse IP : %s @@ -99,7 +99,7 @@ Un DHCP pirate a msg += u"\n" msg += info_machine(mac_pirate) msg += u""" -Merci de votre attention et à bientôt. +Merci de votre attention et à bientôt. -- dhcp-detect.py @@ -111,10 +111,10 @@ dhcp-detect.py print "ok" -# Réception d'une réponse +# Réception d'une réponse def recoit(paquet): # On affiche - print "Réception de : ", paquet.summary() + print "Réception de : ", paquet.summary() # On verifie que c'est bien ce qu'on attend if paquet.getlayer(Ether).dst.upper() == globals()['mac'] and paquet.haslayer(BOOTP) and paquet.getlayer(BOOTP).op == 2 and paquet.getlayer(IP).src != DHCPSERVER: # DHCP pirate ? @@ -140,7 +140,7 @@ def get(): if __name__ == "__main__": - # On quitte les éventuelles instances démonisées en cours + # On quitte les éventuelles instances démonisées en cours try: pid = int(file(PIDFILE).read().strip()) os.kill(pid, 15) @@ -150,12 +150,12 @@ if __name__ == "__main__": createDaemon() file(PIDFILE, "w").write("%d\n" % os.getpid()) else: - print "Le paquet suivant va être envoyé à intervalles réguliers pour tester la présence de DHCP pirates :" + print "Le paquet suivant va être envoyé à intervalles réguliers pour tester la présence de DHCP pirates :" print tosend.summary() openlog("dhcp-detect", LOG_PID) - syslog("Démarrage de dhcp-detect") - # On démarre le thread qui envoie régulièrement le paquet... + syslog("Démarrage de dhcp-detect") + # On démarre le thread qui envoie régulièrement le paquet... Thread(target=send, name="send").start() - # ...et celui qui sniffe régulièrement la réponse + # ...et celui qui sniffe régulièrement la réponse Thread(target=get, name="get").start() diff --git a/surveillance/filtrage_firewall.py b/surveillance/filtrage_firewall.py index 01bc2033..37f6faa1 100755 --- a/surveillance/filtrage_firewall.py +++ b/surveillance/filtrage_firewall.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- encoding: iso-8859-15 -*- +# -*- encoding: utf-8 -*- ########################### @@ -17,21 +17,21 @@ import re sys.path.append('/usr/script/surveillance') import strptime -# Définition de constantes : +# Définition de constantes : ############################ reseau = ["138.231.136.0/21", "138.231.148.0/22"] -# Ouverture de la base de données : +# Ouverture de la base de données : ################################### pgsql = psycopg2.connect(host='pgsql.adm.crans.org', database='filtrage', user='crans') -# Ancienne méthode pour faire de l'autocommit. +# Ancienne méthode pour faire de l'autocommit. # Sous wheezy, il faudra remplacer par pgsql.set_session(autocommit=True) !!! pgsql.set_isolation_level(0) curseur = pgsql.cursor() ########################################### -# Récupération des tables de protocoles : # +# Récupération des tables de protocoles : # ########################################### requete = "SELECT nom,id_p2p from protocole_p2p" @@ -56,7 +56,7 @@ for cellule in tableau: # Parser ler log du firewall: /var/log/firewall/filtre.log : # ############################################################## -# Définition des motifs des comparaisons : +# Définition des motifs des comparaisons : ########################################## motif_p2p = re.compile("^(.*) komaz .* IPP2P=([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") @@ -65,7 +65,7 @@ motif_virus = re.compile("^(.*) komaz .* Virus:([^ ]*).* SRC=([^ ]*).* DST=([^ ] motif_flood = re.compile("^(.*) komaz .* Flood:([^ ]*).* SRC=([^ ]*).* DST=([^ ]*).* PROTO=([^ ]*).* SPT=([^ ]*).* DPT=([^ ]*).*") -# On récupère en continu les log du firewall: +# On récupère en continu les log du firewall: ############################################# filtre = os.popen("tail -F /var/log/firewall/filtre.log 2> /dev/null") @@ -89,7 +89,7 @@ for log in filtre: id_p2p = int(protocole_p2p[resultat_p2p.group(2)]) ip_src = resultat_p2p.group(3) ip_dest = resultat_p2p.group(4) - proto = int(protocole[resultat_p2p.group(5)]) #C'est à dire id pour la base + proto = int(protocole[resultat_p2p.group(5)]) #C'est à dire id pour la base port_src = int(resultat_p2p.group(6)) port_dest = int(resultat_p2p.group(7)) date=strptime.syslog2pgsql(date) @@ -114,7 +114,7 @@ for log in filtre: date = resultat_virus.group(1) ip_src = resultat_virus.group(3) ip_dest = resultat_virus.group(4) - proto = int(protocole[resultat_virus.group(5)]) #C'est à dire id pour la base + proto = int(protocole[resultat_virus.group(5)]) #C'est à dire id pour la base port_src = int(resultat_virus.group(6)) port_dest = int(resultat_virus.group(7)) # On remplit la base : @@ -136,7 +136,7 @@ for log in filtre: date = resultat_flood.group(1) ip_src = resultat_flood.group(3) ip_dest = resultat_flood.group(4) - proto = int(protocole[resultat_flood.group(5)]) #C'est à dire id pour la base + proto = int(protocole[resultat_flood.group(5)]) #C'est à dire id pour la base port_src = int(resultat_flood.group(6)) port_dest = int(resultat_flood.group(7)) diff --git a/surveillance/outils/virus.py b/surveillance/outils/virus.py index b02f992f..64a1ba46 100644 --- a/surveillance/outils/virus.py +++ b/surveillance/outils/virus.py @@ -1,5 +1,5 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- ########################### # Import des commmandes : # diff --git a/surveillance/parse_auth_log.py b/surveillance/parse_auth_log.py index 73c6c410..799b2ee5 100755 --- a/surveillance/parse_auth_log.py +++ b/surveillance/parse_auth_log.py @@ -1,13 +1,13 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- +# -*- coding: utf-8 -*- ############################################################################### -# parse_auth_log.py : Détecte les problèmes d'authentifications +# parse_auth_log.py : Détecte les problèmes d'authentifications ############################################################################### # The authors of this code are -# Jérémie Dimino +# Jérémie Dimino # -# Copyright (C) 2006 Jérémie Dimino +# Copyright (C) 2006 Jérémie Dimino # All rights reserved. # # This program is free software; you can redistribute it and/or modify @@ -40,7 +40,7 @@ prise_chbre = {} aujourdhui = datetime.date.today() def trouve_chambre(bat, prise): - """ Trouve la chambre associée à une prise """ + """ Trouve la chambre associée à une prise """ if prise in ('????', 'EXT', 'CRA'): return prise @@ -59,7 +59,7 @@ def trouve_chambre(bat, prise): def trouve_prise(chbre): - """ Trouve la prise associée à une chambre """ + """ Trouve la prise associée à une chambre """ if chbre in ('EXT', '????', 'CRA'): return chbre @@ -72,7 +72,7 @@ def trouve_prise(chbre): def __calcul_max(table): - """ Calcule les différents maxima (voir parse_auth_log pour plus de détails) """ + """ Calcule les différents maxima (voir parse_auth_log pour plus de détails) """ nb_m = 0 nb_p = 0 @@ -93,7 +93,7 @@ def __calcul_max(table): def __ajoute_ligne(errs, ligne, prise, mac, info=None): - """ Ajoute une ligne dans le dico pour la prise et la mac donnée """ + """ Ajoute une ligne dans le dico pour la prise et la mac donnée """ erreur_prise = errs.get(prise) if not erreur_prise: @@ -108,29 +108,29 @@ def __ajoute_ligne(errs, ligne, prise, mac, info=None): erreur_mac['lignes'].append(ligne) -# Correspondance 'noms de mois' -> n° +# Correspondance 'noms de mois' -> n° __mois_num = { 'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12 } def parse_auth_log(fichier_log='/var/log/freeradius/radius_auth.log', jour=None): - """ Retourne la liste des problèmes de connexions: retourne deux dicos, la première étant pour les macs qui n'ont pas été trouvées dans la base et la seconde pour les connexions qui ont eu lieu à partir d'une mauvaise prise + """ Retourne la liste des problèmes de connexions: retourne deux dicos, la première étant pour les macs qui n'ont pas été trouvées dans la base et la seconde pour les connexions qui ont eu lieu à partir d'une mauvaise prise les deux dictionnaires ont la structure suivante: -- nombre_mac_max: nombre maximal d'erreurs trouvées pour une mac -- nombre_prise_max: nombre maximal d'erreurs trouvées pour une prise -- prises: dico associant à une prise la listes des erreurs à partir de cette prise: +- nombre_mac_max: nombre maximal d'erreurs trouvées pour une mac +- nombre_prise_max: nombre maximal d'erreurs trouvées pour une prise +- prises: dico associant à une prise la listes des erreurs à partir de cette prise: - nombre: nombre total d'erreurs survenues sur la prise - - nombre_max: nombre maximal d'erreurs trouvéss pour une mac - - macs: dico associant à une mac la liste des erreurs à partir de cette mac + - nombre_max: nombre maximal d'erreurs trouvéss pour une mac + - macs: dico associant à une mac la liste des erreurs à partir de cette mac - nombre: le nombre d'erreurs survenues pour cette mac sur cette prise - - lignes: la liste des lignes du fichier de logs où la mac apparaît sur cette prise - - info: informations sur le propriétaire (vaut None pour la première table) + - lignes: la liste des lignes du fichier de logs où la mac apparaît sur cette prise + - info: informations sur le propriétaire (vaut None pour la première table) - machine: la machine en question - prise: la prise de sa chambre - chambre: sa chambre - - prop: le propriétaire + - prop: le propriétaire -Si jour est spécifié (de type datetime.date), toutes les connexions avant cette dates seront ignorées. +Si jour est spécifié (de type datetime.date), toutes les connexions avant cette dates seront ignorées. """ try: @@ -139,13 +139,13 @@ Si jour est sp cprint(u"Impossible d'ouvrir le fichier %s" % fichier_log, 'rouge') sys.exit(1) - # Les macs non trouvées + # Les macs non trouvées errs_inconnue = {} - # Les pc connectés sur la mauvaise prise + # Les pc connectés sur la mauvaise prise errs_prise = {} - # Les recherches déjà effectuées sur les macs + # Les recherches déjà effectuées sur les macs mac_machine = {} annee = None @@ -161,12 +161,12 @@ Si jour est sp if annee == None: if nouveau_mois > aujourdhui.month: - # Là on suppose qu'il s'agit de l'année dernière + # Là on suppose qu'il s'agit de l'année dernière annee = aujourdhui.year - 1 else: annee = aujourdhui.year elif mois > nouveau_mois: - # Là on suppose qu'on est passé à l'année suivante + # Là on suppose qu'on est passé à l'année suivante annee += 1 mois = nouveau_mois @@ -213,7 +213,7 @@ Si jour est sp def affiche_erreurs(errs, message, min_mac=1, min_prise=1): - """ Affiche les infos contenues dans un dico renvoyé par parse_auth_log """ + """ Affiche les infos contenues dans un dico renvoyé par parse_auth_log """ if errs['nombre_mac_max'] >= min_mac and errs['nombre_prise_max'] >= min_prise: @@ -248,35 +248,35 @@ def __usage(err=''): def __param_entier(opt, val): - """ Récupère un entier passé en ligne de commande """ + """ Récupère un entier passé en ligne de commande """ try: return int(val) except: - __usage(u'La valeur du paramètre %s est incorecte (doit être un entier positif)' % opt) + __usage(u'La valeur du paramètre %s est incorecte (doit être un entier positif)' % opt) def __aide(): """ Aide """ cprint(u"""Usage: %s [OPTIONS] -Parse les logs d'authentifications et affiche les erreurs trouvées (macs inconnues ou connexion d'une machine sur une prise autre que celle du propriétaire). +Parse les logs d'authentifications et affiche les erreurs trouvées (macs inconnues ou connexion d'une machine sur une prise autre que celle du propriétaire). Options: -h, --help affiche cette aide - -l, --log fichier de log à parser (par défaut: /var/log/freeradius/radius_auth.log) - -m, --min-mac nombre minimal d'occurrences d'une mac sur une prise pour qu'elle soit reportée - -n, --min-prise nombre minimal d'erreurs sur une prise pour qu'elle soit reportée + -l, --log fichier de log à parser (par défaut: /var/log/freeradius/radius_auth.log) + -m, --min-mac nombre minimal d'occurrences d'une mac sur une prise pour qu'elle soit reportée + -n, --min-prise nombre minimal d'erreurs sur une prise pour qu'elle soit reportée -i, --inconnue n'affiche que les erreurs de mac inconnues - -p, --prise n'affiche que les connexions sur une prise autre que celle du propriétaire + -p, --prise n'affiche que les connexions sur une prise autre que celle du propriétaire -d, --date ignorer totalement les lignes avant cette date - peut être: + peut être: - une date absolue sous la forme AAAAMMJJ -- une date relative à aujourd'hui sous la forme + -Par exemple pour ne considérer que les deux dernier jours: +2 +- une date relative à aujourd'hui sous la forme + +Par exemple pour ne considérer que les deux dernier jours: +2 -Rapporter toutes anomalies à .""" % sys.argv[0].split('/')[-1].split('.')[0]) +Rapporter toutes anomalies à .""" % sys.argv[0].split('/')[-1].split('.')[0]) sys.exit(0) @@ -288,7 +288,7 @@ if __name__ == '__main__': # Info que l'on veut afficher aff_inconnue = True aff_prise = True - # Date de départ + # Date de départ jour = None import getopt, time @@ -318,7 +318,7 @@ if __name__ == '__main__': try: jour = datetime.date(*(time.strptime(val, "%Y%m%d")[0:3])) except: - __usage(u'La valeur du paramètre %s est incorecte (doit être de la forme AAAAMMJJ)' % opt) + __usage(u'La valeur du paramètre %s est incorecte (doit être de la forme AAAAMMJJ)' % opt) else: cprint(u'Option inconnue: %s' % opt, 'rouge') __usage() @@ -328,7 +328,7 @@ if __name__ == '__main__': errs_inconnue, errs_prise = parse_auth_log(fichier_log, jour) if aff_inconnue: - affiche_erreurs(errs_inconnue, u"Pour les connexions suivantes la mac n'a pas été trouvée dans la base:", min_mac, min_prise) + affiche_erreurs(errs_inconnue, u"Pour les connexions suivantes la mac n'a pas été trouvée dans la base:", min_mac, min_prise) if aff_prise: - affiche_erreurs(errs_prise, u"Les connexions suivantes ont eu lieu sur une prise autre que celle du proriétaire:", min_mac, min_prise) + affiche_erreurs(errs_prise, u"Les connexions suivantes ont eu lieu sur une prise autre que celle du proriétaire:", min_mac, min_prise) diff --git a/surveillance/statistiques.py b/surveillance/statistiques.py index d6a0e95a..c1753fa5 100755 --- a/surveillance/statistiques.py +++ b/surveillance/statistiques.py @@ -1,11 +1,11 @@ #! /usr/bin/env python -# -*- encoding: iso-8859-15 -*- +# -*- encoding: utf-8 -*- """ -Script d'envoi des statistiques des déconnections -et du trafic de la journée à disconnect@ +Script d'envoi des statistiques des déconnections +et du trafic de la journée à disconnect@ -Copyright (C) Xavier Pessoles - Étienne Chové - Michel Blockelet +Copyright (C) Xavier Pessoles - Étienne Chové - Michel Blockelet Licence : GPLv2 """ @@ -111,9 +111,9 @@ liste_upload = tableau(data = [ (l[1], l[2], ipv4or6(str(l[0])), socket.getfqdn( titre = ['upload', 'download', 'proto', 'machine'], largeur = [10, 10, 10, 40], format = ['o', 'o', 's', 's'], - alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15') + alignement = ['d', 'd', 'c', 'c']).encode('utf-8') -# Trafic exempté : +# Trafic exempté : ################## requete = """(SELECT ip_crans, sum(upload) AS somme, sum(download) FROM upload @@ -149,7 +149,7 @@ liste_exemptes = tableau(data = [[l[1], l[2], ipv4or6(str(l[0])), socket.getfqdn titre = ['upload', 'download', 'proto', 'machine'], largeur = [10, 10, 10, 30], format = ['o', 'o', 's', 's'], - alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15') + alignement = ['d', 'd', 'c', 'c']).encode('utf-8') # Upload des serveurs : ####################### @@ -170,7 +170,7 @@ liste_serveurs = tableau(data = liste_serveurs, titre = ['upload', 'download', 'proto', 'serveur'], largeur = [10, 10, 10, 30], format = ['o', 'o', 's', 's'], - alignement = ['d', 'd', 'c', 'c']).encode('iso-8859-15') + alignement = ['d', 'd', 'c', 'c']).encode('utf-8') # statistiques des gros uploads depuis les serveurs @@ -178,7 +178,7 @@ liste_serveurs = tableau(data = liste_serveurs, # Liste des IP des serveurs gros_uploads_des_serveurs = stats(ip_crans=ips_serveurs, show=['ip_crans', 'ip_ext'], upload_mini=50, - show_limit=100).encode('iso-8859-15') + show_limit=100).encode('utf-8') ############################ # Statistiques virus/p2p : # @@ -206,10 +206,10 @@ liste_etherunk = tableau(data = [[l[0], socket.getfqdn(str(l[1]))] for l in curseur.fetchall()], titre = ['nombre','ip'], largeur = [10, 30], - alignement = ['d','c']).encode('iso-8859-15') + alignement = ['d','c']).encode('utf-8') -# Machines actuellement déconnectées : +# Machines actuellement déconnectées : ###################################### requete = "SELECT DISTINCT ip_crans FROM avertis_virus" curseur.execute(requete) @@ -220,9 +220,9 @@ for IP in infections: liste_virus.append(["%s" % (str(hostname))]) liste_virus = tableau(liste_virus, - titre=['machine'], largeur=[30]).encode('iso-8859-15') + titre=['machine'], largeur=[30]).encode('utf-8') -# Machines ayant fait des attaques virus dans la journée : +# Machines ayant fait des attaques virus dans la journée : ########################################################## requete = """SELECT * FROM (SELECT ip_src,count(ip_src) as compteur FROM virus WHERE date > timestamp 'now' - interval '1 day' @@ -237,10 +237,10 @@ for IP, compteur in curseur.fetchall(): liste_virus2 = tableau(data = liste_virus2, titre = ['machine', 'nombre'], largeur = [30, 12], - alignement = ['c', 'd']).encode('iso-8859-15') + alignement = ['c', 'd']).encode('utf-8') -# Machines ayant fait de attaques flood dans la journée : +# Machines ayant fait de attaques flood dans la journée : ######################################################### requete = """SELECT * FROM (SELECT ip_src,count(ip_src) as compteur FROM flood WHERE date > timestamp 'now' - interval '1 day' @@ -255,7 +255,7 @@ for IP, compteur in curseur.fetchall(): liste_virus3 = tableau(data = liste_virus3, titre = ['machine', 'nombre'], largeur = [30, 12], - alignement = ['c', 'd']).encode('iso-8859-15') + alignement = ['c', 'd']).encode('utf-8') ############# @@ -266,11 +266,11 @@ expediteur = "disconnect@crans.org" destinataire = "disconnect@crans.org" message = """From: %(From)s To: %(To)s -Subject: Statistiques des =?iso-8859-1?Q?derni=E8res?= 24h +Subject: Statistiques des =?utf-8?q?derni=C3=A8res?= 24h Message-Id: <%(uuid)s1@crans.org> -Content-Type: text/plain; charset="iso-8859-15" +Content-Type: text/plain; charset="utf-8" -*Gros uploads des serveurs* (charybde et sable sont exemptés totalement) +*Gros uploads des serveurs* (charybde et sable sont exemptés totalement) %(gros_uploads_des_serveurs)s @@ -282,23 +282,23 @@ Content-Type: text/plain; charset="iso-8859-15" %(liste_etherunk)s -*Machines actuellement déconnectées pour virus* +*Machines actuellement déconnectées pour virus* %(liste_virus)s -*Machines ayant commis des attaques virales dans la journée* +*Machines ayant commis des attaques virales dans la journée* %(liste_virus2)s -*Machines ayant commis des attaques virales de type flood dans la journée* +*Machines ayant commis des attaques virales de type flood dans la journée* %(liste_virus3)s -*Statistiques de trafic des adhérents* (tout le trafic) +*Statistiques de trafic des adhérents* (tout le trafic) %(liste_upload)s -*Statistiques de trafic des adhérents exemptés* (juste le trafic exempté) +*Statistiques de trafic des adhérents exemptés* (juste le trafic exempté) %(liste_exemptes)s diff --git a/utils/chambre-on-off.py b/utils/chambre-on-off.py index b0eddca4..14ac7ae1 100755 --- a/utils/chambre-on-off.py +++ b/utils/chambre-on-off.py @@ -1,12 +1,12 @@ #! /usr/bin/env python -# -*- coding: iso-8859-15 -*- -"""chambre_on_off.py: Affiche le statut, active ou désactive une prise +# -*- coding: utf-8 -*- +"""chambre_on_off.py: Affiche le statut, active ou désactive une prise syntaxe : chambre-on-off.py chbre chbre de la forme A101d - peut être : + peut être : - on : activer la prise - - off : désactiver la prise + - off : désactiver la prise - absent : affiche le statut de la prise """ @@ -17,10 +17,10 @@ sys.path.append("/usr/scripts/gestion/") import hptools def chambre_on_off(chambre, cmd = None): - """Active ou désactive une prise + """Active ou désactive une prise - chambre: numéro de chambre - cmd: si fourni, "on" ou "off" pour activer ou désactiver la prise + chambre: numéro de chambre + cmd: si fourni, "on" ou "off" pour activer ou désactiver la prise si cmd n'est pas fourni, ne fait qu'afficher le statut de la prise """ # connexion au switch