class WebLogout(Resource): def __init__(self): 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): session = request.getSession() _ = getTranslatorFromSession(request) if hasattr(session, 'username'): del(session.username) del(session.userId) del(session.kind) del(session.name) del(session.lastname) del(session.locale) request.write(self.template.startPage(session, _('Cerrar Sesion'))) request.write('<div class="message"><h2>' + _('La sesion ha sido cerrada') + '</h2>' + _('Que tenga un buen dia.') + '</div>') else: request.write(self.template.startPage(session)) request.write('<div class="warning"><h2>' + _('Sesion inexistente') + '</h2>' + _('Debe iniciar una sesion antes de cerrarla!') + '</div>') request.write(self.template.finishPage(session)) del(session._) request.finish() return server.NOT_DONE_YET
class WebContent(Resource): def __init__(self): Resource.__init__(self) self.template = WebTemplates() self.pages = static.File('./htdocs/content/') def getChild(self, path, request): return self def render_GET(self, request): d = defer.maybeDeferred(getTranslatorFromSession, request) d.addCallback(self.writeContent, request) return server.NOT_DONE_YET def writeContent(self, trans, request): session = request.getSession() _ = trans request.write(self.template.startPage(session, \ _('Beppo - Sistema de educacion a distancia'))) page = self.pages.getChild(request.prepath[-1], request) if hasattr(page, 'getContent'): request.write(page.getContent()) else: request.write(self.template.notFound(session)) request.write(self.template.finishPage(session)) request.finish() return
class WebSettings(Resource): _ = dummyTranslator def __init__(self): _ = dummyTranslator 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 d = defer.maybeDeferred(lambda: None) if not hasattr(session, 'username'): d.addCallback(lambda a: request.write(self.template.notAuthenticated(session))) elif session.kind == ADMIN: try: user_id = int(request.args.get('user_id', None)[0]) except: user_id = session.userId else: user_id = session.userId message = False if "submit" in request.args.keys(): try: time = int(request.args.get('fk_timezone')[0]) lang = int(request.args.get('language')[0]) except ValueError, TypeError: request.write(self.template.unexpectedArguments(session, \ _('Argumento no valido'))) message = True query = "select * from language, timezone where \ language.id = %d and timezone.id = %d" d.addCallback(lambda a: self.db.db.runQuery(query, (lang, time))) d.addCallback(self.updateDBAndSession, request, user_id) d.addCallback(self.printStartPage, request, message) d.addCallback(lambda a: self.printContent(request, user_id)) # 4) Se termina la página d.addCallback(lambda a: request.write(self.template.finishPage(session))) d.addCallback(lambda a: request.finish()) return d
class WebUserInfo(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 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 info = WebGetUserInfo(self.db, session) # 0) Se empieza la página request.write(self.template.startPage(session, _('Informacion de usuario'))) 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, puede ver todos los usuarios elif "user_id" in request.args.keys() and "kind" in request.args.keys(): try: user_id = int(request.args['user_id'][0]) kind = int(request.args['kind'][0]) msg = '<h2>' + _('Informacion de usuario') + '</h2>' d.addCallback(lambda a: info.getUserInfo(user_id, kind)) except ValueError: request.write(self.template.unexpectedArguments(session, \ _('Argumento no valido'))) user_id = kind = msg = None d.addCallback(lambda a: None) d.addCallback(self.printContent, request, d, user_id, kind, session, msg) else: request.write(self.template.unexpectedArguments(session, \ _('Falta algun argumento'))) d.addCallback(lambda a: request.write(self.template.finishPage(session))) d.addCallback(lambda a: request.finish()) return d def printContent(self, data, request, d, userId, kind, session, msg): d.addCallback(lambda a: request.write(msg)) d.addCallback(lambda a: request.write(data)) return
def __init__(self, server): self.db = DBConnect self.rOpen = server.openRoomsAndLenQueues # clave room -> valor cant gente self.subjects = server.openRoomsAndSubjects # clave room -> valor lista materias self.sbOpen = server.shouldBeOpenAndClosedRooms self.template = WebTemplates() Resource.__init__(self)
def __init__(self, server): Resource.__init__(self) self.db = DBConnect() self.template = WebTemplates() self.putChild("roominfo", WebRoomInfo(server)) self.putChild("userinfo", WebUserInfo()) self.putChild("login", WebLogin()) self.putChild("logout", WebLogout()) self.putChild("static", static.File("./htdocs/")) self.putChild("board_archive", static.File("./archive/")) self.putChild("content", WebContent()) self.putChild("calendar", static.File("./calendar/")) self.putChild("subjects", WebSubjects()) self.putChild("settings", WebSettings()) self.putChild("subject_admin", WebSubjectAdmin()) self.putChild("schedules", WebSchedules()) self.putChild("admin", WebAdmin()) self.putChild("archive", WebArchive()) self.putChild("list", WebListUsers()) self.putChild("tutor", WebTutor()) self.putChild("tutor_info", WebTutorInfo()) self.putChild("tutor_data", WebTutorData()) self.putChild("tutor_sessions", WebTutorSessions()) self.putChild("client", WebClient()) self.putChild("report", WebClientReport()) self.putChild("mail", WebSendMail()) self.putChild("my_pupils", WebMyPupils()) self.putChild("my_pupils_info", WebMyPupilsInfo()) self.putChild("pupil_edit", WebPupilEdit()) self.putChild("new_pupil", WebPupilInsert()) self.putChild("pc_arrange", WebPCArrangeRoot()) self.putChild("editadmin", WebEditAdmin())
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 __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)
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)
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> " % (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
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
class WebAdmin(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 # A esta pagina sólo se podrá acceder si tenemos permisos de administrador. # Mostrará un link para ver las listas de: clientes, tutores y alumnos 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): _ = trans session = request.getSession() d = defer.maybeDeferred(lambda: None) # Se escribe el comienzo de la página request.write(self.template.startPage(session, _('Administracion de usuarios'))) # Si no es admin o no esta loggeado, no seguimos if not hasattr(session, 'username') or session.kind != ADMIN: d.addCallback(lambda a: request.write(self.template.notAuthenticated(session))) else: d.addCallback(lambda a: self.sysStatus(request)) d.addCallback(self.printContent, request) # Se escribe el final de 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 sysStatus(self, request): """Busca la información acerca de la cantidad de usuarios, alumnos y tutores que tiene el sistema. """ query = "select count(*), kind from person group by kind order by kind asc" d = self.db.db.runQuery(query) return d def printContent(self, rows, request): _ = request.getSession()._ subjects = _('Listado de materias disponibles y cantidad de tutores que la tienen como seleccionada para poder dar clases. Tambien se pueden realizar alta y bajas de materias') tutors = _('Tiempo que los tutores pasaron en el sistema, dividido por tipos de conexion. Detalle de las sesiones de cada tutor. Se puede elegir un rango de fechas para visualizar') rooms = _('Informacion de las aulas del sistema, cantidad de alumnos en el aula, los tutores que se encuentran a cargo y las materias que estan brindando. Listado de aulas que deberian estar abiertas y no lo estan, con la informacion del tutor correspondiente') board = _('Archivos en formato PDF (Portable Document Format) que contienen las pizarras de las clases brindadas por los tutores del sistema') admin = [{'id': 'subject_admin', 'item': _('Administrar materias'), \ 'title': _('Materias'), 'alt': _('Materias'), 'desc': subjects, \ 'link': '/subject_admin', 'image': '/static/graphics/subjects.gif', \ 'width': '16', 'height': '16'}, {'id': 'tutor_info', 'item': _('Informacion de tutores'), \ 'title': _('Tutores'), 'alt': _('Tutores'), 'desc': tutors, \ 'link': '/tutor_info', 'image': '/static/graphics/subjects.gif', \ 'width': '16', 'height': '16'}, {'id': 'roominfo', 'item': _('Informacion de aulas'), \ 'title': _('Aulas'), 'alt': _('Aulas'), 'desc': rooms, \ 'link': '/roominfo', 'image': '/static/graphics/tutor_info.gif', \ 'width': '16', 'height': '16'}, {'id': 'tutor', 'item': _('Agregar tutores'), 'title': _('Tutores'), \ 'alt': _('Tutores'), 'desc': _('Agregar nuevos tutores al sistema'), \ 'link': '/tutor', 'image': '/static/graphics/mortarboard.gif', \ 'width': '16', 'height': '16'}, {'id': 'client', 'item': _('Agregar clientes'), 'title': _('Clientes'), \ 'alt': _('Clientes'), 'desc': _('Agregar nuevos clientes al sistema'), \ 'link': '/client', 'image': '/static/graphics/buddy.gif', \ 'width': '16', 'height': '16'}, {'id': 'archive', 'item': _('Archivo de pizarras'), 'title': _('Archivo'), \ 'alt': _('Archivo'), 'desc': board, 'link': '/archive', \ 'image': '/static/graphics/ps.png', 'width': '16', 'height': '16'}] page = '' if len(rows) != 0: page += '<h2>' + _('Administracion del sistema:') \ + '</h2><div style="padding-left: 40px"><table id="admin_table" border="0">' for item in admin: page += """<tr><td><a href='%s' id='%s'><img src='%s' width='%s' height='%s' alt='%s' title='%s'/></a><a href='%s'>%s</a> </td><td>%s</td> </tr>""" \ % (item['link'], item['id'], item['image'], item['width'], \ item['height'], item['alt'], item['title'], item['link'], \ item['item'], item['desc']) page += """</table></div><h2>""" + _('Informacion de usuarios en el sistema:') \ + """</h2><div style="padding-left: 40px" id='users'>""" \ + """<ul id="systemusers">""" for i in range(len(rows)): # row[0] es la cantidad de row[1] que hay en la base if rows[i][1] == TUTOR: page += '<li>%d <a href="/list?kind=%d">' % (rows[i][0], TUTOR) \ + _('Tutores') + '</a> ' + _('en el sistema') + '</li>' elif rows[i][1] == PUPIL: page += '<li>%d <a href="/list?kind=%d">' % (rows[i][0], PUPIL) \ + _('Alumnos') + ' </a> ' + _('en el sistema') + '</li>' elif rows[i][1] == CLIENT: page += '<li>%d <a href="/list?kind=%d">' % (rows[i][0], CLIENT) \ + _('Clientes') + ' </a> ' + _('en el sistema') + '</li>' elif rows[i][1] == ADMIN: page += '<li>%d <a href="/list?kind=%d">' % (rows[i][0], ADMIN) \ + _('Administradores') + ' </a> ' + _('en el sistema') + '</li>' else: page += '<li>%d' % rows[i][0] + \ _('Usuarios no categorizados en el sistema') + '</li>' page += '</ul></div>' else: page += '<h2>' + _('No hay usuarios en el sistema') + '</h2>' request.write(page) return
class WebRoomInfo(Resource): def __init__(self, server): self.db = DBConnect self.rOpen = server.openRoomsAndLenQueues # clave room -> valor cant gente self.subjects = server.openRoomsAndSubjects # clave room -> valor lista materias self.sbOpen = server.shouldBeOpenAndClosedRooms 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, \ _('Informacion de Pizarras en el sistema'))) d = defer.maybeDeferred(lambda :None) 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>' + _('Estado del sistema') + '</h2>' + \ _('Aqui se muestran las aulas que se encuentran abiertas, una descripcion de ellas y la lista de aulas que deberian estar abiertas.') # La función que procesa e imprime el contenido de la pagina else: msg = '<h2>' + _('Estado del sistema') + '</h2>' + \ _('Aqui se muestran las aulas que se encuentran abiertas y una descripcion de ellas') self.printContent(request, d, session, msg) # 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, session, msg): rOpen = self.rOpen() subjects = self.subjects() d.addCallback(lambda a: request.write(msg)) d.addCallback(lambda a: self._getORoomInfo(rOpen)) d.addCallback(self._printORoomTable, request, rOpen, subjects) if session.kind == ADMIN: d.addCallback(lambda a: self._getSBORoomInfo(self.sbOpen())) d.addCallback(self._printSBORoomTable, request) # 2) Se imprime un mensaje de bienvenida configurable return d def _getORoomInfo(self, openRooms): ids = tuple([int(b) for b in openRooms.keys() if b != GENERAL] + [0]) if len(ids) > 1: query = "select username, id from person where id in %s" d = self.db.db.runQuery(query, (ids,)) else: d = defer.maybeDeferred(lambda: []) return d def _getSBORoomInfo(self, sbopenRooms): if sbopenRooms != []: query = "select username, id from person where id in %s" d = self.db.db.runQuery(query, (tuple(sbopenRooms + [0]),)) else: d = defer.maybeDeferred(lambda: []) return d def _printORoomTable(self, rows, request, openRooms, subjects): _ = request.getSession()._ page = """<br/><br/> <table class="table_list" id="opened_rooms"> <caption>""" + _('Aulas abiertas:') + """</caption> <tr class="header_list"> <th>""" + _('Aula') + """</th> <th>""" + _('Usuarios conectados') + """</th> <th>""" + _('Tutor a cargo') + """</th> <th>""" + _('Materias') + """</th> </tr>""" if len(openRooms) == 1: page += '<tr><td colspan ="4" style="text-align: center">' + \ _('Ningun aula abierta') + ' </td></tr>' else: for room in rows: rm = room[1] connected = openRooms.get(str(room[1])) in_charge = "<a href='/tutor_data?user_id=%s'> %s </a>" % (room[1], room[0]) sub = self.printSubjects(subjects.get(str(room[1]))) page += """ <tr> <td> %s </td> <td> %s </td> <td> %s </td> <td> %s </td></tr>""" % (rm, connected, in_charge, sub) + """ </td></tr>""" page += '</table><br/><br/>' page += _('Usuarios en la cola general:') + '%d' % openRooms.get(GENERAL) request.write(page) def printSubjects(self, subjects): return " - ".join(subjects) def _printSBORoomTable(self, rows, request): _ = request.getSession()._ page = """<br/><br/> <table class="table_list" id="sbopen_rooms"> <caption>""" + _('Aulas que deberian estar abiertas y no estan:') + """</caption> <tr class="header_list"> <th>""" + _('Aula') + """</th> <th>""" + _('Tutor') + """</th> </tr>""" if len(rows) == 0: page += """ <tr><td colspan ="3" style="text-align: center">""" + \ _('No hay tutores ausentes') + """</td></tr>""" else: for room in rows: page += """ <tr> <td> %s </td> <td> <a href="/tutor_data?user_id=%s"> %s </a> </td> </tr>""" % (room[1], room[1], room[0]) page += '</table>' request.write(page)
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
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))
def __init__(self, db): self.db = db self.template = WebTemplates() Resource.__init__(self)
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> " % (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)
def __init__(self): Resource.__init__(self) self.template = WebTemplates() self.pages = static.File('./htdocs/content/')
class WebRoot(Resource): #def __init__(self, users, openRooms, shouldBeOpenRooms): def __init__(self, server): Resource.__init__(self) self.db = DBConnect() self.template = WebTemplates() self.putChild("roominfo", WebRoomInfo(server)) self.putChild("userinfo", WebUserInfo()) self.putChild("login", WebLogin()) self.putChild("logout", WebLogout()) self.putChild("static", static.File("./htdocs/")) self.putChild("board_archive", static.File("./archive/")) self.putChild("content", WebContent()) self.putChild("calendar", static.File("./calendar/")) self.putChild("subjects", WebSubjects()) self.putChild("settings", WebSettings()) self.putChild("subject_admin", WebSubjectAdmin()) self.putChild("schedules", WebSchedules()) self.putChild("admin", WebAdmin()) self.putChild("archive", WebArchive()) self.putChild("list", WebListUsers()) self.putChild("tutor", WebTutor()) self.putChild("tutor_info", WebTutorInfo()) self.putChild("tutor_data", WebTutorData()) self.putChild("tutor_sessions", WebTutorSessions()) self.putChild("client", WebClient()) self.putChild("report", WebClientReport()) self.putChild("mail", WebSendMail()) self.putChild("my_pupils", WebMyPupils()) self.putChild("my_pupils_info", WebMyPupilsInfo()) self.putChild("pupil_edit", WebPupilEdit()) self.putChild("new_pupil", WebPupilInsert()) self.putChild("pc_arrange", WebPCArrangeRoot()) self.putChild("editadmin", WebEditAdmin()) def getChild(self, path, request): if path in ('', 'index.html', 'index'): return self else: return static.File.childNotFound def render_GET(self, request): #verifico el parametro get por si hay que borrar una clase. keys = request.args.keys() if "del" in keys: d = defer.maybeDeferred(lambda: None) alumno = request.getSession().userId erase = DBDelete(self.db) clase = int(request.args['del'][0]) d.addCallback(lambda a: erase.deletePA(clase, alumno)) #borramos la cosa. #falta imprimir mensaje de operacion correcta #como llego a la funcion de internacionalizacion? #d.addCallback(lambda a: request.write('<div class="message">' + \ # _('La clase se ha cancelado correctamente') \ # + '</div>')) d = defer.maybeDeferred(getTranslatorFromSession, request) d.addCallback(self.writeWelcomeMessage, request) return server.NOT_DONE_YET def writeWelcomeMessage(self, trans, request): _ = trans session = request.getSession() request.write(self.template.startPage(session, \ _('Beppo - Sistema de educacion a distancia'))) d = defer.maybeDeferred(lambda: None) if hasattr(session, 'username'): d.addCallback(lambda a: self.template.homePageContent(session)) d.addCallback(request.write) d.addCallback(lambda a: self.template.commonInfo(trans)) d.addCallback(request.write) else: d.addCallback(lambda a: request.write('<h1>' + _('Bienvenido!') \ + '</h1> <p>' + \ _('Aqui podra conocer todas las ventajas de utilizar el sistema Beppo, y lo intentaremos convencer de que lo compre.') + '</p>')) d.addCallback(lambda a: request.write(self.template.finishPage(session))) d.addCallback(lambda a: request.finish()) return d
def __init__(self): self.template = WebTemplates() Resource.__init__(self)
class WebLogin(Resource): def __init__(self): self.db = DBConnect() self.template = WebTemplates() self.render_POST = self.render_GET Resource.__init__(self) def getChild(self, path, request): if path == "": return self else: return static.File.childNotFound def render_GET(self, request): session = request.getSession() _ = getTranslatorFromSession(request) d = defer.maybeDeferred(lambda: None) if hasattr(session, 'username'): request.write(self.template.startPage(session, _('Iniciar Sesion'))) request.write('<div class="message">' + \ _('La sesion ya estaba iniciada') + '</div>') elif "username" in request.args.keys() and "pwd" in request.args.keys(): query = "select username, id, kind, first_name, \ last_name from person where username = %s and password = %s" username = QuotedString(request.args['username'][0]) pwd = sha.new(request.args['pwd'][0]).hexdigest() #hashing sent plain-password in sha-1 d = self.db.db.runQuery(query, (username, pwd)) d.addCallback(self.authenticateUser, request) else: request.write(self.template.startPage(session)) request.write("""<h2>""" + _('Inicio de Sesion') + """</h2> \ <form action="" method="post"><div>""" + _('Nombre de Usuario') \ + """: <label for="username"><input type="text" size="5" name="username" \ id="username" value="Root"/></label><br/>""" + _('Contrasena') \ + """: <label for="pwd"><input type="password" size="5" name="pwd" \ id="pwd" value="lala"/></label><br/><input id="submit" type="submit" value=\"""" + \ _('Entrar!') + """\"/></div></form>""") d.addCallback(lambda a:request.write(self.template.finishPage(session))) d.addCallback(lambda a:request.finish()) d.addErrback(log.err) return server.NOT_DONE_YET def authenticateUser(self, rows, request): session = request.getSession() _ = session._ # Ya sabemos que está if len(rows) == 1: row = rows[0] session.username = row[0] session.userId = row[1] session.kind = row[2] session.name = row[3] session.lastname = row[4] d = defer.maybeDeferred(getTranslatorFromSession, request, refresh=True) d.addCallback(self.welcomeMessage, request, row[3], row[4]) return d elif len(rows) == 0: request.write(self.template.startPage(session)) request.write('<div class="warning"><h2>' + \ _('Nombre de Usuario o Contrasena incorrecta') + '</h2>' + \ _('Por favor verifique su nombre de usuario y contrasena.') + '<br/>' + \ _('Recuerde que su nombre de usuario y contrasena son sensibles a mayusculas y minusculas!') + '</div>') else: request.write(self.template.startPage(session)) request.write('<div class="error">' + \ _('Existen varios usuarios en el sistema con las mismas credenciales. Por favor notifique al administrador del sistema') + '</div>') return def welcomeMessage(self, trans, request, first, last): session = request.getSession() _ = trans d = defer.maybeDeferred(lambda: None) d.addCallback(lambda a: request.write(self.template.startPage(session))) d.addCallback(lambda a: request.write('<div class="message">' + \ _('Bienvenido') + ', %s %s</div>' % (first, last))) d.addCallback(lambda a: self.template.homePageContent(session)) d.addCallback(request.write) d.addCallback(lambda a: self.template.commonInfo(trans)) d.addCallback(request.write) return d
class WebListUsers(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 # A esta pagina sólo se podrá acceder si tenemos permisos de administrador. # Mostrará una lista de clientes, tutores, etc. de acuerdo a lo que se le pase por # direccion 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 # Se escribe el comienzo de la página request.write(self.template.startPage(session, \ _('Listado de usuarios del sistema'))) d = defer.maybeDeferred(lambda: None) keys = request.args.keys() # Si no es admin o no esta loggeado, no seguimos if not hasattr(session, 'username') or session.kind != ADMIN: request.write(self.template.notAuthenticated(session)) else: if "kind" in request.args.keys(): try: kind = int(request.args['kind'][0]) if "del" in keys: erase = DBDelete(self.db) client = QuotedString(request.args['del'][0]) d.addCallback(lambda a: erase.deletePerson(client, kind)) d.addCallback(lambda a: request.write('<div class="message">' + \ _('El usuario ha sido borrado correctamente') + '</div>')) elif ("ia" in keys or "pc" in keys) and "user_id" in keys and \ not ("ia" in keys and "pc" in keys): hours = ("ia" in keys) and "ia" or "pc" user = QuotedString(request.args['user_id'][0]) cant = float(request.args[hours][0].replace(",", ".")) d.addCallback(lambda a: self.setClientHours(user, cant, hours)) d.addCallback(lambda a: request.write('<div class="message">' + \ _('Se ha actualizado correctamente la cantidad de horas disponibles') + '</div>')) d.addCallback(lambda a: self.listClient(request)) except ValueError: d.addCallback(lambda a: \ request.write(self.template.unexpectedArguments(session, \ _('Argumento no valido')))) else: d.addCallback(lambda a: \ request.write(self.template.unexpectedArguments(session, \ _('Falta el argumento \'kind\'')))) # Se escribe el final de la página d.addCallback(lambda a: request.write(self.template.finishPage(session))) d.addCallback(lambda a: request.finish()) return d def setClientHours(self, user, cant, hours): if hours == "pc": query = "update client set pc_available = %f where id=%s """ else: query = "update client set ai_available = %f where id=%s """ d = self.db.db.runOperation(query, (cant, user)) return d def listClient(self, request): """Busca la información para todos los usuarios del tipo dado por la request y llama a printContent con el resultado de la busqueda """ kind = int(request.args['kind'][0]) try: pag = int(request.args['pag'][0]) except: pag = 0 if kind == TUTOR: cols = "tutor.id, username, first_name, last_name" fromWhere = "from tutor, person where tutor.id = person.id" order = "order by id asc" elif kind == PUPIL: cols = "p.id, p1.username, p1.first_name, p1.last_name, p2.username, p.fk_client" fromWhere = "from person p1, person p2, pupil p where p.id = p1.id and p2.id = p.fk_client" order = "order by p.id asc" elif kind == CLIENT: cols = "client.id, username, first_name, \ last_name, organization, client.ai_available, client.pc_available, \ count(pupil.id)" fromWhere = "from client left join pupil on \ (pupil.fk_client = client.id) left join person on (client.id = person.id) \ group by client.id, person.username, person.first_name, person.last_name, \ client.organization, client.ai_available, client.pc_available" order = "order by id asc" elif kind == ADMIN: cols = "person.id, username, first_name, last_name" fromWhere = "from person where kind = %s" % kind order = "order by id asc" else: # kind desconocido cols = "person.id, username, first_name, last_name" fromWhere = "from person where kind = %s" % kind order = "order by id asc" cols += ", (SELECT count(*) %s)" % fromWhere query = "SELECT %s %s %s LIMIT %d OFFSET %d" % (cols, fromWhere, order, ITEMS_PAG, ITEMS_PAG*pag) print repr(query) d = self.db.db.runQuery(query) d.addCallback(self.printContent, kind, request) return d def printContent(self, rows, kind, request): """Lista todos los usuarios del sistema del typo kind (de acuerdo al resultado de la consulta rows """ _ = request.getSession()._ if len(rows) != 0: def paginacion(): total = rows[0][-1:][0] #la ultima columna es el total de datos para la consulta try: actual = int(request.args['pag'][0]) except: actual = 0 if total > ITEMS_PAG: request.write('<div> <strong>' + _('Página:') + '</strong>') for pagina in range(int(total/ITEMS_PAG)+1): tip = "href" if pagina == actual: tip = "id" link = "<a %s='/list?kind=%d&pag=%d'>%d</a> " % (tip,kind,pagina,pagina+1) request.write(link) request.write('</div><br />') request.write('<h2>' + _('Usuarios del sistema:') + '</h2>') if kind == TUTOR: request.write(""" <script type="text/javascript"> function del_confirm(tutor){ return confirm(\"""" + _('Esta seguro de borrar el tutor') + """ \"+tutor+"?"); } </script> """) request.write(""" <table class="table_list" id="usersinsystem"> <tr> <th class="icon_list"></th> <th class="icon_list"></th> <th class="icon_list"></th> <th class="icon_list"></th> <th class="header_list">""" + _('Usuario') + """</th> <th class="header_list">""" + _('Apellido') + """</th> <th class="header_list">""" + _('Nombre') + """</th> </tr>""") for i in range(len(rows)): # row tiene todos los datos de los usuarios del tipo kind request.write("""<tr> <td class="row_list"><a href="tutor?user_id=%s" class="link_image"><img src="/static/graphics/modify.gif" width="16" height="16" alt=\"""" % rows[i][0] + _('Modificar') + """\" title=\"""" + _('Modificar') + """\"/></a></td> <td class="row_list"><a href="?kind=%s&del=%s" class="link_image" onclick="return del_confirm('%s')"><img src="/static/graphics/delete.gif" width="16" height="16" alt=\"""" % (TUTOR, rows[i][0], rows[i][1]) + _('Borrar') + """\" title=\"""" + _('Borrar') + """\"/></a></td> <td class="row_list"><a href="/schedules?user_id=%s" class="link_image"><img src="/static/graphics/schedule.gif" width="16" height="16" alt=\"""" % rows[i][0] + _('Asignar horas') + """\" title=\"""" + _('Asignar horas') + """\"/></a></td> <td class="row_list"><a href="/subjects?user_id=%s" class="link_image"><img src="/static/graphics/subjects.gif" width="16" height="16" alt=\"""" % rows[i][0] + _('Asignar materias') + """\" title=\"""" + _('Asignar materias') + """\"/></a></td> <td class="row_list"><a href="/userinfo?user_id=%s&kind=%d">%s</a></td> <td class="row_list">%s</td> <td class="row_list">%s</td> </tr>""" % (rows[i][0], TUTOR, rows[i][1], rows[i][3], rows[i][2])) request.write('</table>') paginacion() request.write('<a href="/tutor"> ' + _('Agregar tutores') +'</a>') elif kind == PUPIL: request.write(""" <script type="text/javascript"> function del_confirm(pupil){ return confirm(" """ + _('Esta seguro de borrar el alumno') + """ "+pupil+"?"); } </script>""") request.write(""" <table class="table_list" id="usersinsystem"> <tr> <th class="icon_list"></th> <th class="icon_list"></th> <th class="header_list">""" + _('Usuario') + """</th> <th class="header_list">""" + _('Apellido') + """</th> <th class="header_list">""" + _('Nombre') + """</th> <th class="header_list">""" + _('Cliente') + """</th> </tr>""") for i in range(len(rows)): request.write("""<tr> <td class="row_list"><a href="pupil_edit?pupil_id=%s&user_id=%s" class="link_image"><img src="/static/graphics/modify.gif" width="16" height="16" alt=\"""" % (rows[i][0], rows[i][5]) + \ _('Modificar') + """\" title=\"""" + _('Modificar') + """\"/></a></td> <td class="row_list"><a href="?kind=%s&del=%s" class="link_image" onclick="return del_confirm('%s')"><img src="/static/graphics/delete.gif" width="16" height="16" alt=\"""" %(PUPIL, rows[i][0], rows[i][1]) + _('Borrar') + """\" title=\"""" + _('Borrar') + """\"/></a></td> <td class="row_list"><a href="/userinfo?user_id=%s&kind=%d">%s</a></td> <td class="row_list">%s</td> <td class="row_list">%s</td> <td class="row_list">%s</td></tr>""" %(rows[i][0], PUPIL, rows[i][1], rows[i][3], rows[i][2], rows[i][4])) request.write('</table>') paginacion() elif kind == CLIENT: request.write(""" <script type="text/javascript"> function del_confirm(client, pupils){ message = \"""" + _('Esta seguro de borrar el cliente') + """\"+client+"?\\n"; if (pupils > 0){ message += \"(""" + _('Aun tiene') + """ \" + pupils + \" """+_('alumno(s) a cargo') + """)\"; } return confirm(message); } function ask_hours(client, hour_type){ var hours = NaN; while((!hours && hours != 0) && hours != null){ hours = prompt(" """ + _('Indique la cantidad de horas a asignar:') + """ ", "100"); if(hours != null) hours = parseFloat(hours); } if(parseFloat(hours) >= 0){ var url = "?kind=%s&" + hour_type + "=" + parseFloat(hours) + "&user_id=" +client; location.href = url; } } </script> """ % CLIENT) request.write(""" <table class="table_list" id="usersinsystem"> <tr> <th class="icon_list"></th> <th class="icon_list"></th> <th class="icon_list"></th> <th class="icon_list"></th> <th class="header_list">""" + _('Usuario') + """</th> <th class="header_list">""" + _('Apellido') + """</th> <th class="header_list">""" + _('Nombre') + """</th> <th class="header_list">""" + _('Organizacion') + """</th> <th class="icon_list"></th> <th class="header_list">""" + _('Horas disponibles (AI)') + """</th> <th class="header_list">""" + _('Horas disponibles (CP)') + """</th> <th class="icon_list"></th> </tr>""") for i in range(len(rows)): request.write("""<tr> <td class="row_list"><a href="client?user_id=%s" class="link_image"><img src="/static/graphics/modify.gif" width="16" height="16" alt=\"""" % (rows[i][0],) + _('Modificar') + """\" title=\"""" + _('Modificar') + """\"/></a></td> <td class="row_list"><a href="?kind=%d&del=%s" onclick="return del_confirm('%s', %d)" class="link_image"><img src="/static/graphics/delete.gif" width="16" height="16" alt=\"""" % (CLIENT, rows[i][0], rows[i][1], rows[i][7]) + _('Borrar') + """\" title=\"""" + _('Borrar') + """\"/></a></td> <td class="row_list"><a href="new_pupil?user_id=%s" class="link_image"><img src="/static/graphics/board.gif" width="16" height="16" alt=\"""" % (rows[i][0],) + _('Agregar alumno') + """\" title=\"""" + _('Agregar alumno') + """\"/></a></td> <td class="row_list"><a href="report?user_id=%s" class="link_image"><img src="/static/graphics/board.gif" width="16" height="16" alt=\"""" % (rows[i][0],) + _('Ver alumnos') + """\" title=\"""" + _('Ver alumnos') + """\"/></a></td> <td class="row_list"><a href="/userinfo?user_id=%s&kind=%d">%s</a></td> <td class="row_list">%s</td> <td class="row_list">%s</td> <td class="row_list">%s</td> <td class="row_list"><a href="" class="link_image" onclick="ask_hours(\'%s\', \'ia\'); return false;"><img src="/static/graphics/schedule.gif" width="16" height="16" alt=\"""" % (rows[i][0], CLIENT, rows[i][1], rows[i][3], rows[i][2], rows[i][4], rows[i][0]) + _('Asignar horas') + """\" title=\"""" + _('Asignar horas') + """\"/></a></td> <td class="row_list">%s</td> <td class="row_list">%s</td> <td class="row_list"><a href="" class="link_image" onclick="ask_hours(\'%s\', \'pc\'); return false;"><img src="/static/graphics/schedule.gif" width="16" height="16" alt=\"""" % (self.hoursFormat(rows[i][5]), self.hoursFormat(rows[i][6]), rows[i][0]) + _('Asignar horas') + """\" title=\"""" + _('Asignar horas') + """\"/></a></td></tr>""") request.write('</table>') paginacion() request.write('<a href="/client">' + _('Agregar clientes') + '</a>') elif kind == ADMIN: request.write(""" <table class="table_list" id="usersinsystem"> <tr> <th class="header_list"></th> <th class="header_list">""" + _('Usuario') + """</th> <th class="header_list">""" + _('Apellido') + """</th> <th class="header_list">""" + _('Nombre') + """</th> </tr>""") for i in range(len(rows)): request.write("""<tr> <td class="row_list"><a href="editadmin?user_id=%s" class="link_image"><img src="/static/graphics/modify.gif" width="16" height="16" alt=\"""" % (rows[i][0],) + _('Modificar') + """\" title=\"""" + _('Modificar') + """\"/></a></td> <td class="row_list"><a href="/userinfo?user_id=%s&kind=%d">%s</a></td> <td class="row_list">%s</td> <td class="row_list">%s</td> </tr>"""% (rows[i][0], ADMIN, rows[i][1], rows[i][3], rows[i][2])) request.write('</table>') paginacion() request.write('<a href="/editadmin"> ' + _('Agregar Administrador') +'</a>') else: for i in range(len(rows)): request.write('<li>' + _('Usuarios') + '%s %s, %s</li>' % (rows[i][0], rows[i][4], rows[i][5])) else: request.write('<h2> ' + _('No hay usuarios de este tipo en el sistema') + '</h2>') request.write('<a href="/admin" id="back"> ' + _('Volver') + '</a>') return def hoursFormat(self, hours): return (hours == None) and "0.0" or hours
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))
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
def __init__(self): self.db = DBConnect() self.template = WebTemplates() Resource.__init__(self)
class WebArchive(Resource): _ = dummyTranslator 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 las pizarras guardadas en la base de datos 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, \ _('Archivo de pizarras'))) 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 else: msg = _('Este es el archivo de las pizarras correspondientes a las clases dadas en el sistema. Puedes bajar cualquiera de las pizarras haciendo click en el nombre del archivo. La informacion de la fecha que aparece corresponde a la fecha de finalizacion de la clase') msg = '<h2>' + _('Archivo') + '</h2>' + msg + '<br/>' d.addCallback(lambda a: request.write(msg)) # La función que imprime el contenido, pero con otros argumentos self.printContent(request, d) # 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): """Consulta las sesiones del tutor user_id en la base de datos y las manda a imprimir """ query = "select a.filename, s.fk_tutor, p.username, s.fk_pupil, p2.username, \ a.comment, s.time_end from archive a left join session s \ on (s.id = a.fk_session) left join person p on (p.id = s.fk_tutor) \ left join person p2 on (p2.id = s.fk_pupil)" d.addCallback(lambda a: self.db.db.runQuery(query)) d.addCallback(self.printData, request) return d def printData(self, rows, request): # cada row de rows trae: # [0]: filename # [1],[2]: tutor id, tutor username # [3],[4]: pupil id, pupil username # [5]: comentario # [6]: fecha y hora de fin de esa session _ = request.getSession()._ if len(rows) == 0: string = "<div class='client_info'>" + _('El archivo esta vacio') + '</div>' else: string = _('Se encontraron %d archivos:') % len(rows) string += """ <table class="table_list" id="archive"> <tr> <th class="header_list">""" + _('Archivo') + """</th> <th class="header_list">""" + _('Tutor') + """</th> <th class="header_list">""" + _('Alumno') + """</th> <th class="header_list">""" + _('Fecha') + """</th> <th class="header_list">""" + _('Comentario') + """</th> </tr> """ for row in rows: tutor_name = (row[2] is not None) and \ "<a href='/userinfo?user_id=%s&kind=%d'>%s</a>" % \ (row[1], TUTOR, row[2]) or _('El tutor ya no esta en el sistema') pupil_name = (row[4] is not None) and \ "<a href='/userinfo?user_id=%s&kind=%d'>%s</a>" % \ (row[3], PUPIL, row[4]) or _('El alumno ya no esta en el sistema') date = (row[6] is not None) and row[6].Format(DATETIME_FORMAT) or "" string += """ <tr class="row_list"> <td><a href="%s">%s</a></td> <td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> </tr>""" % ("board_archive/" + row[0], row[0], tutor_name, pupil_name, date, row[5]) string += """</table>""" request.write(string) return
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 "&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&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 "-"
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> " % (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&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)
def __init__(self): _ = dummyTranslator self.db = DBConnect() self.render_POST = self.render_GET self.template = WebTemplates() Resource.__init__(self)
def __init__(self): self.db = DBConnect() self.template = WebTemplates() self.render_POST = self.render_GET Resource.__init__(self)