Out Of Bounds Exception!

Mi lugar de irreflexión y algo de programación

Codeando un servidor web en python para administrar programas remotamente (I)

Tras una temporadilla considerable sin pasarme por estos lares a actualizar con alguna aventura de las mías, hoy, por fin, vuelvo a las andadas.

Y lo hago nada más y nada menos que con un programa que se me ocurrió en una de esas tardes ociosas típicas: un proceso que actúe como servidor web, mostrando una página html pseudodinámica (luego explico por qué el ‘pseudo’) que permita a un usuario administrar (iniciar, detener y comunicarse) una serie de programas configurables.

La idea me vino debido a que mis compañeros de clase y yo solemos jugar a diversos juegos según la temporada, y muchas veces a uno le toca hacer de servidor para alguno en concreto, por lo que se hace algo pesado estar pendiente de cuando los otros quieren jugar y tú no quieres o no estás. Por lo tanto, creé este programa para evitarme eso, símplemente me basta con tener el pc encendido conectado a internet y el servidorcillo web corriendo.

Tras esta pequeña introducción, vamos al lío. Primero hay que elegir el lenguaje de programación, el cual tiene que cumplir, al menos, dos requisitos: mínimo consumo de memoria y facilidad para lo que queremos hacer. Expongo a continuación mis 3 lenguajes preferidos y vamos descartando:

C++ no es precisamente trivial para abrir sockets ni en el manejo de procesos sobre Windows, por no hablar de que la programación sobre esta plataforma, para mí, es horrible, así que ni me lo planteo.
Java y su consumo de memoria no es precisamente óptimo y, aunque probablemente se pueda configurar la máquina virtual para que no ocupe esos odiosos 50 MB de ram para hacer una suma, quiero algo simple y lo quiero ya, así que descartado.
Python… qué puedo decir de mi amado Python, es más simple que el mecanismo de un chupete, consume poco más que un programa en C y además es posible que el resultado sea portable a Linux y todo. No se hable más.

¡Y empieza el codeo! Empecemos con la clase principal, que incluye el sevidor (nótese que soy algo nuevo en Python, así que es probable que muchas cosas se puedan hacer mejor o más rápido; si es así decídmelo y lo actualizo con mucho gusto).

Función main que es la que arranca todo el tema (llamada cuando se arranca el script):

def main():
    try:
        print 'Programs loaded...'
        loadProgramList()
        server = HTTPServer(('', 8080), ServerHandler)
        print 'Started httpserver...'
        server.serve_forever()
    except KeyboardInterrupt:
        print '^C received, shutting down server'
        server.socket.close()

if __name__ == '__main__':
    main()

Carga la lista de programas y arranca el servidor, simple, ¿no?

La función loadProgramList símplemente va a abrir un archivo de programas que tiene el siguiente formato (nótese que cada campo está separado por una tabulación, no por un espacio):

#NOMBRE RUTA PROCESO DESC
TaskManager V:\Window$\System23\taskmgr.exe taskmgr Programa bonito

La función es la que sigue:

def loadProgramList():
    file = open('programs')
    
    global programs
    programs = list()
        
    for line in file:
        if line.find('#') != 0 and line != '':
            line = line.replace('\n','').split("\t")
            programs.append({'name':line[0], 'path':line[1], 'process':line[2], 'manager':None})
            
    return programs

Programs es una variable global en la que guardamos una lista donde cada programa es un diccionario clave-valor con las propiedades extraídas del fichero y un extra, manager, que luego explicaré.

Vamos a la clase del ServerHandler:

class ServerHandler(BaseHTTPRequestHandler):
    
    def do_GET(self):
        try:
            if not self.path.endswith('favicon.ico'):                
                                   
                self.send_response(200)
                self.send_header('Content-type', 'text/html')
                self.end_headers()
                self.wfile.write(makeHtml())                    
                return
                
        except IOError:
            self.send_error(404,'File Not Found: %s' % self.path)
            return     

Algo simplificado, pero igualmente válido para explicar las bases. Cuando nos soliciten una página por get, contestamos con el resultado de la función makeHtml

Para terminar con la primera parte, veamos cómo es esta función:

def makeHtml():
    html = ''
    
    file = open('index.html')
    
    #load the html
    for line in file:
        html += line
            
    #find server's tags
    regex = re.compile(r' .*? ')
    tags = regex.findall(html)
    
    #replace server's tags
    for tag in tags:
        keyword = tag.replace('', '').replace('', '').strip()
        if keyword == ...
            content = ...
            html = html.replace(tag, content)
    return html

Vamos por partes, primero abrimos la página en html que hemos creado (con su css, javascript y demás ya hecho) y buscamos nuestras etiquetas personalizadas, que tendrán la forma <py>tag</py> donde ‘tag’ estará definido en el código (o, en caso de que en un futuro se quiera expandir esto, en un fichero). Ahora se sustituye cada una de las etiquetas por un contenido concreto, en mi caso haré que por cada programa se cree una etiqueta <li> para mostrar una serie de pestañas hechas con JQuery. Por otro lado debajo de esto añadiré, también para cada programa, un contenido concreto (varios botones, una caja de texto, etc) para el manejo de cada programa. En resumen, queda algo así:

El estilo ya es cosa de cada uno, yo como soy algo cutre lo he hecho lo más simple posible =P

En la parte 2 añadiré algunas mejoras y veremos cómo arrancar procesos y comunicarnos con ellos.

¡Un saludo!

Anuncios

Una respuesta a “Codeando un servidor web en python para administrar programas remotamente (I)

  1. Ybn Isaac 15 mayo, 2013 en 16:43

    bastante interesante..

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: