#!/usr/bin/env python # -*- coding: utf-8 -*- # # CRANS_UTILS.PY-- Utils for Cr@ns gestion # # Copyright (c) 2010, Cr@ns # Author: Antoine Durand-Gasselin # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # * Neither the name of the Cr@ns nor the names of its contributors may # be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import calendar, netaddr, re, time, smtplib, sys sys.path.append('/usr/scripts/gestion') import config from unicodedata import normalize def ip_of_mid(mid): """Convertit un mid en son IP associée""" for net, plage in config.mid.items(): if mid >= plage[0] and mid <= plage[1]: break else: raise ValueError("Mid dans aucune plage: %d" % mid) return netaddr.IPAddress(netaddr.IPNetwork(config.NETs[net][0]).first + mid - plage[0]) def strip_accents(a): """ Supression des accents de la chaîne fournie""" res = normalize('NFKD', a).encode('ASCII', 'ignore') return unicode(res) def strip_spaces(a): """ Suppression des espaces et des apostrophes""" return a.replace(u' ', u'_').replace(u"'", u'') def mailexist(mail): """Vérifie si une adresse mail existe ou non grace à la commande vrfy du serveur mail """ mail = mail.split('@', 1)[0] # try: s = smtplib.SMTP('smtp.adm.crans.org') s.putcmd("vrfy", mail) r = s.getreply()[0] in [250, 252] s.close() # except: # raise ValueError(u'Serveur de mail injoignable') return r def format_ldap_time(tm): u"""Formatage des dates provenant de la base LDAP Transforme la date YYYYMMDDHHMMSS.XXXXXXZ (UTC) en date DD/MM/YY HH:MM (local)""" tm_st = time.strptime(tm.split('.')[0], "%Y%m%d%H%M%S") # struct_time UTC timestamp = calendar.timegm(tm_st) tm_st = time.localtime(timestamp) # struct_time locale return time.strftime("%d/%m/%Y %H:%M", tm_st) def format_mac(mac): u""" Formatage des adresses mac Transforme une adresse pour obtenir la forme xx:xx:xx:xx:xx:xx Retourne la mac formatée. """ mac = netaddr.EUI(mac) if not mac: raise ValueError(u"MAC nulle interdite\nIl doit être possible de modifier l'adresse de la carte.") return str(mac).replace('-', ':') def format_tel(tel): u"""Formatage des numéros de téléphone Transforme un numéro de téléphone pour ne contenir que des chiffres (00ii... pour les numéros internationaux) Retourne le numéro formaté. """ tel_f = tel.strip() if tel_f.startswith(u"+"): tel_f = u"00" + tel_f[1:] if u"(0)" in tel_f: tel_f = tel_f.replace(u"(0)", u"") tel_f = re.sub(r'\D', '', tel_f) return tel_f def validate_name(value, more_chars=""): """Valide un nom: ie un unicode qui contient lettres, espaces et apostrophes, et éventuellement des caractères additionnels""" if re.match("^[A-Za-z0-9]([-' %s]?[A-Za-z0-9])*$" % more_chars, normalize('NFKD', value).encode('ASCII', 'ignore')): return value else: raise ValueError("Nom invalide ('%s')" % value) def ldap_sanitize(s): """ Échappe les caractères spéciaux ldap. (Si vous avez une méthode plus propre pour coder ça, je suis preneur) Todo: rajouter conversion pour caractère utf-8 multioctets ? (cf http://blog.dzhuvinov.com/?p=585 ) """ replace = { '*': '\\2a', '(': '\\28', ')': '\\29', '\\': '\\5c', '\x00': '\\00'} def conv(c): try: return replace[c] except KeyError: return c return "".join([conv(c) for c in s])