ZombieKiosk (o cómo hacer un navegador en modo kiosko para la BNCT)

UI de ZombieKiosk

Hace ya algo más de  un mes (por cuestiones de examenes) fuí a la BNCT (Biblioteca Nacional de Ciencia y Tecnología) y ví las máquinas de consulta del catálogo (unas IBM lentium Pentium II) corriendo sobre XP, cuestión que no me agradó mucho por cuestiones de rendimiento; y una semana después como si alguien de administración me hubiese leido la mente, de repente las ví corriendo LTSP + CentOS + Firefox (elección que si bien se basa en Software Libre, a mi parecer no era correcta por el consumo de memoria de Firefox), afortunadamente @Bk_ag, @P1R0 y yo pudimos contactar a Carlos Ruíz Juárez, el Jefe de Servicios Técnicos de la BNCT, para proponerle montar algo mas ligero en el servidor de esos clientes ligeros, para lo que propuse hacer un ‘mini navegador web’ escrito en python, GTK+, y usando WebKit como motor de renderizado (aprovechando mis pocos conocimientos), y montarlo como única aplicación (por motivos no sólo de rendimiento, sino también de seguridad al no dar más opciones de software) para lanzarlo usando LTSP (ya después contaré la posterior ruptura de nervios al montar el LTSP ).

Después de esta larga historia pasaré a contar cómo se gestó ZombieKiosk:

La interfáz se ideó para que fuera foolproof, sencilla y sólo usando las opciones necesarias, la ventana no puede cerrarse de ningún modo (se lanza a pantalla completa, aunque en la captura de arriba la tengo en modo ventana, y la unica forma de cerrarla es matando el proceso).

Se agregó una función para leer archivos de configuración para no modificar el código en caso de querer cambiar la dirección web del catálogo ( y por si alguien lo quiere implementar en otro lado)

Como ya comenté usé python, pygtk, pywebkit y glade (para diseñar la interfáz), en Ubuntu/Debian, lo unico que necesitan hacer para instalar lo necesario es dar en la terminal:

sudo aptitude install python2.6 python-gtk2 python-webkit

si quieren correr zKiosk e incluso los invito a modificarlo, jugar con su código fuente.

El código de zKiosk se encuentra en su página de Google Code.

#/usr/bin/env python
import gtk
import pygtk
import webkit
import ConfigParser
from os import popen

#Introducimos el valor por default a la configuracion, en caso de que no exista
cfg = ConfigParser.SafeConfigParser({'web': 'http://148.204.48.96/uhtbin/webcat', 'theme': 'gtkrc'})
# Leemos el archivo de configuracion
cfg.read(["config.cfg"])
#Asignamos los valores de la configuracion a variables para su uso posterior
web = cfg.get("Biblio","web")
theme = cfg.get("Biblio","theme")
#Parseamos el archivo del estilo visual
gtk.rc_parse(theme)

class Window:
	def __init__(self):
		self.builder = gtk.Builder()
		self.builder.add_from_file('zkiosk-ui.glade')
		self.window = self.builder.get_object('window1')
		self.Browser = self.builder.get_object('Browser')

		#inicializa el widget del motor de renderizado y lo agrega a la interfaz
		self.webview = webkit.WebView()
		self.Browser.add(self.webview)

		#cambiando a pantalla completa
		maxx = gtk.gdk.screen_width()
		maxy = gtk.gdk.screen_height()
		self.window.set_size_request(maxx,maxy) 

		self.window.show_all() #mustra los elementos de la ventana

		#conectando los botones y eventos de la ventana a las funciones
		self.builder.connect_signals(self)

	def home(self, widget):
		self.webview.open(web)

	def back(self, widget):
		self.webview.go_back()

	def fwd(self, widget):
		self.webview.go_forward()

	def refresh(self, widget):
		self.webview.reload()

	def about(self, widget):
		self.window.set_modal(False) #Quita la exclusividad del foco de la ventana principal y permite controlar el cuadro de acerca de..
		self.About=self.builder.get_object('aboutb') #Accesamos al objeto correspondiente a ese dialogo

		def openW(widget,url,url2): # Evita abrir el sitio en el cuadro de dialogo acerca de
			print url

		gtk.about_dialog_set_url_hook(openW,"") # Evita abrir el sitio en el cuadro de dialogo acerca de
		# Obtenemos los eventos generados
		Response = self.About.run()
		#Si se presiona el boton de cerrar o se cierra el cuadro lo oculta y restaura el foco en la ventana principal
		if Response == gtk.RESPONSE_DELETE_EVENT or Response == gtk.RESPONSE_CANCEL:
			self.About.hide()
			self.window.set_modal(True)

	def noclose(widget, event,data): #evita que se cierre la ventana principal
		return True

if __name__ == '__main__':
	w = Window()
	popen("xsetroot -cursor_name left_ptr")
	w.webview.open(web)
	gtk.main()
Anuncios