Usar la tecla Alt en Photoshop con Linux

El único programa para el que no he encontrado un equivalente en GNU Linux es Adobe Photoshop. Sé que GIMP es un excelente programa pero yo no consigo hacerme con él y por eso uso Adobe Photoshop a través de WINE.

Funciona muy bien, esta gente de WINE son unos cracks, pero hay una pequeña cosa que me estaba irritando, una pequeña china en el zapato. En Photoshop se utiliza la tecla Alt como modificador de algunas herramientas; por ejemplo si tenemos seleccionada la lupa haciendo clic en la imagen la agrandamos y haciendo Alt – clic la reducimos. Sin embargo en Gnome la tecla Alt también se utiliza para mover una ventana pinchando sobre cualquier parte de ella, y esto es una gozada porque no hace falta mover el ratón hasta colocarlo exactamente en la barra de título, podemos mover la ventana pulsando Alt y moviéndola desde cualquier punto de la ventana.

Esto hace que si en Photoshop intentamos pulsar Alt y pinchar en una imagen esta no se reduce, el sistema operativo da preferencia a la acción de mover la ventana, y esto es un fastidio. Podría modificar las preferencias de GNOME y desasignar la tecla Alt del movimiento de la ventana, pero también llevo mucho tiempo usándola y no quiero cambiarla.

¿La solución? Pulsar primero la tecla de Windows y luego Alt. No estoy muy seguro de por qué funciona, pero es así. Aunque es un poco más engorroso porque nos obliga a pulsar una tecla más como las dos están pegadas realmente no es muy complicado de hacer, y recuperamos el modificador Alt para las herramientas de Photoshop.

Nota adicional: para incluir fuentes en Photoshop deberemos copiarlas a la carpeta .wine/drive_c/windows/Fonts de nuestro usuario y luego asegurarnos de reiniciar WINE mediante el comando

wineserver -k

Posicionar de forma absoluta elementos dentro de celdas en Firefox

Una nota rápida para no tirarme media hora en el futuro sufriendo por esto…

Firefox tiene un bug muy curioso: si intentamos posicionar elementos de forma absoluta dentro de una celda (ya sea una celda de tabla normal o un div con estilo display:table-cell) él amablemente nos enseña el dedo más largo de su peluda patita y los coloca con respecto al primer elemento de fuera de la tabla.

Para evitarlo hay que crear como primer hijo de la celda un div con posición relativa que ocupe todo el ancho y alto de la celda, y meter dentro de él los elementos que queramos posicionar de forma absoluta. Entonces sí funciona.

Redirigir al usuario y continuar trabajando en PHP

Hay veces en las que debemos realizar alguna tarea con PHP que lleva demasiado tiempo (convertir imágenes, videos, etc…). En estos casos no es elegante dejar esperando al usuario, es preferible redirigirle a una página donde se le informe de que se está llevando a cabo la tarea.

Una solución podría ser implementar un sistema de workers que realicen el trabajo; así nuestro script de PHP simplemente tendría que lanzar el trabajo y terminaría inmediatamente. Esta es la mejor solución porque los sistemas de workers permiten un escalado horizontal.

Pero hay ocasiones en las que por las características de nuestro proyecto no se pueden o no se quieren implementar estos workers. En estos casos nos bastará con redirigir al usuario a una página informativa y realizar el trabajo desde nuestro script de PHP.

Esta técnica la encontré, y está perfectamente documentada, en esta página, que podéis consultar para una explicación detallada. Aquí me limito a copiar el código:

    //Redirect to messageToUser.php
    header("Location: messageToUser.php");
    //Erase the output buffer
    ob_end_clean();
    //Tell the browser that the connection's closed
    header("Connection: close");

    //Ignore the user's abort (which we caused with the redirect).
    ignore_user_abort(true);

    //Extend time limit to 30 minutes
    set_time_limit(1800);
    //Extend memory limit to 10MB
    ini_set("memory_limit","10M");
    //Start output buffering again
    ob_start();

    //Tell the browser we're serious... there's really
    //nothing else to receive from this page.
    header("Content-Length: 0");

    //Send the output buffer and turn output buffering off.
    ob_end_flush();
    //Yes... flush again.
    flush();

    //Close the session.
    session_write_close();

    //Do some work

    //Then notify the user that it's finished

Actualización 14/09/2021: si usamos PHP-FPM hay una función que nos permite cerrar la conexión con el navegador y seguir haciendo lo que queramos en nuestro código, fastcgi_finish_request.

Enlaces en páginas web sin especificar protocolo

Últimamente he estado viendo en bastantes sitios que los enlaces a documentos externos se escriben sin especificar el protocolo. Es decir, en lugar de escribir

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

escribiríamos esto

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>

Así a bote pronto me ha chocado un poco, porque de toda la vida yo pensaba que era el http:// lo que distinguía a un enlace externo de uno que hacía referencia a un documento dentro del árbol de ficheros de nuestra página.

Pero por lo visto resulta que es el // lo que hace que el navegador interprete el enlace como externo, por lo que nos podemos ahorrar el http o https en la URL siempre que queramos que el enlace use el protocolo http y no otros como ftp, mailto, o tel.

Además tenemos una ventaja añadida si quitamos el protocolo: el navegador usará el protocolo que esté usando la página en la que está el enlace. Si hemos accedido a ella mediante http usará http, y si hemos accedido mediante https usará https. Esto significa que si estamos cargando un fichero con http (contenido no seguro) en una página cargada con https (contenido seguro) el navegador no protestará (que yo recuerde esto solamente lo hace Internet Explorer).

Actualización del 17/11/2015: no es solo Internet Explorer, otros navegadores también bloquean por ejemplo ficheros de JS cargados desde una URL no segura si se ha accedido a la página a través de una URL segura. Un motivo más para usar esta forma de escribir las URL.

Extensión Google Chrome para videos de YouTube que se cuelgan esperando a clickberry.tv

Antes de cambiar de ordenador utilizaba Ubuntu 12.10 32 bits y me pasaba una cosa muy extraña: en muchas páginas había incrustados videos de YouTube que no podía ver; el navegador Google Chrome se quedaba mostrando el mensaje “Esperando a clickberry.tv” durante un buen rato y finalmente mostraba un mensaje de error en el vídeo.

Al cambiar el ordenador e instalar Ubuntu 13.10 64 bits pensaba que el problema se solucionaría pero resulta que no, me sigue pasando lo mismo. Después de mucho buscar en Google no he encontrado ninguna solución, ni siquiera he podido encontrar referencias de que esto le pase a alguien más.

Como el problema era bastante molesto decidí investigar las extensiones de Chrome para intentar solucionar el asunto. Resulta que las extensiones son simplemente HTML, CSS y JS, así que resulta muy sencillo hacer una. Este es el código JS que soluciona el problema:

$(document).find("iframe").each(function()
{
	var src = $(this).attr("src");

	if (src.indexOf("youtube.com/embed") > -1)
	{
		var code = src.split("/embed/")[1].split("?")[0];
		var button = $(document.createElement("div"));
		button.addClass("button");
		button.html(chrome.i18n.getMessage("button_caption"));
		button.click(function()
		{
			window.open("http://www.youtube.com/watch?v=" + code);
		});
		button.insertBefore($(this));
	}
});

Realmente no soluciona el problema, el video incrustado sigue esperando a clickberry.tv, pero la extensión añade un botón encima que abre el video en la página de YouTube, donde se ve sin problemas.

La extensión está disponible de forma gratuita en la Chrome Web Store.

Cargar un programa al inicio con retardo

Es posible que alguna vez necesitemos que un programa se inicie al arrancar Ubuntu pero con cierto retardo, por ejemplo pasados dos minutos. Para eso tenemos que añadir el programa en la aplicación “Startup Applications”, pero en lugar de poner simplemente el nombre del ejecutable del programa pondremos esto:

bash -c "sleep 2m && /ruta/del/ejecutable"

Con el código del ejemplo (sleep 2m) retrasaremos dos minutos la ejecución del programa, si quisiéramos que fueran treinta segundos pondríamos sleep 30 (por defecto el argumento de sleep es en segundos).

Túnel SSH para acceder a máquina remota

Mi conexión a Internet no tiene IP fija, y eso supone a veces un problema. Hay veces que por motivos de seguridad el acceso a un servidor está restringido a ciertas direcciones IP y si no tengo IP fija no me la pueden autorizar.

En estos casos lo que hago es dar la dirección IP de algún servidor que tengo contratado (servidor intermedio) y que no tiene restricción de IPs; entro por SSH a mi servidor y desde ahí hago SSH al servidor final. Esto funciona bien, pero es un poco engorroso, así que es mejor utilizar un túnel SSH. Lo que hace el túnel es conectar un puerto de mi ordenador con el puerto 22 del servidor final a través del servidor intermedio. El comando para hacer esto es:

sudo ssh -Nf -L localhost:32:SERVIDOR_FINAL:22 USUARIO_INTERMEDIO@SERVIDOR_INTERMEDIO

Una vez hecho esto, conectando al puerto 32 de mi localhost estaré accediendo al puerto 22 del servidor final. Si, por ejemplo, quisiera subir un fichero a ese servidor, podría hacerlo con el comando scp:

scp -P 32 /home/koas/fichero.jpg USUARIO_FINAL@localhost:/home/www/fichero.jpg

Enviar paquetes UDP desde línea de comandos

Estoy haciendo un programa para poder hacer una consola tipo Firebug pero para código PHP, y la idea es que el PHP envíe datos a esa consola mediante UDP. He empezado a hacer el programa y para hacer pruebas rápidas del servidor necesitaba enviar paquetes UDP. La solución más sencilla es un programa que se llama sendip, que permite enviar paquetes de distintos tipos a cualquier destino.

Para instalarlo en Ubuntu:

sudo apt-get install sendip

Una vez instalado, el uso es muy sencillo:

sudo sendip -p ipv4 -p udp -is 192.168.0.199 -us 5000 -ud 1947 -d "Soy un paquete udp" localhost

Los parámetros son estos:

  • -p ipv4: le indica al programa que usaremos  ipV4.
  • -p udp: le indica al programa que usaremos UDP.
  • -is 192.168.0.199: es la dirección IP de origen del paquete.
  • -us 5000: puerto de origen.
  • -ud 1947: puerto de destino.
  • -d “Soy un paquete udp”: los datos a enviar.
  • localhost: el host al que enviaremos el paquete.

Minimizador de JS y CSS

En las páginas que están en producción es conveniente minimizar el código JavaScript y el CSS para que pesen menos y ayuden a que la velocidad de carga de la página sea rápida. Si bien los navegadores cachean estos ficheros y esto solamente se aplica a la primera carga siempre conviene que sea lo más rápida posible (además de reducir el ancho de banda que consumimos en nuestro servidor).

Hay muchos minimizadores de código JavaScript y de CSS, yo uso JavaScript Minifier simplemente porque tiene un enlace en la misma página a su minimizador de CSS, y hace todo el proceso más rápido.