Migrar Thunderbird de "mbox" a "IMAP" (III): ¡Migración!

Tras lo descrito en los artículos Migrar Thunderbird de "mbox" a "IMAP" (I): Consideraciones y Migrar Thunderbird de "mbox" a "IMAP" (II): Prueba de concepto tenemos la suficiente confianza en el sistema para decidirnos hacer la migración.

Lo primero que hay que decir es que en mis pruebas veo que, sin complicarme la vida, puedo mover al IMAP4 cuatro mensajes por segundo. Parece rápido, pero con un millón de mensajes necesitaré 70 horas ininterrumpidas. Es mucho tiempo, pero no es un problema siempre que pueda seguir usando el Thunderbird mientras tanto y siempre que pueda continuar la migración sin problemas en caso de fallo o de que apague el ordenador. Es decir, no importa el tiempo si puedo seguir trabajando con normalidad mientras tanto. Ese era el plan. ¡Qué equivocado estaba!.

Pero no adelantemos acontecimientos.

El primer paso de la migración consiste en replicar la estructura del árbol de carpetas de correo y mover todos los mensajes al servidor IMAP4. Debemos copiar la estructura y mover los datos, pero mantener la estructura original en su sitio. Con mil carpetas, esto no es trivial.

Mi primera idea fue escribirme un pequeño programa en Python que recorra las carpetas de correo mbox y transfiera su contenido a Dovecot a través de IMAP4. Este enfoque tiene varios inconvenientes:

  • Hay que escribirlo y depurarlo. Lleva tiempo y hay riesgo de perder correo.

  • Me interesa conservar todos los atributos de los mensajes: leído o no, respondido, se ha hecho forward, el mensaje tiene etiquetas, etc.

    El formato interno de Thunderbird está aceptablemente documentado, pero la gestión de estos flags en IMAP4 complica bastante el código: al mover los mensajes hay que limpiar las cabeceras propietarias de Thunderbird y luego hay que poner los flags correspondientes en el IMAP4. El mapeo de un lado a otro no está documentado y habría que hacer experimentos. Bugs, tiempo, riesgo...

  • Los mensajes movidos al IMAP4 hay que borrarlos de las carpetas de correo origen. Thunderbird no tiene un API para que programas externos interactúen con sus carpetas de correo (este es otro motivo para migrar a IMAP4). Esto nos deja dos alternativas:

    • El programa de migración debe funcionar con el Thunderbird cerrado. Cuando termina de mover una carpeta de correo a IMAP4 debe truncar el fichero mbox original o bien modificar las banderas de los mensajes para marcarlos como borrados.

      Cuando abrimos el Thunderbird detectará que sus ficheros de metadatos tienen una fecha anterior a la última modificación de las carpetas de correo y se reconstruirán con los mensajes borrados.

      Esto es simple pero requiere tener el Thunderbird cerrado mientras se hace la migración. Y la migración lleva días.

    • Otra posibilidad es que el programa de migración vaya guardando, por ejemplo, el hash o el Message-ID de los mensajes que se han movido al IMAP4. Podemos ejecutar el programa de migración varias veces, y que ignore los mensajes que ya ha movido. Esto nos permite seguir trabajando con el Thunderbird, pero hay muchas complicaciones con mensajes que cambian: un mensaje que se marca como leído, otro que se mueve a otra carpeta de correo...

      Podemos ser disciplinados y no tocar en el Thunderbird las carpetas que estamos moviendo en este momento. Pero resulta complejo. Frágil.

En resumen: elaborar un programa propio para migrar es complicado y nos obliga a dejar de usar el Thunderbird mientras dura la migración, que puede llevar días. O bien debemos tener mucho cuidado coordinando nuestro uso de Thunderbird con el proceso de migración. Es fácil meter la pata.

¿Qué más opciones tenemos?.

Mover los mensajes a mano es un dolor con mil carpetas de correo, pero es una opción a valorar si las carpetas grandes tardan varios minutos en ser transferidas. Dejando a un lado el riesgo de meter la pata, el tiempo de intervención manual es despreciable comparado con el tiempo de migración total. Pero hay dos problemas inesperados:

  • Cuando se mueve correo entre carpetas de correo "normales" y la cuenta IMAP4, los mensajes se copian en orden inverso. Es decir, primero los más recientes. No es raro que yo ordene los mensajes por orden de entrada en vez de por la fecha declarada en el correo, por diversos motivos. Con esto me lo ordenaría por orden inverso.

    Parece un bug de Thunderbird.

  • Cuando movemos correo entre carpetas de correo "normales" y la cuenta IMAP4... el correo no se mueve sino que se copia. Es decir, luego hay que ir a las carpetas de correo origen y borrar a mano el correo movido. Con cuidado de no borrar correo nuevo que haya podido entrar durante el proceso.

    No sé si decir que esto es un bug o una medida de seguridad y precaución de Thunderbird. En cualquier caso resulta muy inconveniente en el contexto que nos ocupa.

    Un inconveniente evidente es que lo que estamos guardando es una copia de los mensajes, así que atributos como respondido o forward se pierden.

  • Para mover un mensaje "de verdad" no podemos arrastrar toda la carpeta de correo, sino que debemos entrar dentro, seleccionar todos los mensajes y arrastrarlos manualmente. Pero esto nos obliga también a que la carpeta destino ya exista, lo que crea pasos manuales adicionales. Más oportunidades para meter la pata.

Hay una extensión muy interesante llamada Awesome Auto Archive que nos permite mover el correo de un lado a otro de forma muy configurable. Perfecto para lo que queremos [1]. ¡Y mueve los mensajes en orden de entrada!. Pero tarda mucho en arrancar y finalizar, y el Thunderbird muere 99% de las veces cuando se va a iniciar la copia. A veces consigo que avance algo jugando con la opción Age para intentar mover el correo poco a poco, aunque lleve más tiempo. Pero es un auténtico martirio. Me decido a probar otras opciones tras perder un par de días con esta extensión y echar pestes sobre ella [2].

Si funcionase bien sería perfecta para la tarea [3].

Luego comprobaré que los petes de Thunderbird se producen también con otras extensiones, así que tal vez el problema no sean las extensiones sino bugs en el propio Thunderbird. Llegar a esa conclusión me ha llevado varios días, mucha mala sangre, y ganarme el infierno eterno a base de blasfemias y pensamientos inconfesables.

[2] Incluso invertí algo de tiempo investigando el código fuente de Awesome Auto Archive para eliminar fuentes de lentitud que a mí no me afectan en este contexto, como la eliminación de duplicados. Pero Thunderbird seguía reventando de forma consistente, una y otra vez. Un puñetero infierno.
[3]

La única pega que le pongo a esta extensión, aparte de que Thunderbird reviente (posiblemente problema del propio Thunderbird, no de esta extensión), es que no crea en el destino carpetas de correo vacías. Es decir, si estamos moviendo un árbol de correo y hay carpetas que no tienen mensajes, no se recrean en el IMAP4.

No es mala cosa para una extensión pensada para archivar correo, pero en este caso me fastidia. Yo le añadiría una preferencia al respecto en la configuración.

Más posibilidades: Thunderbird tiene una opción de archivado de correo. Tiene buena pinta. Pero a) es manual, b) aunque permite mantener la estructura de carpetas de correo, como poco lo mete dentro de una carpeta anual (con el año en el nombre de la carpeta, vaya) y c) no mueve los mensajes no leídos o los que tienen tags. Investigando por ahí veo algunas extensiones de Thunderbird que nos pueden resultar útiles. Por ejemplo AutoarchiveReloaded. Esta extensión me permite archivar todos los mensajes (aunque no estén leídos, estén marcados con una estrella o tengan un tag), hacerlo en todas las carpetas poniendo una fecha límite (para poder migrar progresivamente) y aplicar estas reglas a todas las carpetas de correo de forma masiva, sin necesidad de seleccionar los mensajes uno a uno. Tiene muy buena pinta.

El archivado me permite guardar los archivos en otra cuenta. En este caso, en la cuenta IMAP4. Lamentablemente cuando intentamos mover las carpetas de correo IMAP4 a su posición correcta, nos sale un error de La carpeta ya existe. En cambio si lo hacemos desde las carpetas de correo tradicionales no hay problema. Pruebo entonces a archivar en los buzones normales y luego mover, año a año, al IMAP4 pero... Thunderbird muere durante el archivado. Como he comentado un poco más arriba no parece un problema de extensiones, parece un bug del propio Thunderbird.

Otra extensión a considerar es Copy Folder, pero no preserva respondido o forward aunque sí los tags.

Recapitulemos nuestra situación. Llevo tres días durmiendo poco y mal y con el ordenador encendido 24 horas. He migrado más o menos la mitad de mi correo electrónico con mucho sudor y lágrimas. Mucho. Las opciones de archivado nativas de Thunderbird son muy pobres [4] y aunque existen extensiones prometedoras lo cierto es que funcionan muy mal. Me paso más tiempo relanzando el Thunderbird tras un casque que moviendo mensajes de un lado a otro. Lo cual, por cierto, implica que la migración interfiere mucho con mi trabajo diario. Pero viendo que tengo el mismo problema, idéntico, con varias extensiones diferentes tengo la certeza de que en realidad el problema está en el propio Thunderbird.

[4]

Un programa debe funcionar bien pero, obviamente, no puede cubrir el 100% de las necesidades de todo el mundo. Lo que para alguien es imprescindible, otro usuario ni sabrá que existe. Así que en vez de hacer un programa inmenso con opciones muy usadas y otras que no se usan nunca (y esos dos conjuntos son diferentes para cada usuario) Mozilla promueve un ecosistema de extensiones que permiten que la comunidad vaya creando infinidad de extensiones útiles y que los usuarios instalen y empleen solo las que necesitan.

Esto tiene ventajas (dinamismo, flexibilidad) e inconvenientes (compatibilidad, calidad desigual, visibilidad) pero es un beneficio neto para todos.

Es de señalar que el plan original era bueno. Si no me hubiera tropezado con bugs inesperados este artículo hubiera sido mucho más corto y yo sería un hombre más feliz. Pero es importante recordar que estamos hablando de bugs, así que si algún lector necesita realizar una migración similar mi consejo es que también pruebe estos casos y estas extensiones. Puede ser que una actualización de las mismas o del propio Thunderbird conviertan el asunto en un paseo. Pero si te encuentras el camino de piedras que me he encontrado yo no pierdas más tiempo por ahí; no es un problema tuyo ni tus mensajes tienen nada raro. Aprovecha tu tiempo pensando otra estrategia si la herramienta presuntamente perfecta no funciona. No estás haciendo nada mal, te has tropezado con un bug ajeno.

Una habilidad valiosa es la capacidad de cortar pérdidas. En algún momento hay que dejar de invertir en un agujero negro. Aprovecha la experiencia que te brindo. Ya he invertido yo por ti :-(.

Por otra parte, si tienes menos carpetas de correo que yo o no dependes tanto como yo de los tags y demás banderas de los mensajes, posiblemente tengas una migración mucho más tranquila.

Ahora mismo la opción de desarrollar mi propia herramienta de migración en Python no parece tan mala idea, después de todo.

Miro por la ventana. Hace una tarde estupenda y tengo la playa al final de la calle. Algo falla en mis prioridades :-).

Actualización 20140915: Una vez que parece claro que tendremos que pasar de las extensiones de Thunderbird, uno de los primeros pasos será recrear en el IMAP4 la estructura de directorios que tenemos en los mbox de Thunderbird. Esto nos facilita mucho la vida.

Para ello ejecutamos el siguiente script:

$ find . -print | \
  grep "\.msf$" | \
  sed -e 's=\./==g' -e 's=\.sbd/=/=g' -e 's=\.msf$==g' | \
  sort | \
  grep -v "^\(ZFS\|ebay\|CouchSurfing\|hack\|ietf\|Illumos\|listas administratrivia\|Mozilla\|noticias2\|p2p\|p2p2\|Python ES\|Releases\|TOR\|torrents\|trekking\)$" | \
  while read -r nombre; \
    do \
      doveadm mailbox create "${nombre//\"/\\\"}" ;
    done 2>&1 | \
  grep -v already

Lanzamos el script en el directorio mbox de nuestro Thunderbird. Buscará las carpetas de correo (extensión *.msf) y normalizará el path entero de las mismas (por ejemplo, suprimiendo el *.sbd que indica subcarpetas en Thunderbird). Luego eliminamos una serie de nombres, que en mi caso son las Saved Searches. Esto tienes que ajustarlo a tu caso concreto. Hacemos la ordenación alfabética para estar seguros de crear primero las carpetas padre antes de intentar crear las hijas.

Por último iteramos sobre los nombres resultantes y creamos las carpetas en el IMAP4. Obsérvese el uso de la metasustitución que nos proporciona Bash para escapar las comillas que pueda haber en el nombre de la carpeta. El nombre en sí de la carpeta está en UTF-8. El comando de Dovecot ya se encarga de realizar la conversión al formato interno de IMAP4 (mUTF-7).

El grep final es para ver los errores. No interesan los errores que no se refieran a carpetas ya existentes. Tal y como está el script puede llamarse varias veces y que una carpeta ya exista no es problema. Pero no queremos perdernos ningún error sepultado en medio de mensajes de "la carpeta ya existe".

Actualización 20140920: Puedes leer la continuación de la historia en Migrar Thunderbird de "mbox" a "IMAP" (IV): Alimentando el IMAP4 y limpieza general.