Example #1
0
class WebSchedules(Resource):
    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para modificar los horarios de cualquier tutor.
    # Si somos tutor, sirve para modificar solo los propios.
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        request.write(self.template.startPage(session, _('Modificacion de horarios')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
        # 2.1) Admin debe proveer el argumento user_id
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
                    msg = """<h2>""" + _('Administracion de horarios') + """</h2>""" + _('Selecciona las horas en las que el tutor se encuentra disponible.')
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, _('falta el parametro user_id')))
        # 3) Si es Tutor, administra sus propios horarios
        elif session.kind == TUTOR:
            user_id = session.userId
            msg = """<h2>""" + _('Seleccion de horarios') + """</h2>""" + _('Indica los horarios (en tu hora local) en los que te encuentras disponible.')
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id, msg)
        else:
        # 4) Si no es ni ni Admin, ni Tutor, ni nadie, es alguien que no está
        #    autorizado a administrar horarios
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def printContent(self, request, d, userId, msg):
        # 1) Si se envían datos, se actualiza la base primero. 
        # La actualizacion consiste en eliminar todos los horarios previos, 
        # hace el packSchedule, e insertar los nuevos horarios. 
        _ = request.getSession()._
        if "submit" in request.args.keys():
            op = "delete from tutor_schedule where fk_tutor = %d"
            d.addCallback(lambda a: self.db.db.runOperation(op, (userId, )))

            d.addCallback(lambda a: self.packSchedule(request.args.get('sch', []), str(INSTANT), userId))
            #instants = self.packSchedule(request.args.get('sch', []), str(INSTANT), userId)
            d.addCallback(self.addSched, userId,INSTANT)
            
            d.addCallback(lambda a: self.packSchedule(request.args.get('sch', []), str(PRECOORD), userId))
            d.addCallback(self.addSched, userId,PRECOORD)
            d.addCallback(lambda a: request.write("""<div class="message"><h2>""" + _('Cambios guardados.') + """</h2>""" + _('Se guardaron los cambios correctamente') + """</div>"""))
            
        # 2) Se imprime un mensaje de bienvenida configurable
        d.addCallback(lambda a: request.write(msg))
        # 3) Se buscan los datos nuevos en la base
        d.addCallback(self.requestScheduleData, userId)
        # 4) Se imprime un formulario con los datos actualizados
        d.addCallback(self.printForm, request, userId)
        return d
        
    def addSched(self, tipoH, userId,TIPO):
        for sched in tipoH:
            self.addSchedule(userId, sched, TIPO)
        return None
    
        

    def packSchedule(self, checks, kind, userId):
        try: # Mapeamos a integer y filtramos valores inadecuados
            checks = [int(chk[:-2]) for chk in checks
                      if chk[-1] == kind]
        except ValueError:
            return []
        checks.sort()

        scheds = []
        last_hour = None
        start_time = None
        end_time = None
        for hour in checks:
            if last_hour is None:
                start_time = hour
            elif last_hour < hour - 1:
                scheds.append((start_time, end_time))
                start_time = hour
            last_hour = hour
            end_time = hour + 1
        # Falta el último span, que lo agregamos ahora:
        if end_time is not None:
            if end_time == LASTDAY_MIDNIGHT:
                if start_time == 0: # Este tipo labura 24/7!
                    scheds.append((0, end_time))
                elif len(scheds) > 0 and scheds[0][0] == 0: # El horario abarca las 0 del domingo
                    scheds.append((start_time, end_time + scheds[0][1]))
                    del(scheds[0])
                else:
                    scheds.append((start_time, end_time))
            else:
                scheds.append((start_time, end_time))
        # Convertimos a DateTime

        d = self.queryOffset(userId)
        d.addCallback(self.getSpans, scheds)
        return d

    def getSpans(self, rows, scheds):
        spans = []
        
        # Elegimos mayo del 2005 porque el 1ero cae domingo.
        #creamos la fecha considerando el timezone

        mktimestamp = lambda x: DateTime(2005, 5, 1 + x / 48, (x % 48) / 2, (x % 2) * 30) - DateTimeDelta(0,rows[0][0])
        for sched in scheds:
            spans.append((mktimestamp(sched[0]), mktimestamp(sched[1])))            
        return spans

    def unpackSchedule(self, rows):
        checks = [''] * LASTDAY_MIDNIGHT
        for row in rows:
            start_check = row[0] * 48 + row[1] * 2 + row[2] / 30
            end_check = row[3] * 48 + row[4] * 2 + row[5] / 30
            if end_check <= start_check:
                end_check += LASTDAY_MIDNIGHT
            for hour in range(start_check, end_check):
                checks[hour % LASTDAY_MIDNIGHT] = str(row[6])
        return checks

    def requestScheduleData(self, data, userId):
        d = self.queryOffset(userId)
        d.addCallback(self.addOffset, data, userId)
        return d
    
    
    #VER refactoring de estos metodos! 
    #resolver el gmtoffset directamente en una consulta
    # ver WebGetUserInfo para ejemplo
    
    def queryOffset(self, userId):
         query1 = 'select timezone.gmtoffset from timezone, person where \
                  timezone.id = person.fk_timezone and person.id = %d'                
         return self.db.db.runQuery(query1, (userId, ))


    def addOffset(self, rows, request, userId):
        if rows[0][0] >= 0:
            query = "select extract(dow from time_start + interval '%i hour' ), \
                     extract(hour from time_start + interval '%i hour'), \
                     extract(minute from time_start + interval '%i hour'), \
                     extract(dow from time_end + interval '%i hour'), \
                     extract(hour from time_end + interval '%i hour'), \
                     extract(minute from time_end + interval '%i hour'), schedule_type \
                     from tutor_schedule where fk_tutor = %d"     
        else:
            query = "select extract(dow from time_start - interval '%i hour' ), \
                     extract(hour from time_start - interval '%i hour'), \
                     extract(minute from time_start - interval '%i hour'), \
                     extract(dow from time_end - interval '%i hour'), \
                     extract(hour from time_end - interval '%i hour'), \
                     extract(minute from time_end - interval '%i hour'), schedule_type \
                     from tutor_schedule where fk_tutor = %d"
        of = abs(rows[0][0])
        print "offset = %i" % of
        return self.db.db.runQuery(query, (of,of,of,of,of,of,userId,))


    def printForm(self, rows, request, userId):
        _ = request.getSession()._
        checks = self.unpackSchedule(rows)
        days = [_('Domingo'), _('Lunes'), _('Martes'), _('Miercoles'), _('Jueves'), _('Viernes'), _('Sabado')]
        classes={'': 'sch_unchecked', '1': 'sch_instant', '2': 'sch_precoord'}
        titles={'': _('No disponible'), '1': _('Disponible para acceso instantaneo'),
                '2': _('Disponible para clases precoordinadas')}

        string = """
<script type="text/javascript">
<!--
function change_cell (tag) {
  var classes=new Array();
  classes[''] = 'sch_unchecked';
  classes['1'] = 'sch_instant';
  classes['2'] = 'sch_precoord';
  var titles = new Array();
  titles[''] = '""" + _('No disponible') + """';
  titles['1'] = '""" + _('Disponible para acceso instantaneo') + """';
  titles['2'] = '""" + _('Disponible para clases precoordinadas') + """';

  var input = tag.getElementsByTagName('input')[0];
  if (!input) return;
  parts = input.value.split('a');
  var sel = document.getElementById('sch_kind');
  if (!sel) return;
  opts = sel.getElementsByTagName('input');
  if (opts[0].checked) { var opt = '1' }
  else if (opts[1].checked) { var opt = '2' }
  else {
     alert('""" + _('No ha seleccionado un tipo de horario!') + """');
     var opt = '';
  }
  if (parts[1] == opt) { opt = '' }
  input.value = parts[0] + 'a' + opt;
  tag.className = classes[opt];
  tag.title = titles[opt];
}
-->
</script>
<form action="" method="get">
  <fieldset class="sched" id="sch_kind">
   <legend>""" + _('Tipo de horarios') + """</legend>
   <p class="sch_instant"><label for="instant"><input id="instant" type="radio" name="kind" value="1" checked="checked" />
           """ + _('Acceso instantaneo') + """</label></p>
   <p class="sch_precoord"><label for="precoord"><input id="precoord" type="radio" name="kind" value="2" />
           """ + _('Clases precoordinadas') + """</label></p>
  </fieldset>
</form>
<form action="" method="get">
  <div>
  <table id="schedule">
    <tr>
      <th></th>
"""
        for day in days:
            string += '<th class="sch_header">%s</th>\n' % day
        for hour in range(48):
            string += '</tr><tr>\n<td class="sch_row">%d:%02dhs</td>\n' % (hour / 2, (hour % 2) * 30)
            for day in enumerate(days):
                pos = 48 * day[0] + hour
                val = checks[pos]
                string += '<td class="%s" title="%s" onclick="change_cell(this)"><input type="text" name="sch" value="%da%s" /></td>\n' % (classes[val], titles[val], pos, val)
        string += """
   </tr><tr><td class="sch_row">24:00hs</td>\n</tr></table>
   <input type="hidden" name="user_id" value="%d"/>
   <input type="submit" name="submit" value=\"""" % userId + _('Enviar') + """\" />
   </div>
  </form>
"""
        request.write(string)
        return

    def addSchedule(self,userId, sched, kind):
        operation = "insert into tutor_schedule \
                    (fk_tutor, time_start, time_end, schedule_type) \
                    values (%d, %s, %s, %d)"
        return self.db.db.runOperation(operation, (userId, str(sched[0]), str(sched[1]), kind))
Example #2
0
class WebPerson(Resource):
    _ = dummyTranslator
    fields = [{'name': 'username', 'pos': 1, 'desc': _('Nombre de usuario'), \
         'required': True, 'isPass': False, 'maxlength': 80, 'query': "person"},
        {'name': 'password', 'pos': 2, 'desc': _('Contrasena'), \
         'required': True, 'isPass': True, 'maxlength': 80, 'query': "person"},
        {'name': 'password2', 'pos': 2, 'desc': _('Repita contrasena'), \
         'required': True, 'isPass': True, 'maxlength': 255, 'query': ""},
        {'name': 'first_name', 'pos': 3, 'desc': _('Nombre'), 'required': True, \
         'isPass': False, 'maxlength': 255, 'query': "person"},
        {'name': 'last_name', 'pos': 4, 'desc': _('Apellido'), 'required': True, \
         'isPass': False, 'maxlength': 255, 'query': "person"},
        {'name': 'email', 'pos': 5, 'desc': _('eMail'), 'required': True, \
         'isPass': False, 'maxlength': 255, 'query': "person"}]

    def __init__(self, table, title, kind, query, empty, xtra_fields):
        _ = dummyTranslator
        self.db = DBConnect()
        self.render_POST = self.render_GET
        self.template = WebTemplates()
        self.table = table
        self.title = title
        self.kind = kind
        
        self.query = query
        self.empty = empty
        self.fields = WebPerson.fields + xtra_fields
        Resource.__init__(self)
        

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        request.write(self.template.startPage(session, self.title))
        d = defer.maybeDeferred(lambda :None)

        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        elif session.kind == ADMIN:
            try:
                user_id = int(request.args.get('user_id', [-1])[0])
                msg = '<h2>' + self.title + ": " + _('Datos personales') + '</h2> ' + \
                    _('Recuerde que los campos indicados con <sup>*</sup> son obligatorios<br>') 
                if user_id!=-1: 
                    msg += _('Si desea conservar la contraseña actual deje los campos en blanco') + '<br/>' 
                

    # La función que procesa e imprime el contenido de la pagina
                self.printContent(request, d, user_id, msg)
            except ValueError:
                request.write(self.template.unexpectedArguments(session, \
                    _('user_id deberia ser entero')))
        # 3) Administra sus propios datos
        elif session.kind == self.kind:
            user_id = session.userId
            msg = '<h2>' + _('Tus Datos personales') + '</h2>' + \
                _('Recuerda que los campos indicados con <sup>*</sup> son obligatorios')
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id, msg)
        else:
        # 4) Es alguien que no está autorizado a administrar materias
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())

        return server.NOT_DONE_YET

    def checkRequest(self, d, request):
        session = request.getSession()
        _ = session._
        args = dict([(i, request.args[i][0]) for i in request.args.keys()])
        if "submit" in request.args.keys():
            for value in self.fields:
                if value['name'] not in args.keys():
                    args[value['name']] = ''
                    d.addCallback(lambda a: \
                        request.write(self.template.unexpectedArguments(session, \
                        _('Falta el argumento \'%s\'') % value['name'])))
                elif len(args[value['name']]) > value['maxlength']:
                    args[value['name']] = args[value['name']][:value['maxlength']]
                    d.addCallback(lambda a: \
                        request.write(self.template.unexpectedArguments(session, \
                        _('Longitud excesiva del argumento \'%s\'') % value['name'])))
            if(args['password'] != args['password2']):
                request.write(self.template.unexpectedArguments(session, \
                    _('Las contrasenas no coinciden')))

            if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", args['email']) == None:
                request.write(self.template.unexpectedArguments(session, \
                    _('El email ingresado es incorrecto')))

        return args

    def printContent(self, request, d, userId, msg):
        # si se estan enviando datos
        _ = request.getSession()._
        
       
        #si se trata de una edicion las contraseñas no son requeridas. 
	#Dejarlas en blanco es la forma de no modificarlas 

        if int(request.args.get('user_id', [-1])[0])!=-1:
            self.fields[1]['required'] = self.fields[2]['required'] = False
        else:
            self.fields[1]['required'] = self.fields[2]['required'] = True
        
        
        args = self.checkRequest(d, request)

        if "submit" in args.keys():
            # si tenemos que actualizar
            if userId > 0:
                person = []
                kind = []
    
                #si se ha modificado, encripto el nuevo password
                if args['password']!="":
                    args['password'] = sha.new(args['password']).hexdigest() 
                
                for field in self.fields:
                    if field['query'] == "person":
                        #si los password estan en blanco no se incluyen en la query de actualizacion                       
                        if not(field['name']=='password' and args['password']==""):
                            person.append(field['name'] + " = '" + args[field['name']] + "'")
                    elif field['query'] == self.table:
                        kind.append(field['name'] + " = '" + args[field['name']] + "'")
                person = ", ".join(person)
                kind = ", ".join(kind)
                update_person = "update person set " + person + " where id = %s"
                update_kind = "update " + str(self.table) + " set " + kind + " where id=%s"
                d.addCallback(lambda a: self.db.db.runOperation(update_person, (userId,)))
                if self.table != "admin":
                    d.addCallback(lambda a: self.db.db.runOperation(update_kind, (userId,)))
                d.addCallback(lambda a: request.write("""<div class="message">""" + \
                    _('Datos actualizados con exito') + """</div>""") or userId)
            #antes de insertar debemos chequear si el usuario ya existe
            else:
                query = "select username from person where username = %s"
                username = args['username']
                d.addCallback(lambda a: self.db.db.runQuery(query, (username,)))
                d.addCallback(self._insertDB, request, args)
        else:
            d.addCallback(lambda a:userId)
        d.addCallback(self._requestData, request, msg)

        d.addErrback(self.printError, request)
        d.addCallback(self.printForm, request, args, userId)

    def _requestData(self, userId, request, msg):
        request.write(msg)
        # no se estan mandando datos, se los solicita
        if userId > 0:
            d = self.db.db.runQuery(self.query, (userId,))
            return d
        # ni se mandan ni se solicitan datos (formulario en blanco)
        else:
            return self.getEmptyRow(None, self.empty)

    def printError(self, failure, request):
        """Imprime el error de failure y genera una fila
        vacia para la consulta de la base de datos
        """
        session = request.getSession()
        d = defer.maybeDeferred(lambda :None)
        d.addCallback(lambda a: request.write("""<div class="error"> %s </div>""" % \
            failure.getErrorMessage()))
        d.addCallback(self.getEmptyRow, self.empty)
        return d

    def _insertDB(self, rows, request, args):
        """inserta una persona en la base de datos y llama a la
        función que inserta a la misma persona como self.kind
        """
        session = request.getSession()
        _ = session._
        if len(rows) == 0:
            person_name = []
            person_value = []
            
            #encripto el password
            if args['password']!="":
                args['password'] = sha.new(args['password']).hexdigest()  
            
            for field in self.fields:
                if field['query'] == "person":
                    person_name.append(field['name'])
                    person_value.append("'" + args[field['name']] + "'")
                    
            person_name = ", ".join(person_name) + ", language, fk_timezone, demo"
            person_value = ", ".join(person_value) + \
              ", " + str(session.locale_id) + ", 2, False"
            person_op = "insert into person (kind, " + person_name + ") values \
                (%d"+ ", " + person_value + ")"
                
            d = self.db.db.runOperation(person_op, (self.kind,))        
            
            if self.table != "admin":
                query = "select id from person where username=%s"
                username = QuotedString(args['username'])
                d.addCallback(lambda a: self.db.db.runQuery(query, (username,)))
                d.addCallback(self.insertKind, request, args)
            else:
                d.addCallback(lambda a: request.write("""<div class="message">""" + \
                    _('Administrador ingresado con exito') + """</div>"""))
            
            
            return d
        else:
            return failure.Failure(_('El usuario %s ya existe en el sistema') % \
                args['username'])

    def insertKind(self, rows, request, args):
        """Inserta un usuario en la base de datos de acuerdo a los
        datos de rows
        """
        _ = request.getSession()._
        assert(len(rows) == 1)


        kind_name = []
        kind_value = []
        for field in self.fields:
            if field['query'] == self.table:
                kind_name.append(field['name'])
                kind_value.append("'" + args[field['name']] + "'")

        kind_name = ", ".join(kind_name)
        kind_value = ", ".join(kind_value)

  
        kind_op = "insert into " + self.table + "(id, " + kind_name + ") values \
            (%d"+ ", " + kind_value + ")"
            
        
            
        d = self.db.db.runOperation(kind_op, (rows[0][0],))
        d.addCallback(lambda a: request.write("""<div class="message">""" + \
            _('Usuario ingresado con exito') + """</div>""") or rows[0][0])
        return d

    def getEmptyRow(self, data, size):
        """Devuelve una consulta vacia de tamaño size"""
        return [[""] * size]

    def printCheckArgs(self, request):
        """Para cada diccionario de la lista fields chequea si el campo es
        obligatorio y arma la funcion de JavaScript para el chequeo de datos.
        Agrega a continuacion el chequeo de que las contraseñas coincidan
        """
        _ = request.getSession()._
        page = """
<script type="text/javascript" src="/static/js/valid.js"></script> \n
<script type="text/javascript">\n function check_args(form){
message='';"""

        for i in self.fields:
            if i['required']:
                page += 'if(form.%s.value == "") message += "- ' % i['name'] + \
                  _('El campo %s es obligatorio') % _(i['desc']) + '\\n";\n'
        page += """if(form.password.value != form.password2.value)
        message += \"- """ + _('Las contraseñas no coinciden') + """\";\n"""

        page += """if(!isEmailAddress(form.email))
        message += \"\\n- """ + _('El email ingresado es incorrecto') + """\"\n;


    if(message){
        alert(" """ + _('Error en el ingreso de datos:') + """\\n"+message+"\\n");
        return false;
    }else{
        return true;
    }
}
</script>
"""
        request.write(page)
        return

    def printForm(self, row, request, args, userId):
        """Para cada diccionario de la lista fields arma el campo del
        formulario correspondiente.
        """
        _ = request.getSession()._
        if len(row) == 0:
            request.write(self.template.unexpectedArguments(request.getSession(), \
                _('El usuario solicitado no existe')))
            row = self.getEmptyRow(None, self.empty)

        self.printCheckArgs(request)
        page = """<form action="" method="post" \
            onsubmit="return check_args(this)"><div> """
        for i in self.fields:
            value = args.get(i['name'], row[0][i['pos']])
            required = i['required'] and "<sup>*</sup>" or ""
            text = i['isPass'] and "password" or "text"
            #dejo los campos password en blanco por defecto.
            if value is None or i['name']=='password' or i['name']=='password2':
                value = ''

            page += """<label for='%s'>%s%s: <input type='%s' name='%s'
size="20" value='%s' maxlength="%d" id="%s" /></label><br/>\n""" % (i['name'], _(i['desc']), required, text, i['name'], value, i['maxlength'], i['name'])
        page += """<input type="submit" id="submit" name="submit" value=\"""" + _('Guardar') + """\"/>"""
        if userId > 0:
            page += """<input type="hidden" name="user_id" value='%s'/>""" % userId
        page += """</div></form>"""
        request.write(page)
        return
Example #3
0
class WebPCArrangeCommon(Resource):
    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    # Si estamos autenticados como admin, sirve para coordinar clases para cualquier alumno.
    # Si somos alumno, sirve para coordinar clases propias.
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans

        msg = '<div id="pchelp"><h3>' + _('Pasos para precoordinar una clase') + \
              '</h3><ol class="steps"><li class="one">' + _('Elige la materia') + \
              '</li><li class="two">' + _('Elige el tutor') + '</li><li class="three">' + \
              _('Elige el horario') + '</li></ol></div>\n'

        msg = msg + self.stepMessage(session)

        # 0) Se empieza la página
        request.write(self.template.startPage(session, _('Modificacion de horarios')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
        # 2.1) Admin debe proveer el argumento user_id
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, _('falta el parametro user_id')))
        # 3) Si es Pupil, coordina sus propias clases
        elif session.kind == PUPIL:
            user_id = session.userId
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id, msg)
        else:
        # 4) Si no es ni ni Admin, ni Pupil, ni nadie, es alguien que no está
        #    autorizado a administrar horarios
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def packSchedule(self, checks):
        try: # Mapeamos a integer y filtramos valores inadecuados
            checks = [int(chk) for chk in checks]
        except ValueError:
            return []
        checks.sort()

        scheds = []
        last_hour = None
        start_time = None
        end_time = None
        for hour in checks:
            if last_hour is None:
                start_time = hour
            elif last_hour < hour - 1:
                scheds.append((start_time, end_time))
                start_time = hour
            last_hour = hour
            end_time = hour + 1
        # Falta el último span, que lo agregamos ahora:
        if end_time is not None:
            if end_time == LASTDAY_MIDNIGHT:
                if start_time == 0: # Este tipo labura 24/7!
                    scheds.append((0, end_time))
                elif len(scheds) > 0 and scheds[0][0] == 0: # El horario abarca las 0 del domingo
                    scheds.append((start_time, end_time + scheds[0][1]))
                    del(scheds[0])
                else:
                    scheds.append((start_time, end_time))
            else:
                scheds.append((start_time, end_time))
        # Convertimos a DateTime

        spans = []
        base = today() + 3
        def mktimestamp(x):
            day = base + x / 48

            #VER 
            #incluir DateTimeDelta del userId
            return DateTime(day.year, day.month, day.day, (x % 48) / 2, (x % 2) * 30)
        for sched in scheds:
            spans.append((mktimestamp(sched[0]), mktimestamp(sched[1])))
        return spans

    def scheduleDescription(self, scheds, request, withDay):
        session = request.getSession()
        _ = session._
        days = [_('lunes'), _('martes'), _('miercoles'), _('jueves'), _('viernes'), _('sabado'), _('domingo')]
        desc = ''
        for sch in scheds:
            if sch[0].day == sch[1].day:
                if withDay:
                    desc += days[sch[0].day_of_week] + ' ' + sch[0].strftime("%d-%m-%Y") + \
                            ', ' + _('de') + ' ' + sch[0].strftime('%H:%M') + \
                            ' ' + _('a') + ' ' + sch[1].strftime('%H:%M')
                else:
                    desc += days[sch[0].day_of_week] + ' ' + _('de') + ' ' + \
                            sch[0].strftime('%H:%M') + ' ' + _('a') + ' ' + \
                            sch[1].strftime('%H:%M')
            else:
                if withDay:
                    desc += _('de') + ' ' + days[sch[0].day_of_week] + ' ' + \
                            sch[0].strftime('%d-%m-%Y, %H:%M') + ' ' + _('a') + \
                            ' ' + days[sch[1].day_of_week] + ' ' + \
                            sch[1].strftime('%d-%m-%Y, %H:%M')
                else:
                    desc += _('de') + ' ' + days[sch[0].day_of_week] + ' ' + \
                            sch[0].strftime('%H:%M') + ' ' + _('a') + ' ' + \
                            days[sch[1].day_of_week] + ' ' + sch[1].strftime('%H:%M')
            desc += '<br />'
        return desc
Example #4
0
class WebMyPupilsInfo(Resource):
    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para ver los alumnos de cualquier cliente
    # Si somos cliente, sólo podremos ver los propios
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

        msg = """<h2>""" + _('Cuentas de alumnos') + """</h2>"""

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        request.write(self.template.startPage(session, \
         _('Informacion de cuentas de usuarios')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
        # 2.1) Admin debe proveer el argumento user_id
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
                    d.addCallback(lambda a: self.requestData(user_id))
                    d.addCallback(self.printTitle, request)
                    self.printContent(request, d, user_id)
        # La función que procesa e imprime el contenido de la pagina
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                     _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                 _('falta el parametro user_id')))
        # 3) Si es cliente, muestra la información de alumnos propios
        elif session.kind == CLIENT:
            user_id = session.userId
            d.addCallback(lambda a: self.requestData(user_id))
            d.addCallback(self.printTitle, request)
            self.printContent(request, d, user_id)
        else:
        # 4) Si no, es alguien que no está autorizado
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def requestData(self, user_id):
        query = "select p.first_name, p.last_name, c.organization from person p, \
                 client c where c.id = p.id and p.id = %s"
        d = self.db.db.runQuery(query, (user_id,))
        return d

    def printTitle(self, data, request):
        _ = request.getSession()._
        if len(data) != 1:
            msg = """<h2>""" + _('Cuentas de alumnos') + """</h2>"""
        else:
            client = "%s %s (%s)" % (data[0][0], data[0][1], data[0][2])
            msg = """<h2>""" + _('Cuentas de alumnos de %s') % client + """</h2>"""
        request.write(msg)



    def printContent(self, request, d, userId):
        # 1) Si se envían datos, se actualiza la base primero
        _ = request.getSession()._
        # 3) Se buscan los datos en la base
        query = "select username, password, first_name, last_name, email, \
          ai_available, pc_available, expires from pupil a, person p \
          where p.id = a.id and fk_client= %d"
        d.addCallback(lambda a: self.db.db.runQuery(query, (userId, )))
        # 4) Se imprime los datos
        d.addCallback(self.printForm, request, userId)
        return d


    def printForm(self, rows, request, userId):
        _ = request.getSession()._
        string = ""
        fields = [{'pos': 0, 'desc': _('Nombre de usuario')},
                  {'pos': 1, 'desc': _('Constrasena')},
                  {'pos': 2, 'desc': _('Nombre')},
                  {'pos': 3, 'desc': _('Apellido')},
                  {'pos': 4, 'desc': _('eMail')},
                  {'pos': 5, 'desc': _('Hs. AI restantes')},
                  {'pos': 6, 'desc': _('Hs. CP restantes')},
                  {'pos': 7, 'desc': _('Vencimiento')}]

        if len(rows) == 0:
            string += '<div class="message"><b>' + \
              _('No se registran alumnos a cargo') + '</b></div>'
        else:
            string += _('Informacion de %d alumnos') % len(rows) + ':<br/>'
            for pupil in rows:
                string += '<div class="pupil_info"><ul>'
                for f in fields:
                    string += '<li><b>' + f['desc'] + ': </b> ' + self.getFormat(pupil[f['pos']], f['pos']) + '</li>'
                string += '</ul></div><br/>'

        request.write(string)
        return

    def getFormat(self, data, pos):
        if pos == 7:
            return data.Format(DATETIME_FORMAT)
        else:
            return str(data)
Example #5
0
class WebClientReport(Resource):
    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Muestra un acceso a Listado de datos personales de alumnos (para recortar)
    # y Detalle de horas por alumno
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        request.write(self.template.startPage(session, _('Reportes de alumnos')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
        # 2.1) Admin debe proveer el argumento user_id
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                        _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                    _('falta el parametro user_id')))
        # 3) Si es Cliente, administra sus propios horarios
        elif session.kind == CLIENT:
            user_id = session.userId
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id)
        else:
        # 4) Si no es ni ni Admin, ni Cliente, ni nadie, es alguien que no está
        #    autorizado a administrar alumnos
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def printContent(self, request, d, userId):
        d.addCallback(lambda a: self.requestData(userId))
        d.addCallback(self.printData, request, userId)
        return d

    def requestData(self, userId):
        query = "select p.first_name, p.last_name, c.organization \
                 from person p, client c where c.id = p.id and p.id = %s"
        d = self.db.db.runQuery(query, (str(userId),))
        return d

    def printData(self, data, request, userId):
        session = request.getSession()
        user = (session.kind == ADMIN) and "?user_id=%s" % (str(userId),) or ""
        _ = session._
        if len(data) != 1:
            string = '<div class="error">' + _('El usuario no existe en el sistema') \
                + '</div>'
        else:
            client = "%s %s (%s)" %(data[0][0], data[0][1], data[0][2])
            string = """<h2>""" + _('Reportes de alumnos de %s') % client \
                + """</h2>""" + _('Seguimiento de alumnos')
            string += "<div id='client_menu'><ul>" + \
            '<li> <a href="/my_pupils_info%s">' % user + \
                _('Datos personales:') +  ' </a> ' + \
                _('Listado de datos personales los alumnos a cargo') + \
                '</li><li> <a href="/my_pupils%s">' % user + _('Horas:') + ' </a> ' + \
                _('Detalle de las horas usadas y disponibles por alumno') + \
                '</li></ul></div>' + '<a href="javascript:history.back()" id="back">' + \
                _('Volver') + '</a>'
        request.write(string)
        return
Example #6
0
class WebTutorSessions(Resource):
    _ = dummyTranslator

    typeToString = {IACLASS: _('Acceso Instantaneo'), PACLASS: _('Clase Precoordinada'), WAITING: _('En espera'), OFFLINE_QUESTION: _('Pregunta offline'), EXTRA_IACLASS: _('AI (Fuera de turno)'), EXTRA_WAITING: _('Espera (Fuera de turno)'), DECIDING: _('Analizando pregunta'), ABSENT: _('Ausente'), POST_PROCESS: _('Postprocesado')}.get

    typeToStyle = {IACLASS: "ia_row", PACLASS: "pc_row", WAITING: "waiting_row", OFFLINE_QUESTION: "offline_row", EXTRA_IACLASS: "extra_ia_row", EXTRA_WAITING: "extra_waiting_row", DECIDING: "deciding_row", ABSENT: "absent_row", POST_PROCESS: "postprocess_row"}.get

    eCodeToString = {NORMAL: _('Fin horario'), TUTOR_ENTER: _('Arribo'), PUPIL_ENTER: _('Entrada de alumno'), TUTOR_END: _('Terminada por Tutor'), PUPIL_END: _('Terminada por alumno'), TUTOR_QUIT: _('Desconexion Tutor'), SERVER_RESTART: _('Reconexion servidor'), QUESTION_ANSWERED: _('Pregunta contestada'), QUESTION_NOT_ANSWERED: _('Pregunta no contestada'), ACCEPTED: _('Pregunta aceptada'), REJECTED: _('Pregunta no aceptada'), CORRECTED: _('Postprocesado'), NOT_CORRECTED: _('No postprocesado'), None: '-'}.get

    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para modificar las
    # materias de cualquier tutor.
    # Si somos tutor, sirve para modificar solo los propios.
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        request.write(self.template.startPage(session, \
          _('Historial de sesiones del tutor')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
                    msg = '<h2>' + _('Sesiones del tutor') + '</h2>'
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                      _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                  _('falta el parametro user_id')))
        # 3) Si es Tutor, ve sus propias sesiones
        elif session.kind == TUTOR:
            user_id = session.userId
            msg = '<h2>' + _('Tus sesiones') + '</h2>' + \
              _('Este es el detalle de tus sesiones en el sistema:') + '<br/>'
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id, msg)
        else:
        # 4) Si no es ni ni Admin, ni Tutor, ni nadie, es alguien que no está
        #    autorizado a administrar horarios
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d


    def printContent(self, request, d, user_id, msg):
        """Consulta las sesiones del tutor user_id en la
         base de datos y las manda a imprimir
         """
        try:
            pag = int(request.args['pag'][0])
                    
        except:
            pag = 0
        
        d.addCallback(lambda a: request.write(msg))
        now = DateTime.now()
        query =  """select s.session_type, s.time_start, s.time_end, s.error_code, \
         p.username, p.id, (select count(*) from session s left join person p on (p.id = s.fk_pupil) \
         where fk_tutor = %d and s.time_end < '%s') from session s left join person p on (p.id = s.fk_pupil) \
         where fk_tutor = %d and s.time_end < '%s' order by time_start desc LIMIT %d OFFSET %d"""
        d.addCallback(lambda a: self.db.db.runQuery(query, (user_id, now,user_id, now,ITEMS_PAG, ITEMS_PAG*pag)))
        d.addCallback(self.printData, request, pag)
        return d

    def printData(self, rows, request,pag):
        _ = request.getSession()._
                    
        if len(rows) == 0:
            string = _('No se registran sesiones') + '<br/>'
            def paginacion(): pass
        else:
            total = rows[0][-1:][0] #la ultima columna es el total de datos para la consulta
            try:            
                user_id = int(request.args['user_id'][0])
            except:
                pass
                            
            def paginacion():
                actual = pag
                if total > ITEMS_PAG:
                    request.write('<div style="text-align: left;"> <strong>' + _('Página:') + '</strong>')
                    for pagina in range(int(total/ITEMS_PAG)+1):
                        tip = "href"
                        if pagina == actual:
                            tip = "id"
                        link = "<a %s='/tutor_sessions?user_id=%d&pag=%d'>%d</a>&nbsp;" % (tip,user_id,pagina,pagina+1)
                        request.write(link)
                    request.write('</div><br />')
                   
            


            if total < ITEMS_PAG:
                lim = total
            else:
                lim = ITEMS_PAG
            string = _('Mostrando %d a %d de %d sesiones:') % (ITEMS_PAG*pag+1, lim*(pag+1), total)
            string += """
<table class="table_list" id="sessions">
 <tr>
  <th class="header_list">""" + _('Tipo de sesion') + """</th>
  <th class="header_list">""" + _('Comienzo') + """</th>
  <th class="header_list">""" + _('Fin') + """</th>
  <th class="header_list">""" + _('Duracion') + """</th>
  <th class="header_list">""" + _('Razon cierre') + """</th>
  <th class="header_list">""" + _('Alumno') + """</th>
 </tr>
"""
            for row in rows:
                session_type = _(self.typeToString(row[0], ''))
                style = _(self.typeToStyle(row[0]))
                start = row[1].Format(DATETIME_FORMAT)
                end = row[2].Format(DATETIME_FORMAT)
                diff = self.dateDiffFormat(row[2] - row[1])
                pupil = (row[4] is not None) and row[4] or ""
                pupil_id = (row[5] is not None) and row[5] or ""
                reason = _(self.eCodeToString(row[3], '-'))
                string += """
<tr class="%s">
 <td>%s</td>
 <td>%s</td>
 <td>%s</td>
 <td>%s</td>
 <td>%s</td>
 <td> <a href="/userinfo?user_id=%s&amp;kind=%d"> %s </a> </td>
</tr>""" % (style, session_type, start, end, diff, reason, pupil_id, PUPIL, pupil)
            string += """</table>"""
        request.write(string)
        paginacion()
        return

    def dateDiffFormat(self, date):
        hours = int(date.hours)
        minutes = int(date.minutes)
        seconds = int(date.seconds)
        return "%02d:%02d:%02d" % (hours, minutes % 60, seconds % 60)
Example #7
0
class WebTutorInfo(Resource):
    _ = dummyTranslator
    MAX_TYPE = POST_PROCESS + 1
    session_types = [{'code': IACLASS, 'desc': _('A.I.'), 'arr': 0},
    {'code': PACLASS, 'desc': _('C.P.'), 'arr': 1},
    {'code': EXTRA_IACLASS, 'desc': _('Sin turno'), 'arr': 2},
    {'code': OFFLINE_QUESTION, 'desc': _('Preguntas offline'), 'arr': 3},
    {'code': WAITING, 'desc': _('En espera'), 'arr': 4},
    {'code': EXTRA_WAITING, 'desc': _('En espera (Sin turno)'), 'arr': 5},
    {'code': ABSENT, 'desc': _('Ausente'), 'arr': 6},
    {'code': POST_PROCESS, 'desc': _('Postprocesado'), 'arr': 7}]

    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para modificar las materias de
    # cualquier tutor.
    # Si somos tutor, sirve para modificar solo los propios.
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        header = """
<link rel="stylesheet" type="text/css" media="all" href="/calendar/calendar-win2k-cold-1.css" title="win2k-cold-1" />
<script type="text/javascript" src="/calendar/calendar.js"></script>
<script type="text/javascript" src="/calendar/lang/calendar-sp.js"></script>
<script type="text/javascript" src="/calendar/calendar-setup.js"></script>"""

        request.write(self.template.startPageWithHeader(session, header, \
         _('Informacion de tutores')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
            msg = '<h2>' + _('Informacion de los tutores del sistema') + '</h2>'
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, msg)
        else:
        # 4) Si no es Admin es alguien que no está
        #    autorizado a ver la información de tutores
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def printContent(self, request, d, msg):
        """Consulta los datos de tutores de la base de datos y los manda
        a imprimir
        """
        args = self.checkRequest(d, request)
        try:
            pag = int(request.args['pag'][0])
        except:
            pag = 0
            
        d.addCallback(lambda a: request.write(msg))
        d.addCallback(lambda a: self.printForm(request, args))
        d.addCallback(lambda a: self.requestData(request, args['start'], args['end'],pag))
        d.addCallback(self.printData, request,pag)
        return d


    def requestData(self, request, time_start, time_end, pag):
        """Consulta los datos de los tutores en la tabla session con los límites de
        fecha dados por time_start y time_end
        """
        
        query = "select p.username, p.id, sum(dmin('%s', s.time_end) - \
          dmax('%s', s.time_start)) as total, s.session_type, (select count(*) \
          from person p, tutor t where p.id = t.id) from person p, \
          tutor t left join session s on (s.fk_tutor = t.id and \
          s.time_start < '%s' and s.time_end > '%s') where t.id = p.id \
          group by p.id, p.username, s.session_type \
          order by username, session_type"
        
        
        query += " LIMIT %d OFFSET %d" %  (ITEMS_PAG, ITEMS_PAG*pag)
        d = self.db.db.runQuery(query, ((time_end, time_start) * 2))
        d.addCallback(self.requestTotal, time_start, time_end)
        return d

    def requestTotal(self, rows, time_start, time_end):
        """recupera los totales de TODOS los tutores en una lista session_type | total"""
        
        query = "select  s.session_type, extract(epoch from sum(dmin('%s', s.time_end) \
            - dmax('%s', s.time_start))/3600 ) as total  from person p, tutor t join session s on \
            (s.fk_tutor = t.id and s.time_start < '%s' and s.time_end > '%s') where \
            t.id = p.id group by s.session_type order by s.session_type"
        d = self.db.db.runQuery(query, ((time_end, time_start) * 2))
        d.addCallback(lambda b: (rows, b))
        return d

    def printData(self, rowsAndTotales, request, pag):
        _ = request.getSession()._
        
        rows, totales = rowsAndTotales
        colDatos = {}
        for col in totales:
            colDatos[col[0]] = col[1]
        
        length = len(rows)
        string = ""
        if length == 0:
            string += _('No hay resultados disponibles') + '<br/>'
        else:
            #averiguo cuantos usuarios distintos hay
            i = 0
            current = rows[0][0]
            count = 1
            while i < length:
                if rows[i][0] != current:
                    current = rows[i][0]
                    count = count + 1
                i = i + 1
            #inicializo matriz resultado
            res = [[0] * self.MAX_TYPE for i in range (0,count)]
            #inicializo matriz sumas
            sum = [0] * self.MAX_TYPE

            j = 0 #marca la fila de res
            curr_row = 0 #marca la fila de rows
            current = rows[0][0]
            res[0][0] = (rows[0][0], rows[0][1])
            while(curr_row < length):
                if rows[curr_row][2] != None:
                    res[j][rows[curr_row][3]] = (rows[curr_row][2]).hours
                    sum[rows[curr_row][3]] += (rows[curr_row][2]).hours
                curr_row = curr_row + 1
                if curr_row < length and rows[curr_row][0] != current:
                    current = rows[curr_row][0]
                    j = j + 1
                    res[j][0] = (rows[curr_row][0], rows[curr_row][1])

            #string = _('Informacion de %d tutores:') % count + '<br/>'
            string += '<table class="table_list"><tr class="header_list"> '
            string += '<th>' + _('Tutor') + '</th>'
            for i in self.session_types:
                string += '<th>' + _(i['desc']) + '</th>'
            string += '</tr>'

            for row in res:
                string += '<tr style="text-align: center">'
                string += '<td style="text-align: left">'
                string += '<a href="/tutor_sessions?user_id=%s">%s</a></td>' \
                   % (row[0][1], row[0][0])

                for i in self.session_types:
                    data = row[i['code']]
                    string += '<td>%.2f hs.</td>' % data
                string += '</tr>'
            string += '<tr class="last_row">'
            string += '<td>' + _('Subtotal') + '</td>'
            for i in self.session_types:
                string += '<td>%.2f hs.</td>' % sum[i['code']]
            string += '</tr>'
            
            #imprimo los totales. 
            string += '<tr class="last_row">'
            string += '<td>' + _('Total') + '</td>'
            for i in self.session_types:
                if i['code'] in colDatos.keys():
                    string += '<td>%.2f hs.</td>' % colDatos[i['code']]
                else:
                    string += '<td>%.2f hs.</td>' % 0.0               

            string += '</tr></table>'
        
        request.write(string)
        #PAGINACION
        try:      
            total = rows[0][-1:][0] #la ultima columna es el total de datos para la consulta
            if total > ITEMS_PAG:
                request.write('<div> <strong>' + _('Página:') + '</strong>')
                if total % ITEMS_PAG == 0:
                    una_mas = 0
                else:
                    una_mas = 1                
                for pagina in range(int(total/ITEMS_PAG)+una_mas):
                    tip = "href"
                    if pagina == pag:
                        tip = "id"
                    link = "<a %s='/tutor_info?pag=%d'>%d</a>&nbsp;" % (tip,pagina,pagina+1)
                    request.write(link)
                request.write('</div><br />')
        except IndexError:
            pass
        #FIN PAGINACION


        return

    def dateFormat(self, date):
        return (date != 0) and date.hours or 0

    def checkRequest(self, d, request):
        """
        Chequea si los campos de fecha vienen con datos (en cuyo caso arma la fecha con
        esos datos -notar que valores mal formateados generan la fecha de hoy-) o no
        (en cuyo caso genera una fecha por defecto)
        """
        session = request.getSession()
        args = dict([(i, request.args[i][0]) for i in request.args.keys()])
        try:
            args["start"] = DateTime.strptime(args["start"], DATE_FORMAT)
            end = DateTime.strptime(args["end"], DATE_FORMAT)
            # para tomar en cuenta todo el día del final
            args["end"] = end + DateTime.RelativeDateTime(days=+1)
        except (KeyError, DateTime.Error):
            now = DateTime.now()
            start = DateTime.DateTime(now.year, now.month)
            args["start"] = start
            end = DateTime.now()
            # para tomar en cuenta todo el día del final
            args["end"] = end + DateTime.RelativeDateTime(days=+1, hour=0,minute=0,second=0)
            return args
        return args

    def printForm(self, request, args):
        _ = request.getSession()._
        start = args['start'].Format(DATE_FORMAT)
        end = (args['end'] - DateTime.RelativeDateTime(days=+1)).Format(DATE_FORMAT)
        string = """
<form action="#" method="get">
<table cellspacing="0" cellpadding="0" style="border-collapse: collapse">
<tr>
 <td>""" + _('Fecha Inicio:') + """</td>
 <td><input type="text" name='start' id="time_start" value="%s"/></td>
 <td><img src="/static/graphics/calendar.gif" width="16" height="16" alt=\"""" % start + _('Elegir fecha') + """\" title=\"""" + _('Elegir fecha') + """\" id="calendar_from" style="cursor: pointer; border: 1px solid black;"/> </td>
 <td>""" + _('(dd/mm/aaaa)') + """</td>
</tr>
<tr>
 <td>""" + _('Fecha Fin:') + """ </td>
 <td><input type="text" name="end" id="time_end" value="%s"/></td>
 <td><img src="/static/graphics/calendar.gif" width="16" height="16" alt=\"""" % end + _('Elegir fecha') + """\" title=\"""" + _('Elegir fecha') + """\" id="calendar_to" style="cursor: pointer; border: 1px solid black;"/> </td>
 <td>""" + _('(dd/mm/aaaa)') + """</td>
</tr>
<tr>
<td colspan="4" align="center"><input type="submit" name="submit" value=\"""" + _('Actualizar') + """\"/></td>
</tr>
</table>
</form>
<script type="text/javascript">
    Calendar.setup({
        inputField     :    "time_start",     // id of the input field
        ifFormat       :    "%s",      // formato de entrada
        button         :    "calendar_from",  // id del trigger
        align          :    "Tl",           // alineamiento
        singleClick    :    true
    });
    Calendar.setup({
        inputField     :    "time_end",     // id of the input field
        ifFormat       :    "%s",      // formato de entrada
        button         :    "calendar_to",  // id del trigger
        align          :    "Tl",           // alineamiento
        singleClick    :    true
    });
</script>
""" % (DATE_FORMAT, DATE_FORMAT)
        request.write(string)
        return
Example #8
0
class WebSubjectAdmin(Resource):
    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para ver, agregar y borrar materias
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        request.write(self.template.startPage(session, _('Administracion de materias')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
            msg = '<h2>' + _('Administracion de Materias') + '</h2>' + _('Estas son las materias disponibles en el sistema. Desde aqui se pueden agregar y borrar materias') + '<br/>'
        # La función que procesa e imprime el contenido de la pagina
            self.printContent(request, d, msg)
        else:
        # 4) Si no es Admin, es alguien que no está autorizado a
        # administrar materias
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def printContent(self, request, d, msg):
        # 1) Si se envían datos, se agrega
        try:
            pag = int(request.args['pag'][0])
        except:
            pag = 0        
        _ = request.getSession()._
        if "submit" in request.args.keys():
            op = "insert into subject (name) values (%s)"
            name = QuotedString(request.args['name'][0])
            d.addCallback(lambda a: self.db.db.runOperation(op, (name,)))
            d.addCallback(lambda a: request.write("""<div class="message"><h2>""" + \
             _('Materia agregada') + '</h2>' + \
             _('La materia ha sido guardada correctamente') + """</div>"""))
        elif "del" in request.args.keys():
            # si nos piden borrar, llamamos al metodo de borrar materias de
            # DBDelete, el cual borra la materia si no tiene referencias
            # y si no devuelve False
            erase = DBDelete(self.db)
            delete = int(request.args['del'][0])
            d.addCallback(lambda a: erase.deleteSubject(delete))
            d.addCallback(self.printSubjectDelete, request)
        # 2) Se imprime un mensaje de bienvenida configurable
        d.addCallback(lambda a: request.write(msg))
        # 3) Se buscan los datos nuevos en la base
        op = "select s.id, s.name, count(fk_subject), (select count(*) from subject) from subject s \
              left join tutor_subject t on (s.id = t.fk_subject) \
              group by s.id, s.name order by name asc"
              
        op += " LIMIT %d OFFSET %d" %  (ITEMS_PAG, ITEMS_PAG*pag)              
        d.addCallback(lambda a: self.db.db.runQuery(op))
        d.addCallback(self.printForm, request, pag)
        return d

#return confirm("¿Está seguro de borrar la materia" + subject + "?\n (" + tutors + " " + "tutores la tienen como seleccionada)");

    def printForm(self, rows, request, pag):
        """recibe el resultado de una consulta de materias e imprime la tabla que las
           muestra y permite borrarlas. ademas imprime un formulario para agregar
           materias (y el codigo JavaScript de chequeo correspondiente)
        """
        _ = request.getSession()._
        string = """
<script type="text/javascript">
function del_confirm(subject, tutors){
    string = \" """ + _('Esta seguro de borrar la materia') + """ \"+subject+\"?\\n\";
    if(tutors == 1){
        string += \"(""" + _('1 tutor la tiene como seleccionada') + """)\";
    }else if(tutors > 0){
        string += \"(\" + tutors + \" \" + \"""" + \
        _('tutores la tienen como seleccionada') + """)\";
    }
    return confirm(string);
}
</script>

<br/>
<table class="table_list" id="subjects">
 <tr>
  <th class="icon_list"></th>
  <th class="header_list">""" + _('Materia') + """</th>
  <th class="header_list">""" + _('# Tutores') + """</th>
 </tr>
"""
        for i in range(len(rows)):
            string += """
<tr>
<td class="row_list"><a href="?del=%d" onclick="return del_confirm('%s', %d)" class="link_image"><img src="/static/graphics/delete.gif" width="16" height="16" alt=\"""" %  (rows[i][0], rows[i][1], rows[i][2])+ _('Borrar') + """\" title=\"""" + _('Borrar') + """\"/></a></td>
<td class="row_list">%s</td>
<td class="row_list">%d</td>
</tr>""" % (rows[i][1], rows[i][2])
        string += """
</table>
<br/>
<script type="text/javascript">
function check_args(form){
    if(form.name.value == ""){
        alert(\"""" + _('El nombre de la materia no puede ser vacio') + """\");
        return false;
    }else{
        return true;
    }
}
</script>
<form action="" method="get" onsubmit="return check_args(this)" ><div>
<input type="text" name="name" id="name" size="20"/>
<input type="submit" name="submit" id="submit" value=\"""" + _('Insertar') + """\" size="15"/></div>
</form>
"""
        request.write(string)
        #PAGINACION
        try:        
            total = rows[0][-1:][0] #la ultima columna es el total de datos para la consulta
            print "total ", total
            if total > ITEMS_PAG:
                request.write('<div> <strong>' + _('Página:') + '</strong>')
                if total % ITEMS_PAG == 0:
                    una_mas = 0
                else:
                    una_mas = 1
                for pagina in range((total/ITEMS_PAG) + una_mas):
                    tip = "href"
                    if pagina == pag:
                        tip = "id"
                    link = "<a %s='/subject_admin?pag=%d'>%d</a>&nbsp;" % (tip,pagina,pagina+1)
                    request.write(link)
                request.write('</div><br />')
            #FIN PAGINACION
        except IndexError:
            pass        
        
        
        return

    def printSubjectDelete(self, result, request):
        """Chequea el resultado de la llamada al metodo de DBDelete para el borrado
           de una materia. Imprime el mensaje correspondiete, de acuerdo si la materia
           ha sido o no borrada
        """
        _ = request.getSession()._
        if result == False:
            msg = """<div class="error"><h2>""" + _('Materia no borrada') + """</h2>""" + \
                _('Existen clases por darse o preguntas por contestarse para esta materia')\
                 + """</div>"""
        else:
            msg = """<div class="message"><h2>""" + _('Materia borrada') + """</h2>""" + \
                _('La materia ha sido borrada correctamente') + """</div>"""
        request.write(msg)
Example #9
0
class WebMyPupils(Resource):
    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para ver los alumnos de cualquier cliente
    # Si somos cliente, sólo podremos ver los propios
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        request.write(self.template.startPage(session, \
         _('Informacion de cuentas de usuarios')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        msg = """<h2>""" + _('Cuentas de alumnos') + """</h2>"""
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
        # 2.1) Admin debe proveer el argumento user_id
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                     _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                 _('falta el parametro user_id')))
        # 3) Si es cliente, muestra la información de alumnos propios
        elif session.kind == CLIENT:
            user_id = session.userId
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id)
        else:
        # 4) Si no, es alguien que no está autorizado
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def printContent(self, request, d, userId):
        _ = request.getSession()._
        # 2) Si se envían datos, se actualiza la base primero
        d.addCallback(lambda a: self.requestData(userId))
        d.addCallback(self.printTitle, request)
        if "del" in request.args.keys():
            try:
                to_delete = int(request.args["del"][0])
                query3 = "select id from pupil where id = %d and fk_client = %d"
                d.addCallback(lambda a: self.db.db.runQuery(query3, (to_delete, userId)))
                d.addCallback(self.checkUser, userId, request)
            except ValueError:
                d.addCallback(lambda a: \
                 request.write(self.template.unexpectedArguments(session, \
                 _('user_id deberia ser entero'))))
        # 3) Se buscan los datos en la base
        query = "select c.ai_available, c.pc_available, count(p.id) \
          from client c left join pupil p on (p.fk_client = c.id) \
          where c.id = %d group by c.ai_available, c.pc_available"
        d.addCallback(lambda a: self.db.db.runQuery(query, (userId, )))
        d.addCallback(self.printClientInfo, request)
        query2 = "select a.id, last_name, first_name, ai_available, ai_total, \
           pc_available, pc_total, expires from person p, pupil a \
           where p.id = a.id and fk_client = %d"
        d.addCallback(lambda a: self.db.db.runQuery(query2, (userId, )))
        # 4) Se imprime los datos
        d.addCallback(self.printForm, request, userId)
        return d

    def checkUser(self, rows, userId, request):
        session = request.getSession()
        _ = session._
        d = defer.maybeDeferred(lambda: None)
        if len(rows) != 1:
            d.addCallback(lambda a: \
                 request.write(self.template.unexpectedArguments(session, \
                 _('No es alumno del cliente'))))
        else:
            erase = DBDelete(self.db)
            to_delete = str(rows[0][0])
            d.addCallback(lambda a: erase.deletePupil(to_delete))
            d.addCallback(lambda a: request.write('<div class="message">' + \
             _('El usuario ha sido borrado correctamente') + '</div>'))
        return d

    def requestData(self, userId):
        query = "select p.first_name, p.last_name, c.organization \
                 from person p, client c where c.id = p.id and p.id = %s"
        d = self.db.db.runQuery(query, (str(userId),))
        return d

    def printTitle(self, data, request):
        _ = request.getSession()._
        if len(data) == 1:
            client = "%s %s (%s)" % (data[0][0], data[0][1], data[0][2])
            msg = """<h2>""" + _('Cuentas de alumnos de %s') % client + """</h2>"""
        else:
            msg = """<h2>""" + _('Cuentas de alumnos') + """</h2>"""
        request.write(msg)
        return

    def printForm(self, rows, request, userId):
        """ recibimos [(first_name, last_name, ai_total, pc_total,
        ai_available, pc_available, expires)]
        """
        session = request.getSession()
        _ = session._

        string = ""

        if len(rows) != 0:
            taia = tait = tpca = tpct = 0
            string += """
<script type="text/javascript">
function del_confirm(pupil){
    return confirm(\"""" + _('Esta seguro de borrar el alumno') + """ \"+pupil+"?");
}
</script>
"""
            string += """<br/>
<table class="table_list" id="pupil_info">
 <tr>
  <th class="icon_list"></th>
  <th class="icon_list"></th>
  <th class="header_list">""" + _('Alumno') + """</th>
  <th class="header_list">""" + _('Horas AI (restan/total)') + """</th>
  <th class="header_list">""" + _('Horas PC (restan/total)') + """</th>
  <th class="header_list">""" + _('Vencimiento') + """</th>
 </tr>
"""
            for r in rows:
                aia = self.getFloatFormat(r[3])
                ait = self.getFloatFormat(r[4])
                pca = self.getFloatFormat(r[5])
                pct = self.getFloatFormat(r[6])
                taia += aia
                tait += ait
                tpca += pca
                tpct += pct
                link = (session.kind == ADMIN) and "&amp;user_id=%s" % (str(userId),) or ""
                string += """
<tr class="row_list">
 <td><a href="pupil_edit?pupil_id=%s%s" class="link_image"><img src="/static/graphics/modify.gif" width="16" height="16" alt=\"""" % (r[0], link) + \
  _('Modificar') + """\" title=\"""" + _('Modificar') + """\"/></a></td>
 <td><a href="?del=%s%s" class="link_image" onclick="return del_confirm('%s')"><img src="/static/graphics/delete.gif"  width="16" height="16" alt=\"""" % (r[0], link, r[2] + " " + r[1]) + _('Borrar alumno') + """\" title=\"""" + _('Borrar alumno') + """\"/></a></td>

 <td><a href="/userinfo?user_id=%s&amp;kind=%d">%s, %s</a></td>
 <td>%.1f/%.1f</td>
 <td>%.1f/%.1f</td>
 <td>%s</td>
</tr>
""" % (r[0], PUPIL, r[1], r[2], aia, ait, pca, pct, self.getDateFormat(r[7]))
            string += """
<tr>
 <td class="last_row"></td>
 <td class="last_row"></td>
 <td class="last_row">Total</td>
 <td class="last_row">%.1f/%.1f</td>
 <td class="last_row">%.1f/%.1f</td>
 <td class="last_row"></td>
</tr>
</table>""" % (taia, tait, tpca, tpct)

        user = (session.kind == ADMIN) and "?user_id=" + str(userId) or ""
        string += "<a href='/new_pupil%s'>" % user + _('Agregar alumnos') + "</a>"
        string += "<a href='javascript:history.back()' id='back'>" + _('Volver') + "</a>"
        request.write(string)
        return

    def printClientInfo(self, rows, request):
        _ = request.getSession()._
        fields = [{'pos': 0, 'desc': _('Horas AI disponibles')},
                  {'pos': 1, 'desc': _('Horas CP disponibles')},
                  {'pos': 2, 'desc': _('Cantidad de alumnos')}]
        if len(rows) != 1:
            string = '<div class="message">' + _('No se registran datos para el usuario') \
               + '</div>'
        else:
            string = '<div class="client_info">' + \
                _('Informacion de alumnos y horas:') + '<ul>'
            for row in rows:
                for i in fields:
                    string += '<li><b>' + i['desc'] + ': </b>' + str(row[i['pos']]) \
                      + '</li>'
            string += '</ul></div>'
        request.write(string)
        return

    def getFloatFormat(self, value):
        """esta puede eliminarse cuando la base de datos ponga valores por defecto
        a ai_available y pc_available"""
        return (value != None) and value or 0.0

    def getDateFormat(self, value):
        """esta puede eliminarse cuando la base de datos ponga valores por defecto
        a expires"""
        return (value != None) and value.Format(DATETIME_FORMAT) or "-"
Example #10
0
class WebSubjects(Resource):
    def __init__(self):
        self.db = DBConnect()
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para modificar las materias de cualquier tutor.
    # Si somos tutor, sirve para modificar solo los propios.
    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        # 0) Se empieza la página
        request.write(self.template.startPage(session, _('Modificacion de materias')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
        # 2.1) Admin debe proveer el argumento user_id
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
                    msg = '<h2>' + _('Administracion de materias') + '</h2>' + \
                     _('Selecciona las materias que el tutor sepa ensenar, para actualizar los datos en el sistema.')
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                       _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                   _('falta el parametro user_id')))
        # 3) Si es Tutor, administra sus propias materias
        elif session.kind == TUTOR:
            user_id = session.userId
            msg = '<h2>' + _('Seleccion de materias') + '</h2>' + \
                _('Selecciona las materias que sepas ensenar, para actualizar tus datos en el sistema.')
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id, msg)
        else:
        # 4) Si no es ni ni Admin, ni Tutor, ni nadie, es alguien que no está
        #    autorizado a administrar materias
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return d

    def printContent(self, request, d, userId, msg):
        _ = request.getSession()._
        # 1) Si se envían datos, se actualiza la base primero
        if "submit" in request.args.keys():
            op = "delete from tutor_subject where fk_tutor = %d"
            d.addCallback(lambda a: self.db.db.runOperation(op, (userId, )))
            for sbj in request.args.get('sbj', []):
                try:
                    sbj = int(sbj)
                    d.addCallback(self.addSubject, userId, sbj)
                except ValueError: # Alguien editó la url a mano?
                    d.addCallback(lambda a: \
                     request.write(self.template.unexpectedArguments(session, + \
                        _('sbj deberia tomar valores enteros.'))))
            d.addCallback(lambda a: request.write('<div class="message"><h2>' + \
                _('Cambios guardados.') + '</h2>' + \
                _('Se guardaron los cambios correctamente') + '</div>'))
        # 2) Se imprime un mensaje de bienvenida configurable
        d.addCallback(lambda a: request.write(msg))
        # 3) Se buscan los datos nuevos en la base
        d.addCallback(self.requestSubjectData, userId)
        # 4) Se imprime un formulario con los datos actualizados
        d.addCallback(self.printForm, request, userId)
        return d


    def requestSubjectData(self, data, userId):
        query = 'select s.id, s.name, t.fk_tutor from subject as s \
                 left join tutor_subject as t on (t.fk_subject = s.id \
                 and t.fk_tutor = %d)'
        return self.db.db.runQuery(query, (userId,))

    def printForm(self, rows, request, userId):
        _ = request.getSession()._
        string = """<form action="" method="GET">
  <select id="sbj" name="sbj" size="%d" multiple="multiple">""" % len(rows)
        for sbj in rows:
            selected = ''
            if sbj[2] is not None:
                selected = ' selected="selected"'
            string += '<option value="%s" %s>%s</option>\n' % (sbj[0], selected, sbj[1])
        string += """
   </select>
   <input type="hidden" name="user_id" value="%d"/>
   <input type="submit" name="submit" value=\""""  % userId + _('Enviar') + """\"/>
  </form>
"""
        request.write(string)
        return

    def addSubject(self, data, userId, sbj):
        operation = "insert into tutor_subject (id, fk_tutor, fk_subject) \
                     values (nextval('pk_seq_tutor_subject'), %d, %d)"
        return self.db.db.runOperation(operation, (userId, sbj))
Example #11
0
class WebSchedules(Resource):
    def __init__(self, db):
        self.db = db
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    # Si estamos autenticados como admin, sirve para modificar los horarios de cualquier tutor.
    # Si somos tutor, sirve para modificar solo los propios.
    def render_GET(self, request):
        session = request.getSession()
        _ = getTranslatorFromSession(session)
        # 0) Se empieza la página
        request.write(self.template.startPage(session, _('Modificacion de horarios')))
        d = defer.maybeDeferred(lambda:None)
        # 1) Verificar que esté autenticado ante el sistema
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        # 2) Si es Admin, administra todos los usuarios
        elif session.kind == ADMIN:
        # 2.1) Admin debe proveer el argumento user_id
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args['user_id'][0])
                    msg = '<h2>' + _('Administracion de horarios') + '</h2>' + _('Selecciona las horarios de acceso instantaneo para el tutor.')
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, _('falta el parametro user_id')))
        # 3) Si es Tutor, administra sus propios horarios
        elif session.kind == TUTOR:
            user_id = session.userId
            msg = '<h2>' + _('Seleccion de horarios') + '</h2>' + _('Selecciona los horarios en los que estas disponible para horas de acceso instantaneo.')
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id, msg)
        else:
        # 4) Si no es ni ni Admin, ni Tutor, ni nadie, es alguien que no está
        #    autorizado a administrar horarios
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())
        return server.NOT_DONE_YET

    def printContent(self, request, d, userId, msg):
        # 1) Si se envían datos, se actualiza la base primero
        _ = request.getSession()._
        if "submit" in request.args.keys():
            op = "delete from tutor_schedule where fk_tutor = %d"
            d.addCallback(lambda a: self.db.db.runOperation(op, (userId, )))
            instant = self.packSchedule(request.args.get('sched_ai', []))
            for sched in instant:
                d.addCallback(self.addSchedule, userId, sched, INSTANT)
            precoord = self.packSchedule(request.args.get('sched_pc', []))
            for sched in precoord:
                d.addCallback(self.addSchedule, userId, sched, PRECOORD)
            d.addCallback(lambda a: request.write('<div class="message"><h2>' + _('Cambios guardados.') + '</h2>' + _('Se guardaron los cambios correctamente') + '</div>'))
        # 2) Se imprime un mensaje de bienvenida configurable
        d.addCallback(lambda a: request.write(msg))
        # 3) Se buscan los datos nuevos en la base
        d.addCallback(self.requestScheduleData, userId)
        # 4) Se imprime un formulario con los datos actualizados
        d.addCallback(self.printForm, request, userId)
        return d

    def packSchedule(self, checks):
        try: # Mapeamos a integer y filtramos valores inadecuados
            checks = filter(lambda x: 0 <= x  and x < LASTDAY_MIDNIGHT, map(int, checks))
        except ValueError:
            return []
        checks.sort()

        scheds = []
        last_hour = None
        start_time = None
        end_time = None
        for hour in checks:
            if last_hour is None:
                start_time = hour
            elif last_hour < hour - 1:
                scheds.append((start_time, end_time))
                start_time = hour
            last_hour = hour
            end_time = hour + 1
        # Falta el último span, que lo agregamos ahora:
        if end_time is not None:
            if end_time == LASTDAY_MIDNIGHT:
                if start_time == 0: # Este tipo labura 24/7!
                    scheds.append((0, end_time))
                elif len(scheds) > 0 and scheds[0][0] == 0: # El horario abarca las 0 del domingo
                    scheds.append((start_time, end_time + scheds[0][1]))
                    del(scheds[0])
                else:
                    scheds.append((start_time, end_time))
            else:
                scheds.append((start_time, end_time))
        # Convertimos a DateTime

        spans = []
        # Elejimos mayo del 2005 porque el 1ero cae domingo.
        mktimestamp = lambda x: DateTime(2005, 5, 1 + x / 24, x % 24)
        for sched in scheds:
            spans.append((mktimestamp(sched[0]), mktimestamp(sched[1])))
        return spans

    def unpackSchedule(self, rows):
        checks = {}
        checks['ai'] = [False] * LASTDAY_MIDNIGHT
        checks['pc'] = [False] * LASTDAY_MIDNIGHT
        for row in rows:
            start_check = row[0] * 24 + row[1]
            end_check = row[2] * 24 + row[3]
            if end_check < start_check:
               end_check += LASTDAY_MIDNIGHT
            for hour in range(start_check, end_check):
                if row[4] == INSTANT:
                    checks['ai'][hour % LASTDAY_MIDNIGHT] = True
                elif row[4] == PRECOORD:
                    checks['pc'][hour % LASTDAY_MIDNIGHT] = True
        return checks

    def requestScheduleData(self, data, userId):
        return self.db.db.runQuery('select extract(dow from time_start), extract(hour from time_start), extract(dow from time_end), extract(hour from time_end), schedule_type from tutor_schedule where fk_tutor = %d', (userId,))

    def printForm(self, rows, request, userId):
        _ = request.getSession()._
        checks = self.unpackSchedule(rows)
        days = [_('Domingo'), _('Lunes'), _('Martes'), _('Miercoles'), _('Jueves'), _('Viernes'), _('Sabado')]
        string = """
<script>
<!--
function change_cell (tag) {
  input = tag.getElementsByTagName('input')[0]
  if (!input) return;
  input.checked = ! input.checked;
  if (input.checked) {
    var other = tag.id.substring(0, 6) + (((tag.id[6] * 1) + 1) % 2);
    other = document.getElementById(other);
    input = other.getElementsByTagName('input')[0]
    input.checked = false;
    other.className = other.className.substring(0, 7) + 'unchecked';
    other.title = '""" + _('No disponible') + """';
    var style = tag.className.substring(0, 7) + "checked";
    var tit = '""" + _('Disponible') + """';
  } else {
    var style = tag.className.substring(0, 7) + "unchecked";
    var tit = '""" + _('No disponible') + """';
  }
  tag.className = style;
  tag.title = tit;
}
-->
</script>

<form action="" method="GET">
  <fieldset class="sched">
    <legend>""" + _('Tipo de horarios') + """</legend>
      <p class="sch_instant">""" + _('Acceso instantaneo') + """</p>
      <p class="sch_precoord">""" + _('Clases Precoordinadas') + """</p>
  </fieldset>
</form>
<form action="" method="GET">
  <table id="schedule">
    <tr>
      <th></th>
"""
        for day in days:
            string += '<th colspan="2">%s</th>\n' % day
        string += '\n</tr><tr><th></th>\n'
        for day in days:
            string += '<th>AI</th><th>PC</th>\n'
        for hour in range(24):
            string += '</tr><tr>\n<td class="sch_row">%dhs</td>\n' % hour
            for day in enumerate(days):
                check = 24 * day[0] + hour
                for sufix, kind in enumerate(('ai', 'pc')):
                    if checks[kind][check]:
                        string += """<td id="sch%03d%d" class="sch_%s_checked" title=" """ %(check, sufix, kind) + _('Disponible') + """ " onmousedown="change_cell(this)"><input type="checkbox" name="sched_%s" value="%d" checked="checked"/></td>\n""" % (kind, check)
                    else:
                        string += """<td id="sch%03d%d" class="sch_%s_unchecked" title=" """  % (check, sufix, kind) + _('No disponible') + """ " onmousedown="change_cell(this)"><input type="checkbox" name="sched_%s" value="%d" /></td>\n""" % (kind, check)
        string += """
   </tr><tr><td class="sch_row">24hs</td>\n</tr></table>
   <input type="hidden" name="user_id" value="%d"/>
   <input type="submit" name="submit" value="""  % userId + _('Enviar') + """/>
  </form>
"""
        request.write(string)
        return

    def addSchedule(self, data, userId, sched, kind):
        return self.db.db.runOperation("insert into tutor_schedule (fk_tutor, time_start, time_end, schedule_type) values (%d, %s, %s, %d)", (userId, str(sched[0]), str(sched[1]), kind))
Example #12
0
class WebPupilInsert(Resource):
    def __init__(self):
        _ = dummyTranslator
        self.fields = [{'name': 'username', 'pos': 1, 'desc': _('Nombre de usuario'), \
            'required': True, 'type': 'text', 'maxlength': 80, 'query': "person"},
        {'name': 'password', 'pos': 2, 'desc': _('Contrasena'), 'required': True, \
            'type': 'password', 'maxlength': 80, 'query': "person"},
        {'name': 'password2', 'pos': 2, 'desc': _('Repita contrasena'), 'required': True, \
            'type': 'password', 'maxlength': 80, 'query': ""},
        {'name': 'first_name', 'pos': 3, 'desc': _('Nombre'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "person"},
        {'name': 'last_name', 'pos': 4, 'desc': _('Apellido'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "person"},
        {'name': 'email', 'pos': 5, 'desc': _('eMail'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "person"},
        {'name': 'ai_total', 'pos': 6, 'desc': _('Horas de AI'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "pupil"},
        {'name': 'pc_total', 'pos': 7, 'desc': _('Horas de CP'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "pupil"}]
        self.db = DBConnect()
        self.render_POST = self.render_GET
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = trans
        request.write(self.template.startPage(session, _('Pagina del Alumno')))
        d = defer.maybeDeferred(lambda :None)
        msg = '<h2>' + _('Nuevo alumno') + '</h2> ' + \
          _('Recuerde que los campos indicados con <sup>*</sup> son obligatorios')
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        elif session.kind == ADMIN:
            if "user_id" in request.args.keys():
                try:
                    user_id = int(request.args.get('user_id', [-1])[0])
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                        _('user_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                    _('Falta el argumento user_id')))
        elif session.kind == CLIENT:
            user_id = session.userId
        # La función que imprime el contenido, pero con otros argumentos
            self.printContent(request, d, user_id, msg)
        else:
        # 4) Si no es ni ni Admin, ni Cliente es alguien no autorizado a ver alumnos
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())

        return d

    def checkRequest(self, d, request):
        session = request.getSession()
        _ = session._
        args = dict([(i, request.args[i][0]) for i in request.args.keys()])
        if "submit" in request.args.keys():
            for value in self.fields:
                if value['name'] not in args.keys():
                    args[value['name']] = ''
                    d.addCallback(lambda a: \
                        request.write(self.template.unexpectedArguments(session, \
                        _('Falta el argumento \'%s\'') % value['name'])))
                elif len(args[value['name']]) > value['maxlength']:
                    args[value['name']] = (args[value['name']][:value['maxlength']])
                    d.addCallback(lambda a: \
                        request.write(self.template.unexpectedArguments(session, \
                        _('Longitud excesiva del argumento \'%s\'') % value['name'])))
            if args['password'] != args['password2']:
                request.write(self.template.unexpectedArguments(session, \
                    _('Las contrasenas no coinciden')))

            if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", args['email']) == None:
                request.write(self.template.unexpectedArguments(session, \
                                    _('El email ingresado es incorrecto')))
            try:
                args['ai_total'] = float(args['ai_total'])
                args['pc_total'] = float(args['pc_total'])
            except ValueError:
                request.write(self.template.unexpectedArguments(session, \
                    _('El argumento de Hora debe ser numerico')))
        return args

    def printContent(self, request, d, userId, msg):
        _ = request.getSession()._
        args = self.checkRequest(d, request)
        d.addCallback(lambda a: request.write(msg))
        #chequeamos que el cliente exista
        query = "select ai_available, pc_available from client where id = %d"
        d.addCallback(lambda a: self.db.db.runQuery(query, (userId,)))
        d.addCallback(self._checkAndInsert, request, userId, args)
        d.addErrback(self.printError, request)
        d.addCallback(self.printForm, request, args, userId)


    def _printAvailable(self, row, request):
        _ = request.getSession()._
        string = _('Detalle de horas disponibles:') + "<br/>" + \
          "<ul id='client_info'><li>" + _('Horas AI disponibles:') + \
          ' %.1f' % row[0][0] + "</li><li>" + _('Horas CP disponibles:') + \
          ' %.1f' % row[0][1] + "</li></ul>"
        d = defer.maybeDeferred(lambda: request.write('<div class="client_info">' + \
          string + '</div>') or row)
        d.addCallback(lambda a: row)
        return d


    def printError(self, failure, request):
        """Imprime el error de failure y genera una fila
        vacia para la consulta de la base de datos
        """
        session = request.getSession()
        d = defer.maybeDeferred(lambda :None)
        d.addCallback(lambda a: request.write("""<div class="error"> %s </div>""" % \
             failure.getErrorMessage()))
        d.addCallback(self.getEmptyRow, 8)
        return d


    def _checkAndInsert(self, rows, request, userId, args):
        _ = request.getSession()._
        if len(rows) == 1:
            ai_available = rows[0][0]
            pc_available = rows[0][1]

            if 'submit' in request.args.keys():
                username = QuotedString(args['username'])
                ai_asked = args['ai_total']
                pc_asked = args['pc_total']
                if (ai_asked <= ai_available and pc_asked <= pc_available):
                    query = "select username from person where username = %s"
                    d = self.db.db.runQuery(query, (username,))
                    d.addCallback(self._insertDB, request, userId, args)
                else:
                    return failure.Failure(_('Ha solicitado mas horas de las que dispone'))
            else:
                d = defer.maybeDeferred(lambda: self.getEmptyRow(None, 8))
        else:
            return failure.Failure(_('El cliente solicitado no existe'))
        return d

    def _insertDB(self, rows, request, userId, args):
        """inserta una persona en la base de datos y llama a la
        función que inserta a la misma persona como alumno
        """
        _ = request.getSession()._
        if len(rows) != 0:
            return failure.Failure(_('El usuario ya existe en el sistema'))
        else:
            person_name = []
            person_value = []
            
            #encripto el password
            if args['password']!="":
                args['password'] = sha.new(args['password']).hexdigest()  
            
            for field in self.fields:
                if field['query'] == "person":
                    person_name.append(field['name'])
                    person_value.append("'" + args[field['name']] + "'")
            person_name = ", ".join(person_name) + ", language, fk_timezone"
            person_value = ", ".join(person_value) + ", " + str(PUPIL) + ", 2"
            person_op = "insert into person (kind, " + person_name + ") values \
                (%d"+ ", " + person_value + ")"
            d = self.db.db.runOperation(person_op, (PUPIL,))
            query = "select id from person where username = %s"
            username = QuotedString(args['username'])
            d.addCallback(lambda a: self.db.db.runQuery(query, (username,)))
            d.addCallback(self.insertPupil, request, userId, args)
        return d


    def insertPupil(self, rows, request, userId, args):
        """Inserta un alumno en la base de datos de acuerdo a los
        datos de rows
        """
        _ = request.getSession()._
        assert(len(rows) == 1)
        pupil_name = []
        pupil_value = []
        expire_time = DateTime.now() + DateTime.RelativeDate(**EXPIRE_TIME)
        for field in self.fields:
            if field['query'] == "pupil":
                pupil_name.append(field['name'])
                pupil_value.append("'" + str(args[field['name']]) + "'")
        pupil_name = ", ".join(pupil_name) + ", fk_client, ai_available, pc_available, expires"
        pupil_value = ", ".join(pupil_value) + ", %d, %f, %f, '%s'" % (userId, args['ai_total'], args['pc_total'], expire_time)
        pupil_op = "insert into pupil (id, " + pupil_name + ") values \
            (%d" + ", " + pupil_value + ")"
        client_op = "update client set ai_available = ai_available - %f, pc_available = pc_available - %f where id = %s"
        d = self.db.db.runOperation(pupil_op, (rows[0][0],))
        d.addCallback(lambda a: self.db.db.runOperation(client_op, (args['ai_total'], args['pc_total'], args['user_id'])))
        d.addCallback(lambda a: request.write('<div class="message">' + \
            _('Usuario ingresado con exito') + '</div>') or self.getEmptyRow(None, 8))
        return d

    def getEmptyRow(self, data, size):
        """Devuelve una consulta vacia de tamaño size"""
        return [[""] * size]

    def printCheckArgs(self, hours, request):
        """Para cada diccionario de la lista fields chequea si el campo es
        obligatorio y arma la funcion de JavaScript para el chequeo de datos.
        Agrega a continuacion el chequeo de que las contraseñas coincidan
        """
        _ = request.getSession()._
        ai = hours[0][0]
        pc = hours[0][1]
        page = """
<script type="text/javascript" src="/static/js/valid.js"></script>

<script type="text/javascript">\n function check_args(form){
message='';"""

        for i in self.fields:
            if i['required']:
                page += """if(form.%s.value == "")
                message += "- """ % i['name'] + \
                _('El campo %s es obligatorio') % _(i['desc']) + """\\n";\n"""
        page += """if(form.password.value != form.password2.value)
        message += \"- """ + _('Las contrasenas no coinciden') + """\\n";
if(!isNaN(parseFloat(form.ai_total.value))){
    form.ai_total.value = parseFloat(form.ai_total.value);
}else{
    message += \"- """ + _('El campo Horas AI disponibles debe ser numerico') + """\\n";
}
if(form.ai_total.value > """ + str(ai) + """){
    message += \"- """ + _('Se ha excedido en las Horas AI asignadas') + """\\n";
}
if(form.ai_total.value < 0){
    message += \"- """ + _('El campo Horas de AI debe ser positivo') + """\\n";
}
if(!isNaN(parseFloat(form.pc_total.value))){
    form.pc_total.value = parseFloat(form.pc_total.value);
}else{
    message += \"- """ + _('El campo Horas PC disponibles debe ser numerico') + """\\n";
}
if(form.pc_total.value > """ + str(pc) + """){
    message += \"- """ + _('Se ha excedido en las Horas PC asignadas') + """\\n";
}
if(form.pc_total.value < 0){
    message += \"- """ + _('El campo Horas de PC debe ser positivo') + """\\n";
}
if(form.pc_total.value == 0 && form.ai_total.value == 0){
    message += \"- """ + _('Debe asignarle horas al alumno') + """\\n";
}

if(!isEmailAddress(form.email)){
        message += \"- """ + _('El email ingresado es incorrecto') + """\\n";
}





if(message){
    alert(" """ + _('Error en el ingreso de datos:') + """\\n"+message+"\\n");
    return false;
}else{
    return true;
}
}
</script>
"""
        request.write(page)
        return

    def printForm(self, row, request, args, userId):
        """Para cada diccionario de la lista fields arma el campo del
        formulario correspondiente.
        """
        session = request.getSession()
        _ = session._
        d = self.db.db.runQuery("select ai_available, pc_available from client where id = %d", (userId,))
        d.addCallback(self._printAvailable, request)
        d.addCallback(self.printCheckArgs, request)
        page = """<form action="" method="post" \
            onsubmit="return check_args(this)"><div> """
        for i in self.fields:
            value = row[0][i['pos']]
            required = i['required'] and "<sup>*</sup>" or ""
            text = i['type']
            page += """<label for="%s">%s%s: <input type="%s" name="%s"
    size="20" value="%s" maxlength="%d" id="%s" /></label><br/>\n""" % \
        (i['name'], _(i['desc']), required, text, i['name'], value, i['maxlength'], i['name'])
        d.addCallback(lambda a: request.write(page))
        d.addCallback(lambda a: request.write("""<input type="submit" \
            name="submit" id="submit" value=\"""" + _('Guardar') + """\"/>"""))
        if userId > 0:
            d.addCallback(lambda a: request.write("""<input type="hidden" name="user_id" value="%s"/>""" % userId))
        d.addCallback(lambda a: request.write("""</div></form>"""))
        return d
Example #13
0
class WebPupilEdit(Resource):
    def __init__(self):
        _ = dummyTranslator
        self.fields = [{'name': 'username', 'pos': 1, 'desc': _('Nombre de usuario'), \
            'required': True, 'type': 'text', 'maxlength': 80, 'query': "person"},
        {'name': 'password', 'pos': 2, 'desc': _('Contrasena'), 'required': False, \
            'type': 'password', 'maxlength': 80, 'query': "person"},
        {'name': 'password2', 'pos': 2, 'desc': _('Repita contrasena'), 'required': False, \
            'type': 'password', 'maxlength': 80, 'query': ""},
        {'name': 'first_name', 'pos': 3, 'desc': _('Nombre'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "person"},
        {'name': 'last_name', 'pos': 4, 'desc': _('Apellido'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "person"},
        {'name': 'email', 'pos': 5, 'desc': _('eMail'), 'required': True, \
            'type': 'text', 'maxlength': 255, 'query': "person"}]
        self.db = DBConnect()
        self.render_POST = self.render_GET
        self.template = WebTemplates()
        Resource.__init__(self)

    def getChild(self, path, request):
        if path == "":
            return self
        else:
            return static.File.childNotFound

    def render_GET(self, request):
        d = defer.maybeDeferred(getTranslatorFromSession, request)
        d.addCallback(self.doAuthentication, request)
        return server.NOT_DONE_YET

    def doAuthentication(self, trans, request):
        session = request.getSession()
        _ = session._
        request.write(self.template.startPage(session, _('Pagina del Alumno')))
        d = defer.maybeDeferred(lambda :None)
        msg = '<h2>' + _('Informacion de alumno') + '</h2>'
        msg += _('Recuerda que los campos indicados con <sup>*</sup> son obligatorios<br>')
        msg += _('Si desea conservar la contraseña actual deje los campos en blanco')
        if not hasattr(session, 'username'):
            request.write(self.template.notAuthenticated(session))
        elif session.kind == ADMIN:
            if 'user_id' in request.args.keys() and 'pupil_id' in request.args.keys():
                try:
                    user_id = int(request.args.get('user_id', [-1])[0])
                    pupil_id = int(request.args.get('pupil_id')[0])
        # La función que procesa e imprime el contenido de la pagina
                    self.printContent(request, d, user_id, pupil_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                        _('user_id y pupil_id deberian ser enteros')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                        _('Faltan argumentos requeridos')))
        # 3) Si es Cliente, ve solo su alumno
        elif session.kind == CLIENT:
            user_id = session.userId
            if 'pupil_id' in request.args.keys():
                try:
                    pupil_id = int(request.args.get('pupil_id')[0])
        # La función que imprime el contenido, pero con otros argumentos
                    self.printContent(request, d, user_id, pupil_id, msg)
                except ValueError:
                    request.write(self.template.unexpectedArguments(session, \
                        _('pupil_id deberia ser entero')))
            else:
                request.write(self.template.unexpectedArguments(session, \
                        _('Faltan argumentos requeridos')))
        else:
        # 4) Si no es ni ni Admin, ni Cliente es alguien que no está
        #    autorizado a modificar alumnos
            request.write(self.template.notAuthorized(session))
        # 5) Se termina la página
        d.addCallback(lambda a: request.write(self.template.finishPage(session)))
        d.addCallback(lambda a: request.finish())

        return d

    def checkRequest(self, d, request):
        session = request.getSession()
        _ = session._
        args = dict([(i, request.args[i][0]) for i in request.args.keys()])
        if "submit" in request.args.keys():
            for value in self.fields:
                if value['name'] not in args.keys():
                    args[value['name']] = ''
                    d.addCallback(lambda a: \
                        request.write(self.template.unexpectedArguments(session, \
                        _('Falta el argumento \'%s\'') % value['name'])))
                elif len(args[value['name']]) > value['maxlength']:
                    args[value['name']] = (args[value['name']][:value['maxlength']])
                    d.addCallback(lambda a: \
                        request.write(self.template.unexpectedArguments(session, \
                        _('Longitud excesiva del argumento \'%s\'') % value['name'])))
            if(args['password'] != args['password2']):
                request.write(self.template.unexpectedArguments(session, \
                    _('Las contrasenas no coinciden')))
            
            if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", args['email']) == None:
                request.write(self.template.unexpectedArguments(session, \
                    	_('El email ingresado es incorrecto')))

        return args


    def printContent(self, request, d, userId, pupilId, msg):
        # si se estan enviando datos
        _ = request.getSession()._
        args = self.checkRequest(d, request)
        if "submit" in args.keys():
            # si tenemos que actualizar
            query = "select username from person where username = %s and id <> %d"
            d.addCallback(lambda a: self.db.db.runQuery(query, (args['username'], pupilId)))
            d.addCallback(self._updateUser, request, pupilId, args, userId)
        else:
            d.addCallback(lambda a:userId)
        d.addCallback(self._requestData, request, pupilId, msg)
        d.addErrback(self.printError, request)
        d.addCallback(self.printForm, request, args, userId)

    def _updateUser(self, row, request, pupilId, args, userId):
        _ = request.getSession()._
        if len(row) == 0:
            person = []
            
            #encripto el password
            if args['password']!="":
                args['password'] = sha.new(args['password']).hexdigest()  
            
            for field in self.fields:
                if field['query'] == "person":
                    #si los password estan en blanco no se incluyen en la query de actualizacion                       
                    if not(field['name']=='password' and args['password']==""):
                        person.append(field['name'] + " = '" + args[field['name']] + "'")
            person = ", ".join(person)
            
            update_person = "update person set " + person + " where id = %s"
            d = self.db.db.runOperation(update_person, (pupilId,))
            d.addCallback(lambda a: request.write('<div class="message">' + \
                    _('Datos actualizados con exito') + '</div>') or userId)
        else:
            return failure.Failure(_('El usuario %s ya existe en el sistema') % \
                row[0][0])
        return d

    def _requestData(self, userId, request, pupilId, msg):
        request.write(msg)
        # no se estan mandando datos, se los solicita
        query = "select person.id, username, password, first_name, last_name, \
            email from person, pupil, client where person.id = pupil.id and \
            client.id = pupil.fk_client and client.id = %s and person.id = %s"
        d = self.db.db.runQuery(query, (userId, pupilId))
        return d

    def printError(self, failure, request):
        """Imprime el error de failure y genera una fila
        vacia para la consulta de la base de datos
        """
        session = request.getSession()
        d = defer.maybeDeferred(lambda :None)
        d.addCallback(lambda a: request.write("""<div class="error"> %s </div>""" % \
             failure.getErrorMessage()))
        d.addCallback(self.getEmptyRow, 6)
        return d

    def getEmptyRow(self, data, size):
        """Devuelve una consulta vacia de tamaño size"""
        return [[""] * size]

    def printCheckArgs(self, request):
        """Para cada diccionario de la lista fields chequea si el campo es
        obligatorio y arma la funcion de JavaScript para el chequeo de datos.
        Agrega a continuacion el chequeo de que las contraseñas coincidan
        
        TO-DO: si las contraseñas estan en blanco, ignorar el update. 
        
        """
        _ = request.getSession()._
        page = """
<script type="text/javascript" src="/static/js/valid.js"></script>

<script type="text/javascript">\n function check_args(form){
message='';"""

        for i in self.fields:
            if i['required']:
                page += """if(form.%s.value == "")
                message += "- """ % i['name'] + \
                _('El campo %s es obligatorio') % _(i['desc']) + """\\n";\n"""
        page += """if(form.password.value != form.password2.value)
        message += \"- """ + _('Las contrasenas no coinciden') + """\";\n"""

        page += """if(!isEmailAddress(form.email))
        message += \"- """ + _('El email ingresado es incorrecto') + """\";


    if(message){
        alert(" """ + _('Error en el ingreso de datos:') + """\\n"+message+"\\n");
        return false;
    }else{
        return true;
    }
}
</script>
"""
        request.write(page)
        return

    def printForm(self, row, request, args, userId):
        """Para cada diccionario de la lista fields arma el campo del
        formulario correspondiente.
        """
        session = request.getSession()
        _ = session._
        if len(row) == 0:
            request.write(self.template.unexpectedArguments(session, \
            _('El usuario solicitado no existe')))
            row = self.getEmptyRow(None, 6)

        self.printCheckArgs(request)
        page = """<form action="" method="post" \
            onsubmit="return check_args(this)"><div> """
        for i in self.fields:
            value = args.get(i['name'], row[0][i['pos']])
            required = i['required'] and "<sup>*</sup>" or ""
            text = i['type']

            #dejo los campos password en blanco por defecto.
            if value is None or i['name']=='password' or i['name']=='password2':
                value = ''

            page += """<label for="%s">%s%s: <input type="%s" name="%s"
    size="20" value="%s" maxlength="%d" id="%s" /></label><br/>\n""" % \
        (i['name'], _(i['desc']), required, text, i['name'], value, i['maxlength'], i['name'])
        request.write(page)
        request.write("""<input type="submit" name="submit" id="submit" value=\"""" + \
            _('Guardar') + """\"/>""")
        if userId > 0:
            request.write("""<input type="hidden" name="user_id" value="%s"/>""" % userId)
        request.write("""</div></form>""")
        return