Personal Website

My Web: MindEchoes.com

Wednesday, March 31, 2010

PyTv 1.3!


PyTv 1.3 Disponible!

La versión 1.3 de PyTv ya esta disponible, esta nueva versión con respecto a la anterior presenta los siguientes cambios:
  • La opción de "Refresh" se implementa como un hilo para evitar que se trabe la aplicación como sucedía.
  • Mejorada la descarga de la información de los torrents y subtitulos disponibles (mucho mas preciso).
  • Descarga la información de la serie cuando PyTv vuelve a tener conexión a internet en caso de que haya un error o se cierre el programa antes de recolectar todos los datos.
  • Comprueba que no se agregue más de una vez la misma serie.
  • Muestra la Imagen (o Caratula) de las Series en la Notificación y en la Tabla con información de los episodios (la opción para que descargue las caratulas y las muestre puede deshabilitarse desde Preferencias).
  • Mejoras en la captura de la información de las series (para reconocer casos atípicos con los que fallaba, teóricamente reconociendo todas las series ahora).
  • Descarga Automática: con esta opción seleccionada en Preferencias, al estar disponible la información de los torrents y subtitulos de las series, descarga todos los torrents y abre las paginas de los subtitulos para que se elijan cuales descargar.
Menu PyTv:


Notificaciones Tradicionales:



Notificaciones con Iconos de las Series:



Tabla Tradicional:


Tabla con Iconos de las Series:



Pagina oficial del Proyecto: http://code.google.com/p/pytv-series/
Descargar código fuente: pytv-1.3.zip
Descargar Instalador i386: pytv-1.3_i386.deb
Descargar Instalador amd64: pytv-1.3_amd64.deb

La Pelicula Mas Picante Del Universo!

Pawan Sinha explica cómo el cerebro aprende a ver

Un Genio Este Tipo!



Tiene subtitulos en español si los eligen...

Sunday, March 28, 2010

Por Que El Planeta Tierra se llama "Tierra"?

Se me cruzó esta pregunta en la cabeza quien sabe por que, y aunque algunos pudieran decir que es muy trivial, a mi no me parece que lo sea tanto y quería sacarme la duda.
Osea, en un planeta con una población mundial de más de 6.706.993.152 (esa cantidad era en el año 2008), ¿por qué todos conocemos a este planeta con el nombre de: Tierra?

O sus distintas variaciones (si google translate no me mintió):

  • Tierra (Español)
  • Earth (Ingles)
  • Terre (Francés)
  • Terra (Italiano)
  • Aarde (Holandés)
  • Jord (Sueco)

Buscando en Internet, se encuentra rápidamente que el nombre de los planetas del sistema solar (incluido la Tierra), proviene de la mitología Griega y Romana:

  • Mercurio: Mensajero de los dioses y dios del Comercio.
  • Venus: Diosa del amor.
  • Tierra: (Gea, Gaya, Gaia) Diosa que personifica la Tierra, Diosa Madre o Gran Diosa, su equivalente en el panteón romano es Terra.
  • Marte: Dios de la Guerra.
  • Júpiter: Dios supremo y creador del Universo.
  • Saturno: Dios titan, padre de Júpiter.
  • Urano: Dios del Cielo.
  • Neptuno: Dios del Mar.

Gea (o sus distintos derivados) es la gran Madre Tierra, la diosa más primitiva presente en la mayoría de las culturas antiguas. Así es como los Griegos personificaban a la Tierra como Gea (o Gaia, Gaya), los Romanos como Tellus o Terra, en la mitología nórdica la Tierra es personificada como Jörð, etc, etc.

Y es de ahí de donde sale el nombre del Planeta Tierra!
De una representación mitológica del planeta como una Diosa Madre, y de sus distintos nombres y derivados es de donde cada lengua toma la palabra "Tierra" para referirse al planeta.

Tuesday, March 23, 2010

Digale NO!

Digale NO a ser un "Programador" que solo sabe depender de un IDE y sus Wizards!

Jugando con Go

Bueno, andaba con ganas de postear algo, y se me ocurrió empezar a hacer mini-programitas usando Go (el lenguaje de Google), y de paso no colgarme y empezar a hacer algo con este lenguaje como para ir aprendiendo sino me quedo en lo básico nomas... pero bueno, ahora empecemos por lo básico:

Qué es Go y Como Instalarlo??: Post en MundoGeek

Compilando con Go
Como se ve en el Post de MundoGeek, hay diversas formas de compilar según la arquitectura, en mi caso, en Ubuntu en lugar de andar usando "6g" o "6l", directamente lo que hice fue en el archivo ".bashrc" en el "home" fue agregar o descomentar las lineas:


if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi

Lo cual permite cargar el archivo ".bash_aliases" si existe, y en ese archivo crear alias para ciertos comandos que quiera ejecutar para que sean mas directos o fáciles de recordar, como por ejemplo:

Contenido de ".bash_aliases":

alias goc='6g'
alias go='6l -o prog'

De esta forma, ahora para compilar mi programa que se encuentre en un archivo de nombre "programa.go" solo tendría que hacer:

$ goc programa.go
(se crea el archivo programa.6 o programa.8 según la arquitectura)


$ go programa.6
(en mi caso es "6" por ser de 64 bits, y por como quedo configurado el alias, el ejecutable se llamaría "prog", esa parte del alias podría omitirse si quisiéramos darle nombre a cada programa en particular, en mi caso lo puse así porque como estoy haciendo ejemplos para aprender y probar todos en carpetas distintas se me hacia mas rápido)

Y por ultimo podemos hacer:
$ ./prog
Y ejecutamos el programa!

Para que un programa sea ejecutable en Go debe declararse que su paquete sea "main" (al menos el archivo por donde comienza la ejecución). La función "main" del paquete "main" es donde el programa comienza su ejecución.

Típico "Hola Mundo":
package main
import "fmt"
func main(){
    fmt.Printf("Hola mundo\n");
}

El paquete "fmt" es el que se encarga de las entradas y salidas formateadas (vendría a ser algo así como el "stdio.h" de C para usar el printf... solo que acá es... Printf! jeje)
Las funciones son declaradas en Go con la palabra reservada "func".

Un detalle en cuanto a las funciones en Go, es que en lugar de utilizar las palabras reservadas "private" o "public" como en muchos lenguajes para especificar el tipo de acceso a la función, esto se denota colocando la primer letra del nombre del método en Mayúscula para el acceso Publico o en Minuscula para el acceso Privado.
Otro tema interesante es la inicialización de variables que puede omitirse el tipo y hay varias formas de declarar las variables, pero sera un tema para el próximo post.

En este Post no voy a profundizar mucho mas en el lenguaje (sobre todo porque recién lo estoy aprendiendo), sino que voy a ir directo a algunos ejemplos básicos:

Ejemplo Simple de Iteración:
package main
import "fmt"
func main(){
    for i:= 0; i < 10; i++ {
        fmt.Printf("Hola %d\n", i)
    }
}

Como se puede ver el tipo de la variable "i" no es necesario declararlo en este caso, y es un tradicional for que imprimi 10 "Hola "[y el numero que toma la variable "i"], la cual va del 0 al 9.


Recorriendo String con For
Antes de seguir con el ejemplo, en Go los String son un tipo de dato nativo a diferencia de C (Wiii!!)

package main
import "fmt"
func main(){
    s := "diego sarmentero";
    for _, c := range(s){
        fmt.Printf("%c\n", c)
    }
}

En este ejemplo también podemos ver que no es necesario declarar el tipo de la variable "s".
Y en cuanto al for, vemos que es posible utilizar una especie de "for-each" en Go, pero es un tanto distinto a lo que uno podría estar acostumbrado, para empezar vemos que tenemos "_, c" esto es porque en la primer posición se estaría obteniendo el valor de cada iteración (la tipica variable i), la cual se recibe con "_" indicando que es ignorado y en la segunda posición se obtiene una variable de tipo carácter, con el valor correspondiente a la posición que se esta leyendo en el string.
La función range() (no les suena de Python?), especifica la cantidad de elementos por la que se iterara.

Recibiendo Argumentos
El siguiente programa utiliza el paquete "flag" para leer los argumentos que recibe el programa al ser ejecutado, luego con un for recorre los argumentos utilizando como tope el valor obtenido por la función "flag.NArg()" la cual devuelve el número de la cantidad de argumentos ingresados, y va concatenando en un string cada uno de estos argumentos separados por un espacio y luego imprime ese string en pantalla (en este ejemplo puede verse que pueden hacerse varias importaciones, declaraciones de constantes, etc, simplemente colocando la palabra reservada y luego dentro de un parentesis todo a lo que se aplica):

package main
import(
    "os";
    "flag";
)
const(
    Space = " ";
)
func main(){
    flag.Parse();
    s := "";
    for i := 0; i < flag.NArg(); i++ {
        if i > 0 {
            s += Space
        }
        s += flag.Arg(i)
    }
    os.Stdout.WriteString(s + "\n")
}

Invocando una Función y Retornando un valor:
En este ejemplo podemos ver como se crea un array, se pasa la referencia a este array a una función, sin necesidad de explicitar el tamaño del mismo como se suele hacer en algunos casos en C, sino que dentro del método se utiliza la función len() para calcular el tamaño del mismo (la típica: sizeof(array)/sizeof(array[0])), entonces en la función se recorre el array, se van sumando sus valores y luego se devuelve el resultado. Cabe destacar, que la variable a retornar se define en la declaración del método mismo y al colocar el "return" no es necesario especificar ahí la variable.
Otro tema interesante es que un mismo método puede retornar mas de una variable, pero eso es un tema para el siguiente post.

package main
import "fmt"
func main(){
    var array = [4]int{1, 2, 3, 4};
    s := sum(&array);
    fmt.Printf("%d\n", s)
}
func sum(a []int) (b int){
    for i:= 0; i < len(a); i++ {
        b += a[i]
    }
    return
}

Servidor Web
Y para terminar, este es un ejemplo que vi en UbuntuLife y que queria poner para que se vea lo facil que se pueden hacer algunas cosas:
Con “Go” podemos incluso crear un servidor web en apenas muy pocas lineas de codigo:

package main
import (
"http";
"io";
)
func main() {
    //define la funcion para manejar la peticion a "/test_go"
    http.Handle("/test_go", http.HandlerFunc(RequestHandler));
    //esperar conexiones entrantes en el puerto 1234
    err := http.ListenAndServe(":1234", nil);
    //si se produce algun error:
    if err != nil {
         panic("Error: ", err.String());
    }
}
func RequestHandler(c *http.Conn, req *http.Request) {
    //recuperar e imprimir los parametros:
    str :=  "<strong>Protocol:</strong> " +
    req.Proto + "" +"<strong>Method:</strong> " +
    req.Method + "" +"<strong>User-Agent:</strong> " +
    req.UserAgent;
    //escribir la respuesta:
    io.WriteString(c, str);
}


Al ejecutarlo se creara el servidor web que quedara esperando a las peticiones entrantes.
Abre ahora un navegador y mete como URL: http://127.0.0.1:1234/test_go
De manera inmediata deberias poder ver la respuesta del server:

Sunday, March 21, 2010

Compilado de Imágenes (Sci-Fi)

Compilado de Imágenes del Espacio y Ciencia Ficción

Instalador DEB para programas Python

Bueno, trabajando con PyTv quise hacer un paquete DEB para que sea mas fácil instalar el programa, y acá dejo los pasos que seguí para poder hacerlo:

Primero es necesario tener instalados los siguientes paquetes: dpkg-dev y dh-make, los cuales pueden instalarse de la siguiente forma:

sudo apt-get install dpkg-dev dh-make

Para ir dejando las cosas claras, vamos a tomar la carpeta "pytv-series" como la carpeta donde actualmente estaría contenido el programa que se ha desarrollado (los nombres de las carpetas, etc. deben ser adaptados según el programa para el que se este haciendo el paquete, los nombres que aparecen acá son a modo de ejemplo).
Supongamos que la carpeta del programa desarrollado y las carpetas que vamos a crear parten del "home", por una simple cuestión de simplicidad, luego simplemente habría que reemplazar "home" por la ruta a donde se tenga realmente las carpetas.

1) Primero vamos a necesitar crear una carpeta donde trabajar:
~$ mkdir deb
~$ cd deb
Luego una vez dentro de esa carpeta, procedemos a crear una carpeta con el nombre de nuestro programa y la versión:
~$ mkdir pytv-1.2
En este último directorio creado debemos copiar una versión empaquetada de nuestro programa, la cual podemos realizar de la siguiente forma:

(Accedemos a la carpeta de nuestro programa)
~$ cd /home/pytv-series
~$ tar cfzv pytv-1.2.tar.gz *
~$ cp * /home/deb/pytv-1.2
~$ cd /home/deb/pytv-1.2
("pytv-series" es la carpeta donde esta nuestro código fuente y "pytv-1.2" es la carpeta creada para este ejemplo donde vamos a poner todos los archivos necesarios para crear el paquete DEB. El empaquetado creado con "tar" debe llevar el nombre y versión del programa para el que lo queremos hacer)
Los fuentes que fueron empaquetados dentro de "pytv-1.2.tar.gz" también es necesario copiarlos dentro de la misma carpeta ("/home/deb/pytv-1.2")

2) Dentro de nuestra carpeta de trabajo donde quedamos después del último comando ejecutado, utilizamos el comando dh_make (el cual es uno de los programas instalados al iniciar) de la siguiente forma:

~$ sudo dh_make -e diego.sarmentero@gmail.com
      -f pytv-1.2.tar.gz -c GPL

Este comando se encarga del proceso de "debianización" del directorio. Los parámetros especificados son los siguientes:

  • -e diego.sarmentero@gmail.com : es el e-mail del creador del programa
  • -f pytv-1.2.tar.gz : indicamos el nombre del paquete comprimido que contiene nuestro programa
  • -c GPL : indicamos la licencia del programa
Luego de haber ejecutado el último comando, podremos ver que se ha creado una carpeta llamada "debian" en el directorio en el que nos encontramos.

3) Entramos dentro de la carpeta "debian" y nos encontramos con una serie de archivos, algunos de ellos no serán de utilidad para nuestro propósito, por lo que podemos eliminarlos:

(dentro de la carpeta "debian"):
~$ rm *.ex *.EX
Ahora procedemos a editar los demás archivos para nuestro programa:

CHANGELOG
Simplemente (si no tenemos historiales de cambios o cosas asi) es necesario colocar la versión del programa y el nombre del autor:


pytv (1.2) stable;


-- Diego Sarmentero Fri, 05 Mar 2010 17:50:57 -0300

COMPAT
No es necesario hacer ninguna modificación con este archivo (por lo menos yo no lo hice :P), así que lo podemos dejar así como esta.

CONTROL
Este es uno de los mas importante, ya que establece las categorias, dependencias, y otras configuraciones del programa. Para PyTv la configuración quedo como sigue y se explica a continuación:


Source: pytv
Section: utility
Priority: extra
Maintainer: Diego Sarmentero
Build-Depends: debhelper (>= 7)
Standards-Version: 3.8.1
Homepage:


Package: pytv
Architecture: any
Depends: python (>=2.5.2-1ubuntu1), python-qt4 (>=4.4.4-2), sqlite (>=2.8.17-6build1), python-beautifulsoup (>=3.1.0.1-2)
Description: PyTv: Tv Series notification utility

Los detalles a configurar mas relevantes son:

  • Source: (OPCIONAL) el nombre del paquete fuente del que proviene él paquete binario, en caso de que ambos sean distintos. En este caso se podría omitir pero tampoco hace mal dejarlo.
  • Section: (OPCIONAL) define la categoría del paquete. Una forma simple de verlo es que dentro de esta categoría lo podremos encontrar en el menú de Aplicaciones. Otras categorías son: "games", "devel", "text", "video", "sound", etc.
  • Maintainer y Homepage: Es la información del desarrollador (o el que mantenga) el programa y la web del mismo programa
  • Package: (CAMPO NECESARIO) determina el nombre del paquete.
  • Architecture: La arquitectura para la que se compiló el paquete. Arquitecturas comunes son ‘i386’, 'amd64', ‘m68k’, ‘sparc’, ‘alpha’, ‘powerpc’, etc. La opción "all" es para paquetes independientes de la arquitectura como lo son los scripts de Perl o la documentación.
  • Depends: Este quizás sea el mas importante de configurar si nuestro programa necesita de alguna librería adicional o lo que fuera. Lo que necesitamos poner es el nombre del paquete con el que se tiene dependencia y a partir de que versión (según con la que hayamos trabajado para hacer el programa). Es importante respetar el formato que se muestra arriba. Los paquetes y sus versiones se pueden consultar en el Gestor De Paquetes.
  • Description: en la documentación de figura como NECESARIO, así que por las dudas poner aunque sea una pequeña descripción del proyecto... no cuesta nada jeje
COPYRIGHT
Para este archivo solo es necesario modificar el nombre del autor y la url de la página del proyecto.

DIRS
Contiene la ruta de los directorios que el paquete necesitará para para instalar el programa.
En el caso de PyTv:

usr/bin
usr/share/pytv
usr/share/applications

En la segunda linea sería necesario reemplazar "pytv" por el nombre del paquete de la aplicación con la que se esta trabajando.

DOCS
En mi caso este archivo permaneció vació, pero si hay alguna documentación referente al proyecto que se pueda agregar, ese podría ser un lugar donde colocarla.

README.Debian
En él ponemos comentarios que consideremos importantes para quien vaya a utilizar el programa. Este archivo no es obligatorio, en mi caso agregue simplemente lo siguiente:

pytv for Debian/Ubuntu
----------------------

http://code.google.com/p/pytv-series/

-- Diego Sarmentero Fri, 05 Mar 2010 17:50:57 -0300

RULES
Este archivo tiene una configuración un tanto extensa, aunque no complicada, yo recomendaría simplemente descargar el ejemplo al final del Post y utilizar como base el archivo RULES presente en el zip.
La única sección que sería necesario modificar es: "install: build", cambiando donde figure "pytv" por el nombre de la aplicación con la que se esta trabajando.

4) Luego de esto dejamos la carpeta debian y volvemos a la carpeta pytv-1.2 que contenia a debian.
Un detalle importante es en cuanto al manejo de imagenes y archivos creados por el programa.
En el caso de PyTv al desarrollar las imagenes eran accedidas a través de rutas relativas al directorio donde se esta ejecutando el programa, y SQLite utilizaba también un archivo para la Base de Datos accediendo a él de forma relativa al directorio actual:

#Cargando imagen
pixmap = QtGui.QPixmap('pytv.png')
#Accediendo a la Base de Datos
import sqlite3 as dbapi
db = dbapi.connect(".pytv.dat")

Pero esto nos puede ocasionar un problema cuando la aplicación este instalada, por lo que una opción recomendable seria darle a las rutas de los archivos una ruta absoluta, como por ejemplo:

pixmap = QtGui.QPixmap('/usr/share/pytv/pytv.png')

Que es donde se copiarían en el caso de PyTv todos los archivos del programa segun especificamos al configurar el archivo DIRS y RULES en la carpeta DEBIAN en el punto anterior.
Otro detalle a tener en cuenta, como es en el caso de la Base de Datos que se crea en PyTv para ser usada con SQLite, es que todo lo que antes se creaba utilizando una ruta relativa en el directorio actual, ahora pasaria a crearse a partir del "home".

5) Creando el archivo ".desktop"
El archivo ".desktop" cumple la función de ser una especie de acceso directo. Se trata de un archivo de texto que contiene información de nuestro programa, define un icono y permite que el usuario lance el programa haciendo doble clic sobre el. El archivo "pytv.desktop" (el cual debe estar dentro de la carpeta "pytv-1.2" en el caso de este ejemplo) contiene lo siguiente:


[Desktop Entry]
Encoding=UTF-8
Name=PyTv
Icon=/usr/share/pytv/pytv.png
Comment=PyTv: Tv Series notification utility
Exec=/usr/bin/pytv
Terminal=false
Type=Application
Categories=GNOME;Utility;
StartupNotify=False

Como podemos ver es basicamente información descriptiva acerca de la aplicación, donde lo mas relevante serían las rutas de la imagén y ejecutable del programa.

6) Dentro de la carpeta "pytv-1.2" en la que seguimos trabajando, creamos el archivo pytv (en el caso de este ejemplo, obviamente "pytv" debería ser reemplazado por la aplicación con la que se esta trabajando), el cual contiene lo siguiente:

#!/bin/sh
python /usr/share/pytv/pytv.py

7) Momento de crear el Paquete DEB
Lo único que debemos hacer es situarnos en la carpeta "pytv-1.2" (reemplazar con el nombre de nuestra aplicación... si si, sigo insistiendo :P).

cd /home/deb/pytv-1.2

y luego ejecutar el comando:

sudo dpkg-buildpackage

Y ya deberíamos tener creado nuestro archivo ".deb" en la carpeta "deb".
En esta carpeta van a aparecer otros archivos mas junto con el ".deb" pero no son de importancia, así que pueden ser eliminados sin problema.
Y ahora podemos proceder a instalar la aplicación:





Advertencia: Al generar el Paquete DEB lo crea por la configuración del archivo CONTROL para la arquitectura especifica de la maquina en la que se esta trabajando. En mi caso "amd64", quizas haya otra forma que no se :P, pero para hacer un instalador "i386" lo que hice fue abrir la carpeta en una maquina virtual con otra arquitectura y correr el comando "sudo dpkg-buildpackage" dentro de la maquina virtual, y de paso probar en esa arquitectura si el instalador funcionaba correctamente.

Resultado final de los archivos de configuración y fuentes utilizados en el ejemplo: DESCARGAR

Friday, March 19, 2010

PyTv 1.2!!


PyTv 1.2 Terminado!!

La nueva versión de PyTv (y probablemente la última porque ya no se me ocurre que agregarle... a no ser que aparezcan bugs :P) esta terminada!
Esta versión ademas de hacer lo mismo que la anterior de que nos permite cargar una serie y avisarnos cuando exista un nuevo episodio de la misma, agrega nuevas Features para que consultar información de las series sea de forma mas directa, agregando algunas nuevas opciones en el menu:


  • Today Episodes: nos permite ver directamente al apretar en esa opción cuales son las series que se estrenan en el día actual, sin tener que ir al calendario y seleccionar el día.
  • Calendar: presenta las mismas funcionalidades de la versión anterior, agregando nuevas caracteristicas como ser que se marcan los días donde se estrenaran nuevos episodios.
  • Next Episode From...: nos muestra la pantalla principal de PyTv y haciendo click sobre alguna de las series que cargamos que nos muestra la lista, nos mostrara un mensaje diciendo que fecha se estrena el proximo episodio y cual sera el nombre del mismo.
  • Downloads: es el cambio mas importante de esta versión, habilitando en las preferencias las opciones de descargas, dejamos que PyTv busque por nosotros los archivos de video y subtitulos de los nuevos episodios cuando se encuentren disponibles. Luego podremos entrar a esta opción y nos mostrara el torrent y el subtitulo (si elegimos las 2 opciones) de los episodios que se hayan estrenado el día anterior y estén disponibles para descargarlos.
  • Refresh: no hace mas que volver a emitir todas las notificaciones de los episodios y recargar la información de lo que este disponible para descargar (si esas opciones estan activas en las preferencias).
En la página principal del Proyecto se encuentran disponibles las siguientes descargas:

QuickDB ".com.ar"!!


A partir de hoy se encuentra disponible el sitio:

Reuniendo toda la información relevante al Proyecto, y también destinado bastante a la parte de Desarrollo con Guias para Desarrolladores, etc.

Thursday, March 18, 2010

Mercurial

Ayer Emilio Ramirez me empezo a contar sobre Mercurial, y hoy en la lista de PyAr mandaron este link:


Y solo voy a decir: "Adios Subversion!"

Ni voy a intentar explicar Mercurial (pros, contras, etc) porque no hay forma de hacerlo mejor que en ese Tutorial.
Muy Recomendada Lectura!!

Wednesday, March 17, 2010

The Inverse Graphing Calculator

En esta página podemos escribir alguna palabra o frase y nos crea una ecuación que tiene lo que escribimos como grafico:

Saturday, March 13, 2010

Fundamentos de QuickDB

Esta es una Presentación de 6 Slides solamente que muestra las partes fundamentales de QuickDB:

Friday, March 12, 2010

Code Bubble

Repensando el paradigma de interfaz de usuario de entornos de desarrollo integrado
Parece un muy buen IDE, hace rato pensaba que sería re practico tener un IDE que te permita plasmar todas tus ideas y analizar el código bien de forma gráfica en un solo lugar.

Monday, March 8, 2010

Aprender a Programar en 21 Dias

Muy bueno!! La verdadera (y posiblemente unica) forma de aprender a programar en 21 dias en C++:
Visto en: http://mundogeek.net/

Sunday, March 7, 2010

Navegador Web en 63 Lineas de Codigo!

Gracias a Python y PyQt es posible programar un Navegador Web en solo 63 lineas de código (e incluso menos).
Utilizamos QtWebKit para el manejo de la página web y el componente que renderiza la página, etc.

Este simple navegador permite:
  • Navegar por las paginas de forma tradicional
  • Muestra una barra de progreso para poder ver como se va cargando la página
  • Posee boton para cargar la página anterior
  • Boton para ir a la siguiente página
  • Boton recargar la página actual
  • Boton para parar la carga de la página actual
  • Y en la barra de direcciones podemos escribir una url, o tambien escribir simplemente las palabras que estamos buscando y nos realiza automaticamente la busqueda en Google (al mejor estilo Chrome)
  • Dar el foco a la Barra de Direcciones con "Ctrl+J"
Screenshots del Navegador:




Para ver el código: PyBrowser.py
Para descargarlo: Descarga

PyQT: Aplicacion en SystemTray

La idea de este Post es explicar de forma simple, como realizar una aplicación en Python, utilizando PyQt, donde esta aplicación corra en el SystemTray (o pueda minimizarse al SystemTray) y tengamos un menu desplegable al presionar el icono de la aplicación en el SystemTray.

Primero que nada necesitamos importar algunos modulos que seran usados por nuestra aplicación:
import sys
from PyQt4 import QtGui, QtCore
  • El modulo "sys", nos permite poner a correr la aplicación usando utilidades del sistema.
  • El modulo PyQt4, es el binding de Qt para Python y contiene todos los componentes graficos que podamos precisar, manejo de eventos de los componentes, etc. Principalmente se usara "QtGui" para crear instancias de los componentes gráficos, y "QtCore" para conectar señales de estos componentes con alguna operación.
Una vez importados los modulos necesarios, procedemos a crear una clase que extienda de QWidget para construir la aplicación, y le daremos un icono y nombre a la ventana cuando se muestre:
import sys
from PyQt4 import QtGui, QtCore

class PyTest(QtGui.QWidget):

    def __init__(self):
        QtGui.QWidget.__init__(self)
        #cargar imagen para icono
        pixmap = QtGui.QPixmap('pytv.png')
        #setear el nombre de la ventana
        self.setWindowTitle('PyTest!')
        #colocar el icono cargado a la ventana
        self.setWindowIcon(QtGui.QIcon(pixmap))
        #creamos objeto Style para hacer uso de los iconos de Qt
        self.style = self.style()

En la primer linea del método lo que debemos hacer es invocar el constructor de la clase Padre, luego creamos un objeto QPixmap pasandole la ruta del archivo imagen (en este caso es una ruta relativa en el mismo directorio de ejecución), y luego le damos el nombre e icono a la ventana.

Ahora para crear un Menu y agregarle Acciones (cada elemento del menu) hay diversas formas, podemos crear un objeto accion y luego agregarlo al menu pasandole ese objeto, tambien podemos llamar al método "addAction" de menu pero esta vez pasarle un String y nos devolvera una instancia de un objeto QAction con ese nombre ya inicializado, y diversas formas mas.
En este caso vamos a usar la opción del String que es más fácil y directa:
#Menu
self.menu = QtGui.QMenu('PyTv')
#accion mostrar
show = self.menu.addAction(self.style.standardIcon
  (QtGui.QStyle.SP_ArrowRight), 'Show Window')
#accion salir
exit = self.menu.addAction(self.style.standardIcon
       (QtGui.QStyle.SP_TitleBarCloseButton), 'exit')
Ahora que contamos con el Menu creado, vamos a conectar las distintas señales del Menu con operaciones que queremos que se realicen para responder a los eventos del usuario.
#SIGNAL->SLOT
QtCore.QObject.connect(exit, QtCore.SIGNAL("triggered()"),
   sys.exit)
QtCore.QObject.connect(self.menu, QtCore.SIGNAL("clicked()"),
   lambda: self.menu.popup(QtGui.QCursor.pos()))
QtCore.QObject.connect(show, QtCore.SIGNAL("triggered()"),
   self.showWindow)
"QtCore.QObject.connect" nos permite conectar una señal de alguno de nuestros objetos de QtGui con una acción que queremos que se realice.
La conexión SIGNAL->SLOT es una forma de decir que con determinada señal se va a ejecutar determinado fragmento de código. En Python a diferencia de C++ no hace falta que implementemos un método SLOT, simplemente podemos pasarle el nombre del método que deseamos que se ejecute como se ve en el tercer caso donde se conecta la señal "triggered()" del objeto QAction "show" con el método "showWindow(self)" de la actual Clase.
En cambio, la segunda señal se prentende conectar a un método que debe recibir algún parametro al ser invocado, para estos casos podemos hacer uso de "lambda" en Python y llamar a cualquier función que deseemos.
En el caso del menu, es necesario que sea definido como una variable de la Clase, porque sino es posible que la señal asociada al menu deje de responder en algún momento.

Ahora vamos a crear el icono de SystemTray, hacerlo visible en el SystemTray y agregarle el Menu que ya creamos para que este se despliegue al presionar el boton derecho del mouse sobre el icono:
#SystemTray
self.tray = QtGui.QSystemTrayIcon(QtGui.QIcon(pixmap), self)
self.tray.setToolTip('PyTest')
self.tray.setVisible(True)
self.tray.setContextMenu(self.menu)
Ahora procedemos a crear la función que se ejecuta al presionar la acción del Menu: "Show Window" (este método lo que hara es mostrar la ventana del programa cuando este evento es disparado)
    def showWindow(self):
        self.setVisible(True)
Ahora si queremos que al cerrar la ventana no se cierre la aplicación sino que se minimice al SystemTray, lo que tenemos que hacer es sobreescribir el método "closeEvent" de la clase QWidget de la que heredamos de la siguiente forma:
    def closeEvent(self, event):
        event.ignore()
        self.hide()
  • "event.ignore()" lo que hace es ignorar la señal de cierre de la aplicación que esta por ejecutarse.
  • "self.hide()" oculta la ventana pero mantiene corriendo la aplicación
Ahora supongamos que queremos que al abrirse la aplicación no se muestre ninguna ventana, sino que se inicie directamente solo con el icono en el SystemTray, para ello debemos sobreescribir el método "show" de la Clase padre QWidget:
    def show(self):
        pass
Debido a esto, cuando necesitemos mostrar la ventana, como en el caso de la acción "Show Window", deberemos invocar el metodo "setVisible(bool)" como se puede ver en el método mas arriba, ya que si llamaramos a "self.show()" no sucederia nada.

Y por último, hacer que nuestra aplicación pueda ser ejecutable:
app = QtGui.QApplication(sys.argv)
pytest = PyTest()
pytest.show()

sys.exit(app.exec_())
Para descargar el ejemplo completo: pytest.zip

Saturday, March 6, 2010

Los Piratas de las Aguas Negras


Esto si que se llama "nostalgia"!! jeje
De la nada me acorde de este dibujito que veia cuando era chico: "Los Piratas de las Aguas Negras"
Y me dieron ganas de volverlo a ver... probablemente pase como con todas las cosas viejas, donde el recuerdo difiere muchisimoooooo de lo que es en realidad... pero bueno, hay que sacarse las ganas.

Cuento: Una Historia Realista

Anoche mientras leia un libro me colgue pensando como muchas veces los principales de la historia son extremadamente grosos, esta claro que tienen que tener algo que los haga resaltar, pero a veces parece ya demasiado y algunas cosas me causaban gracia, entonces me puse a pensar como sería una historia mas realista y escribi este cuento:

Friday, March 5, 2010

PyTv! 1.0


PyTv! Terminado!

Despues de colgarme un par de días programando, termine lo que considero una versión estable de PyTv.
PyTv es un programa bastante util para aquellos que sean tan fanaticos de las series de televisión como yo. Con PyTv lo unico que hacemos es decirle el nombre de la serie que nos interesa (por ejemplo: "the big bang theory"), y listo!
El programa se encargara de buscar en Google la lista de episodios de esa serie, de los resultados obtenidos abrira la pagina correspondiente de Wikipedia, comprobara cual es la ultima temporada disponible, y bajara toda la información de numero de temporada y episodio, nombre del episodio y fecha de emisión del mismo.
Se guarda localmente esa información para no tener que hacer uso de internet cada vez que el programa se abre, y PyTv se encargara de avisarnos cada vez que se estrene un nuevo capitulo de alguna de las series que seguimos.

SystemTray

Menu

Pantalla Principal

Notificaciones


Preferencias/Configuración

Calendario

Detalle de Calendario

Información de la Serie

Tambien esta la opción de abrir un pequeño calendario y presionando en alguno de los días nos mostrara la información de los episodios que sean estrenado ese día, como asi tambien, se puede elegir ese episodio y consultar la información referente a la serie en IMDB presionando un boton o ver el trailer del episodio en YouTube.
Si una Serie terminara su temporada, PyTv comprobaria cuando comienza la nueva temporada de dicha serie y al estar disponible, descargaria la información de la misma, sin tener que preocuparnos por andar pendiente de cuando empiezan los nuevos episodios, etc.

Código: pytv-1.0.zip
Instaladores DEB: i386, amd64