Películas y series, tanda invierno 2023

Viene lento el ver películas, cuesta encontrarle tiempo, pero como del último post pasó más de medio año, se juntaron. Por otro lado, ¡casi no hay nuevas anotadas! Las series fluyen, sin embargo. Todo un signo de los tiempos que vivimos (?).

De series, entonces, tengo varias para recomendar. Sex Education me gustó mucho. What We Do in the Shadows tiene sus momentos y les tiene que gustar ese tipo de humor... la pueden disfrutar un montón. También me gustó mucho Killing Eve aunque no termina del todo bien. Si les gustan las series basadas en diálogos intensos (no aburridos) e inteligentes, prueben State of the Union, son muy cortitos los episodios y está muy bien..

The Man Who Fell to Earth me gustó muchísimo, pero creo que tienen que haber visto la película (que no es tan fácil de ver) o haber leido el libro, no sé cuan disfrutable es sin el contexto previo.

Me falta la última temporada de Marcella (policial británico bastante oscuro), y estoy arrancando Dead to Me. Con Moni estamos viendo Workin' Moms y también está para recomendar.

Series

Vamos con las películas vistas, entonces...

  • All Inclusive: +0. Una comedia liviana, quizás demasiado liviana, pero si buscan eso está bien.

  • Crimson Tide: +1. Esta la había visto hace mucho, pero no recordaba lo buena que está.

  • Doctor Strange in the Multiverse of Madness: +0. Mírenla si les gusta la saga en cuestión o les copa las de superhéroes.

  • Enola Holmes: +0. Una de detectives, interesante para ver con les chiques :)

  • Freaky: -0. Pensé que iba a tener más vueltas de tuerca sobre lo obvio, pero no.

  • Free Guy: +1. Mitad acción mitad comedia mitad ciencia ficción mitad nerd, muy divertida, me gustó montón.

  • G.O.R.A.: -1. No la pude ni terminar de ver :/

  • Morbius: -0. Nada nuevo bajo el sol.

  • Reminiscence: +0. Interesante a nivel de propuesta de ciencia ficción, se lleva bien, no tiene nada superespecial.

  • Sin rodeos: +0. Otra comedia liviana, muy divertida.

  • The French Dispatch: +0. Me gustó, pero si no les gusta las películas "raras", ni se acerquen.

  • The Game Changers: -0. En algún punto es interesante, pero no soporto la "metodología de documental" que usa...

  • The Midnight Sky: +0. Muy linda, pero muy lenta por partes. Es de esas "películas raras de Clooney", pero bien.

Free Guy

Mas peliculas anotadas para ver:

  • 血を吸う薔薇: (Drama, Terror) A fateful decision in 1960s China echoes across space and time to a group of scientists in the present, forcing them to face humanity's greatest threat. [David Benioff, D.B. Weiss, Alexander Woo]

  • Dune: Part Two: (2023; Acción, Aventura, Ciencia ficción) Sigue el viaje mítico de Paul Atreides mientras se une a Chani y los Fremen en una guerra de venganza contra los conspiradores que destruyeron a su familia. Al enfrentarse a una elección entre el amor de su vida y el destino del universo conocido, Paul se esfuerza por evitar un futuro terrible que solo él puede prever. [D: Denis Villeneuve, Toby Hefferman; A: Timothée Chalamet, Zendaya, Rebecca Ferguson, Josh Brolin, Austin Butler]

  • Everything Everywhere All at Once: (2022; Acción, Aventura, Ciencia ficción) Cuando una ruptura interdimensional altera la realidad, Evelyn, una inmigrante china en Estados Unidos, se ve envuelta en una aventura salvaje en la que sólo ella puede salvar el mundo. Perdida en los mundos infinitos del multiverso, esta heroína inesperada debe canalizar sus nuevos poderes para luchar contra los extraños y desconcertantes peligros del multiverso mientras el destino del mundo pende de un hilo. [D: Daniel Scheinert, Daniel Kwan; A: Michelle Yeoh, Ke Huy Quan, Stephanie Hsu, James Hong, Jamie Lee Curtis]

  • Indiana Jones and the Dial of Destiny: (2023; Aventura, Acción) Quinta entrega de la saga 'Indiana Jones'. [D: James Mangold; A: Harrison Ford, Phoebe Waller-Bridge, Antonio Banderas, John Rhys-Davies, Toby Jones]

  • Oppenheimer: (2023; Drama, Historia) Película sobre el físico J. Robert Oppenheimer y su papel como desarrollador de la bomba atómica. Basada en el libro 'American Prometheus: The Triumph and Tragedy of J. Robert Oppenheimer' de Kai Bird y Martin J. Sherwin. [D: Christopher Nolan, Richard Molloy; A: Cillian Murphy, Emily Blunt, Matt Damon, Robert Downey Jr., Florence Pugh]

  • Henry's Crime: (2010; Crimen, Comedia) Henry (Keanu Reeves) es un hombre apático y sin proyectos. Trabaja como empleado en una estación de peaje y está casado con una mujer encantadora pero muy frustrada (Judy Greer). Pero, cuando lo involucran erróneamente en el atraco a un banco y lo envían a la cárcel, un criminal (James Caan) conseguirá sacarlo de su letargo. [D: Malcolm Venville; A: Keanu Reeves, Vera Farmiga, James Caan, Judy Greer, Fisher Stevens]

  • The Creator: (2023; Ciencia ficción, Acción, Suspense) Thriller post-apocalíptico que involucra un futuro impactado por una guerra entre humanos e IA. [D: Gareth Edwards; A: John David Washington, Gemma Chan, Ken Watanabe, Sturgill Simpson, Madeleine Yuna Voyles]

Crimson Tide

Finalmente, el conteo de pendientes por fecha:

(Sep-2016)    1
(Feb-2017)   21   9   1
(Jun-2017)   21  18   5
(Dic-2017)   19  18  16   5   2   1
(May-2018)   22  22  22  17   9   2
(Sep-2018)       12  12  12  10   3   1
(Mar-2019)           13  13  13  12   2   1   1
(Ago-2019)               10  10  10   7   2   1
(Feb-2020)                    8   8   8   8   1
(Ago-2020)                        9   9   9   4
(Ene-2021)                            5   5   5   2
(Sep-2021)                                5   5   3
(Sep-2022)                                   20  19
(Jun-2023)                                        7
Total:       84  79  69  57  52  45  32  30  37  31
Comentarios Imprimir

Facilitar la instalación distribuida de sensores y actuadores

Uno de los proyectos que tenía anotado de hace rato para volver a jugar un poquito con electrónica era armar un framework para poder instalar sensores (y en un futuro) actuadores por ahí sin tener que preocuparme por cableado, juntar los datos, y varios detalles más.

El último par de semanas estuve trabajando en una especificación inicial para eso, la puse en el README del proyecto de Github donde voy a ir subiendo todo: Distributed Sensors and Actuators Framework.

El framework a grandes rasgos tiene tres tipos de nodos:

  • Manager: El nodo central con la interfaz administrativa para el operador humano y una API para exponer todo. Permitiría ver toda la data que mandan los sensores, poder interactuar con los mismos, etc.

  • Sensores y actuadores: Los nodos que generan y transmiten la info, o reciben data y actúan acordemente. Acá la idea es tener un hardware basado en ESP32 programado en Python.

  • Configurador: Es el nodo que configura los nodos distribuidos para que puedan conectarse al Manager. Se usa una sola vez por cada nodito distribuido para que se configure automáticamente.

La interacción entre los nodos

Vayan al proyecto para leer bien el detalle de a qué habilita el nodo central de administración, toda la funcionalidad de los nodos distribuidos y cómo trabaja el configurador, más gráficos, etc.

¡Se agradecen comentarios!

Comentarios Imprimir

Controlando más de un reproductor de música al mismo tiempo

Nunca usé (y en general no me gustan) esos teclados que tienen 450 botoncitos para 450 cosas distintas... subir y bajar el volumen, abrir un navegador web, pasar la aspiradora, etc. Mi teclado es bastante normalito.

Dicho eso, sí hay funcionalidades que quiero tener, y las obtengo con combinaciones de teclas. Las que más uso son CTRL más el + del teclado numérico para subir el volumen, CTRL más el - del teclado numérico para bajarlo, y CTRL+SHIFT más la barra espaciadora para play/pause.

Estoy muy acostumbrado a eso. Incluso cuando uso la laptop directamente (no enchufada a un monitor y a un teclado grande), y tengo botonitos especiales de subir y bajar el volumen, el play/pause es imprescindible.

¿Cómo lo obtengo? Paso a explicar el play/pause que es lo que me trajo una problemática a resolver. En la configuración del sistema agrego un acceso rápido personalizado para la combinación ctrl-shift-espacio, indicando que genere una llamada D-Bus con los siguientes parámetros:

  • Aplicación remota: org.mpris.MediaPlayer2.clementine

  • Objeto remoto: /org/mpris/MediaPlayer2

  • Función: org.mpris.MediaPlayer2.Player.PlayPause

Mi reproductor de música es Clementine. YMMV.

Clementine, mi reproductor de música preferido

Todo muy lindo, hasta que luego de una situación particular que no viene al caso quise empezar a escuchar Spotify en la compu. En mi primer experiencia al respecto, levanto Spotify, me pongo a escuchar música, y sigo laburando en la compu como si nada. De repente quiero poner pausa, tiro el Ctrl+Shift+Espacio... y nada, claro, porque eso disparó una señal a Clementine (que estaba cerrada).

Para que me funcione con Spotify tendría que configurar el acceso personalizado del sistema para que llame al destino org.mpris.MediaPlayer2.spotify, objeto /org/mpris/MediaPlayer2, función org.mpris.MediaPlayer2.Player.PlayPause.

Claro, eso me desconfigura el uso de Clementine.

No, no voy a configurar uno o el otro en función de que esté usando Clementine o Spotify. No, tampoco voy a tener dos hotkeys distintos. ¿La solución? Tener un duplicador/repetidor de llamadas, algo que ponga a correr en el sistema y que cuando le ejecute una función via D-Bus (al apretar Ctrl+Shift+Espacio) eso genere ambas dos llamadas a Clementine y Spotify.

Lo que uso para explorar otras músicas o escuchar algo raro

A priori no es algo demasiado complicado de hacer. Pero como corresponde, le pregunté "a internet" si ya había algo así hecho antes. Primero a Google, no encontré nada potable. Luego por Twitter, donde João me retrucó con la idea de preguntarle a ChatGPT.

A diferencia de otras ocasiones, tuve excelentes resultados en esta interacción con la famosa IA. Le pregunté como hacer el script, en qué paquete venía el módulo que usó y cómo poner ese script como demonio automáticamente.

Como es esperable del estado actual de esa inteligencia artificial, lo que me dijo no anduvo. Le estuve tirando de la cuerda un rato, y al mismo tiempo tratando de solucionar el problema yo. Logré un resultado que a priori funcionó y luego la IA me terminó sugiriendo algo con la misma estructura.

Pero este resultado funcional tenía un detalle que me hacía ruido: dependía de paquetes de GTK para el reactor. Le pedí que me diera algo que funcionara con un loop de asyncio (que está en la biblioteca estándar) y me pasó algo... que tampoco funcionaba (fallaba un import). Me sugirió que revise un par de paquetes pero tenía todo en regla. Finalmente me terminé fijando yo y le dije que en la documentación no hablaba para nada de ese módulo que ella decía. Ahí me cambió la historia y pasó a sugerirme una biblioteca totalmente distinta para comunicarme con dbus.

El código que me pasó para esta biblioteca... tampoco funcionaba. Estuve un rato pasándole errores que obtenía al ejecutar el código y haciendo los cambios que me ofrecía, hasta que obtuve un error que cuando se lo pasé a la IA me terminó indicando algo de la biblioteca que habíamos empezado (no esta que estábamos usando ahora).

Me cansé de seguir a la cosa esta que estaba pegando palazos en la oscuridad e invertí un rato para debuguear el código, y contrastándolo con el ejemplo de la página de la biblioteca (que por si solo tampoco funciona), terminé logrando algo que sí anduvo.

D-Bus no es d-bus

En este punto ya tenía un dbusreplicator.py que al ejecutarlo en una terminal me permitía hacer play/pause en Clementine y/o Spotify de forma transparente. Una hermosura.

Ahora a ponerlo para que arranque sólo cuando entro en la compu y que se re-inicie ante cualquier percance. Tenía las instrucciones de ChatGPT (la tercer imagen que enlacé arriba) que estaban casi bien... la idea de usar systemd y el .service que recomendó estaban bien, pero el gran detalle es que la aplicación tiene que correr en el espacio del usuario, así puede conectarse al D-Bus de la sesión del usuario (no del sistema).

En fin, fue un recorrido interesante, y ahora ya lo tengo laburando prolijito :). Dejé el programejo en Python, el archivo para systemd (y unas notitas al respecto) en esta carpeta.

Comentarios Imprimir

Toqueteando el teclado

El teclado es una de las mejores interfaces que tenemos con la computadora. Nos acompaña desde hace mucho más de medio siglo y fue cambiando mucho con el tiempo. Hoy en día mismo hay muchas variaciones, pero en general apenas pensamos en su complejidad: los enchufamos, apretamos las teclas y esperamos que las letras aparezcan en la pantalla.

Disclaimer 1: mucho de lo que diga en los próximos párrafos, pero no todo, dependerá de qué distribución de teclado tengas y cómo esté configurado, ya voy a ir marcando esos detalles.

También estamos acostumbrades a que hayan teclas con distintas funcionalidades. Las "letras" son directas (las apretamos y algo aparece), pero otras son modificadoras (el "shift", el "alt"). Hay teclas que parecen agregadas, como las de función que están un poco más arriba, o el teclado numérico de la derecha que incluso ni está en las laptops más pequeñas. Hay otras más raras incluso, como el "Break" o "Sys Rq" que tampoco usamos demasiado (o nada).

El teclado que uso en el escritorio

Pero, ¿cuál es el "recorrido" entre que apretamos una tecla y aparece una letra en nuestro editor de textos? Esto es lo que les voy a contar un poco por arriba, ya que tuve que aprenderlo para configurar mi teclado como yo quería. No es la idea entender toda la complejidad del sistema de entrada del teclado, pero sí lo necesario para poder configurarlo un poco.

Entendiendo las relaciones

Mi objetivo era poder meter caracteres de forma simple cuando estaba escribiendo. Claro, si quiero la "j" aprieto la j, si quiero la "L" aprieto SHIFT+l, si quiero una "é" aprieto ALTGR+e, o incluso si necesito un "¼" aprieto ALTGR+SHIFT+6. ¿Pero qué pasa si quiero un "∞" o un "🔥"? ¡No están! ¿Cómo las agrego?

Disclaimer 2: se pone más espesa la cosa acá; lo siguiente está basado en mi sistema operativo y entorno de escritorio (Kubuntu 22.04, con KDE Plasma 5.24, sobre X11); aunque creo que todos los sistemas "más o menos modernos" van a ser iguales o muy parecidos. Puede fallar.

En los ubuntus la parte de manejo del teclado bajo X11 está en /usr/share/X11/xkb/. Los símbolos que va a tirar cada tecla están bajo ese directorio en /symbols/ en un archivo que dependerá de tu distribución de teclado.

Yo tengo un teclado inglés internacional, así que el archivo que me interesa es el /usr/share/X11/xkb/symbols/us. Ahí dentro no todo es tan directo, ya que puede estar configurado de varias maneras, en distintas "variantes". Como les decía antes, yo uso English (intl., with AltGr dead keys), que en el archivo lleva el código altgr-intl. En esa sección encuentro la definición de cada tecla, como...

key <AC07> { [        j, J,           idiaeresis,   Idiaeresis      ] };
key <AB02> { [        x, X,           oe,           OE              ] };

...pero no todas, ya que aquí están solo las diferencias contra el mapa "base" (en realidad es una estructura de herencia en árbol); en este caso dice include "us(intl)", lo que indica que es el archivo us (el que ya estamos viendo), el mapa intl, y así siguiendo.

Entonces, cada línea de esas nos da una tecla. Entre los corchetes podemos tener dos o cuatro elementos. Los primeros/únicos dos indica qué carácter aparece cuando apretamos la tecla y cuando la apretamos con Shift, y si tenemos tercer y cuarto elemento es AltGr+tecla y Shift+AltGr+tecla. Para el primer caso del ejemplo mostrado, sería entonces:

TECLA:              j
SHIFT+TECLA:        J
ALTGR+TECLA:        ï
SHIFT+ALTGR+TECLA:  Ï

Vemos que a veces no se usan los caracteres en sí sino sus nombres; la conversión está definida en este archivo de las fuentes de X11: /usr/include/X11/keysymdef.h. También se puede usar el código Unicode directamente, arrancando con U (ej: U13BF).

Paréntesis. "AltGr" viene de /alternate graphic/, "alternativa gráfica". Cierro paréntesis.

Mi layout; azul para AltGr (verde si es compuesta)

Sigamos.

En el ejemplo que vimos es obvio que la tecla en cuestión es "la de la jota", ¿pero qué es ese código AC07 con que se define? Si arranca con A la segunda letra es la fila de teclas "comunes" de la parte principal de teclado, arrancando con A la primera fila de abajo, y la posición de la tecla arrancando de 1 a la izquierda. Entonces para nuestro teclado la AC es la tercer fila, la que arranca con la tecla a y si contamos para la derecha, la séptima AC07 es la j. Otros prefijos indican otras zonas: FK son las teclas de función, KP las del teclado numérico, y así. Y también hay teclas con nombre específico: TAB, CAPS, RTRN, etc.

Más paréntesis. Si miramos nuestro teclado vemos que la primera fila (la de abajo de todo, la de la barra espaciadora) no tiene "teclas comunes", entonces AA no tendría sentido... pero hay todo tipo de teclados, este por ejemplo nos muestra un caso con signos en esa fila. Hay de todo en este mundo. Nuevamente cierro paréntesis.

¿Pero cómo sabe el sistema que cuando apretamos físicamente una tecla de nuestro teclado esa es la quinta de la tercer fila? Ahí ya depende del tipo de teclado y cómo se lee su entrada. Podemos preguntarlo:

$ setxkbmap -query
rules:      evdev
model:      pc104
layout:     us
variant:    altgr-intl

Allí tenemos el layout con variante y todo (que ya mencioné arriba para llegar a la configuración del teclado), pero lo que quiero destacar es el rules, que en mi caso (y en la mayoría de los Linux modernos) es evdev, una interfaz de entrada que traduce los eventos de los drivers de los dispositivos y los pone a disposición de las capas superiores al kernel, como X.

Podemos leer fácilmente la entrada de estos eventos. Jugando, yo me hice un programita que muestra los códigos de cada tecla. Y luego encontré que hay una pequeña utilidad que también lo hace: showkey.

Si corremos cualquiera de los dos nos va a dar que "la tecla de la J" genera el código 36. Esto lo traducimos usando el archivo /usr/share/X11/xkb/keycodes/evdev donde vemos la correspondencia entre AC07 (el código para la línea de la J que vimos arriba) y el 44, que es 36 (que obtuvimos del teclado) más 8 (que es el mínimo que declara ese mismo archivo):

default xkb_keycodes "evdev" {
    minimum = 8;
    maximum = 255;
(...)
    <AC07> = 44;

Agregando un carácter

Hagamos ahora el recorrido útil, motivado por el deseo de tener una combinación de teclas que me escriba el símbolo del infinito.

La idea sería ponerlo en una tecla que no tenga carácter especial (para no pisar alguno potencialmente útil). Me decidí por SHIFT+ALTGR+M, que por default tiene al mismo mu que ALTGR+M.

Con el showkey veo que la tecla es la 50, y usando el archivo keycodes/evdev veo que 58 corresponde a AB07, lo cual tiene sentido porque la M es la séptima tecla en la segunda fila de mi teclado.

Yendo al symbols/us veo que la variante altgr-intl no define AB07. Vamos a su "ancestro", intl, y allí la encontramos:

key <AB07> { [         m,          M,            mu,               mu ] };

Reemplazo el cuarto valor por infinity (podría haber puesto U221E pero el nombre es más descriptivo):

key <AB07> { [         m,          M,            mu,         infinity ] };

Luego, para refrescar el uso de ese mapa (sin tener que reloguearme o reiniciar la máquina):

sudo setxkbmap us -variant altgr-intl

Y listo: .

Lo ideal sería poder tener el dibujo de los caracteres "extras" en el frente de cada tecla, como en mi añorada Commodore 128:

Pasado ¿y futuro? del diseño de teclas
Comentarios Imprimir

Dos releases: PyEmpaq y Runish

Estos días que tuve un poco más de tiempo libre le metí a redondear un par de proyectos.

En realidad fue terminar de cerrar el milestone de uno con features nuevos bastante complejos, e implementar desde cero el segundo (con una funcionalidad muy chiquita pero útil).

El primero es PyEmpaq, del cual ya les hablé en otro momento.

PyEmpaq es un simple pero poderoso empaquetador de Python para correr cualquier proyecto en cualquier lado con las dependencias que necesite mientras sean instalables en un entorno virtual.

Con PyEmpaq pueden convertir cualquier proyecto de Python en un archivo único .pyz, con todo el contenido del proyecto dentro.

Ese único archivo es todo lo que necesita ser distribuido. Cuando la usuaria final lo ejecute, se expandirá el proyecto original, sus dependencias se instalarán en un entorno virtual, y se correrá. Como no se necesitan permisos o privilegios especiales, todo puede correr en cualquier entorno.

Tanto el empaquetado como la ejecución son completamente multiplataformas. Esto significa que se puede empaquetar el proyecto en Linux, Windows, MacOS o donde sea, y correrá bien en Linux, Windows, MacOS o donde sea. El único requerimiento es tener Python instalado previamente.

¿Qué hay de nuevo en la versión 0.3.1? Principalmente...

  • Agregué opciones 'include' y 'exclude' en la configuración para tener el control completo del contenido del proyecto empaquetado.

  • Ahora se reusa el directorio del proyecto existente sólo si se completó satisfactoriamente en una instalación previa.

  • Soporta declarar una versión mínima de Python para correr el proyecto empaquetado.

  • Se expone el path del archivo .pyz al proyecto cuando se ejecuta.

Pueden hacer click en el logo para ir a la documentación completa...

PyEmpaq

El otro proyecto, que tenía anotado desde hace rato pero no le había tirado ni una línea de código es Runish.

Runish es una pequeñísima herramienta de línea de comando para encontrar caracteres Unicode o explicarlos (la pueden instalar desde PyPI).

Por ejemplo, si quieren un carácter que tenga un paraguas:

$ runish umbrella
☂  UMBRELLA
☔ UMBRELLA WITH RAIN DROPS
⛱  UMBRELLA ON GROUND
🌂 CLOSED UMBRELLA
🏖 BEACH WITH UMBRELLA

O si ven un carácter por ahí y no terminan de entenderlo o quieren su descripción exacta:

$ runish ☂
UMBRELLA

Cortito y al pie. O al dedo.

Comentarios Imprimir