Archivos para Uncategorized

ACL2::Procesador: nueva versión 1.187

Estos últimos días he estado dándole fuerte al teclado y he escrito el nuevo analizador Lisp, basado en el algoritmo del libro “Common Lisp: the Language”, tras descartar dos ramas con un analizador basado en Parse::Eyapp que producía árboles de referencias a listas Perl, y otro que producía árboles AST. Por supuesto, hay algunos cambios y simplificaciones, dado que no intento tener un entorno de ejecución de Lisp, sino simplemente de análisis del código. Por ejemplo, se preserva el espacio en blanco, y los comentarios de líneas (“; hola”) y de bloque (#| hola |#), aunque se pueden limpiar fácilmente. Es curioso saber que los comentarios de bloque en Lisp, a diferencia de los de C++, sí que se anidan.

De hecho, una vez implementado (un algoritmo recursivo descendente LL(1)), me sorprende lo flexible que es Lisp en algunos aspectos. Ya conocía la existencia de las macros de Lisp y en su momento las usé para crearme un pequeño marco de trabajo para definir reglas de un chatbot, en CLIPS, pero no sabía que había algo parecido a nivel léxico. También se conocen como macros, pero se tratan de caracteres especiales que invocan determinadas funciones, generando las estructuras apropiadas. Si uno ve el algoritmo base (sin macros), es curioso ver que sólo podríamos leer átomos (símbolos y números), aunque aún así, se pueden leer números enteros, flotantes, y racionales (fracciones exactas, como 22/9, sin pasar a coma flotante). Los famosos “(” y “)” que producen listas son, de hecho, macros, y también “;” (produce comentarios), “`” y “,” y demás. De todas formas, como el repertorio de carácteres disponibles para macros parece estar ya prefijado por el estándar Common Lisp, se suelen usar las dispatching macros para añadir extensiones, que consisten en secuencias de caracteres de la forma #nX, donde n es un número entero y X es un carácter que identifica la función a invocar..

Por ejemplo, está #|, que sirve para crear los comentarios en bloque, #=, que sirve para construir estructuras de datos en Lisp con múltiples referencias al mismo elemento (incluso referencias cíclicas), #nA (para obtener matrices multidimensionales), #( (para vectores), etc. Hay incluso macros para definir números en bases arbitrarias (incluyendo fracciones: ¿alguien quiere escribir una fracción en base 7?).

Evidentemente, no lo he implementado todo en ACL2::Lisp::Parser. El algoritmo principal está, incluso con los detalles del tratamiento de mayúsculas (el símbolo hola se entiende como HOLA, pero hol\a es HOLa, por ejemplo), pero la lectura de números en bases distintas a la decimal y la mayoría de las macros de # (excepto #|, que es muy común) no está hecha. Dicho módulo trae read_lisp_program (lee programas), read_lisp_token (lee elementos individuales) y try_read_lisp_token (intenta leer e informa de la localización en que se produce el fallo de análisis, si hay uno). Podía haberlo escrito con Parse::RecDescent, pero como vi que al final no me produciría una gran ventaja frente a escribirlo manualmente con el libro de Lisp por delante, lo descarté, para evitar añadirme una dependencia más.

En base a este código, he reescrito todas las partes que dependían de ACL2::AnalisisLisp en alguna medida, incluyendo el código que limpiaba la salida de ACL2, deshaciendo el ajuste de líneas en los párrafos de texto, y no tocando los párrafos que constituían expresiones Lisp. Antes había una expresión regular un tanto críptica que funcionaba en la mayoría de los casos, pero ahora el código de limpieza sabe cuándo algo puede ser código Lisp o no. El resto del código ha sufrido cambios parecidos. El mayor cambio externo es que ahora se incluyen los comentarios originales del código Lisp en la salida XML y se reproduce exactamente el código original, en vez de una versión “limpiada”. Como de costumbre, el cambio al analizador Lisp y la jerarquía de nodos del árbol de sintaxis abstracto ha sido un cambio más interno que externo, pero de todos modos será útil para seguir adelante y añadir nuevas funcionalidades.

Dejar un comentario

Versión 1.186 de ACL2::Procesador

Acabo de marcar en SVN y subir a la forja de Rediris la versión 1.186 de ACL2::Procesador. Aceptaron el artículo que enviamos mis antiguos directores de PFC y yo a ACL2 2009, así que es hora de darle un lavado de cara en algunos aspectos, aprovechando que estoy en vacaciones de Semana Santa :-D .

Las principales novedades que trae esta versión son básicamente:

  • Organización de órdenes en categorías: muchas órdenes repetían el mismo código una y otra vez. Este era sobre todo el caso de las órdenes que no producen prácticamente ninguna salida específica, como DEFPKG, DEFABBREV o DEFMACRO. Ahora lo que se hace es agrupar estas órdenes en categorías, para que compartan el mismo código. Con eso podré añadir más rápidamente órdenes de ACL2 que no sean tan usadas. Las órdenes que necesitan código específico se siguen usando directamente (como DEFUN, DEFTHM o ENCAPSULATE). De hecho, el orden actual para una orden X cualquiera es:
  1. Se intenta cargar el módulo ACL2::Orden::X, y analizar la orden mediante una instancia la clase contenida en dicho módulo.
  2. Si no funciona, se prueban en un orden prefijado todas las categorías, y se usa la primera que funcione. Actualmente, hay dos: DefinitionCategory (para las órdenes DEFXXX que no necesitan código especial) y FallbackCategory. La segunda categoría lo acepta todo, e imprime la salida de ACL2 como una lista de párrafos y S-expresiones, junto con el resumen debidamente procesado, si lo tenía. Su utilidad es para no fallar estrepitosamente ante órdenes de ACL2 aún no implementadas o código Lisp arbitrario (ACL2 es un entorno Lisp, al fin y al cabo). De todas formas, ACL2::Procesador sigue dando fallos fatales cuando no entiende algo en la salida de una orden para la que tiene código específico (de lo contrario, las pruebas de regresión serían inútiles).
  • Revisión del algoritmo de análisis de un fichero .lisp: ahora el grafo de dependencias es más sencillo, descartando los antiguos nodos que incluían a los ficheros .acl2 que servían para establecer el estado inicial de ACL2 antes de certificar un libro. Esto se debe a que ahora, cuando se procesa un fichero X.lisp y se encuentra un fichero X.acl2 o cert.acl2 en el mismo directorio, se usan los contenidos del primero de esos ficheros en vez del propio fichero X.lisp. Es ACL2 el que lee X.lisp y lo interpreta. De todas formas, ACL2 de hecho vuelve a volcar las fórmulas de X.lisp en la salida del evento CERTIFY-BOOK. Este nuevo esquema es más fiable de entrada, y además ahora le añadimos un prólogo y un epílogo a cada fichero .lisp procesado para asegurarnos de que funcione en más implementaciones de Lisp.

Esta versión ha sido probada con ACL2 2.9.4 bajo CLisp 2.44.1 (paquete Ubuntu 1:2.44.1-4ubuntu2), ACL2 3.0.1 bajo CMUCL (paquete Debian cmucl, versión 19a-release-20040728-9), ACL2 3.1 bajo CLisp, ACL2 3.2.1 bajo GCL (paquete Debian gcl 2.6.7-45), ACL2 3.3 bajo GCL, y ACL2 3.4 bajo GCL. Con eso tengo cubiertas varias implementaciones de Lisp y varias versiones de ACL2.

Para la siguiente versión, lo que quiero hacer es cambiar el “analizador” Lisp que tengo (me da vergüenza llamarlo así :-D ) por uno que implemente el algoritmo de la función read, tal y como viene en el libro  de “Common Lisp, the Language”, particularmente en las secciones 22.1 y 22.2. Tenía hecho una gramática LALR(1) tentativa en Parse::Eyapp (muy buen módulo para los fans de bison/flex o ANTLR) en una de mis ramas, pero va a ser que no: la sintaxis es demasiado compleja como para hacerla fácilmente :-/. Por ejemplo, ahora mismo el código no tiene forma de saber si algún trozo de código Lisp es una lista, un átomo, una cadena, y no entiende de comentarios de bloque. Puestos a parchear el código que hay, prefiero hacer algo en condiciones, que además sea capaz de reconocer correctamente programas Lisp no válidos tal y como lo hace ACL2 (o casi). Seguramente revise un poco el algoritmo, ya que a diferencia del algoritmo original, me interesa poder recuperar el código fuente original al 100%.

Dejar un comentario

KDE 4.2: nada, aún no

KDE 4.2 es supuestamente la primera versión de la serie KDE 4 que sí está dirigida al usuario final, tras una KDE 4.0 sólo para aventureros y una KDE 4.1 para “early adopters”. O eso dicen: yo no estoy tan seguro. Está claro que hay muchísimas ideas buenas detrás, y va a ser un gustazo cuando todo haya quedado fino, pero ahora mismo hay demasiados bugs aquí y allá. Por ejemplo, no conseguí de ninguna de las formas configurar mi pantalla dual, que fue tremendamente fácil en GNOME. Ni tirando de xrandr, ni con KRandRTray, ni poniendo manualmente la entrada Virtual en el xorg.conf, nada de nada.

También me dieron algunos quebraderos de cabeza los widgets: el del tiempo hizo que KDE se cerrara estrepitosamente, y el widget de monitorización del sistema no dejaba de salir por mucho que lo retirara.

Por último, Dragon Player no estaba del todo integrado con KDE, parece: en primer lugar, era incapaz de abrir vídeos que estuvieran bajo alguna carpeta de red. No me sorprende, pero si al final voy a trabajar como en GNOME, pues me quedo con GNOME, la verdad. Tuve otros problemas con las claves SSH y demás, pero éstos sí los pude resolver buscando un poco. Aun así, la verdad es que KDE 4 me está gustando mucho en términos de funcionalidad. Para KDE 4.4 o 4.5, creo que me cambiaré definitivamente :-D .

Dejar un comentario

“git add –interactive” en msysGit (Git bajo MinGW en Windows)

Recientemente tuve que trabajar con Git en Windows. Parece que la versión “oficial” por así decirlo es la compilada por Cygwin, pero no vi ningún binario por ahí para descargar. Instalarme Cygwin en la máquina virtual era demasiado, así que opté por msysGit, una versión de Git ejecutándose bajo MSYS.

MSYS es una implementación de un entorno POSIX minimalista sobre MinGW, un marco base que permite desarrollar programas para Windows sobre herramientas GNU. Es mucho más ligero que Cygwin, y los ejecutables generados no requieren del DLL usual de éste, que ocupa bastante.

La ventaja principal de msysGit es que en teoría consiste simplemente en seguir los pasos de un instalador. Sin embargo, no resulta tan fácil: no todo funciona directamente tras instalarlo. En particular, la terminal estilo bash que proporciona da bastantes problemas: acabé descartándola por la línea de órdenes usual de Windows XP (cmd). Sí, es horrible, pero por lo menos funciona.

Lo que realmente era vital para mí era “git add –interactive” (suelo ponerlo bajo el alias “git ai“): lo uso todo el tiempo, y me resulta realmente útil. git-gui será gráfico, pero es incomodísimo en comparación con él. Además, permite enviar al índice sólo parte de los cambios, dividir los cambios en partes más pequeñas, o incluso editar el cambio antes de pasarlo al índice. También uso mucho “git rebase –interactive” para limpiar mis commits, retirando los enfoques que he ido descartando y disimulando los errores que he cometido :-D .

Para que ambos funcionaran debidamente, tuve que instalar la última versión de less del proyecto GnuWin32, y la última versión oficial de Vim para Windows. Después cambié los nombres de less.exe y vim.exe del subdirectorio bin dentro del de Git a otros que no interfirieran, y puse los directorios en que estaban los binarios del nuevo less y Vim en la variable de entorno PATH.

Con esto quedó todo bien. El único pero es que sólo funciona si uso cmd, pero espero que los de msysGit afinen un poco más el asunto en futuras versiones.

Dejar un comentario

Generador de citas en formato BibTeX de estándares del W3C

Ahora mismo estoy escribiendo un artículo sobre XMLEye para intentar enviarlo al ACL2 Workshop 2009, y tuve que escribir a mano varias veces las entradas BibTeX para más de una tecnología del W3C que estaba utilizando. Las usuales, vamos: XML, XHTML, XPath, XSLT, etc. Los de la Collection of Computer Science Bibliographies (estilo DBLP) tienen un listado, pero no tienen un estilo uniforme.

Como me daba mucha pereza tener que hacerlo a mano, busqué un poco y encontré una web que aparentemente hacía justo lo que quería: transformaba este feed RDF oficial con las últimas y primeras versiones oficiales. Sin embargo, parece que sólo lo hacía cada cierto tiempo, y por ello algunas entradas se encontraban desactualizadas. Vaya hombre. Y además el código que utilizaba no estaba en ningún sitio, así que no podía repetir la transformación por mi cuenta.

Pero bueno, nada que wget y una hoja XSLT sencillita no arreglen. Me he hecho un sencillo guión Bash que descarga con wget la última versión del feed RDF (sólo si la copia local se encuentra desactualizada) y genera un .bib mediante una transformación con xsltproc. Nada muy complicado, pero bueno, me resuelve el problema perfectamente. El código fuente está en su repositorio Git bajo mi cuenta de Gitorious.

Ah, y por cierto: si os vale con una cita en formato XHTML, los del proyecto de automatización de publicaciones del W3C ya lo tienen hecho en condiciones.

Dejar un comentario

Linksys WRT54GL, SMC 7904WBRA2 y Tomato

Ayer mismo tuve que cambiar de equipamiento de red: desde que empecé a usar mldonkey y dejarlo 24/7, mi pobre USR9105 se bloqueaba cada dos por tres. Sospechaba del número de conexiones, pero ni poniendo el límite a 100 me servía. Probé a cambiar los parámetros de tiempos de espera del módulo de NAT del kernel (curiosamente, lleva una versión limitada de Busybox y usa un kernel Linux), pero tampoco tuve mucha suerte. Ni que decir que me traía bastante de los nervios.

Así que decidí cambiar de router, y puestos a ello, preferí cambiar a uno con cuyo firmware pudiera trastear: el Cisco-Linksys WRT54GL. Sé que hay otros routers ya que permiten utilizar firmware de terceras partes, pero éste tenía muy buenas críticas en general, y al fin y al cabo tiene a Cisco por detrás. Nadie fue despedido por comprar de IBM, dicen :-D .

El único “pero” es que el WRT54GL es un router neutro, con lo que necesitaría un módem ADSL con salida Ethernet, cosa de que no dispongo, y que parece más difícil de encontrar de lo que pensaba (por lo menos uno de calidad). Como no quería depender del USR9105, por si acaso, aproveché un SMC Barricade 7904WBRA2 que me enviaron los de Ya.com hace unas cuantas semanas.

La idea general es que el SMC hace sólo de módem y primer firewall (tiene desactivado todos los demás servicios, incluido la parte inalámbrica), utilizando una configuración de “falso monopuesto” por así decirlo: la IP fija del router Linksys es el único host en la DMZ, con lo que recibe todas las conexiones entrantes. Con un latiguillo del WAN del Linksys al switch del SMC y un poco de configuración todo quedó muy bien. El Linksys actúa como segundo firewall y es el que atiende a todas las máquinas de mi LAN.

Por supuesto, el firmware que traía el Linksys no estaba mal, pero no era del todo de mi agrado: de hecho, me gustaba más el de mi USR9105. Así que busqué un poco y encontré varias opciones: DD-WRT, Tomato, y un largo etcétera. De todas ellas miré un poco por encima y Tomato fue la que más me gustó de lejos:

  1. La documentación es muy buena: DD-WRT es el único que podría superarla.
  2. La interfaz de usuario es fantástica, y supera con creces todo lo que he conocido.
  3. Es más ligero que DD-WRT, pero tampoco anda corto en absoluto: además de todo lo que suele traer un router, incorpora muchas funcionalidades de monitorización y el QoS más fácil de configurar que he visto hasta ahora.
  4. Está basado en el código original de Linksys (se hallaba bajo la GPL), con lo que sé que partieron de algo sólido.
  5. Tiene un tomatito muy simpático :-D .

Por ejemplo, nada más instalarlo (aplauso para los de Linksys que sólo tuve que subir un fichero por la interfaz web y punto), pude darme cuenta del origen del problema en última instancia: mldonkey deja muchas conexiones olvidadas a medias, que no contabiliza para el límite de conexiones. Con la información de monitorización de Tomato y algo de prueba y error tengo controlado ese problema, y lo mejor es que de todas formas, si alguna vez se sale de madre, puedo cortar todas las conexiones inactivas con un simple clic.

Otro detalle más: la recepción de Wi-Fi en mi portátil era del 60-65% con el USR, y del 74% inicialmente con el Linksys. Tomato me dejó aumentar la potencia de la señal y ahora tengo un 80%, que no es moco de pavo :-) . Además, permite configurar de forma muy sencilla dnsmasq, que actúa como caché DNS y servidor DHCP: en un momento pude darle a mi servidor Debian una IP estática asignada por MAC y un nombre de host de acuerdo a su DNS dinámica. Ya tenía algo así en mi servidor Debian, pero esto queda mucho mejor (muerte a las IP estáticas :-D ).

En resumen: si el WRT54GL ya es buen hardware de por sí, Tomato lo hace aún mejor, y todo por el módico precio de 70€ (gastos de envío incluidos). Aún tengo que comprobar si aguanta una semana con esta carga de trabajo sin colgarse, pero por lo pronto me está causando muy buenas impresiones. Y sí, mi configuración de red es un poco rara: también tengo un puente de red (nivel 2 OSI) entre el servidor Debian y mi portátil, pero eso ya lo dejo para otro día :-D .

Comentarios (5)

Curso de Python en la OSLUCA

Esto llega ya tarde, pero mejor que nunca: en la Escuela Superior de Ingeniería de Cádiz realizamos el pasado 20 de noviembre un taller introductorio sobre Python. Preparé una serie de materiales con transparencias y código de ejemplo.

Las publico con licencia Creative Commons 3.0 BY-SA, por si alguien quiere las fuentes. Se puede acceder a ellas (y a los PDF resultantes) a través del curso de formación transversal que tenemos en el Campus Virtual de la UCA, que se halla abierto no sólo a nuestros alumnos, sino también a cualquier invitado, como debe ser. Se aceptan contribuciones, por supuesto :-) .

La gracia de estos apuntes es que todos los ejemplos (o casi todos) están probados mediante Python (usando docutils), y que el código LaTeX que los muestra en las transparencias y el entregable se genera con Python (Pygments).

Dejar un comentario

Recuperando un repositorio SVN desde un clon de git-svn

Hoy me vi en la necesidad de recuperar un repositorio SVN perdido a partir de un clon Git creado con git-svn. Miré y encontré cosas sobre cambiar la URL del repositorio, pero no me sirvieron de mucho: el problema es que sencillamente, el antiguo repositorio está kaput y punto.

Rebuscando y mezclando cosas de aquí y aquí, he conseguido una pequeña receta que puede que sirva a alguien. No recupera fechas y los autores sólo a medias, pero bueno, por lo menos recuperamos los datos de las revisiones en sí.

Supongamos que trabajo sólo sobre /tmp y que el clon creado con git-svn del repositorio SVN desparecido está en /tmp/original-git. Lo primero que tenemos que hacer es crear un nuevo repositorio SVN, con una única revisión con un fichero cualquiera, que tenga algún contenido (con un espacio sirve), para que git-svn lo pueda clonar y manejar bien. Para ello, ejecutaremos:

svnadmin create svn-recreado
svn co file:///tmp/svn-recreado recreado
cd recreado
echo " " > borra.me
svn add borra.me
svn ci -m "primera revisión"

Con esto ya tenemos la primera revisión con algún fichero no vacío. Esto es importante, ya que de lo contrario no podremos crear un clon con git-svn. Vamos a crear ese clon. Tal y como sugiere este enlace, necesitaremos la opción de configuración svn.addAuthorFrom si queremos conservar (aunque será en las descripciones y no en el nombre de usuario en sí) la autoría de cada revisión.,o hacer siempre “git svn dcommit –add-author-from”. Puestos a elegir, la primera opción evita despistes. Ejecutamos estas órdenes:

git config --global svn.addAuthorFrom true
git svn clone file:///tmp/svn-recreado recreado-git

Ya tenemos el repositorio SVN y su clon Git con la revisión inicial que necesitamos. Vamos a enviar las revisiones del antiguo repositorio SVN desde /tmp/original-git a /tmp/recreado-git:

cd /tmp/original-git
git push file:///tmp/recreado-git/.git master:refs/heads/old-svn

Con esto hemos empujado las revisiones de la rama principal del antiguo clon Git a una nueva rama llamada old-svn en recreado-git. Esta rama no guarda parentesco alguno con la rama master de recreado-git. Tendríamos algo así:

old-svn: A –> B –> C
master: D

Para que cuando hagamos “git svn dcommit” desde old-svn se envíen las revisiones A, B y C al repositorio SVN, se tienen que cumplir una serie de condiciones. La primera es retirar los git-svn-id de los mensajes de los commits (ya que hacen referencia a la antigua URL y números de revisión). Para eso tenemos git-filter-branch:

git filter-branch --msg-filter 'sed -e /^git-svn-id:/d' old-svn

Esto transforma todos los commits de la rama old-svn, cambiando el mensaje con un guión de sed (más información aquí). Lo que hace este filtro es, en las líneas que cumplen la expresión regular /^git-svn-id:/ (es decir, que empiezan por git-svn-id:) ejecutar la orden “d”, que efectivamente borra dicha línea.

Lo siguiente es crear el enlace D –> A entre las revisiones. Lo desconocía hasta hoy, pero Git permite hacerlo manualmente, utilizando el fichero .git/info/grafts, que consiste en una serie de líneas “<hijo> <padre1> <padre2>…” con los SHA1 correspondientes. Tendremos primero que averiguar los SHA-1 de la última revisión de la rama old-svn y master. Para eso, podemos utilizar git-rev-list:

echo `git rev-list old-svn | tail -1` `git rev-list master | tail -1` >> .git/info/grafts

Ahora, si ejecutamos:

git checkout old-svn
git log

Deberíamos de ver la primera revisión del nuevo repositorio SVN justo después de la primera de nuestro repositorio. Con esto hemos terminado las preparaciones. Cambiamos a la rama master, reunimos con old-svn y enviamos al repositorio SVN:

git checkout master
git merge old-svn
git svn dcommit

Una nota: es posible que se quede calado en mitad de una revisión, como un coche de segunda mano :-D . Con arrancar el proceso de nuevo y continuar el dcommit sirve:

git checkout -f old-svn
git rebase master
git checkout master
git merge old-svn
git svn dcommit

Dejar un comentario

PFC subido a la forja

He subido la documentación del PFC (fuentes y todo, que no falte) a la forja. Era lo único que quedaba pendiente, y me daba algo de remordimiento no tenerlo subido :-D . La documentación se halla bajo la GFDL, así que si alguien ve algún trocito de LaTeX o algún SVG útil, que no dude en cogerlo prestado :-) . Enlace a las fuentes y el PDF aquí.

Dejar un comentario

Experiencias con Canon LiDE 25

El otro día tuve que comprarme un escáner (cosas de la vida hoy en día y su insana afición a los papelajos), y estuve buscando modelos y modelos. De entre los que tenía mi tienda de confianza, estuve mirando y curiosamente el más barato (un Canon LiDE 25) es el que salió mejor parado con un soporte “bueno” (que no completo) por la gente de la base de datos de SANE.

Dicho y hecho, en cuanto llegué a casa sólo tuve que conectarlo por el cable USB y SANE lo reconoció sin más problemas. Acostumbrado a los problemas de mi antiguo (y tanto) Primax Colorado 1200p, la verdad es que fue una maravilla. Ya quisieran los de Windows tener una experiencia de instalación como esta: ni CD de instalación ni chorradas. Por supuesto, no gracias a Canon: resulta que este escáner utiliza el chipset Plustek, revendido por la compañía del mismo nombre a otras compañías, como Epson o HP.

Pero claro, me resultaba algo molesto tener que tirar de SANE o abrir el Gimp manualmente cada vez que quisiera usarlo, si tenía esos tres botoncitos de una sola pulsación. No me esperaba gran cosa, pero recibí una grata sorpresa cuando me enteré de que precisamente hay un proyecto para este tipo de cosas: scanbuttond es un demonio que se queda en segundo plano y pregunta varias veces por segundo mediante libusb por el estado de esos botones, y ejecuta un shell script cuando detecta una pulsación, pasándole el nombre del dispositivo y el número del botón.

En mi Ubuntu Hardy 8.04.1 tuve que instalar los paquetes scanbuttond, tiff2ps y netpbm y seguir las instrucciones (adaptando los guiones un poco) presentados en este howto de la gentuza de Gentoo, ¡y listo! Más o menos esto fueron los cambios que hice:

  • Quité de sbd-print.sh las opciones de scanimage específicas al escáner HP que tenía el autor del howto. Para ello, lo mejor es conseguir el nombre del dispositivo de nuestro escáner con “scanimage –list-devices”, y luego mirar con “scanimage –help -d <dispositivo>”.
  • Cambié el cliente de correo en sbd-mail.sh de Thunderbird a GNOME Evolution. Basta con esto: “sudo -u <usuario> evolution “mailto:foo@bar?attach=${TMPFILE}.jpeg”
  • Añadí la opción “-a” a la invocación de GIMP, con lo que la imagen escaneada se abre en una ventana nueva en vez de abrir otra instancia completa de GIMP. También fue útil añadir “&” al final para que se ejecutara en segundo plano (o si no, no podría escanear otra imagen hasta que cerrara esa instancia de GIMP).

Con eso ya bastaría, pero tendríamos que ejecutar nosotros scanbuttond en nuestra sesión de usuario. Lo cual tampoco está mal, pero prefiero que ese tipo de cosas queden como servicios y estén disponibles aunque no haya X. Así que me hice un guión chapucerillo de /etc/init.d a partir del de winbind (start es “scanbuttond” y stop es “killall scanbuttond”, en fin…), y pensaba que con eso estaría listo, pero no: resulta que, claro, de esa forma se intenta ejecutar Evolution y GIMP desde root, y root no tiene permiso para conectarse a las X. Tampoco quería dejar las X abiertas a cualquiera. En este artículo mencionan algunas alternativas, pero al final me decidí por añadir simplemente estas dos líneas antes del “case” de buttonpressed.sh:

export XAUTHORITY=~misuaurio/.Xauthority
export DISPLAY=":0.0"

Y con esto ya va sin más problemas: tengo así botones para fotocopiar, abrir en el GIMP y enviar por correo, que no está mal. Los resultados del escaneo tampoco son estelares, pero qué vas a pedir de un escáner de 50 euros :-D .

Actualización (27/5/09): sigue funcionando en Jaunty sin problemas. Empezó a hacerme ruidos y demás. lsusb lo mostraba, pero sane-find-scanner y scanimage -L no lo detectaban bien (sane-find-scanner decía que había un escáner, pero no sabía el modelo). Buscando un poco, encontré una orden a partir de la cual sacar bastante información:

sudo SANE_DEBUG_PLUSTEK=12 SANE_DEBUG_DLL=12 SANE_DEBUG_SANEI_USB=255 scanimage -L 2>&1 | tee salida.log | less

Mirando, encontré una línea del estilo de “sanei_usb_open: lisbusb complained: Broken pipe” cerca de donde libusb empezaba a sacar información en serio del escáner, una vez el backend plustek de SANE lo hubo detectado, y bastantes mensajes sobre ioctl y demás. Según parece, la forma más sencilla de interpretar este mensaje es un problema de conexión pura y dura. Sospechaba de mi hub/stand de portátil “made in china”, así que cambié el cable a uno de los puertos USB del portátil, y funciona perfectamente :-D .

Dejar un comentario

Entradas más antiguas »