sábado, 30 de abril de 2011

ebook vs papel (o 6 meses con un Kindle)

Tengo un libro electrónico (un Kindle 3) desde hace unos 6 meses, y le he dado un uso bastante intensivo. Llega el momento de sacar algunas conclusiones respecto al aparatito.

Generalmente se suelen poner ventajas de uno frente al otro, pero no me vale esta comparación, prefiero comparar según el tipo de lectura que estoy haciendo. Suelo leer tres tipos de libros: técnicos o manuales, novelas y libros de partituras (tipo Real Book).

Libros técnicos, manuales o "libros de texto"

Por mi profesión (desarrollador web) tengo que leer mucha documentación, aparte estoy estudiando una ingeniería en la UNED.
Decididamente, el libro electrónico no es cómodo para mí en este contexto. Aunque mi modelo permite hacer anotaciones, no hay nada como el subrayado con lápiz o las notas al margen tradicionales.
En un volumen de papel se ojea y rebusca con mucha facilidad y rapidez, con el "ebook" no me termino de apañar. He comprado alguno en formato electrónico y no me ha convencido, la verdad. También he intentado estudiar alguna asignatura en el "ebook" y no me siento cómodo, sigo muy aferrado a la costumbre de ir leyendo el libro, marcándolo y escribiendo en el cuaderno. A lo mejor es que ya estoy talludito ;-)

Novelas

En mi opinión, en este tipo de libros, el "ebook" tiene todas las de ganar. Puedes tener colecciones enteras en un cacharrito muy reducido, se lee muy bien, puedes poner marcadores en los pasajes más interesantes y en algunas plataformas (como la de Amazon), sincronizar el punto de lectura entre distintos dispositivos: aunque la pantalla del móvil no sea el dispositivo más idóneo para leer mucho rato, está muy bien poder retomar la lectura en la consulta del médico mientras esperas y seguir luego en casa donde lo dejaste en el móvil :)

Por supuesto, leer novelas en papel tiene su encanto y me gusta, pero el "ebook" es infinitamente más práctico ("El Conde de Montecristo" es un buen tocho para ir llevándolo a todas partes).





Partituras

Aquí si que me he llevado un buen chasco con el "ebook". Creía que podría prescindir al fin de los Real Book (son unos libracos de alrededor de 500 páginas), pero no puede ser: primero, mi "ebook" tiene la pantalla muy pequeña (6''), las notas casi no se ven -aunque en un modelo que tenga la pantalla más grande, tipo Kindle DX o iPad se ven bastante bien-; segundo, si ojear un libro técnico es lento, uno de partituras lo es más (suelen ser PDFs compuestos por imágenes, del orden de las decenas de megas).
Además, hacer una anotación rápida en un ensayo de un símbolo musical, cambiar notas, etc, es imposible (aunque esto ya lo sabía).

En este aspecto, tendré que seguir haciendo lo que hasta ahora: imprimir en hojas sueltas los temas que estoy montando si no quiero cargar con el volumen enterito.

Conclusión

En mi opinión, vamos a tener libros en papel mucho tiempo todavía... Es un soporte bastante fiable, duradero y fácilmente editable. Eso sí, los libros electrónicos para determinados tipos de lectura son una maravilla. A ver si las editoras se ponen las pilas, amplían catálogo y ponen precios razonables. Amazon está a la vuelta de la esquina y cada vez tiene más títulos en castellano a buen precio.





miércoles, 12 de enero de 2011

Fallos tontos con INSERT en SQL

El otro día tuve que arreglar un "bug" que yo mismo había causado. En un momento dado, se guardaba un valor en una tabla de N campos. Mi "query" era la siguiente:
INSERT INTO miTabla VALUES ('valor1', 'valor2', 'valor3');

En un momento dato, se hizo necesario añadir un campo más a esta tabla. Inocente de mí, pensé lo siguiente: "si añado el campo con un valor por defecto, no se estropeará ninguna "query", ya que, aunque la consulta no mencione el campo, éste ya tiene un valor por defecto".
Craso error.
La "query" anterior fallaba (estoy utilizando MySQL), ya que se encontraba con un campo más de lo esperado.
Conclusión: hay que escribir explícitamente todos los campos en los INSERT. Nunca se sabe qué cambiará.
INSERT INTO miTabla (campo1, campo2, campo3) VALUES ('valor1', 'valor2', 'valor3');

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