Gestiona tu mensajes y contactos de tu movil nokia

mensajes-nokia.tarEsta idea surgió cuando me tocó cambiar de móvil porque mi pequeño nokia n70 ya pedía el botijo.Por lo que ha pasado el pobre n70 y lo que ha aguantado… pero desde que se me cayó en un cachi de vodka naranja hace unos dos meses ya no ha vuelto a ser el mismo. Pobre móvil, en fin, la vida sigue y ahora tengo un nokia 5310 xpressmusic que es muy cuco.

Vayamos con el tema. El pobre n70 funcionar funciona, pero se bloquea, a veces se queda siempre iluminado (con lo que la batería dura apenas un día) y puesto que en ese teléfono tengo muchos mensajes que no quiero perder (en torno a dos mil) pues sería una tarea un poco suicida la de ir pasando de uno en uno los mensajes.

Busqué aplicaciones para exportar todos estos datos pero o bien no funcionaba en el n70 (symbian viejo) o daba error al leer mensajes de la memoria o… siempre había algún problema.

En un principió pensé en hacer un programa para leer los mensajes directamente del directorio Mail del móvil pero después de ver esos archivos pensé que acabaría antes descifrando todos los jeroglíficos de la pirámides de Egipto que en comprender cómo narices guarda los mensajes. Si alguien tiene documentación acerca de eso que me lo diga y entonces hago el programa en un plis plas (todos ganamos).

Al final me decidí por usar el malvado software de Nokia para exportar los mensajes y contactos a un archivo CSV. CSV es una manera de guardar datos que permite el parseo de un archivo de datos de manera muy sencilla, tanto que desde un script BASH conseguiremos procesarlo.

En el archivo de mensajes cada línea del archivo CSV corresponde a un mensaje y cada linea esta separa por un carácter delimitador. Quizás habrás deducido que simplemente con romper cada línea a partir de esos delimitadores es la solución.

Ahora tenemos los datos pero… ¿Qué hacemos con ellos? Pues muy fácil, si queremos tener los datos accesibles pues usaremos un SGBD (sistema gestor de bases de datos). Yo usaré mi favorito, MySQL (vaya ya tuvo que salir MySQL, para que sueño con él)

Lo que voy a hacer es que a partir de esos archivos CSV se genere una consulta SQL para insertar los datos en MySQL (uy cuantas siglas) y después tener control total sobre ellos y poder hacer las consultas que quiera sobre ellos (qué lujazo!).

Comencemos.

Paso 1: Usar el Nokia Pc Suite para exportar los mensajes y contactos (si nokia dijera como demonios guarda los mensajes o el protocolo de comunicación no haría falta pecar y usar un windows virtualizado para ésto ya no tengo tiempo de andar con ingeniería inversa)

Paso 2: Procesar los archivos.
El formato de estos archivos es:

sms;deliver,"nºEmisor";"no se";"no se";"fecha";"no se";"Contenido del mensaje";

sms indica que es sms
deliver es una palabra literal que aparece
nºEmisor es el número de quien te lo ha enviado
no se es que no se que guarda ese campo porque siempre esta vacío
fecha es la fecha en formato AAAA.MM.DD HH:MM
contenido del mensaje es el mensaje en sí

Y para un mms es algo ta que así

mms;"nºEmisor";"nºReceptor";"no se";"fecha";"no se";"Texto del mensaje";

Ya sabemos que tenemos lo datos, ahora vamos a ver cuales nos interesan.

Observamos que se nos facilita la labor de adivinar si es sms o mms porque al principio no los dice. El primer campo entonces nos vale. Además si es sms el formato es uno mientras que si es mms el formato cambia así que ya podemos ir haciéndonos un poco a la idea de como va a ser la lógica del programa (si es sms haz esto, si no haz lo otro).
A mi sólo me interesa el numero del emisor que lo usaremos para relacionarlo con el emisor (parece lógico pero hay que tener clara desde el principio las claves para relacionar tablas de la base de datos), la fecha y el contenido. Todo eso lo tengo así que adelante.

Ahora vamos a pensar qué consulta SQL queremos generar. En mi caso me decanto por introducir todos los datos con una sola consulta INSERT

INSERT INTO mensajes (numero,fecha,mensaje)
VALUES
(123456789,2009.05.05,'Hola tio que tal'),
(123456789,2009.05.06,'A que mola esto'),
(123456789,2009.05.07,'Ha llegado el cansinoo'),
...
(123456789,2009.12.05,'Ultimo mensaje');

Pero antes, tenemos que tener claro la estructura de la tabla:
Un identificador único como clave primaria, el número de telefono de tamaño 9, la fecha y el mensaje.

CREATE TABLE mensajes (
 id int(11) NOT NULL auto_increment,
 numero char(9) NOT NULL,
 fecha timestamp NOT NULL,
 mensaje varchar(1000) NOT NULL,
 CONSTRAINT mensajes_pk PRIMARY KEY (id)
)

Fíjate que el numero de teléfono lo trato como CHAR y no como INT. Es un error muy común pensar que un numero de teléfono es un número pero no lo es (¿Acaso vas a realizar operaciones matemáticas con ellos?). También funcionaria usando INT, pero seamos profesionales. Un char de tamaño 9 es muchisisisimo más rápido y fácil de manejar para un ordenador que un entero de tamaño 9 y nosotros queremos una base de datos eficiente, verdad? Para este caso no notaríamos la diferencia pero tener buenos hábitos nunca sobra. Aunque bueno, si tenemos decenas de miles de “amigos” y en vez de teléfono móvil tenemos un robot emisor de spam teléfonico pues sí notaríamos la velocidad de las consultas.

Ahora desde BASH a generar esa consultaza.  El script consistirá en usar cut para dividir la líneas.
No me pararé en todos los detalles, si quieres el script completo ve al final.
Abrimos el fichero y por cada línea comprobamos si es un sms o un mms

tipo=`echo $LINEA | cut -f 1 -d ";"`
 if [ "$tipo" == "sms" ]
then
    bla bla bla
else
   es un mms bla bla
fi

Pasamos la línea a cut. A cut le decimos que nos rompa la cadena usando el caracter ; (punto y coma) a través del parámetro -d “;” y que de esos trozos coja el primero -f 1
Después simplemente comprobamos si es sms. Un problema que me surgió es que los datos estan encapsulados bajo comillas. Me explico, el menaje “hola que tal tio” aparece tal y como lo he escrito, con las comillas y no hola que tal tio. Esto es lógico pero nos fastidia si el mensaje tiene dentro unas comillas. Por ejemplo en el mensaje: “hola que tal, he cogido la marca “huevera” porque la marca “cojonera” no estaba”. Una persona ve perfectamente que las comillas en la palabra huevera y cojonera son para especificar la marca y que forman parte del mensaje pero un ordenador pensará que el mensaje termina justo en las segundas comillas, antes de la palabra huevera, y al procesar el resto del texto no lo comprenderá y te lanzará un error. Esta explicación va directamente orientada a MySQL, que es quién al insertar los datos daría este error.

Para evitar ese problema hice una función que quita el primer y último caracter de cada dato. Lo que viene a hacer es una especie de trim a las comillas.

function trim()
{
    actual=$1
    tam=${#actual}
    let tam=$tam-2
    trimeado=${actual:1:$tam}
    echo "'$trimeado'"
}

En BASH, la variable $1 es el primer parámetro asi como $2 es el segundo hasta $9. Si queremos más de 9 parametros usaremos shift para “avanzar” y hacer que $8 valga $9 y así $9 obtiene el valor del siguiente parametro (pero perderíamos el de $1 así que cuidado).
Con ${#actual} obtenemos el tamaño de la cadena (como str_len de php, strlen de C o el metodo length de la clase string de java)
Lo que queremos hacer es eliminar el primer caracter del cual sabemos su posición (la posicion 1) y el último, que ahora ya sabemos su posición.
Al tamaño le restamos dos. No funciona como el un substr de php o java, que le indicas la posición y el tamaño. Aquí especificas el inicio y el fin, por eso hay que restarle dos a la posición final.
Y por último, devolvemos el string “trimeado” (haciendo uso de spanglish del cutre).

Cuando vayamos a generar una consulta SQL, encapsularemos entre comillas simples el string y así no nos darán problemas las comillas dobles.

Otro detalle que nos viene mal es que guada el prefijo de país. Lo de +34 para el caso de españa. Nosotros estamos usando 9 caracteres para identificar números así que vamos a eliminar esos prefijos y para ello usaremos sed con una expresión regular. En este caso la expresión regular es muy sencilla pero pueden ser extremadamente complejas y potentes. Nosotros sólo queremos quitar +NN de cada número (si lo hay).
Fácil, la expresión regular sería s/+[0-9][0-9]//g  por ejemplo. Una expresión regular va limitada por //. Lo que va fuera son por así decirlo parámetros. La “s” es para indicarle que busque. En este caso va a buscar un símbolo más + seguido por dos números. En caso de encontrarlo, lo sustituye por nada y la g del final es un hábito que tengo yo para evitar bucles infinitos pero para este caso no hace falta ya que hacemos sólo 1 reemplazo.

Bien, ya tenemos todas las herramientas. Dividir la cadena de texto, adaptar los datos… ahora vamos a juntarlo.
Para sacar el número de teléfono de un sms lo hacemos así:

trim “`echo $LINEA | cut -f 3 -d “;” | sed -e “s/+[0-9][0-9]//g”`”

Uff, que línea más fea, ¿verdad? Y cualquier signo (comilla, barra…) tiene que estar en esa posición o sino falla. Pero no es fea la línea, es bonita pero a su modo.
Primero se ejecuta el comando que está entre las comillas simples echo $LINEA | cut -f 3 -d “;” | sed -e “s/+[0-9][0-9]//g”
Eso envía a cut la línea, cut extrae el tercer elemento y luego con sed corregimos el número. Con este comando pasamos de tener:
sms;deliver;”+34655655655″;””;””;”2007.07.07 07:07″;””;”Mensajeeerl” a tener “655655655”. Luego eso lo pasamos como parámetro a la función trim para que nos deje 655655655.
Para obtener la fecha y el mensaje hacemos lo mismo, pero omitiendo la parte del sed que no es necesaria y cambiando la posición de cut (lo de -f)
La fecha la dejamos tal cual ya que MySQL la interpreta bien en ese formato.

Ya lo tenemos todo. Ahora solo queda crear la consulta y meterla en un archivo. Yo esto lo he hecho mediante echo variable >> archivo pero ahí cada uno elige.
Aquí el código completo, tiene algún detalle más como por ejemplo para meter los datos de archivo de origen y destino mediante parámetros y cosas así.

SCRIPT PARA GENERA LA CONSULTA SQL A PARTIR DEL CSV

#!/bin/bash

function trim()
{
   actual=$1
   tam=${#actual}
   let tam=$tam-2
   trimeado=${actual:1:$tam}
   echo "'$trimeado'"
}

if [ $# -lt 2 ]
then
   echo "Uso: ./$1 archivoOrigen.csv archivoDestino.sql";
else
  origen=$1
  destino=$2

  echo "INSERT INTO mensajes (numero,fecha,mensaje) VALUES " > $destino
  while read LINEA
  do
   tipo=`echo $LINEA | cut -f 1 -d ";"`
   echo "(" >> $destino
   if [ "$tipo" == "sms" ]
   then
      #La expresion regular del sed es para quitar el prefijo del pais
      trim "`echo $LINEA | cut -f 3 -d ";" | sed -e "s/+[0-9][0-9]//g"`" >> $destino
      echo "," >> $destino
      trim "`echo $LINEA | cut -f 6 -d ";"`" >> $destino
      echo "," >> $destino
      trim  "`echo $LINEA | cut -f 8 -d ";"`" >> $destino
   else
      trim "`echo $LINEA | cut -f 2 -d ";" | sed -e "s/+[0-9][0-9]//g"`" >> $destino
      echo "," >> $destino
      trim "`echo $LINEA | cut -f 5 -d ";"`" >> $destino
      echo "," >> $destino
      trim  "`echo $LINEA | cut -f 7 -d ";"`" >> $destino
   fi
  echo ")," >> $destino
  done < $origen
  cantidadLineas=`wc -l $destino |cut -d " " -f 1`
  let cantidadLineas=$cantidadLineas-1
  head -$cantidadLineas $destino > tmp.sql
  echo ");" >> tmp.sql
  rm $destino
  mv tmp.sql $destino
fi

El archivo lo adjunto tambien, junto al de los contactos.

Paso 3: La base de datos mola
Para interpretar el archivo de contactos seria hacer lo mismo. Yo uso esta tabla:

CREATE TABLE contactos (
       numero char(9) NOT NULL,
      nombre varchar(255) NOT NULL,
      PRIMARY KEY  (numero),
      UNIQUE KEY nombre (nombre)
)

Uso como clave primaria el número de teléfono (entiendo que solo puede haber una persona con un número) y como clave alternativa el nombre. Si una persona tiene varios teléfonos pues le pones un nombre diferente a cada teléfono (es mi modo de verlo).

Luego los datos se relacionan a través del número de teléfono. Ahora podemos hacer todas las consultas que queramos.
Por ejemplo, quiero ver los mensajes de un tal Juan no se qué:

SELECT * FROM contactos
JOIN mensajes USING (numero)
WHERE nombre LIKE 'Juan%'

Con eso nos apareceran todos los mensajes cuyo nombre de autor empiece por Juan (Juan, Juanito, Juan el de Palencia)
Quiero saber los mensajes que he recibido este último mes, pues algo tan fácil como

SELECT count(*) FROM mensajes
WHERE EXTRACT(YEAR_MONTH FROM fecha) = EXTRACT(YEAR_MONTH FROM NOW())

Las posibiliades son infinitas, puedes incluso buscar en el texto o lo que quieras (a ver qué gestor de mensajes es tan potente). El problema esta en saber SQL claro. Y si ya te sobra más tiempo pues puedes desarrollar tu propia interfaz en php (o java o el leguaje que te guste) y acceder desde ahí. Seguramente cuando me aburra haga una pero de momento no… que tengo muchas cosas que hacer. Aunque si alguien me dice como leer mensajes del telefono (ya sea por bluetooth o cable) pues me animaría bastante. Uh, podría ser el comienzo de un Nokia Pc suite libre? Habrá que seguir soñando.

Termino diciendo que el uso práctico que le puedas dar a estos script es nulo o acercándose bastante a nulo pero creo que a alguien sin mucho conocimiento de BASH le pueden ayudar estos códigos para sus chapucillas caseras.

Nos vemos!

ARCHIVO CON LOS SCRIPTS

mensajes-nokia.tar

You may also like...

3 Responses

  1. Ces dice:

    Se lo he pasado a un colega que entiende de estas cosas, igual hasta lo adapta a su necesidad :)

    Un saludo 😉

  2. Maxpowel dice:

    Agradeceré cualquier ayuda, y si necesita algo por aquí andaré

  3. juan dice:

    demasiado protocolo… algo mas facil -necesito un mejor programa que no sea pc suite!! que me facilite a guardar sms a la computadora!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *