martes, 7 de diciembre de 2010

Adiós, Twitter

Martes, 7 de diciembre, 12h. Julian Assange se ha entregado a la policía británica esta mañana.

"Trending topics" del momento: trending

Adiós, Twitter. A tomar el pelo, a otro/a. Ya bastante nos lo toman en otros sitios.

13:16h - Actualización: parece que ya sale algo:

trending2

Actualización (enero de 2011): al final me he vuelto a crear una cuenta de Twitter. Soy un bocazas ;-)

jueves, 9 de septiembre de 2010

Autentificación con OAuth en Twitter utilizando oauthtwitter.py

Como venían anunciando desde hace algún tiempo, desde el 31 de agosto de 2010, Twitter ya no permite que las aplicaciones se autentifiquen utilizando "Basic Authentication" (mandar el usuario y contraseña en la petición http, resumiendo).

El método que debe utilizarse ahora es OAuth, una especie de estándar para que aplicaciones y clientes se autentifiquen sin proporcionar credenciales. Facebook, Linkedin, Twitter y otros servicios similares lo utilizan.

El caso es que un script que actualizaba periódicamente (programado como tarea cron) el "timeline" de una cuenta ya no funciona y hay que reescribirlo para que utilice OAuth.

En la página de Twitter recomiendan varias librerías para diferentes lenguajes, para Python mencionan, entre otras, oauth-python-twitter2.

Esta librería es muy fácil de utilizar y se adecúa perfectamente a mis necesidades. Para utilizarla debemos instalar los módulos oauth2 y simplejson. En mi equipo (corre Ubuntu) es tan fácil como esto:
$ sudo apt-get install python-simplejson
$ sudo easy_install oauth2

Una vez instalados, ya podemos utilizar la librería.

OAuth para "dummies" como yo


Voy a resumir mucho cómo funciona OAuth en Twitter.

Lo primero que tenemos que hacer es crear una aplicación cliente en Twitter. Al terminar se nos proporcionarán dos claves que debemos guardar como oro en paño: "Consumer key" y "Consumer secret".

Con este par de claves se solicita a Twitter un "request token", un valor temporal que utilizaremos para pedirle permiso al usuario de nuestra aplicación y que nos deje actuar en su cuenta.

El usuario otorga permiso a nuestra aplicación (aunque la aplicación esté asociada a nuestra cuenta, incluso debemos autorizarla para que acceda a nuestra cuenta) a través de una interfaz web. Si registramos nuestra aplicación como un servicio web, al autorizar el usuario a nuestra aplicación, llegarán a nuestro servicio web claves nuevas que serán permanentes (oauth token y oauth secret token).

Si la aplicación no la registramos como servicio web, sino como "Desktop", cuando el usuario aprueba nuestra aplicación, Twitter le da un "PIN" (como el del teléfono móvil) que deberá introducir en la aplicación "Desktop". Con este PIN, Twitter nos proporciona entonces los oauth token y oauth secret token.
Este último es mi caso, mi script, a todos los efectos, es como un cliente "Desktop".

Con estos oauth tokens que Twitter nos da cuando el usuario autoriza a nuestra aplicación, ya podemos interaccionar con la cuenta del usuario, ahora nuestra aplicación se autentificará en Twitter con las claves "consumer" y los "oauth token".

Utilizando oauth-python-twitter2


Antes de nada: hay un pequeño bug en el código del autor: hay que comentar la línea 82. También hay que tener instalados los módulos oauth2 y simplejson.

El primer script que prepararemos sólo lo utilizaremos una vez, para dar permiso a la aplicación que hemos creado que pueda actuar en nuestra cuenta. Está basado en el script que acompaña a la librería oauth-python-twitter2:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# autorizacion-usuario.py
from oauth import oauth
from oauthtwitter import OAuthApi
consumer_key = "LA CLAVE DE MI APLICACIÓN"
consumer_secret = "LA CLAVE SECRETA DE MI APLICACIÓN"
# Autenficación
twitter = OAuthApi(consumer_key, consumer_secret)
# Capturamos solicitud de autorización, primero credenciales temporales
temp_credentials = twitter.getRequestToken()
# Muestra la URL para que el usuario autorice a nuestra aplicación
print(twitter.getAuthorizationURL(temp_credentials))
# Capturamos el PIN y pedimos credenciales definitivas
oauth_verifier = raw_input('¿Cuál es el PIN? ')
access_token = twitter.getAccessToken(temp_credentials, oauth_verifier)
# Mostramos los token: estos ya no cambiarán
print("oauth_token: " + access_token['oauth_token'])
print("oauth_token_secret: " + access_token['oauth_token_secret'])

Una vez que lo hemos ejecutado, pegado en el navegador la URL para autorizar a la aplicación y proporcionado el PIN, tendremos unas credenciales permanentes (los oauth_token) para la cuenta de usuario. Vamos a utilizarlas:

#!/usr/bin/python
# -*- coding: utf-8 -*-
# actualizar-status.py
import sys
from oauth import oauth
from oauthtwitter import OAuthApi
consumer_key = "LA CLAVE DE MI APLICACIÓN"
consumer_secret = "LA CLAVE SECRETA DE MI APLICACIÓN"
oauth_token = "EL TOKEN QUE NOS DEVOLVIÓ EL SCRIPT ANTERIOR"
oauth_token_secret = "EL TOKEN QUE NOS DEVOLVIÓ EL SCRIPT ANTERIOR"
twitter = OAuthApi(consumer_key, consumer_secret, oauth_token, oauth_token_secret)
twitter.UpdateStatus("Esto es una prueba")

Hemos actualizado el "timeline" de la cuenta de usuario que autorizó nuestra aplicación. Sencillo a más no poder ;-)

P.S.: Al final he acabado utilizando en el trabajo, por cuestiones de compatibilidad, una librería en PHP: twitteroauth

jueves, 29 de julio de 2010

Monitorizar un Apache que se cuelga

Hay veces que tenemos problemas en un servidor de producción y tenemos que mantenerlo en pie sea como sea hasta que encontramos una solución.

Se me ocurrió que, si miraba en el log de apache y buscaba la cadena típica que deja el PHP (o lo que esté fastidiando) cuando se "estropea", podría automatizar el reinicio del servidor hasta que diese con el problema. En mi caso, el mod_php5 hacía que el Apache se muriese con un "segmentation fault".

Éste es mi sencillo "script":


LINEAS=20
TOPE=18
CADENA="exit signal Segmentation fault"
REINICIAR="service httpd restart"
FICHREPORTE="/root/resultadosReinicios.log"
FICHLOG="/var/log/httpd/error_log"
NUMLINEASCHUNGAS=`tail --lines=$LINEAS $FICHLOG | grep "$CADENA" | wc -l`

if [ $NUMLINEASCHUNGAS -gt $TOPE ]; then
$REINICIAR
echo `date` ": se ha reiniciado el apache." >> $FICHREPORTE
cat From: `hostname`
To: mi@direccion.correo
Subject: Acabo de reiniciar el Apache

Hola, soy el script que monitoriza el Apache de `hostname` y lo acabo de reiniciar.
EOF

fi


La finalidad de este script es poderte ir a dormir y al menos estar tranquilo durante la noche sin que el teléfono suene ;-)
En distros de la "familia Debian" se reiniciaría el Apache con un /etc/init.d/apache2 restart

martes, 11 de mayo de 2010

Tira nº 70: vídeos en el iPad


Por qué no me gusta el iPad

He podido curiosear un iPad un buen rato. Y no me gusta nada.
Mi impresión general es que es un cacharro que quiere hacer de todo y no consigue hacer nada del todo bien (con una excepción: el navegador Safari que trae es muy bueno):

  • Reproductor multimedia: como reproductor de música es muy grande. Como reproductor de vídeo, por diseño, es unipersonal (a menos que te guste tener una cabeza pegada a la tuya mientras ves un vídeo).

  • Lector de "ebooks": de serie no trae ninguna aplicación salvo el "Vista previa" para leer PDFs. No hay soporte para ePub ni otros formatos. No me dió tiempo a probar otros formatos como DOC o RTF (según la web del producto, sí que los soporta).
    La pantalla es retroiluminada y bastante brillante, algo incómoda para leer mucho tiempo seguido.

  • Consola de videojuegos: el motor gráfico está bien, pero nos ata a los 1024x768 del aparato. Sería comparable a una consola portátil "grandota".

  • Ordenador portátil: pese a la ausencia de teclado físico, se escribe con relativa comodidad, pero el aparato está muy "capado". No tenemos acceso claro al sistema de ficheros, no hay un gestor de archivos,... No tenemos las funciones típicas que esperamos en un ordenador.
    Todas las operaciones de gestión de archivos (cargar fotos externas, música,...) se tienen que hacer a través del programa iTunes instalado en un ordenador (o enviarte las fotos por correo y guardarlas desde ahí o procedimientos similares).

  • Para escribir correo electrónicos, navegar, mensajería instantánea, etc, basta y sobra, pero poco más. Si queremos instalar alguna aplicación, tenemos que pasar por la iTunes Store e instalar sólo las aplicaciones que Apple "bendice".

  • Expansión: no existe ninguna posibilidad. No hay lector de tarjetas de memoria, ni puertos USB, nada. ¿Quieres cargarle las fotos de tu cámara? Necesitas un PC.

  • Autonomía: mayor que la de muchos ordenadores portátiles (hasta 10h., se comenta) pero no es mucha, y más teniendo en cuenta una limitación muy grave: no se puede cargar enchufándolo a un puerto USB en muchos ordenadores porque no dan la potencia suficiente. Te tienes que llevar el cargador encima (es pequeñito, no pesa nada y muy mono, de color blanquito Apple).


En conclusión, ni chicha ni limonada. Demasiado grande para ser un dispositivo para Internet portátil (cualquier "smartphone" o iPod Touch es mucho más manejable( ni tiene las características necesarias para que sustituya a un netbook.

viernes, 16 de abril de 2010

Gasto de memoria en navegadores (otra vez)

Como ya viene siendo habitual, he hecho una comparativa no muy rigurosa de la memoria que consumen los navegadores.

  • 5 pestañas abiertas, dos de ellas con Flash

  • Mac OSX

  • Chrome 5.0.342.9

  • Chromium 4.0.303.0 (36742)

  • Safari 4.0.5

  • Firefox 3.6.3

  • Opera 10.10


Lo dicho, no es una comparativa rigurosa. Lo curioso de Chrome y Chromium es que, pese a consumir más memoria que el resto, dan la sensación subjetiva de ir bastante ligeros. Que cada pestaña y plugin corra en un proceso separado es la causa de las dos cosas: más memoria, sí, pero más "suelto" ;-)

chromium-chrome-ff-safari-opera

lunes, 5 de abril de 2010

Conversiones entre "encodings" sin pérdidas

Hace un tiempo comentaba los problemas que surgían cuando se trabaja con diferentes "encoding".
Lo más seguro hoy en día es trabajar con el mismo "encoding" en todas las capas y sistemas: bases de datos, ficheros php, plantillas html, ficheros js, configuración del servidor web, ...
Lo malo es que no siempre esto es posible. Muchas veces tenemos que integrar contenidos o hacer que dos sistemas diferentes interaccionen y cada uno puede estar configurado de diferente manera.
Para estas tareas de conversión, existen muchas herramientas y funciones. Por ejemplo, en PHP tenemos la función iconv(). Es muy sencilla de utilizar:
string iconv ( string $in_charset , string $out_charset , string $str )

El problema que surge a menudo es cuando estamos pasando de un encoding más "rico" (p. ej., UTF-8) a otro más restringido en caracteres (p. ej., ISO-8859-1). Si se aplica la función sin más, se nos puede cortar la cadena que estamos convirtiendo cuando se encuentra con un carácter extraño al "encoding" de destino (las famosas "comillas tipográficas" de los procesadores de texto, por ejemplo, dan muchos problemas).
Afortunadamente, la función iconv() está preparada para estos casos. Si se utiliza el parámetro $out_charset con la cadena //TRANSLIT, los caracteres problemáticos pueden ser convertidos a un carácter similar en el "encoding" final:
$txtFinal = iconv("UTF-8", "ISO-8859-1//TRANSLIT", $txtOriginal);

jueves, 18 de febrero de 2010