# -*- coding: iso-8859-1 -*- u""" _vi aZ2^ v` .we^ . . .. + _2~ ._auqXZZX ._auqXZZZ` ...._... ~ ._|ii~ .aXZZY""^~~ vX#Z?""~~~._=ii|+++++++ii=, _=|+~- JXXX` )XXX' _|i+~ .__..._. +l= -~- SXXo )XZX: |i> ._%i>~~+|ii| .i| ._s_ass,,. ._a%ssssssss -SXZ6,,. )XZX: =l> _li+~` iii| .ii _uZZXX??YZ#Za, uXUX*?!!!!!!! "!XZ#ZZZZZXZXZ` =i: .|ii| .l|.dZXr 4XXo.XXXs,. -~^^^^^^^` -||, +i|=. |ii| :i>:ZXZ( ]XZX.-"SXZUZUXoa,, +l|, ~~|++|++i|||+~:ZXZ( ]ZZX ---~"?Z#m .__;=- ~+l|=____.___, :ZXZ( ]ZXX_________auXX2 ._||>+~- . -~+~++~~~- :ZXZ( ]ZXZZ#######UX*!" -+-- .>` _ .<}` 3; . .Zc .ii^ )Xo ]XX MoinMoin - Formulaire d'inscription Un formulaire de préinscription au Crans Copyright 2009 Antoine Durand-Gasselin Licence: GPLv3 """ import re, locale, base64, sys, unicodedata from commands import getstatusoutput as gso sys.path.append("/usr/scripts/gestion") from iptools import AddrInNet from MoinMoin import wikiutil from MoinMoin.widget import html from MoinMoin.Page import Page from MoinMoin.PageEditor import PageEditor from MoinMoin.formatter.text_html import Formatter ETABLISSEMENTS = [ ("ENS", u"ENS Cachan"), ("IUT Cachan", u"IUT Cachan"), ("Maximilien Sorre", u"Maximilien Sorre"), ("Gustave Eiffel", u"Gustave Eiffel"), ("P1", u"Paris I"), ("P2", u"Paris II"), ("P3", u"Paris III"), ("P4", u"Paris IV"), ("P5", u"Paris V"), ("P6", u"Paris VI"), ("P7", u"Paris VII"), ("P8", u"Paris VIII"), ("P9", u"Paris IX"), ("P10", u"Paris X"), ("P11", u"Paris XI"), ("P12", u"Paris XII"), ("P13", u"Paris XIII"), ("IUFM", u"IUFM"), ("other", u"Autre...") ] LABOS = [ ("CMLA", u"CMLA - Centre de Mathématiques et de Leurs Applications"), ("GAPP", u"GAPP - Groupe d'Analyse des Politiques Publiques"), ("IDHE", u"IDHE - Institutions et Dynamiques Historiques de l'Economie"), ("LBPA", u"LBPA - Laboratoire de Biotechnologies et Pharmacologie génétique Appliquées"), ("LMT", u"LMT - Laboratoire de Mécanique et Technologie"), ("LPQM", u"LPQM - Laboratoire de Photonique Quantique et Moléculaire"), ("LSV", u"LSV - Laboratoire de Spécification et Vérification"), ("LURPA", u"LURPA - Laboratoire Universitaire de Recherche en Production Automatisée"), ("PPSM", u"PPSM - Laboratoire de Photophysique et Photochimie Supramoléculaires et Macromoléculaires"), ("SATIE", u"SATIE - Systèmes et Applications des Technologies de l\'Information et de l'Energie"), ("STEF", u"STEF - Sciences Techniques Education Formation") ] ANNEE_ENS = [ ("1", u"1A (licence)"), ("2", u"2A (master 1)"), ("3", u"3A (agrégation)"), ("4", u"4A (master 2)"), ("5", u"5A (thèse 1)"), ("6", u"6A (thèse 2)"), ("7", u"7A (thèse 3)"), ("8", u"8A+") ] ANNEE_ETUDE = [ ("-2", u"Seconde"), ("-1", u"Première"), ("0", u"Terminale"), ("1", u"BAC+1 (L1)"), ("2", u"BAC+2 (L2)"), ("3", u"BAC+3 (L3)"), ("4", u"BAC+4 (M1)"), ("5", u"BAC+5 (M2)"), ("6", u"BAC+6 (thèse 1)"), ("7", u"BAC+7 (thèse 2)"), ("8", u"BAC+8 (thèse 3)"), ("9", "Autre") ] SECTIONS_ENS = [ ("A0", u"A0 - Informatique"), ("A1", u"A1 - Mathématiques"), ("A2", u"A2 - Physique fondamentale"), ("A'2", u"A'2 - Physique appliquée"), ("A''2", u"A''2 - Chimie"), ("A3", u"A3 - Biochimie"), ("EEA", u"EEA"), ("B123", u"B123 - Technologie mécanique"), ("B1", u"B1 - Mécanique"), ("B2", u"B2 - Génie civil"), ("B3", u"B3 - Génie mécanique"), ("B1", u"B1 - Mécanique"), ("B2", u"B2 - Génie civil"), ("B3", u"B3 - Génie mécanique"), ("B4", u"B4 - Génie électrique"), ("C", u"C - Art et création industrielle"), ("D2", u"D2 - Economie gestion"), ("D3", u"D3 - Sciences sociales"), ("E", u"E - Anglais") ] class Field(): """Une classe pour représenter les champs Attention, elle ne permet que de rendre les champs en html, et permet d'effectuer des tests unitaires""" error_txt='' error_msg='' error_field='' def __init__(self, id, prompt, default = "", input_type = "text", check=None, CLASS="formulaire_field"): self.id = id self.prompt = html.Text(prompt) self.default = default self.input_type = input_type self.CLASS= CLASS if check != None: self.check_hook = check else: self.check_hook = (lambda x: True) def fill(self, post): self.input = post.get(self.id, [''])[0] def check(self): self.error_txt= '' # Devrait pourtant être déjà vide self.default = self.input ok = self.check_hook(self) if ok: self.content = self.__dict__.get('content', self.input) # des fois qu'on ait oublié de le faire if self.content != self.default and self.default == self.input: self.default = self.content if not self.error_txt and not ok: self.error_txt = u'Valeur %s incorrecte pour le champ %s.' % (self.input, self.id) return ok def render(self, request, parser): champ = html.UL(CLASS=self.CLASS) champ.append(html.LI(CLASS="formulaire_id").append(self.prompt)) input = html.INPUT(type=self.input_type,name=self.id,value=self.default) champ.append(html.LI(CLASS="formulaire_input").append(input)) if self.error_txt: error = wikiutil.renderText(request, parser, self.error_txt) champ.append(html.LI(CLASS="formulaire_error").append(error)) if self.error_msg: request.add_msg(self.error_msg) return champ class MenuField(Field): def __init__(self, id, prompt, fields): Field.__init__(self, id, prompt) self.fields = fields def render(self, request, parser): champ = html.UL(CLASS="formulaire_field_%s" % self.id) champ.append(html.LI(CLASS="formulaire_id").append(self.prompt)) menu = html.SELECT(NAME=self.id, onchange='TestEtudes()') for opt, legend in self.fields: menu.append(html.OPTION(VALUE=opt).append(legend)) champ.append(menu) if self.error_txt: error = wikiutil.renderText(request, parser, self.error_txt) champ.append(html.LI(CLASS="formulaire_error").append(error)) if self.error_msg: request.add_msg(self.error_msg) return champ class PasswordField(Field): def fill(self, post): self.input = post.get(self.id, [''])[0] self.input2 = post.get(self.id+'2',[''])[0] def check(self): self.error_txt= '' # Devrait pourtant être déjà vide self.default = '' if self.input == self.input2: self.content = self.input return True else: self.error_txt = u'Les deux mots de passe diffèrent' return False def render(self, request, parser): champ = html.UL(CLASS="formulaire_field") champ.append(html.LI(CLASS="formulaire_id").append(self.prompt)) input = html.INPUT(type=self.input_type,onchange="testPassword()", name=self.id) champ.append(html.LI(CLASS="formulaire_input").append(input)) champ.append(html.LI().append('')) champ2 = html.UL(CLASS="formulaire_field") champ2.append(html.LI(CLASS="formulaire_id").append('Retapez le mot de passe')) input = html.INPUT(type=self.input_type, name=self.id+'2') champ2.append(html.LI(CLASS="formulaire_input").append(input)) if self.error_txt: error = wikiutil.renderText(request, parser, self.error_txt) champ2.append(html.LI(CLASS="formulaire_error").append(error)) return u'%s\n%s\n' % (champ, champ2) def is_name(self): """Vérifie que le champ input de l'objet passé en argument est un nom valide.""" analysed_content = unicodedata.normalize('NFKD', self.input) try: stripped_content = analysed_content.encode('ASCII', 'ignore') except UnicodeEncodeError: stripped_content = '' if re.match('[a-z][-a-z _]*', stripped_content.lower()): return True else: self.error_txt = u"""Valeur %s incorrecte pour le champ %s. Seules les lettres (éventuellement accentuées), l'espace et le tiret '-' sont acceptés.""" % (self.input, self.id) return False def is_phonenumber(self): chiffres = self.input.replace('.', '') if re.match('(0|\+[0-9][0-9])[0-9]{9}', chiffres): return True else: self.content = '' return True def is_dns(self): dns = self.input.lower() if re.match('[a-z][-a-z0-9_]*', dns): return True else: return False def get_mac(ip): "Récupère la mac" mac= 'XX' + ':XX'*5 if AddrInNet(ip, '138.231.136.0/21'): status, mac = gso("/usr/sbin/arp %s | perl -nle '{print $& if /00(:[0-9a-f]{2}){5}/}'" % ip) # gruik, gruik, grUUIIIk ! mac= mac.strip() return mac def is_valid_mac(self): mac = self.input.lower() if re.search("00((:|-|)[a-f0-9][a-f0-9]){5}", mac): return True else: self.default = get_mac(self.ip) return False class FormulaireInscription(): """Une classe qui représente le formulaire d'inscription Elle contient un champs ``champs'', qui contient une liste de Fields, qui est la liste des champs qui doivent être demandés (dans le bon ordre l'ordre). """ def __init__(self, request): ip = request.remote_addr mac_field = Field("mac", u"Adresse physique de votre carte réseau", check=is_valid_mac, default=get_mac(ip)) mac_field.ip = ip self.champs = [ Field("nom", "Nom", check=is_name), Field("prenom", u"Prénom", check=is_name), Field("tel", u"Numéro de téléphone", check=is_phonenumber), PasswordField("pass", u"Mot de passe", input_type='password'), Field("dns", u"Nom de votre ordinateur", check=is_dns), mac_field, MenuField('etablissement', u"Établissement d'études", ETABLISSEMENTS), Field("etablissement_autre", u"Précisez votre établissement d'études", check=is_name, CLASS='formulaire_field_etablissement_autre'), MenuField('annee_ens', u"Année scolaire à l'ENS", ANNEE_ENS), MenuField('annee', u"Choisissez votre année scolaire", ANNEE_ETUDE), MenuField('section_ens', u"Section", SECTIONS_ENS), MenuField('labo', u"Laboratoire", LABOS), Field("section", u"Précisez votre section", CLASS="formulaire_field_section") ] def _create_form(request, parser, formulaire): url = request.page.url(request) ret = html.FORM(action=url, NAME="preinscription") ret.append(html.INPUT(type='hidden', name='action', value='inscription')) f = html.UL(CLASS="formulaire_preinscription") for field in formulaire.champs: champ = field.render(request, parser) f.append(html.LI().append(champ)) ret.append(f) ret.append(html.HR(CLASS= "invisiblesep")) ret.append(html.INPUT(type="submit", name="inscrire", value=u"Me préinscrire")) return unicode(ret) def _check_form(post, formulaire): u"""Vérifie les paramètres postés par l'utilisateur. Vérifie que toutes les entrées du formulaire (formulaire.fields) sont présentes et bien valides, (en appelant check() pour chaque champs). """ errors = [] for field in formulaire.champs: field.fill(post) for field in formulaire.champs: if not field.check(): errors.append(field.id) return errors def _perform_inscription(request, formulaire): request.emit_http_headers(more_headers = ['Content-Type: text/plain']) results = '' for field in formulaire.champs: results += '%(id)s: %(content)s\n' % field.__dict__ request.write(results) def execute(pagename, request): request.page = Page(request, pagename) request.formatter.setPage(request.page) request.loadTheme('crans-www') formulaire = FormulaireInscription(request) post = request.form parser = wikiutil.searchAndImportPlugin(request.cfg, "parser", request.page.pi['format']) if not request.dicts.has_member("GroupeAdmin", request.user.name) and not request.user == 'AntoineDurandGasselin': request.theme.add_msg(u"Non, car tu es méchant", "error") return(page.send_page()) if post.has_key('inscrire'): if _check_form(post, formulaire) == []: return(_perform_inscription(request, formulaire)) request.emit_http_headers() request.theme.send_title(u"Formulaire de préinscription", pagename=pagename, html_head='') request.write(request.formatter.startContent("content")) form = _create_form(request, parser, formulaire) # THIS IS A BIG HACK. IT NEEDS TO BE CLEANED UP request.write(form) request.write(request.formatter.endContent()) request.theme.send_footer(pagename) request.theme.send_closing_html()