Archivos de la categoría Proyectos

Descarga música grátis, sin morir en el intento

Antes de continuar, quiero dejar muy claro, que no me hago responsable por el uso (o mal uso) del código presentado en este post. Todo ésto fue desarrollado con un fin puramente académico, sin fines de lucro. Siéntanse libres de usar el código, pero no me responsabilizo de cualquier implicación legal que su uso pudiera acarrear.

Descargár música sin tener el derecho sobre la misma es ilegal!! Nunca olviden eso.

Ahora si, sabiendo a lo que vamos, para una de mis asignaturas del master, una de las tareas era explotar un API de algún sitio web (facebook, twitter, linkedin, etc), para extraer información, analizarla y obtener beneficios de la misma: Por ejemplo, y a breves rasgos, pude realizar un análisis del sentimiento de los tweets generados en determinado momento, en paises donde se habla español, que pueden visualizarlo en este enlace.

Para ir un poco más allá, se me ocurrió la idea de extraer el API de un sitio que no tenga una interfaz de programación documentada. El objetivo: El sitio de música http://music.163.com

Este sitio (chino) no tiene un API documentada, pero mediante el uso de algunas herramientas web, como FireBug, pudimos obtener las llamadas que se realizan para obtener datos de artistas, discos y canciones.

Este script está escrito en Python 2.7, y para ejecutarlo basta con descargar el archivo desde este enlace, descomprimirlo, y ejecutar desde la línea de comandos lo siguiente:

python musica.py

El menú presentará 3 opciones de búsqueda: por autor, por disco o por canción. Bastará con escoger el tipo de búsqueda, seleccionar el item de las posibles opciones encontradas, y descargar el item escogido.

Espero les sea de utilidad 😀 y recuerden! No descarguen música ilegal!

Para más información, pueden ingresar a mi repositorio en GitHub

Interfaces Multitouch: Ejemplos en Android y Windows 8

Como parte de una de las asignaturas que estoy tomando en el master acá en la Politécnica de Valencia, se nos pidió realizar aplicaciones que utilicen la interfaz multitouch de dispositivos android, y con windows 8.

Para android, se realizó una pequeña aplicación que permite manipular objetos (en este caso cuadrados de colores) dentro de la pantalla. Usando los eventos translate, pinch y rotate, además de un array de objetos cuadrado (donde se almacena la posicion, tamaño y rotación de cada uno de los cuadrados dibujados en pantalla), se obtiene algo como lo que muestro en el video a continuación:

El código fuente de este ejemplo, lo pueden descargar desde https://github.com/patolin/multitouch

Para windows 8, hice algo un poco más interactivo, y resultó en un pequeño sintetizador de sonido. Mediante la interfaz, se puede escoger entre 3 tipos de onda (sinusoidal, triangular y cuadrada) y sus respectivas envolventes. El video que les muestro a continuación fué grabado en el emulador de tablet de visual studio, ya que lastimosamente no pude grabar video en la prueba final que se hizo sobre una mesa interactiva real

El código fuente de este ejemplo, lo pueden descargar desde https://github.com/patolin/Win8Synth

Paginador para custom post types en wordpress > quick fix!

Quizás se hayan topado con el problemita del paginador, al trabajar con custom types en wordpress. Simplemente el paginador no aparece.

Les dejo este código para arreglar esto. El truco es temporalmente mover la variable $wp_query a un temporal, y cargar $wp_query con el query del custom post type

 

< ?php
$temp = $wp_query;
$wp_query = null;
$wp_query = new WP_Query();
$wp_query->query('post_type=custom_post_type' . '&paged=' . $paged . '&posts_per_page=10');
?>
< ?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>

 

< ?php endwhile; ?>
< ?php previous_posts_link(); ?>
< ?php next_posts_link(); ?>
< ?php $wp_query = null; $wp_query = $temp; ?>

Al final, volvemos la variable $wp_query a su lugar, y listo!

Poniendo a trabajar al Raspberry Pi

El famoso Raspberry Pi. La pequeña computadora de $35 que ha causado furor a nivel mundial, y ha inspirado algunos clones, unos mas potentes que otros, pero, como en todo en la vida, el que pega primero, pega dos veces!

Con el Raspberry han hecho de todo, desde encender y apagar un LED, hasta controlar una torre de telefonía celular (pasando por un sistema casero de vigilancia que funciona 24/7 en mi morada, jugar minecraft, servir tragos….. una larga lista); pero hay realmente pocas aplicaciones “económicamente rentables” que se hayan dado a conocer.

Lo que les voy a comentar no es una aplicación, sino una prueba de concepto, de cómo ésta pequeña tarjeta electrónica, puede realizar un trabajo pesado, con un bajisimo gasto energético. No voy a dar soluciones de código, no extensas explicaciones de como hacer A o B tarea en X lenguaje de programación, solamente voy a comentar mi experiencia con un trabajo “del mundo real” aplicando el Raspberry Pi para su solución.

Resulta que en un proyecto personal, se me encomendó la tarea de extraer determinada información de cierto website, para luego procesarla e indexarla. Para qué hacer esto? Pues el sitio web original no era muy amigable al usuario, y estaba realizado sin una plataforma de base de datos. Entonces la del proyecto quedó planteada de esta manera:

  1. Generar un índice del sitio web, con los links de todas las páginas que contenían la información requerida
  2. Navegar página por página del indice de links, recabando determinada información contenida dentro de cada link
  3. Almacenar la información extraida en una base de datos, para su posterior análisis
  4. Generación de un nuevo índice dinámico, usando la información almacenada en la base de datos.

No suena complicado (en teoría), pero el problema principal era la GRAN cantidad de trabajo. El sitio web antiguo contenia alrededor de 7000 subpáginas con información, y recopilar la misma manualmente era una tarea titánica, hubiera requerido una cantidad considerable de personal, y un tiempo bastante largo para concluirla. Es aquí donde después de echarle cerebro un rato decidí darle una solución viable al problema.

Antes de decidir que y como resolver el problema, decidí investigar un poco, y de paso, esta fué la oportunidad perfecta para programar en Python usando Linux. Este lenguaje brinda muchísimas facilidades en cuanto al procesamiento de páginas web, por lo que se convirtió en el “Weapon of Choice” del proyecto.

Al hablar de facilidades en el procesamiento de páginas web, existen funciones en Python, que nos permiten almacenar el contenido de una página entera, dentro de una variable, por ejemplo, si quisieramos pasar el codigo html de www.patolin.com a una variable, tendríamos el siguiente script:

import urllib2

url="http://www.patolin.com"
page=urllib2.urlopen(url)

Simple no? Con estas 3 líneas de código (que de hecho pueden ser 2 jejeje), logramos que todo el contenido de dicha web, se almacene en la variable “page”. Pero bueno, un punto menos del problema resuelto. Ahora, como buscamos información dentro del contenido de la variable “page”? Es aquí, donde con un poco de Google, encontré la librería BeautifulSoup, que permite analizar código HTML y separarlo según tags…. perfecto para el caso.

Las instrucciones para instalar esta librería se encuentran bien documentadas en el sitio web, así que no presentará ningún problema por si quieren probarla. Ahora, como funciona? muy simple! Miremos el siguiente código:

import urllib2
import BeautifulSoup
url="http://www.patolin.com"
page=urllib2.urlopen(url)
soup = BeautifulSoup(page.read())
titulos=soup.findAll('h2')
foreach titulo in titulos
    print titulo

Pues que hace este pequeño fragmento de código? Primero, como vimos anteriormente, nos captura el contenido de la url www.patolin.com, y lo almacena en la variable “page”, luego dicha variable, pasa a indexarse mediante la librería BeautifulSoup en la variable “soup”, realizamos una búsqueda de todos los tags “<h2>” que son los títulos de los posts de patolin.com. Finalmente, dado que los titulos se guardan en un array, imprimimos en pantalla título por título hasta llegar al final.

Como vemos, algo que quizás pueda resolverse en otros lenguajes más potentes, con algo más de programación, gracias a las librerias existentes se vuelve una tarea bastante trivial en Python. Con estas pocas líneas de código, hemos resuelto una gran parte del problema, ya que con este código, simplemente debemos crear 2 bucles:

  • Uno que revise el índice actual de la página y extraiga todos los links existentes
  • Otro que usando los links extraidos del punto anterior, extraiga el contenido de la página

El como hacer estas tareas, se los dejo de pregunta de examen, pero no es nada del otro mundo. Ahora nos falta el almacenado en la base de datos. Para esto, por conveniencia, vamos a usar MySql como base de datos destino, y como era de esperarse, Python tiene soporte para manejo de MySql integrado en su instalación.

Cargar datos en MySql, se vuelve algo tan simple como ejecutar los siguientes comandos en Python

 

import MySQLdb as mdb

try:
    con = mdb.connect('dbhost', 'usuario', 'clave', 'nombredb')
    cur = con.cursor()
    cur.execute("INSERT INTO datos (titulo, contenido) VALUES (%s, %s)", (varTitulo, varContenido, ))
except mdb.Error, e:
    print "Error %d: %s" % (e.args[0],e.args[1])
    sys.exit(1)
finally:
    if con:
        con.close()

 

En este ejemplo, de una tabla con las columnas “titulo” y “contenido”, basta con cargar los datos en las variables varTitulo, varContenido (ojo con la última coma), e iremos almacenando los datos en nuestra base MySql.

Con todos estos pedazos de código, basta con unirlos, y tenemos lista la aplicación que escanea el contenido de un website, lo procesa, y almacena en una base de datos. La visualización de los datos almacenados en el MySql queda para una sencilla página de PHP, que no viene al caso de este post.

Ahora, donde entra nuestro estimado Raspberry Pi? Pues como les decía, el proceso involucraba analizar 7000 páginas html, y la extracción de la información, incluido el tiempo de carga y almacenamiento en el Mysql (ojo, es una DB en línea, no local) hacía que en promedio demore de 15 a 20 segundos POR PÁGINA, lo que en tiempo total de procesamiento, aproximadamente iba a demorar 38 horas, lo que implicaba tener encendido el computador 38 horas, con el consiguiente consumo de energía.

Instalé el script generado y las librerías en mi Raspberry que está en mi casa, y funcionó correctamente, así que ejecutarlo desde ahí tendrá las siguientes ventajas:

  • El Raspberry Pi, de por sí pasa encendido 24/7, consumiento algo así como 5W, nada comparado con los 700W de mi desktop
  • La conexión a internet de mi casa pasa libre todo el día, desperdiciando un par de Mbps de velocidad
  • El proyecto no era de un apuro terrible, un día más o un día menos era aceptable

Y lo ejecutamos pues desde el Raspberry. Poco a poco la información se iba cargando en el MySql, y cerca de las 48 horas, finalizó. Si vamos al consumo energético, podemos comparar:

  • 700W * 35 horas = 24.5 kwh
  • 5W * 48 horas = 0.24 kwh

No hay por donde perderse. Con un consumo 100 veces menor se realizó la misma tarea usando el computador de bolsillo. El cliente contento, por ver su proyecto cumplido, yo contento por hacer algo bueno en Python, y el planeta contento por el ahorro de energía alcanzado.

🙂

 

 

Error 404 al usar el paginador de entradas de wordpress

En uno de mis proyectos actuales, se me presentó un inconveniente que me estaba poniendo los pelos de punta! En un sitio web un poco complejo en su estructura, simplemente los paginadores de los posts publicados en determinadas categorías no funcionaban, llevando a un error 404, e impidiendo que los visitantes puedan revisar entradas anteriores.

Aparte de eso (y es algo que no me había dado cuenta hasta ahora) es que si en el administrador de wordpress, seleccionamos las entradas de determinada categóría, no se visualizaba ninguna. Inicialmente pensé en un bug de wordpress, pero al investigar un poco (más bien bastante), encontré que el problema se daba por la creación de “Custom Types” dentro de las entradas. Este es nuestro caso, ya que tengo varios tipos distintos de entradas, ya que así fué requerido en la estructura del sitio.

La solución resultó bastante sencilla. Hay que agregar este código al final del archivo functions.php

 

function category_set_post_types( $query ){
    if( $query->is_category ):
        $query->set( 'post_type', 'any' );
    endif;
    return $query;
}
add_action( 'pre_get_posts', 'category_set_post_types' );

Que hará que las entradas normales se mapeen correctamente dentro de las categorías, y así eliminaremos los problemas que teníamos con los paginadores.

Espero les sea de utilidad.