Contenido de la categoría Desarrollo web

« Entradas anteriores

Función de descarga mediante PHP anonimamente con proxys automáticos

Por fin algo de código :)

He desarrollado una función que descarga una URL mediante un proxy con PHP y cURL. Lo bueno (y a la vez lo malo) de la función, es que descarga un listado de IPs (las IPs de los proxys y sus puertos) de una página y va realizando peticiones proxy a proxy hasta que da con uno que funcione, lo malo vendría por la lentitud de la ejecución de la misma, por lo que está pensada para utilizar con CRONJOBS o scripts que no requieran de velocidad de ejecución. Se podría añadir una caché para los proxys de forma que los vaya utilizando hasta que no quede ninguno con vida, pero eso ya sería complicar un poco más la historia y ahora mismo no tengo tiempo para ello.

PHP:
  1. function curl_proxy($url,$proxys){
  2.     $index_proxy = 0;
  3.     $end = false;
  4.     do{
  5.         $proxy = $proxys[$index_proxy];
  6.        
  7.         $ip = $proxy[0];
  8.         $port = $proxy[1];
  9.        
  10.     //  echo "Try: $ip : $port <br>\n";
  11.        
  12.         $ch = curl_init();
  13.         curl_setopt($ch, CURLOPT_URL,$url);
  14.         curl_setopt($ch, CURLOPT_HEADER, TRUE);
  15.        
  16.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  17.         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
  18.         curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
  19.         curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
  20.         curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  21.        
  22.         curl_setopt($ch, CURLOPT_PROXY, "http://$ip:$port");
  23.        
  24.         $info = curl_exec($ch);
  25.         curl_close($ch);
  26.  
  27.         if($index_proxy>=count($proxys)){
  28.             $end = true;
  29.         }
  30.         $index_proxy++;
  31.     }while($info === false || $end === true);
  32.  
  33.     return explode("\r\n\r\n",$info);
  34. }
  35. function obte_llistat_proxys(){
  36.     $proxys = file_get_contents('http://www.samair.ru/proxy/time-01.htm');
  37.     preg_match_all('%<td>([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}):(\d*?)</td><td>(.*?)</td>%s', $proxys, $result, PREG_PATTERN_ORDER);
  38.     $ps = $result[0];
  39.     $ip = $result[1];
  40.     $po = $result[2];
  41.     $ti = $result[3];
  42.    
  43.     $t = count($ps);
  44.    
  45.     $sortida = array();
  46.     for($i=0;$i<$t;$i++){
  47.         $sortida[] = array($ip[$i],$po[$i],$ti[$i]);
  48.     }
  49.     return $sortida;
  50. }
  51.  
  52. print_r(curl_proxy('http://004.es/test/contador.php',obte_llistat_proxys()));

Ah si, he utilizado DOS funciones en lugar de una, la que te devuelve el listado de IPs y la que hace la petición cURL usando el listado de IPs y puertos devueltos por la otra función.

Espero que le vaya bien a alguien. Saludos peñita!

Entidades HTML

A Sloth le gustan las entidades HTML, y HTML5 viene cargadito de ellas: entidades HTML definidas en la revisión 5 del lenguaje. Ahí es nada :D

Lo bueno de FireBug para Internet Explorer 6+

Buxplorer es un pequeño bookmarklet (unas 700 líneas de chatarra) que te iniciará una barra inferior en tu Internet Explorer y que te permitirá recorrer el código HTML viendo los margenes y los paddings de cada elemento, de la misma forma que lo hace Firebug. Es un excelente complemento para la developer toolbar (que tan solo te bordea el elemento).

Hace más de un año que tengo esto pendiente de terminar, naturalmente es una beta que funciona con pinzas, pero funciona:

HTML:
  1. javascript:scScript=document.createElement('script');scScript.src='http://www.javascript.es/bmk/buxplorer.js?nocache='+Math.random();scScript.type='text/javascript';void(document.getElementsByTagName('head')[0].appendChild(scScript));

Recuerda, el bookmarklet que os propongo sólo funciona con Internet Explorer 6.

A ver si alguien se anima a meterle un empujón :), y si lo pruebas, me das tu opinión (O el gran FSM colgará un Ubuntu al azar).

Novato de AdobeAIR (en JavaScript)

Cosas que he aprendido hoy a hacer con AIR y JS:

Abrir una URL en el navegador predefinido del sistema:

JavaScript:
  1. function openInBrowser(url) {
  2.     air.navigateToURL( new air.URLRequest(url));
  3. }

Guardar datos en un fichero:

JavaScript:
  1. var flash = window.runtime.flash;
  2. var file = flash.filesystem.File;
  3. var fm = flash.filesystem.FileMode;
  4. var fs = new flash.filesystem.FileStream();
  5. var dir = file.applicationStorageDirectory; //carpeta de la aplicación (más abajo más carpetas)
  6. var arx = dir.resolvePath("data.obj"); //data.obj es el nombre del fichero
  7. fs.open(arx, fm.WRITE);//abrimos para guardar fm.UPDATE para actualizar
  8. fs.writeUTFBytes('Hola mundo!');

Más carpetas del sistema:

JavaScript:
  1. var flash = window.runtime.flash;
  2. var _file = flash.filesystem.File;
  3.  
  4. // Carpeta de aplicación. Carpeta privada sólo para la aplicación actual;
  5. _file.applicationStorageDirectory;
  6.  
  7. // La carpeta donde se encuentra instalada la aplicación. Sólo lectura.
  8. _file.applicationDirectory;
  9.  
  10. //Escritorio del SO
  11. _file.desktopDirectory;
  12.  
  13. //la carpeta de documentos usuario del SO (C:\Documents and Settings\usuario\Mis Documentos, Users/usuario/Documents, etc...)
  14. _file.documentsDirectory;
  15.  
  16. //la carpeta del usuario del SO  (C:\Documents and Settings\usuario, Users/usuario, etc...)
  17. _file.userDirectory;

Formas de abrir un fichero

JavaScript:
  1. var fm = window.runtime.flash.filesystem.FileMode;
  2.  
  3. //Abre el fichero para sólo poder ser leido.
  4. fm.READ;
  5.  
  6. //Abre un fichero (si no existe lo crea), y borra todo el contenido actual. Solo escritura.
  7. fm.WRITE;
  8.  
  9. //Abre un fichero (si no existe lo crea), y añade todo el contenido al final del fichero. Solo escritura.
  10. fm.APPEND;
  11.  
  12. //Abre un fichero (si no existe lo crea), y permite acceder a cualquier punto del mismo para añadir o leer contenido.
  13. fm.UPDATE;
  14. // esto se usa juntamente con objetoFileStream.position=NumeroInt;

Le puedes cargar CUALQUIER libreria JS (por ejemplo JQuery)

JavaScript:
  1. var elementos = $('#aplicacion #formulario input');

Tiene expresiones regulares!

JavaScript:
  1. var absolute = f.url;
  2. absolute = absolute.replace(/file\:\/\/\/(\w)\:/,'$1:');

objetoFileStream.writeUTF es el diablo, usa objetoFileStream.writeUTFBytes

JavaScript:
  1. //esto aún no se porqué, a ver si alguien me dice porqué writeUTF coloca un bytes de control al inicio del fichero :)

Desactivar la selección de elementos

CSS:
  1. body{
  2.     -webkit-user-select:none;
  3. }

Iré poniendo más cositas hasta que termine el programita que estoy haciendo :).

Función PHP para descargar vídeos de youtube

Funciona en la fecha terrestre 23/08/2009:

PHP:
  1. function descarga_video_youtube($youtube,$nom=false){
  2.         $tot = file_get_contents($youtube);
  3.         preg_match('/, "t": "(.*?)",/s', $tot, $regs);
  4.         $codi = $regs[1];
  5.         $_video_id = explode("=",$youtube);
  6.         $video_id = $_video_id[1];
  7.        
  8.         if(!$nom){
  9.             preg_match('/title": "(.*?)",/s', $tot, $nomini);
  10.             $nom = urldecode($nomini[1]);
  11.         }
  12.         $ruta_video = "videos/$nom.flv";
  13.         $url = "http://www.youtube.com/get_video?video_id=$video_id&t=$codi";
  14.        
  15.         $video = file_get_contents($url);
  16.        
  17.         $fp = fopen($ruta_video,'w');
  18.         fputs($fp,$video,strlen($video));
  19.         fclose($fp);
  20.        
  21.         return true;
  22.     }

El uso es bien sencillo:

Si sólo se le pasa la URL del vídeo, lo descargará en la carpeta videos/titulo del video en youtube.flv

PHP:
  1. descarga_video_youtube("http://www.youtube.com/watch?v=edZYah2CdLY")

Si le añadimos el segundo parámetro (nombre), nos guardará el vídeo en la carpeta videos/nombrequelehayamospuesto.flv

PHP:
  1. descarga_video_youtube("http://www.youtube.com/watch?v=edZYah2CdLY","nombrequelehayamospuesto")

¿que son pagerror.gif y refresh.gif? ¡solucionado!

Vaya, después de varios meses recopilando logs de errores 404 sin ningún tipo de sentido, hoy me he decidido a buscar cual era el motivo por el cual dos imágenes imaginarias (pagerror.gif y refresh.gif) aparecían en dichos logs de páginas no encontradas. Parece ser que el error solo se da en versiones de Internet Explorer 6. Tambien parece que dichas imágenes NO EXISTEN en mi servidor (ni en ninguno de las personas que se hayan encontrado con el problema), pues vaya... y entonces ¿porqué? ¡muy sencillo!.

Resulta que nuestro amigo de la infancia Internet Explorer 6 se resiste a ser como los demás (si, después de tantos años de andaduras el tío no ha madurado lo más mínimo) y cada vez que detecta un iframe sin el atributo src dentro de una página cargado mediante SSL (https://), se decide sin ningún tipo de pudor a cargar una página de error, la cual increíblemente carga las supuestas imágenes desde el servidor donde se ha cargado el iframe. Esto es ... una chapuza, yeah!

¿Solución? fácil, hagamos lo que hagamos que necesitemos un iframe vacío, tan solo tenemos que ponerle el siguiente atributo src:

HTML:
  1. <iframe src="javascript:false;" />

Yo (y mi ego) 1 - Internet Exploter 0

Más información en la keynote de microsoft

pagerror.gif refresh.gif

Configurar VirtualHost para tener varios dominios con su directorio cada uno en Apache

Esto me lo dejo aquí a modo de recordatorio para configurar el dichoso httpd.conf para poder tener varios sitios en local con su correspondiente dominio (local tambien).

Primero añadimos los dominios en el archivo hosts:

127.0.0.1 local.dominio-1.org
127.0.0.1 local.dominio-2.net

Y luego añadimos las siguiente líneas a nuestro querido httpd.conf:

CODE:
  1. NameVirtualHost  127.0.0.1
  2. <VirtualHost local.dominio-1.org>
  3.     ServerName    local.dominio-1.org
  4.     DocumentRoot    "D:/www/dominio-1.org/web/"
  5.     DirectoryIndex  index.php
  6.     AccessFileName  .htaccess
  7.     ErrorLog        "D:/www/dominio-1.org/logs/error.log"
  8.     LogLevel        warn
  9.     CustomLog      "D:/www/dominio-1.org/logs/access.log" combined
  10.     <Directory "D:/www/dominio-1.org/web/">
  11.         Options -Indexes FollowSymLinks
  12.         AllowOverride AuthConfig FileInfo
  13.         Order allow,deny
  14.         Allow from all
  15.     </Directory>
  16. </VirtualHost>
  17.  
  18. <VirtualHost local.dominio-2.net>
  19.     ServerName    local.dominio-2.net
  20.     DocumentRoot    "D:/www/dominio-2.net/web/"
  21.     DirectoryIndex  index.php
  22.     AccessFileName  .htaccess
  23.     ErrorLog        "D:/www/dominio-2.net/logs/error.log"
  24.     LogLevel        warn
  25.     CustomLog      "D:/www/dominio-2.net/logs/access.log" combined
  26.     <Directory "D:/www/dominio-2.net/web/">
  27.         Options -Indexes FollowSymLinks
  28.         AllowOverride AuthConfig FileInfo
  29.         Order allow,deny
  30.         Allow from all
  31.     </Directory>
  32. </VirtualHost>

Y listos! ideal para los que no se aclaran ni p'atrás (como yo :P).

NOTA: modificad las comillas “...” por las de SHIFT+2.
NOTA 2: Creo que nadie lo ha probado, ya que había un fallo en el paste y no se veía el código VirtualHost ...

Talleres subflash 2009

Talleres Subflash... eh yo estoy ahí­!

Un año más los talleres Subflash ya están de vuelta, con gran ilusión yo ya me he apuntado. Para los pocos visitantes de este blog que no conozcáis los talleres Subflash, tan solo os puedo comentar que son los talleres para profesionales del web más amenos, divertidos, familiares y altamente valorados por sus habituales (como un servidor).

Este año repetimos lugar en la Villa Universitaria de Alicante, las fechas son 28, 29 y 30 de Agosto (que cae de viernes a domingo), el precio es de 100€ modalidad completa (los 100€ mejor invertidos del año) y en el momento de escribir esta entrada quedan 26 plazas (de 50).

Si queréis más información no dudéis en visitar la página oficial de los talleres Subflash 2009 o en el post del blog de Subflash.

Ah, y gracias Marcos y a todo el equipo de Subflash por hacer posible estas minivacaciones profesionales.

Bookmarklet para detectar elementos HTML obsoletos

Basandome en una entrada de webintenta donde menciona una CSS para detectar los elementos y atributos obsoletos, propuestos como obsoletos o elementos vacíos, he montado este bookmarklet para cargar en cualquier página, ya que tan solo ejecutando el enlace de los favoritos, se ejecutará un script que cargará la CSS en la página donde nos encontremos.

Detectar elementos obsoletos

Más información de cómo colorea los elementos en la página del autor de la CSS diagnostics

Es divertido de usar, al menos para criticar un rato :^P

Correcto formato de formularios XHTML

Hace una semana mandé un correo a la lista de Ovillo preguntando cual creía la gente que era la forma más correcta de maquetar un formulario. Las respuestas fueron varias y estuvimos comentando cuales eran los pros y los contras de cada método utilizado.

Finalmente y después de mucho divagar e intentar acercar opiniones me llegó un correo de Daniel Navarro donde daba con una muy correcta solución, ya que a las fuentes se remitió y razón no le faltó (olé):

En un DTD estricto se especifica que dentro de un form sólo puede haber elementos de bloque (que no sean otros form). Así que entre los diferentes controles y el form debe de mediar un elemento de bloque como div o fieldset, por ejemplo. Esto te falta en la solución A. Además, obligas a saltos de línea con br y esto limita la flexibilidad de CSS.

Así que finalmente ganó la opción:

XML:
  1. <form>
  2.     <fieldset>
  3.         <div>
  4.             <label for="campo">Campo:</label>
  5.             <input id="campo" type="text" />
  6.         </div>
  7.         ... más aquí ...
  8.     </fieldset>
  9. </form>

Gracias a todos los que participasteis y me ayudasteis!

« Entradas anteriores

Get Adobe Flash playerPlugin by wpburn.com wordpress themes