Me encanta leer, leo constantemente. De hecho me encanta el olor del papel, y hay diferentes papeles que huelen distinto (de cómic, de libro de bolsillo, de libro con hojas estilo revista…) pero llega un momento en que, en tres mudanzas que he tenido que hacer en poco tiempo, las cajas de libros se convierten en un problema. También tengo montones de lecturas pendientes en artículos y blogs de internet, que se quedan colgando mucho tiempo. Llevo tiempo pensando, en mis ratos libres, cómo podría hacer para descargarlos y leerlos tranquilamente con o sin Internet, para sustituir esos libros (o al menos calmar ese gusanillo) unos días. El motivo de pensar en cómo leerlos sin Internet es sencillo: viajo un montón en tren, por mi condición personal (y a veces en avión, por trabajo). En el tren la conexión a Internet es más bien tirando a regulera, y me gusta leer tranquilamente sin la tensión de saber si se me va a ir o no la conexión.
En cualquier caso todo esto son excusas: quería un lector de bolsillo. Si vas a cualquier FNAC lo que te pondrán en destacados es un ebook de Amazon, que se que funciona muy bien y tal pero:
1) No estoy segura de si puede leer artículos como los que yo quiero leer con facilidad. Supongo que si, si los paso a PDF.
2) Me da igual la respuesta de 1, porque es de Amazon.
De nuevo, no me escondo, es un tipo de excusa porque llevo tiempo queriendo proponerme a mi misma diseñar un ebook yo misma. Ya hay algún que otro proyecto así , que he estado ojeando. Pero me gustan las cosas simples, o en cualquier caso las cosas que he hecho de cero, porque me cuesta menos de debuggearlas. Hace tiempo me compré la pantalla de e-ink de Pimoroni “inky What black and white” de 400×300 pixeles, pero no me había puesto a probarla aún. Este fin de semana he estado encerrada, así que he decidido ponerme manos a la obra y ver que podía hacer en un tiempo de “hackathon rápida”, es decir un finde más o menos. Tengo la suerte de que, como apasionada de electrónica (y profe de eso que soy) tengo varios rpi, tarjetas de memoria y cables variados. La mayor parte de mis cosas están ahora mismo en cajas de un trastero, pero conociéndome siempre tengo en el armario una mochila con lo esencial: mi soldador, protoboards, resistencias, cables, adaptadores, tarjetas, un par de nanos, algunos sensores y las raspis. Para este proyecto sólo necesitaba la pantalla, la raspi, cable hdmi, batería, tarjeta con el Debian y un teclado.
El hardware es bien sencillo, simplemente es colocar la pantalla en el GPIO e instalar la librería de Python para controlarlo(). Esto no tenía mucha más ciencia, mi objetivo real era aprovechar esa tecnología para diseñar un lector básico desde cero. Bueno, desde cero no: he reaprovechado un código que viene de ejemplo para ayudarme a mostrar texto por pantalla. El ejemplo de la librería básicamente tiene una lista de personas, elige una random de esa lista, busca alguna cita célebre y la muestra por pantalla. Lo que me interesaba reaprovechar de ese código era el proceso de mostrar texto por pantalla. Básicamente lo que hace el código es interpretar un pequeño texto y “dibujarlo” en el lienzo digital, esa era la complicación, cuadrarlo. Ya que estaba hecho, me ha facilitado un poco la vida. Una vez limpiado y habiéndome quedado sólo con la función que me interesaba, podía pasar a trabajar con la lógica. Me gustaría decir que he hecho lo que me enseñaron en la escuela técnica y es lo que debe hacerse, que es pintar un esquema de lo que hace el programa. Pero la verdad es que me quedaba ratos mirando al techo y pensando en trozos de código que poder debuggear poco a poco, así que no tengo más que el histórico del repositorio para demostrar esa sucesión de pasos. Espero poder explicarlo bien aquí.
Para empezar, los textos. Cada libro o lectura es un directorio diferente, dentro del cual hay varios archivos de texto numerados del 0 al 1 (que son las páginas), un archivo de configuración y un log de páginas. Los textos numerados se iteran en el programa principal, para mostrarlos como páginas; el archivo de configuración es algo inútil por el momento, pero que me parecía que podía ser necesario en el futuro, ya que tiene el número total de páginas, el nombre y el autor; el log de páginas sirve para guardar cuál ha sido la última página leída de una lectura, y no tener que volver a empezar cuando enciendes el lector.
El único inconveniente es separar un texto gordo en varios pequeños, por eso he creado un script que me ayude con eso. Es bastante mejorable, pero me ha ayudado para solventar el problema rápidamente sin quebrarme la cabeza:
Esto me ayudará a separar los artículos que me interesan en el formato necesario para mi lector, según la lógica que he pensado. No me odiéis por poner capturas y no el código, al final viene el repo con todo.
En el código principal, selecciono el nombre del libro a través de un argumento. Es decir al ejecutarlo se vería tal que:
# python3 ebook.py --colour black --book milibro
Que me facilitará la vida luego si quiero hacer un script en bash que colocar en cron para poder ejecutarlo fácilmente sin una pantalla HDMI.
Al comenzar, a parte de configurar cosas del lienzo digital, lo que hago es enterarme bien de qué libro he escogido y en qué página comenzamos.
Por otro lado, creo una variable booleana llamada “the_end” que por defecto es falsa. Esta variable no es nada más y nada menos que un guarrísimo pero efectivo “break”, que volveré verdadera cuando se acabe la lectura de un libro. En mi cabeza resuena lejana la voz de mi profesor de informática de bachillerato diciendo que no usemos esa lógica. Lo siento, Juanri.
Dentro del bucle dependiente de la variable “the_end”, básicamente hago todo lo demás: capturar la página del libro que toca, ir a la siguiente o a la anterior dependiendo de lo que se elija, y mostrar el número en si de la página en grisáceo y al final. Hay pequeños detalles que he ido mejorando según probaba lo que tenía, por ejemplo usar la capitalize() de Python para que al pasar hacia delante o ir hacia atrás, de igual si lo he escrito en minúscula. Dentro de la lógica de pasar páginas también he incluido el caso de estar en la página 0 y querer ir hacia atrás (que simplemente de deja en la misma página) o el pulsar un botón que no sea el de pasar hacia delante o hacia atrás (que tampoco hace nada). Todo esto no lo tenía en cuenta al principio, son cosas que he ido añadiendo haciendo pruebas de bruta durante la tarde, pero son pequeños detallitos que me ponen contenta.
Si la persona dice “ir hacia delante” lo único que hace es incrementar la página y guardarla en el log, mientras que si va hacia atrás, comprueba si es la página 0 (para no hacer nada) y si no, decrece la página y lo guarda en el log.
Es importante que al final de cada iteración se cree un lienzo digital nuevo, esto lo he descubierto porque al principio no lo hacía y el texto se superponía a cada iteración.
# drawing a new canvas
img = Image.new("P", (inky_display.WIDTH, inky_display.HEIGHT))
draw = ImageDraw.Draw(img)
Por otro lado he empezado a hacer el script que se supone que luego meteré en cron, que será el que posteriormente lance el programa sin necesidad de estar mirando a una segunda pantalla de debugging. Es sólo un boceto, pero representa un poco lo que quiero conseguir, que es un registro simple de cuatro libros numerados (como cuando en los teléfonos antiguos tenías un botón asignado para llamar rápido a algunos números) y lanzar el lector con el parámetro del libro seleccionado en el registro.
Esto debería ser suficiente para leer los artículos que quiero en un lector de bolsillo con una pantalla que no me haga mucho daño en los ojos. Lo mejor es que la pantalla en si no necesita mucha batería, de modo que basta con la propia carga de la rpi, que en mi caso recargo con energía solar usando una placa simple del Decathlon. Así que además, es renovable. En cualquier caso hay mil funciones que mi precario lector no tiene:
-
Selección de fuente.
-
Menú visible en el propio lector.
-
Crear notas.
-
Hacer bookmarks.
Y más. Además, depende de un teclado externo, que para facilitarme la vida puede ser un dispositivo bluetooth de estos que tienen forma de mando de juegos y tienen teclado. Pero realmente el código puede ir creciendo, y añadir todas esas funciones eventualmente. La idea de mi prueba era más bien recordarme a mi misma que se podía hacer, sin necesidad de un proyecto especialmente largo o complejo, si no más bien reciclando cosas y guarreando con Python. Vaya, lo que muchas hacemos en un fin de semana.
Al final del domingo tengo algo usable y funcional, aunque fuese precario, así que estoy bastante satisfecha. Para ir haciéndolo, iba implementando cosas poco a poco y guardando cada vez que funcionaba ese pequeño añadido. He tenido que sobreescribir algunas lógicas (por ejemplo, al principio iteraba teniendo en cuenta el número total de páginas, pero se me complicaba la estrategia cuando empecé a usar el log de página) pero el ir avanzando modularmente me ha hecho ir más rápida. Es mi estrategia, en general, para todos mis proyectos.
Repo del proyecto: https://git.sr.ht/~alienagain/RPIebook
Hilo en Mastodon del paso a paso: https://merveilles.town/@alien/108619328480377743
Muy buen artículo.
El problema que veo, es el precio de la pantalla, cuesta lo mismo que un Kindle básico con luz integrada.
El ecosistema del Kindle es muy cómodo para enviar artículos desde la Web, convertir Pdf… Para mi es imbatible.
Un saludo
Hey! gracias por comentar. Como comentaba en el artículo, no es una cuestión de dinero el por qué lo hago, si no por no usar la tecnología de Amazon para libros (y se que hay otras marcas, claro). Por varios motivos, pero para empezar por el DRM. Suponía que enviar artículos con un kindle es fácil! lo hacen todo muy fácil jajaja como todas las big tech.
Precisamente leía esta mañana en el propio aparatito un artículo muy chulo que habla tangencialmente del tema. https://newrepublic.com/article/155993/can-internet-survive-climate-change
Un saludo!
Mola el proyecto :)
Oh. Ver lo que uno puede llegar con sus propias manos a hacer es una gran fuente de inspiración. Gracias, gracias, gracias.