jueves, 20 de diciembre de 2012

Integrar API de Google Maps, archivos kml, kmz y otras fumarolas :D

Ya que andamos en eso de la posteada ahora les voy a dejar un pequeño manual sobre como integrar la API de maps (google) dentro de nuestro código, hay varia documentación en la página developers de google, pero realmente lo que uno busca cuando pone en google: "integrar api de maps" es ver un ejemplo claro y directo para que se pueda entender de mejor forma.

Así que pues ya comentada la información de arriba les paso a dejar un ejemplo.

Lo primero que tenemos que poner en nuestro código es la llamada a la API de maps:


<script type="text/javascript" 
    src="http://maps.googleapis.com/maps/api/js?sensor=false&language=es">
</script>

En este caso la variable sensor está en false, esto nos indica que no hay un dispositivo gps que pueda tomar la ubicación (se pone generalmente en true cuando es para aplicación movil, llámese celular o tableta)

El lenguaje declaramos español, esto es para los menús que se van a mostrar en el mapa. 

Una vez que tenemos esto vamos a empezar con la declaración de nuestro código javascript para que se utilice en la API. 

El código va a ir comentado para que vayan viendo que hace cada linea. 




<script type="text/javascript">
    //Declaramos la variable G, esto para hacer llamadas rápidas dentro de la API, que generalmente se pone
    //algo como: google.maps.LatLng(xxxx,yyyy), con esto lo cambiamos por: G.LatLng
    //Declaramos nuestra variable kml y show que ocuparemos más abajo
    var G = google.maps; var kml = null; var show = false;
    //La variable azcapotzalco la declaramos como la posición inicial en el mapa, esto será parael boton de "reset" que pondremos
    var azcapotzalco = new google.maps.LatLng(19.490544, -99.190493);

    //Inicio función centrar
    //Esta función nos centra la vista del çódigo, viene más explicado en developers de maps
    function HomeControl(controlDiv, map) {

      // Set CSS styles for the DIV containing the control
      // Setting padding to 5 px will offset the control
      // from the edge of the map
      controlDiv.style.padding = '5px';

      // Set CSS for the control border
      var controlUI = document.createElement('DIV');
      controlUI.style.backgroundColor = 'white';
      controlUI.style.borderStyle = 'solid';
      controlUI.style.borderWidth = '2px';
      controlUI.style.cursor = 'pointer';
      controlUI.style.textAlign = 'center';
      controlUI.title = 'Click para colocar en la posición inicial';
      controlDiv.appendChild(controlUI);

      // Set CSS for the control interior
      var controlText = document.createElement('DIV');
      controlText.style.fontFamily = 'Arial,sans-serif';
      controlText.style.fontSize = '12px';
      controlText.style.paddingLeft = '4px';
      controlText.style.paddingRight = '4px';
      controlText.innerHTML = 'Centrar el Mapa';
      controlUI.appendChild(controlText);

      
      google.maps.event.addDomListener(controlUI, 'click', function() {
        //Aquí declaramos que al dar click en el boton se ejecute la acción de centrar con los parametros de 'azcapotzalco'
        map.setCenter(azcapotzalco)
        //Colocamos el zoom inicial del mapa
        map.setZoom(13);
      });
    }
    //Termina código para "resetear" mapa

    //Dentro de esta función vamos a mandar a llamar capas dinamicamente, en este caso son archivos kml los cuales 
    //se pueden generar con Google Earth
    function toggle() {
        if (!this.kmlLayer ) {
            this.kmlLayer = new G.KmlLayer(
                'http://kaguamedia.com/kml/' + this.id + '.kml', //ponemos la ruta de donde va a mandar a llamar los archivos.
                { preserveViewport:true } );
            this.displayIsOn = false;
        }

        //Declaramos que cuando esté desactivado el checkbox no nos muestre la capa
        if ( this.displayIsOn ) {
            this.kmlLayer.setMap( null );
            this.displayIsOn = false;
        }
        else {
            this.kmlLayer.setMap( map );
            this.displayIsOn = true;
            //Declaramos que cuando esté activado el checkbox nos muestre la capa
        };
    };

    
    //Con esta función inicializamos el mapa
    function initialize() {
        //Tomamos los valores del input que agregamos abajo para mostrar las capas
        var layers = document.getElementsByTagName('input');
        //Agregamos las opciones iniciales para la capa, la longitud inicial, el nivel de zoom, que tipo de mapa es 
        //(en este punto podemos declarar ROADMAP, SATELLITE, HYBRID, TERRAIN para diferentes vistas )
        //decimos que si queremos poder manejar el zoom, en overviewMapControl es para que se ponga la vista miniatura
        //dentro de mapTypeControlOptions podemos declarar la forma en la que se verá el menú, con formato vertical 
        //o en forma de "lista"
        var options = {
            center: new G.LatLng(19.490544, -99.190493),
            zoom: 13,
            mapTypeId: G.MapTypeId.ROADMAP,
            scaleControl: true,
            overviewMapControl: true,
            mapTypeControlOptions: {
                style:G.MapTypeControlStyle.DROPDOWN_MENU }
        };

        //Inicializamos el mapa con las opciones que declaramos arriba
        map = new G.Map(document.getElementById('map'), options);
        //En este caso vamos a declarar una capa inicial para nuestro mapa, es un archivo kmz y se cargará al inicializar el mapa
        var kmzLayer = new google.maps.KmlLayer('http://kaguamedia.com/kml/Azcapotzalco.kmz');
        kmzLayer.setMap(map);
        //En esta función vamos a declarar otra capa, en este caso un archivo kml para que de la misma forma se inice con el mapa
        var kmzLayer = new google.maps.KmlLayer('http://kaguamedia.com/kml/Colonias.kml');
        kmzLayer.setMap(map);
        //Agrego de los dos tipos de archivos para que vean que la forma de llamar un kmz y un kml es la misma.
        
        //Creamos el div para la función centrar arriba mostrada
        var homeControlDiv = document.createElement('DIV');
        var homeControl = new HomeControl(homeControlDiv, map);
        homeControlDiv.index = 1;
        map.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv);

        //En esta función vamos a tomar los valores de los checkbox que están declarados en el código para que se manden a llamar
        //las capas de forma dinámica. El valor final de i será igual al número de capas que declaren dentro del id mapas
        for (var i=0; i<2; i++) {
            layers[i].type = 'checkbox';
            G.event.addDomListener(layers[i], 'click', toggle)
        };
    };

    G.event.addDomListener(window, 'load', initialize);

</script>

Una vez explicada la parte del javascript vamos al html:


<!-- en este caso declaramos el div mapas y dentro de el una lista con los input que necesitemos, estás serán las capas que vamos 
  a agregar, el nombre del id es el nombre que se le dará a la capa, ejemplo Metro.kml (así sin el kml, pues lo declaramos arriba en
  el javascript) !-->
<div id="mapas">
<ul>
    <li align="left"><input id="Metro" rel="d1"/>Metro</li>
    <li align="left"><input id="AreasVerdes" rel="d2"/>Areas Verdes</li>
</ul>
</div>
<!-- en este div que le ponemos de nombre map (pues está ya definido en el javascript) declaramos el tamaño del que será el mapa 
  y eso es todo, tenemos nuestro código armado e integrado con algunas funciones de la API de maps !-->
<div id="map" style="width: 700px; height: 600px;"></div><br /><br />
Vamos a ver como queda el archivo final:
http://kaguamedia.com/api_google_maps.php
Espero les sirva de algo! :D
PD. Los kml y kmz usados en este tutorial fueron hechos por compañeros de trabajo, Hector y Luis, si lo llegan a leer muchas gracias, rockean durísimo! :D
Saludotes.
Komtec1

martes, 18 de diciembre de 2012

Cambiar imágenes [casi] como encabezado de instagram :P

Hace poco vi el header en instagram en X perfil, me gustó mucho como se cambian las imágenes de forma aleatoria y se me ocurrió hacerlo en una web, me puse manos a la obra y salio el código que les explico y dejo a continuación :D :D :D

Primero que nada, me base en el siguiente código:
http://www.miguelmanchego.com/2009/recargar-texto-automaticamente-jquery-ajax/

Primero que nada, tenemos que invocar jQuery, despues agregamos el siguiente javascript:

<script language="javascript">
function aleatorio(inferior,superior){
    numPosibilidades = superior - inferior
    aleat = Math.random() * numPosibilidades
    aleat = Math.round(aleat)
    return parseInt(inferior) + aleat
} 

function recargar(){
    var cual = aleatorio(0,15)    
    var image = $("#probando"+cual);
    $("#probando"+cual).fadeOut(function() {
        $.post("get.php", {}, function(data){
        image.attr("src", data).fadeIn();
        });
    });
}
$actual=0;
timer = setInterval("recargar()", aleatorio(3000,9000));
</script>

En la funcion aleatorio definimos el tiempo en que van a recargar las fotos.

Despues en la funcion recargar, primero definimos un aleatorio entre 0 y 15, esto será para cuando coloquemos las imágenes, más adelante verán el por qué.

Agregamos la variable image con el id probando más la variable cual, que como lo mencioné antes, está en aleatorio.

Definimos que el id probando+cual tendrá un fadeOut para que se pueda desvanecer (esto lo invocamos con jQuery), despues dentro de las opciones de fadeOut declaramos una funcion en la que enviamos mediante un metodo (puede ser un post o un get, se que con el post ocupo un recurso que no necesito, se puede cambiar a get si les es más factible) la petición al archivo get.php, no le indicamos un contenido post y declaramos la funcion que nos regresará un valor, en este caso data, en esa función lo que hacemos es cambiar el atributo de image donde el id sea probando+cual y al último le agregamos un fadeIn() para que la muestre.

Ahora el archivo get.php contiene lo siguiente:

<?php
require_once("config.php");
$consulta = mysql_query("SELECT * FROM `tabla`");
    $numero = 0;
    while ($row=mysql_fetch_array($consulta))
    {
        $imagenes[$numero] = $row["imagen"];
        $numero++;
    }
        if($i%rand(1,$numero) == 1)
            echo 'img/default.jpg';
        else
        echo $imagenes[rand(0,$numero)];
        
?>

Llamo el archivo config por que lo hago mediante una conección de base de datos. Seguido hago una consulta y agrego los resultados en un arreglo, al final hago un echo para mostrar un simple texto que contiene la ruta del script, por ejemplo:

"img/archivo.jpg"   (sin las comillas claro)

Ustedes pueden modificar el archivo get para obtener la salida y la ruta que ustedes quieran, pueden hacer un listado de un directorio y de ahí mostrar solo uno, que se yo, lo que quieran :P

Ahora vamos a la parte que muestra las imágenes, en este caso lo acomode con tablas de la siguiente forma:

<table align="center" border="0">
<tr>
    <?php 
    $consulta = mysql_query("SELECT * FROM `tabla`);
    $numero = 0;
    $modal = 1;
    while ($row=mysql_fetch_array($consulta))
    {
        $imagenes[$numero] = $row["imagen"];
        $numero++;
    }
    for ($i=0; $i < 16; $i++) {
        if($i%rand(1,$numero) == 1)
        {
            echo "<td style='background: url(img/default.png) no-repeat center'>
            <img id='probando$i' src='img/default.jpg' width='175' height='109'></td>";
        }
        else
        {
            echo "<td style='background: url(img/default.png) no-repeat center'>
            <img id='probando$i' src='".$imagenes[rand(0,$numero)]."' alt='' width='175' height='109'></td>";
        }
            if ($modal%4==0)
            {
                echo "</tr>";
                if ($i<16)
                echo "<tr>";
            }
        $modal++;
    }
    ?>
</table>

Primero declaro una tabla, y seguido abro php, hago la consulta a la base de datos, declaro $numero como 0 y modal como 1, agrego en un array los valores que obtengo de la base de datos y despues empiezo a mostrar las imágenes, ocupo el modal por que acomodo 4 columnas de la tabla, lo que nos interesa aquí es la parte donde dice: id='probando$i' - esto es lo que nos va a agregar los id's de forma dinámica y en incremento +1 para que así nuestro javascript mande a llamar de forma correcta los id's que ocupa.

Les dejo un enlace de ejemplo de como funciona.

http://kaguamedia.com/header_tipo_instagram.php

Si tienen alguna duda aquí estamos para ayudar, no creo que sea la única forma de hacerlo, pero creo que si es sencilla :D y claro, ustedes pueden acomodar como guste, con diseño responsivo, con algunos divs, o alguna otra cosa para que quede conforme a su diseño.

PD. Si quieren ver como es el encabezado de instagram les dejo un enlace a un perfil

<shamed>
http://instagram.com/Alination
</shamed>

PD2. Si usan el script, me gustaría ver como quedo el final, compartan su enlace :D

Saludos! :D

Komtec1 - @Komtec1

martes, 4 de septiembre de 2012

Firestarter y Hamachi (Ubuntu 12.04)

Recién instale en una máquina Hamachi, tiene Ubuntu 12.04 y tiene instalado Firestarter, al ver que no me daba ping a la máquina pense que era una problema del cortafuegos (en este caso Firestarter). 

Al desactivarlo me di cuenta de que si es un problema del mencionado arriba :P por lo que si quieren que ambos funcionen sin problemas lo que tienen que hacer es lo siguiente: 

Abrir el archivo user-pre que esta en /etc/firestarter  ( /etc/firestarter/user-pre  ) y agregar las siguientes lineas: 


$IPT -A INPUT -i ham0 -j ACCEPT
$IPT -A OUTPUT -o ham0 -j ACCEPT

Con eso permitimos las conexiones entrantes y salientes de nuestra interfaz de hamachi y queda todo listo para funcionar bien :D. 

Por cierto, si quieren hamachi para ubuntu, el deb está aquí: 


Saludos! 

Komtec1


martes, 7 de agosto de 2012

Bypass bloqueo de pantalla Android 2.3.4

Bueno, jugando con el teléfono y cambiando patrones de bloqueo me di cuenta de este bypass, a continuación lo explico:

Si vamos a ajustes -> Ubicación y seguridad   ->


Cambiar bloqueo de pantalla



Nos pide nuestro bloqueo actual



-> si es que el teléfono cuenta con uno, una vez que lo ingresamos nos lleva a la siguiente pantalla donde podemos seleccionar "Ninguno", "Patrón", "PIN" ó "Contraseña



Si seleccionamos Ninguno nos quita el bloqueo, pues ya confirmamos antes nuestro pin, patrón o contraseña que ocupábamos y no nos pide nada más.

Hasta ahí todo bien, ahora, ponemos una contraseña de nuevo, al ingresar no pide nada pues nuestra contraseña ya fue quitada, seleccionamos pin (o el que quieran ustedes), lo ponemos, nos pide la confirmación y todo ok, si salimos con el boton central del telefono (el home) nos lleva a la pantalla principal, si vamos nuevamente a ajustes -> Ubicación y seguridad -> Cambiar bloqueo de pantalla  nos pedirá nuestra contraseña, pero si antes de hacer eso dejamos presionado el boton de home, el administrador de tareas aparece (o los programas recientes)



si damos click en ajustes nos lleva directamente a la última pantalla de ajustes, la cual fue desbloqueo de pantalla, si seleccionamos Ninguno nuevamente nos quita nuestra contraseña, pero ahora con la diferencia de que no nos pidió ninguna confirmación! :D

No se si pase en versiones más recientes de android, si solo sea en el teléfono que tengo (GT-S5830L), por lo que si leen esta entrada y tienen android me encantaría me dijeran si también pasa en sus teléfonos y que versión de android tienen.

Como siempre espero no se hayan aburrido y si llegaron aquí rockean! (H) :P

Saludos!

Komtec1

viernes, 13 de julio de 2012

Script para Anyremote - Clementine

Bueno, recien instale Clementine en la máquina y la verdad es (dirían amigos españoles) "toda una joya, es la ostia", o en otras palabras, me gusta mucho y es demasiado funcional, la estetica no se queda mal y aparte el analizador de espectro que tiene con Nyan Cat es lo que lo hace++ jejeje :P

No está de más mencionar que Clementine se puede configurar para shortcuts personalizados del programa ó para shortcuts del sistema, es decir directo los de ubuntu o su distribución preferida. 

Al querer instalar una aplicación para manejarlo desde el teléfono no encontraba, hasta que salio una que es Anyremote y el script para Clementine, el script es de Lorenzo Pérez de Arce (Leo Catán.-) y lo encontré aquí, al cual se le agradece si es que llega a leer el post! :D. 

Se los dejo a continuación:


%
% Archivo de configuración para el  de Clementine con anyremote (Server-mode)
% Creado, modificado y corregido por Lorenzo Pérez de Arce (Leo Catán.-)
%

% STATUS stable
% XTEST yes
% ENV no
% SOUND app
% FBROwSER v.3i

GuiAppName=Clementine
GuiAppBinary=clementine
GuiAppRun=echo 'A=`ps -ef|grep clementine`; if [ "x$A" == "x" ]; then echo NOK; else echo OK; fi'|bash -f -s
GuiAppIcon=clementine.png
GuiAppType=Application
GuiAppProtocols=Server
GuiAppDesc=A  player.

[Protocol]=Server

(Init)=Include($(CfgDir)/Utils/aliases-server.cfg);\
    Make(var,from_utf,by_value,);\
    Make(var, to_utf,by_value,);
    Exec(echo 'P=`which wget 2> /dev/null|grep wget|grep -v no|wc -l|tr -d " "`;if [ "x$P" == "x1" ]; then true; else $(CfgDir)/Utils/message.sh "ERROR: wget package is not installed"; fi'|bash -f -s);

(Connect)=Set(icons,Clementine,1,vol_down,2,mute,3,vol_up,4,rewind,5,play,6,forward,7,prev,8,stop,9,next,*,question,0,pause,#,no);\
    Set(title,);\
    Set(status,);\
    Exec(clementine);

1=Exec(clementine --volume-down)
2=Exec(amixer -c $(MixerCard) sset $(MixerChannel),0 toggle -q)
3=Exec(clementine --volume-up)

4=Exec(clementine --seek-by -10)
5=Exec(clementine -p);
6=Exec(clementine --seek-by +10)

7=Exec(clementine -r);
8=Exec(clementine -s)
9=Exec(clementine -f);

* *=Exec(clementine -o)
0=Exec(clementine -u)
#=Exec(killall clementine)

[End]


http://pastebin.com/W2D1xC9T (en pastebin por si no se lee bien aquí)

Para que el script se ejecute lo ponen en la siguiente ruta: 

/usr/share/anyremote/cfg-data/Server-mode/

con elnombrequequieran.cfg

después de eso iniciamos anyremote con el archivo de configuración, de esta forma:

anyremote -f /usr/share/anyremote/cfg-data/Server-mode/clementine.cfg 

Lo pueden agregar a las aplicaciones de inicio para que se ejecute de forma automática al prender la pc :D 

Saludos y espero les sirva. 

Komtec1

jueves, 12 de julio de 2012

Descargar sonidos de SoundCloud

Si, se que se pueden descargar con el boton que dice descargar, pero hoy me encontre con un audio que decía: "This track has reached its download limit.", pero si le das play lo reproduce sin problemas, por lo que vamos a ver como descargar ese audio :D 

La canción que descargue fue esta (es buenísima, escuchenla :P):


Lo que necesitamos es live HTTP headers (excelente add on de firefox :D) y por supuesto firefox (hay más navegadores optimizados para juacking? :P). 

Antes de darle play a la canción abrimos live HTTP headers, una vez que este abierto y capturando los headers enviados ahora si le damos play :D, nos va a dar muchas lineas, pero la que nos interesa es una como esta: 


http://media.soundcloud.com/stream/En418s32X2dK?stream_token=VKlK4

GET /stream/En418s32X2dK?stream_token=VKlK4 HTTP/1.1
Host: media.soundcloud.com
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-MX,es;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://a1.sndcdn.com/swf/soundmanager2.swf



En especifico esta: "http://media.soundcloud.com/stream/En418s32X2dK?stream_token=VKlK4"

Si abrimos la consola (o cmd dependiendo su caso) y ponemos: 

wget http://media.soundcloud.com/stream/En418s32X2dK?stream_token=VKlK4

Nos guardará el archivo, lo único que hacemos es renombralo por: "Artista - Cancion.mp3" o como ustedes quieran ponerle, pero sí que sea mp3 y listo, con eso es más que suficiente para que tengamos el audio en nuestra máquina :D 

PD Si no tienen wget para windows pueden buscar aquí, es demasiado útil! :D 

Saludos y espero les sirva! 

Komtec1




miércoles, 11 de julio de 2012

aircrack-ng en Ubuntu 12.04

Bueno, desde hace un rato que uso ubuntu, lo actualice hace algo de tiempo pero nunca lo había ni siquiera empezado a configurar, hoy que me puse a la tarea y estaba instalando cosillas necesarias me tope con aircrack, me daba un error al ejecutar el make, buscando un poco dí con la solución aquí, de todas formas les dejo la correcta forma de instalación: 


sudo apt-get install build-essential
sudo apt-get install libssl-dev
wget http://download.aircrack-ng.org/aircrack-ng-1.1.tar.gz
tar -zxvf aircrack-ng-1.1.tar.gz
cd aircrack-ng-1.1

Entran al directorio de aircrack-ng-1.1 y abren el archivo common.mak, buscan la linea que dice: 

CFLAGS ?= -g -W -Wall -Werror -O3

y borran -Werror, dejando solamente

CFLAGS ?= -g -W -Wall -O3

ejecutan el sudo make && make install y listo, con eso tendrán aircrack corriendo y sin problemas :D 





Saludos! 

Komtec1

jueves, 7 de junio de 2012

Downeverything v0.2

Hace unos días (ayer xD) publiqué un código llamado Downeverything (v0.1) para descargas masivas de directorios principalmente de música, en esta ocasión les traigo a la venta la nueva versión :P, le añadí 3 (disque) mejoras :D las cuales listo a continuación: 


Changelog v0.2

-Al cargar la página dice: "Cargando espera un momento" y al descargar dice: "Descargando, espera un momento" :P simple, pero es un cambio jeje 
-El buffer se limpia/envia de la forma correcta y ahora al dar click en descargar directamente nos manda a la pantalla de espera con un bonito gif animado :P (gracias a una función que encontré en php.net) 
-Muestra el tiempo total de descarga de archivos

Estos son los 3 cambios, sencillos pero al usarlo siento que si cambia un poco la experiencia del usuario! jejee bueno, por la pantalla de espera, que anteriormente nos dejaba "en suspenso" y no sabíamos si descargaba o no.

Les dejo la captura de pantalla de las dos últimas modificaciones: 





Espero les guste, estoy viendo en agregar el total de MB de la descarga y de ahí estimar el tiempo de descarga para que al final también se muestre aproximadamente la velocidad de conexión en kbps




miércoles, 6 de junio de 2012

Downeverything v0.1


Como se han dado cuenta en mis post anteriores, me gusta algo descargar música y conocer grupos nuevos, siempre que encuentro un directorio indexado y con mucha música quiero descargarla toda, hay plugins como DownThemAll para firefox, pero la verdad llegaba el momento en que se me olvidaba seguir seleccionando las carpetas por que estaba ocupado trabajando o simplemente me daba flojera, por lo que no seguía descargando. Hace unos días se me ocurrió hacer un script para automatizar esa tarea y que ya no fuera más pretexto la flojera :P pero hasta el día de hoy me puse manos a la obra :D :D y termino en este script que les dejaré al final del post. 

Les voy a adjuntar un video para que vean como sirve y que es lo que hace en si, por si no me entendieron muy bien xDDD


Me encantaría buscar alguna forma de hacer que se muestre el progreso de descarga, pero la verdad no se aún como hacerlo (con php), de igual forma creo que ocupo mal ob_start(); y ob_end_flush(); para que me pueda ir mostrando cada que descarga una canción, si alguien gusta cooperar con esa parte sería genial, si no ya veré como lo puedo implementar después. 

Me gustaría agregar algo más de ajax para hacerlo muy dinámico, pero ya veremos después, esta es la versión alfa 0.0.0.0.0.0.1 jejeje :P 

Si tienen algún otra idea para esto sería padre que la compartan y si les gusta y les sirve donen 234,987 usd a mi cuenta de paypal (naaa no se crean jajaja, de algún modo u otro tengo que mantener su atención! ya casi llegamos al final :P) 

Bueno, ahora si, después de ver el video, "emocionarse" por como funciona y todo, les dejo el link :D :D :D

http://www.mediafire.com/?g4xuhxvoz7832d2

Espero les sirva y como siempre, disfrútenlo, sonrían que es gratis y voten por AMLO! (xDDD tengo que sacar los dotes partidistas caray!) 

PD. el código esta para que solo descargue mp3, pero no es dificil adaptarlo para que descargue algun otro formato, en la linea 179 pueden agregar la validación. 
PD2. en el script hago uso de http://sourceforge.net/projects/simplehtmldom/ muchas gracias a Jose Solorzano por brindar esta herramienta super funcional! :D 

Saludos grandes :D 

Komtec1